Re: [PATCH 1/1] OMAPDSS: Add sil9022 driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



HI,

	Tomi can you take a look at this one your are back

Best Regards,
J.
On 14:37 Tue 09 Jul     , Sathya Prakash M R wrote:
> From: Srinivas Pulukuru <srinivas.pulukuru@xxxxxx>
> 
> Add driver for SIL9022 DPI-to-HDMI chip.
> 
> Signed-off-by: Srinivas Pulukuru <srinivas.pulukuru@xxxxxx>
> [sathyap@xxxxxx: Ported the driver from 2.6.32 based internal
> kernel to v3.10 kernel]
> Signed-off-by: Sathya Prakash M R <sathyap@xxxxxx>
> ---
> This patch was tested using the legacy OMAP3630 based Zoom3 platform.
> There is no DT support for Zoom , hence board file changes
> made locally were used for validation purpose. 
> Further, DT support will be added for a newer SOC which uses
> the sil9022 HDMI interface chip.
> 
>  drivers/video/omap2/displays/Kconfig         |    8 +
>  drivers/video/omap2/displays/Makefile        |    1 +
>  drivers/video/omap2/displays/panel-sil9022.c | 1274 ++++++++++++++++++++++++++
>  drivers/video/omap2/displays/panel-sil9022.h |  527 +++++++++++
>  4 files changed, 1810 insertions(+)
>  create mode 100644 drivers/video/omap2/displays/panel-sil9022.c
>  create mode 100644 drivers/video/omap2/displays/panel-sil9022.h
> 
> diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
> index c3853c9..53d8bb7 100644
> --- a/drivers/video/omap2/displays/Kconfig
> +++ b/drivers/video/omap2/displays/Kconfig
> @@ -39,6 +39,14 @@ config PANEL_NEC_NL8048HL11_01B
>  		This NEC NL8048HL11-01B panel is TFT LCD
>  		used in the Zoom2/3/3630 sdp boards.
>  
> +config PANEL_SIL9022
> +	tristate "HDMI interface"
> +        depends on OMAP2_DSS_DPI
> +	depends on I2C
> +	help
> +		Driver for SIL9022 DPI-to-HDMI chip
> +		Driver uses i2c to read EDID information.
> +
>  config PANEL_PICODLP
>  	tristate "TI PICO DLP mini-projector"
>  	depends on OMAP2_DSS_DPI && I2C
> diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
> index 58a5176..34cfa8e 100644
> --- a/drivers/video/omap2/displays/Makefile
> +++ b/drivers/video/omap2/displays/Makefile
> @@ -3,6 +3,7 @@ obj-$(CONFIG_PANEL_TFP410) += panel-tfp410.o
>  obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
>  obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
>  obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
> +obj-$(CONFIG_PANEL_SIL9022) += panel-sil9022.o
>  
>  obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
>  obj-$(CONFIG_PANEL_PICODLP) +=  panel-picodlp.o
> diff --git a/drivers/video/omap2/displays/panel-sil9022.c b/drivers/video/omap2/displays/panel-sil9022.c
> new file mode 100644
> index 0000000..3b5cb17
> --- /dev/null
> +++ b/drivers/video/omap2/displays/panel-sil9022.c
> @@ -0,0 +1,1274 @@
> +/*
> + * drivers/video/omap2/panel-sil9022.c
> + *
> + * Copyright (C) 2009 Texas Instruments
> + *
> + * This file is licensed under the terms of the GNU General Public License
> + * version 2. This program is licensed "as is" without any warranty of any
> + * kind, whether express or implied.
> + *
> + * SIL9022 hdmi driver
> + * Owner: kiran Chitriki
> + *
> + */
> +
> +/***********************************/
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/errno.h>
> +#include <linux/string.h>
> +#include <linux/types.h>
> +#include <linux/slab.h>
> +#include <linux/io.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/i2c.h>
> +#include <linux/device.h>
> +#include <linux/delay.h>
> +#include <linux/gpio.h>
> +#include <linux/platform_device.h>
> +
> +#include <video/omapdss.h>
> +#include <video/omap-panel-data.h>
> +#include "panel-sil9022.h"
> +
> +u16 current_descriptor_addrs;
> +
> +static struct i2c_client *sil9022_client;
> +
> +static struct omap_video_timings omap_dss_hdmi_timings = {
> +	.x_res          = HDMI_XRES,
> +	.y_res          = HDMI_YRES,
> +	.pixel_clock    = HDMI_PIXCLOCK_MAX,
> +	.hfp            = 110,
> +	.hbp            = 220,
> +	.hsw            = 40,
> +	.vfp            = 5,
> +	.vbp            = 20,
> +	.vsw            = 5,
> +	.vsync_level	= OMAPDSS_SIG_ACTIVE_LOW,
> +	.hsync_level	= OMAPDSS_SIG_ACTIVE_LOW,
> +	.data_pclk_edge	= OMAPDSS_DRIVE_SIG_RISING_EDGE,
> +	.de_level	= OMAPDSS_SIG_ACTIVE_HIGH,
> +	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
> +};
> +
> +static struct hdmi_reg_data  hdmi_tpi_audio_config_data[] = {
> +	/* Transmitter is brought to Full operation when value of power
> +	 * state register is 0x0 */
> +	{ HDMI_TPI_POWER_STATE_CTRL_REG, TPI_AVI_POWER_STATE_D0		 },
> +	/* TMDS output lines active. bit 3 1:TMDS inactive, 0: TMDS active */
> +	{ HDMI_SYS_CTRL_DATA_REG,  0x01					 },
> +	/*HDCP Enable - Disable */
> +	{ HDMI_TPI_HDCP_CONTROLDATA_REG, 0				 },
> +	/* I2S mode , Mute Enabled , PCM */
> +	{ HDMI_TPI_AUDIO_CONFIG_BYTE2_REG, TPI_AUDIO_INTERFACE_I2S |
> +					    TPI_AUDIO_MUTE_ENABLE |
> +					    TPI_AUDIO_CODING_PCM	 },
> +	/* I2S Input configuration register */
> +	{ HDMI_TPI_I2S_INPUT_CONFIG_REG, TPI_I2S_SCK_EDGE_RISING |
> +					TPI_I2S_MCLK_MULTIPLIER_256 |
> +					TPI_I2S_WS_POLARITY_HIGH |
> +					TPI_I2S_SD_JUSTIFY_LEFT |
> +					TPI_I2S_SD_DIRECTION_MSB_FIRST |
> +					TPI_I2S_FIRST_BIT_SHIFT_YES	 },
> +	/* I2S Enable ad Mapping Register */
> +	{ HDMI_TPI_I2S_ENABLE_MAPPING_REG, TPI_I2S_SD_CHANNEL_ENABLE |
> +					    TPI_I2S_SD_FIFO_0 |
> +					    TPI_I2S_DOWNSAMPLE_DISABLE |
> +					    TPI_I2S_LF_RT_SWAP_NO |
> +					    TPI_I2S_SD_CONFIG_SELECT_SD0 },
> +	{ HDMI_TPI_I2S_ENABLE_MAPPING_REG, TPI_I2S_SD_CHANNEL_DISABLE |
> +					    TPI_I2S_SD_FIFO_1 |
> +					    TPI_I2S_DOWNSAMPLE_DISABLE |
> +					    TPI_I2S_LF_RT_SWAP_NO |
> +					    TPI_I2S_SD_CONFIG_SELECT_SD1 },
> +	{ HDMI_TPI_I2S_ENABLE_MAPPING_REG, TPI_I2S_SD_CHANNEL_DISABLE |
> +					    TPI_I2S_SD_FIFO_2 |
> +					    TPI_I2S_DOWNSAMPLE_DISABLE |
> +					    TPI_I2S_LF_RT_SWAP_NO |
> +					    TPI_I2S_SD_CONFIG_SELECT_SD2 },
> +	{ HDMI_TPI_I2S_ENABLE_MAPPING_REG, TPI_I2S_SD_CHANNEL_DISABLE |
> +					    TPI_I2S_SD_FIFO_3 |
> +					    TPI_I2S_DOWNSAMPLE_DISABLE |
> +					    TPI_I2S_LF_RT_SWAP_NO |
> +					    TPI_I2S_SD_CONFIG_SELECT_SD3 },
> +	{ HDMI_TPI_AUDIO_CONFIG_BYTE3_REG, TPI_AUDIO_SAMPLE_SIZE_16 |
> +					     TPI_AUDIO_FREQ_44KHZ |
> +					     TPI_AUDIO_2_CHANNEL	 },
> +	/* Speaker Configuration  refer CEA Specification*/
> +	{ HDMI_TPI_AUDIO_CONFIG_BYTE4_REG, (0x0 << 0)},
> +	/* Stream Header Settings */
> +	{ HDMI_TPI_I2S_STRM_HDR_0_REG, I2S_CHAN_STATUS_MODE		 },
> +	{ HDMI_TPI_I2S_STRM_HDR_1_REG, I2S_CHAN_STATUS_CAT_CODE	},
> +	{ HDMI_TPI_I2S_STRM_HDR_2_REG, I2S_CHAN_SOURCE_CHANNEL_NUM	 },
> +	{ HDMI_TPI_I2S_STRM_HDR_3_REG, I2S_CHAN_ACCURACY_N_44_SAMPLING_FS },
> +	{ HDMI_TPI_I2S_STRM_HDR_4_REG, I2S_CHAN_ORIGIN_FS_N_SAMP_LENGTH  },
> +	/*     Infoframe data Select  */
> +	{ HDMI_CPI_MISC_IF_SELECT_REG, HDMI_INFOFRAME_TX_ENABLE |
> +					HDMI_INFOFRAME_TX_REPEAT |
> +					HDMI_AUDIO_INFOFRAME		 },
> +};
> +
> +static u8 misc_audio_info_frame_data[] = {
> +	MISC_INFOFRAME_TYPE | MISC_INFOFRAME_ALWAYS_SET,
> +	MISC_INFOFRAME_VERSION,
> +	MISC_INFOFRAME_LENGTH,
> +	0,				/* Checksum byte*/
> +	HDMI_SH_PCM | HDMI_SH_TWO_CHANNELS,
> +	HDMI_SH_44KHz | HDMI_SH_16BIT,	/* 44.1 KHz*/
> +	0x0,   /* Default 0*/
> +	HDMI_SH_SPKR_FLFR,
> +	HDMI_SH_0dB_ATUN | 0x1,		/* 0 dB  Attenuation*/
> +	0x0,
> +	0x0,
> +	0x0,
> +	0x0,
> +	0x0
> +};
> +
> +static u8 avi_info_frame_data[] = {
> +	0x00,
> +	0x00,
> +	0xA8,
> +	0x00,
> +	0x04,
> +	0x00,
> +	0x00,
> +	0x00,
> +	0x00,
> +	0x00,
> +	0x00,
> +	0x00,
> +	0x00,
> +	0x00
> +};
> +
> +void get_horz_vert_timing_info(u8 *edid)
> +{
> +	/*HORIZONTAL FRONT PORCH */
> +	omap_dss_hdmi_timings.hfp = edid[current_descriptor_addrs + 8];
> +	/*HORIZONTAL SYNC WIDTH */
> +	omap_dss_hdmi_timings.hsw = edid[current_descriptor_addrs + 9];
> +	/*HORIZONTAL BACK PORCH */
> +	omap_dss_hdmi_timings.hbp = (((edid[current_descriptor_addrs + 4]
> +					  & 0x0F) << 8) |
> +					edid[current_descriptor_addrs + 3]) -
> +		(omap_dss_hdmi_timings.hfp + omap_dss_hdmi_timings.hsw);
> +	/*VERTICAL FRONT PORCH */
> +	omap_dss_hdmi_timings.vfp = ((edid[current_descriptor_addrs + 10] &
> +				       0xF0) >> 4);
> +	/*VERTICAL SYNC WIDTH */
> +	omap_dss_hdmi_timings.vsw = (edid[current_descriptor_addrs + 10] &
> +				      0x0F);
> +	/*VERTICAL BACK PORCH */
> +	omap_dss_hdmi_timings.vbp = (((edid[current_descriptor_addrs + 7] &
> +					0x0F) << 8) |
> +				      edid[current_descriptor_addrs + 6]) -
> +		(omap_dss_hdmi_timings.vfp + omap_dss_hdmi_timings.vsw);
> +
> +	dev_dbg(&sil9022_client->dev, "<%s>\n"
> +				       "hfp			= %d\n"
> +				       "hsw			= %d\n"
> +				       "hbp			= %d\n"
> +				       "vfp			= %d\n"
> +				       "vsw			= %d\n"
> +				       "vbp			= %d\n",
> +		 __func__,
> +		 omap_dss_hdmi_timings.hfp,
> +		 omap_dss_hdmi_timings.hsw,
> +		 omap_dss_hdmi_timings.hbp,
> +		 omap_dss_hdmi_timings.vfp,
> +		 omap_dss_hdmi_timings.vsw,
> +		 omap_dss_hdmi_timings.vbp
> +		 );
> +
> +}
> +
> +void get_edid_timing_data(u8 *edid, u16 *pixel_clk, u16 *horizontal_res,
> +			  u16 *vertical_res)
> +{
> +	u8 offset, effective_addrs;
> +	u8 count;
> +	u8 i;
> +	u8 flag = false;
> +	/*check for 720P timing in block0 */
> +	for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
> +		current_descriptor_addrs =
> +			EDID_DESCRIPTOR_BLOCK0_ADDRESS +
> +			count * EDID_TIMING_DESCRIPTOR_SIZE;
> +		*horizontal_res =
> +			(((edid[EDID_DESCRIPTOR_BLOCK0_ADDRESS + 4 +
> +			   count * EDID_TIMING_DESCRIPTOR_SIZE] & 0xF0) << 4) |
> +			 edid[EDID_DESCRIPTOR_BLOCK0_ADDRESS + 2 +
> +			 count * EDID_TIMING_DESCRIPTOR_SIZE]);
> +		*vertical_res =
> +			(((edid[EDID_DESCRIPTOR_BLOCK0_ADDRESS + 7 +
> +			   count * EDID_TIMING_DESCRIPTOR_SIZE] & 0xF0) << 4) |
> +			 edid[EDID_DESCRIPTOR_BLOCK0_ADDRESS + 5 +
> +			 count * EDID_TIMING_DESCRIPTOR_SIZE]);
> +
> +		dev_dbg(&sil9022_client->dev,
> +			"<%s> ***Block-0-Timing-descriptor[%d]***\n",
> +			__func__, count);
> +		for (i = current_descriptor_addrs;
> +		      i <
> +		      (current_descriptor_addrs+EDID_TIMING_DESCRIPTOR_SIZE);
> +		      i++)
> +			dev_dbg(&sil9022_client->dev,
> +				"%x ==>		%x\n", i, edid[i]);
> +
> +			dev_dbg(&sil9022_client->dev,
> +				 "<%s>\n"
> +				 "E-EDID Buffer Index	= %d\n"
> +				 "horizontal_res	= %d\n"
> +				 "vertical_res		= %d\n",
> +				 __func__,
> +				 current_descriptor_addrs,
> +				 *horizontal_res,
> +				 *vertical_res
> +				 );
> +
> +		if (*horizontal_res == HDMI_XRES &&
> +		    *vertical_res == HDMI_YRES) {
> +			dev_info(&sil9022_client->dev,
> +				"<%s>\nFound EDID Data for %d x %dp\n",
> +				 __func__, *horizontal_res, *vertical_res);
> +			flag = true;
> +			break;
> +			}
> +	}
> +
> +	/*check for the Timing in block1 */
> +	if (flag != true) {
> +		offset = edid[EDID_DESCRIPTOR_BLOCK1_ADDRESS + 2];
> +		if (offset != 0) {
> +			effective_addrs = EDID_DESCRIPTOR_BLOCK1_ADDRESS
> +				+ offset;
> +			/*to determine the number of descriptor blocks */
> +			for (count = 0;
> +			      count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
> +			      count++) {
> +				current_descriptor_addrs = effective_addrs +
> +					count * EDID_TIMING_DESCRIPTOR_SIZE;
> +				*horizontal_res =
> +					(((edid[effective_addrs + 4 +
> +					   count*EDID_TIMING_DESCRIPTOR_SIZE] &
> +					   0xF0) << 4) |
> +					 edid[effective_addrs + 2 +
> +					 count * EDID_TIMING_DESCRIPTOR_SIZE]);
> +				*vertical_res =
> +					(((edid[effective_addrs + 7 +
> +					   count*EDID_TIMING_DESCRIPTOR_SIZE] &
> +					   0xF0) << 4) |
> +					 edid[effective_addrs + 5 +
> +					 count * EDID_TIMING_DESCRIPTOR_SIZE]);
> +
> +				dev_dbg(&sil9022_client->dev,
> +					 "<%s> Block1-Timing-descriptor[%d]\n",
> +					 __func__, count);
> +
> +				for (i = current_descriptor_addrs;
> +				      i < (current_descriptor_addrs+
> +					   EDID_TIMING_DESCRIPTOR_SIZE); i++)
> +					dev_dbg(&sil9022_client->dev,
> +						"%x ==>		%x\n",
> +						   i, edid[i]);
> +
> +				dev_dbg(&sil9022_client->dev, "<%s>\n"
> +						"current_descriptor	= %d\n"
> +						"horizontal_res		= %d\n"
> +						"vertical_res		= %d\n",
> +					 __func__, current_descriptor_addrs,
> +					 *horizontal_res, *vertical_res);
> +
> +				if (*horizontal_res == HDMI_XRES &&
> +				    *vertical_res == HDMI_YRES) {
> +					dev_info(&sil9022_client->dev,
> +						 "<%s> Found EDID Data for "
> +						 "%d x %dp\n",
> +						 __func__,
> +						 *horizontal_res,
> +						 *vertical_res
> +						 );
> +					flag = true;
> +					break;
> +					}
> +			}
> +		}
> +	}
> +
> +	if (flag == true) {
> +		*pixel_clk = ((edid[current_descriptor_addrs + 1] << 8) |
> +			     edid[current_descriptor_addrs]);
> +
> +		omap_dss_hdmi_timings.x_res = *horizontal_res;
> +		omap_dss_hdmi_timings.y_res = *vertical_res;
> +		omap_dss_hdmi_timings.pixel_clock = *pixel_clk*10;
> +		dev_dbg(&sil9022_client->dev,
> +			 "EDID TIMING DATA supported by zoom2 FOUND\n"
> +			 "EDID DTD block address	= %d\n"
> +			 "pixel_clk			= %d\n"
> +			 "horizontal res		= %d\n"
> +			 "vertical res			= %d\n",
> +			 current_descriptor_addrs,
> +			 omap_dss_hdmi_timings.pixel_clock,
> +			 omap_dss_hdmi_timings.x_res,
> +			 omap_dss_hdmi_timings.y_res
> +			 );
> +
> +		get_horz_vert_timing_info(edid);
> +	} else {
> +
> +		dev_info(&sil9022_client->dev,
> +			 "<%s>\n"
> +			 "EDID TIMING DATA supported by zoom2 NOT FOUND\n"
> +			 "setting default timing values for 720p\n"
> +			 "pixel_clk		= %d\n"
> +			 "horizontal res	= %d\n"
> +			 "vertical res		= %d\n",
> +			 __func__,
> +			 omap_dss_hdmi_timings.pixel_clock,
> +			 omap_dss_hdmi_timings.x_res,
> +			 omap_dss_hdmi_timings.y_res
> +			 );
> +
> +		*pixel_clk = omap_dss_hdmi_timings.pixel_clock;
> +		*horizontal_res = omap_dss_hdmi_timings.x_res;
> +		*vertical_res = omap_dss_hdmi_timings.y_res;
> +	}
> +
> +
> +}
> +
> +
> +static int
> +sil9022_blockwrite_reg(struct i2c_client *client,
> +				  u8 reg, u16 alength, u8 *val, u16 *out_len)
> +{
> +	int err = 0, i;
> +	struct i2c_msg msg[1];
> +	u8 data[2];
> +
> +	if (!client->adapter) {
> +		dev_err(&client->dev, "<%s> ERROR: No HDMI Device\n", __func__);
> +		return -ENODEV;
> +	}
> +
> +	msg->addr = client->addr;
> +	msg->flags = I2C_M_WR;
> +	msg->len = 2;
> +	msg->buf = data;
> +
> +	/* high byte goes out first */
> +	data[0] = reg >> 8;
> +
> +	for (i = 0; i < alength - 1; i++) {
> +		data[1] = val[i];
> +		err = i2c_transfer(client->adapter, msg, 1);
> +		udelay(50);
> +		dev_dbg(&client->dev, "<%s> i2c Block write at 0x%x, "
> +				      "*val=%d flags=%d byte[%d] err=%d\n",
> +			__func__, data[0], data[1], msg->flags, i, err);
> +		if (err < 0)
> +			break;
> +	}
> +	/* set the number of bytes written*/
> +	*out_len = i;
> +
> +	if (err < 0) {
> +		dev_err(&client->dev, "<%s> ERROR:  i2c Block Write at 0x%x, "
> +				      "*val=%d flags=%d bytes written=%d "
> +				      "err=%d\n",
> +			__func__, data[0], data[1], msg->flags, i, err);
> +		return err;
> +	}
> +	return 0;
> +}
> +
> +static int
> +sil9022_blockread_reg(struct i2c_client *client,
> +		      u16 data_length, u16 alength,
> +		      u8 reg, u8 *val, u16 *out_len)
> +{
> +	int err = 0, i;
> +	struct i2c_msg msg[1];
> +	u8 data[2];
> +
> +	if (!client->adapter) {
> +		dev_err(&client->dev, "<%s> ERROR: No HDMI Device\n", __func__);
> +		return -ENODEV;
> +	}
> +
> +	msg->addr = client->addr;
> +	msg->flags = I2C_M_WR;
> +	msg->len = 1;
> +	msg->buf = data;
> +
> +	/* High byte goes out first */
> +	data[0] = reg;
> +	err = i2c_transfer(client->adapter, msg, 1);
> +	dev_dbg(&client->dev, "<%s> i2c Block Read1 at 0x%x, "
> +			       "*val=%d flags=%d err=%d\n",
> +		 __func__, data[0], data[1], msg->flags, err);
> +
> +	for (i = 0; i < alength; i++) {
> +		if (err >= 0) {
> +			mdelay(3);
> +			msg->flags = I2C_M_RD;
> +			msg->len = data_length;
> +			err = i2c_transfer(client->adapter, msg, 1);
> +		} else
> +			break;
> +		if (err >= 0) {
> +			val[i] = 0;
> +			/* High byte comes first */
> +			if (data_length == 1)
> +				val[i] = data[0];
> +			else if (data_length == 2)
> +				val[i] = data[1] + (data[0] << 8);
> +			dev_dbg(&client->dev, "<%s> i2c Block Read2 at 0x%x, "
> +					       "*val=%d flags=%d byte=%d "
> +					       "err=%d\n",
> +				 __func__, reg, val[i], msg->flags, i, err);
> +		} else
> +			break;
> +	}
> +	*out_len = i;
> +	dev_dbg(&client->dev, "<%s> i2c Block Read at 0x%x, bytes read = %d\n",
> +		__func__, client->addr, *out_len);
> +
> +	if (err < 0) {
> +		dev_err(&client->dev, "<%s> ERROR:  i2c Read at 0x%x, "
> +				      "*val=%d flags=%d bytes read=%d err=%d\n",
> +			__func__, reg, *val, msg->flags, i, err);
> +		return err;
> +	}
> +	return 0;
> +}
> +
> +
> +/* Write a value to a register in sil9022 device.
> + * @client: i2c driver client structure.
> + * @reg: Address of the register to read value from.
> + * @val: Value to be written to a specific register.
> + * Returns zero if successful, or non-zero otherwise.
> + */
> +static int
> +sil9022_write_reg(struct i2c_client *client, u8 reg, u8 val)
> +{
> +	int err = 0;
> +	struct i2c_msg msg[1];
> +	u8 data[2];
> +	int retries = 0;
> +
> +	if (!client->adapter) {
> +		dev_err(&client->dev, "<%s> ERROR: No HDMI Device\n", __func__);
> +		return -ENODEV;
> +	}
> +
> +retry:
> +	msg->addr = client->addr;
> +	msg->flags = I2C_M_WR;
> +	msg->len = 2;
> +	msg->buf = data;
> +
> +	data[0] = reg;
> +	data[1] = val;
> +
> +	err = i2c_transfer(client->adapter, msg, 1);
> +	dev_dbg(&client->dev, "<%s> i2c write at=%x "
> +			       "val=%x flags=%d err=%d\n",
> +		__func__, data[0], data[1], msg->flags, err);
> +	udelay(50);
> +
> +	if (err >= 0)
> +		return 0;
> +
> +	dev_err(&client->dev, "<%s> ERROR: i2c write at=%x "
> +			       "val=%x flags=%d err=%d\n",
> +		__func__, data[0], data[1], msg->flags, err);
> +	if (retries <= 5) {
> +		dev_info(&client->dev, "Retrying I2C... %d\n", retries);
> +		retries++;
> +		set_current_state(TASK_UNINTERRUPTIBLE);
> +		schedule_timeout(msecs_to_jiffies(20));
> +		goto retry;
> +	}
> +	return err;
> +}
> +
> +/*
> + * Read a value from a register in sil9022 device.
> + * The value is returned in 'val'.
> + * Returns zero if successful, or non-zero otherwise.
> + */
> +static int
> +sil9022_read_reg(struct i2c_client *client, u16 data_length, u8 reg, u8 *val)
> +{
> +	int err = 0;
> +	struct i2c_msg msg[1];
> +	u8 data[2];
> +
> +	if (!client->adapter) {
> +		dev_err(&client->dev, "<%s> ERROR: No HDMI Device\n", __func__);
> +		return -ENODEV;
> +	}
> +
> +	msg->addr = client->addr;
> +	msg->flags = I2C_M_WR;
> +	msg->len = 1;
> +	msg->buf = data;
> +
> +	data[0] = reg;
> +	err = i2c_transfer(client->adapter, msg, 1);
> +	dev_dbg(&client->dev, "<%s> i2c Read1 reg=%x val=%d "
> +			       "flags=%d err=%d\n",
> +		__func__, reg, data[1], msg->flags, err);
> +
> +	if (err >= 0) {
> +		mdelay(3);
> +		msg->flags = I2C_M_RD;
> +		msg->len = data_length;
> +		err = i2c_transfer(client->adapter, msg, 1);
> +	}
> +
> +	if (err >= 0) {
> +		*val = 0;
> +		if (data_length == 1)
> +			*val = data[0];
> +		else if (data_length == 2)
> +			*val = data[1] + (data[0] << 8);
> +		dev_dbg(&client->dev, "<%s> i2c Read2 at 0x%x, *val=%d "
> +				       "flags=%d err=%d\n",
> +			 __func__, reg, *val, msg->flags, err);
> +		return 0;
> +	}
> +
> +	dev_err(&client->dev, "<%s> ERROR: i2c Read at 0x%x, "
> +			      "*val=%d flags=%d err=%d\n",
> +		__func__, reg, *val, msg->flags, err);
> +	return err;
> +}
> +
> +static int
> +sil9022_read_edid(struct i2c_client *client, u16 len,
> +	       char *p_buffer, u16 *out_len)
> +{
> +	int err =  0;
> +	u8 val = 0;
> +	int retries = 0;
> +	int i = 0;
> +	int k = 0;
> +
> +	len = (len < HDMI_EDID_MAX_LENGTH) ? len : HDMI_EDID_MAX_LENGTH;
> +
> +	/* Request DDC bus access to read EDID info from HDTV */
> +	dev_info(&client->dev, "<%s> Reading HDMI EDID\n", __func__);
> +
> +	/* Bring transmitter to low-Power state */
> +	val = TPI_AVI_POWER_STATE_D2;
> +	err = sil9022_write_reg(client, HDMI_TPI_DEVICE_POWER_STATE_DATA, val);
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: Failed during bring power state - low.\n",
> +			 __func__);
> +		return err;
> +	}
> +
> +	/* Disable TMDS clock */
> +	val = 0x11;
> +	err = sil9022_write_reg(client, HDMI_SYS_CTRL_DATA_REG, val);
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: Failed during bring power state - low.\n",
> +			 __func__);
> +		return err;
> +	}
> +
> +	val = 0;
> +	/* Read TPI system control register*/
> +	err = sil9022_read_reg(client, 1, HDMI_SYS_CTRL_DATA_REG, &val);
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: Reading DDC BUS REQUEST\n", __func__);
> +		return err;
> +	}
> +
> +	/* The host writes 0x1A[2]=1 to request the
> +	 * DDC(Display Data Channel) bus
> +	 */
> +	val |= TPI_SYS_CTRL_DDC_BUS_REQUEST;
> +	err = sil9022_write_reg(client, HDMI_SYS_CTRL_DATA_REG, val);
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: Writing DDC BUS REQUEST\n", __func__);
> +		return err;
> +	}
> +
> +	 /*  Poll for bus DDC Bus control to be granted */
> +	dev_info(&client->dev, "<%s> Poll for DDC bus access\n", __func__);
> +	val = 0;
> +	do {
> +		err = sil9022_read_reg(client, 1, HDMI_SYS_CTRL_DATA_REG, &val);
> +		if (retries++ > 100)
> +			return err;
> +
> +	} while ((val & TPI_SYS_CTRL_DDC_BUS_GRANTED) == 0);
> +
> +	/*  Close the switch to the DDC */
> +	val |= TPI_SYS_CTRL_DDC_BUS_REQUEST | TPI_SYS_CTRL_DDC_BUS_GRANTED;
> +	err = sil9022_write_reg(client, HDMI_SYS_CTRL_DATA_REG, val);
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: Close switch to DDC BUS REQUEST\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	memset(p_buffer, 0, len);
> +	/* change I2C SetSlaveAddress to HDMI_I2C_MONITOR_ADDRESS */
> +	/*  Read the EDID structure from the monitor I2C address  */
> +	client->addr = HDMI_I2C_MONITOR_ADDRESS;
> +	err = sil9022_blockread_reg(client, 1, len,
> +				    0x00, p_buffer, out_len);
> +	if (err < 0 || *out_len <= 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: Reading EDID from "
> +			"HDMI_I2C_MONITOR_ADDRESS\n", __func__);
> +		return err;
> +	}
> +
> +	for (i = 0; i < *out_len; i++) {
> +		if ((i / 18) < 3) {
> +			dev_dbg(&client->dev, "byte->%02x	%x\n",
> +				i, p_buffer[i]);
> +			continue;
> +		}
> +		if ((i/18 >= 3 && i/18 <= 6) && (i%18 == 0))
> +			dev_dbg(&client->dev, "\n DTD Block %d\n", k++);
> +
> +		if ((i/18 == 7) && (i%18 == 0))
> +			dev_dbg(&client->dev, "\n");
> +
> +		dev_dbg(&client->dev, "byte->%02x	%x\n", i, p_buffer[i]);
> +	}
> +
> +	/* Release DDC bus access */
> +	client->addr = SI9022_I2CSLAVEADDRESS;
> +	val &= ~(TPI_SYS_CTRL_DDC_BUS_REQUEST | TPI_SYS_CTRL_DDC_BUS_GRANTED);
> +	err = sil9022_write_reg(client, HDMI_SYS_CTRL_DATA_REG, val);
> +
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: Releasing DDC  Bus Access\n",
> +			__func__);
> +		return err;
> +		}
> +
> +	/*  Success */
> +	return 0;
> +}
> +
> +static int
> +sil9022_enable_audio(struct i2c_client *client)
> +{
> +	int err = 0;
> +	u8  val = 0;
> +	u8  crc = 0;
> +	u32 count = 0;
> +	int index = 0;
> +
> +	for (index = 0;
> +	      index < sizeof(hdmi_tpi_audio_config_data) /
> +	      sizeof(struct hdmi_reg_data);
> +	      index++) {
> +		err = sil9022_write_reg(
> +			client,
> +			hdmi_tpi_audio_config_data[index].reg_offset,
> +			hdmi_tpi_audio_config_data[index].value);
> +		if (err != 0) {
> +			dev_err(&client->dev,
> +				"<%s> ERROR: Writing "
> +				"tpi_audio_config_data[%d]={ %d, %d }\n",
> +				__func__, index,
> +				hdmi_tpi_audio_config_data[index].reg_offset,
> +				hdmi_tpi_audio_config_data[index].value);
> +			return err;
> +			}
> +		}
> +
> +	/* Fill the checksum byte for Infoframe data*/
> +	count = 0;
> +	while (count < MISC_INFOFRAME_SIZE_MEMORY) {
> +		crc += misc_audio_info_frame_data[count];
> +		count++;
> +	}
> +	crc = 0x100 - crc;
> +
> +	/* Fill CRC Byte*/
> +	misc_audio_info_frame_data[0x3] = crc;
> +
> +	for (count = 0; count < MISC_INFOFRAME_SIZE_MEMORY; count++) {
> +		err = sil9022_write_reg(client,
> +					(HDMI_CPI_MISC_IF_OFFSET + count),
> +					misc_audio_info_frame_data[count]);
> +		if (err < 0) {
> +			dev_err(&client->dev,
> +				"<%s> ERROR: writing audio info frame"
> +				" CRC data: %d\n", __func__, count);
> +			return err;
> +		}
> +	}
> +
> +	/* Decode Level 0 Packets */
> +	val = 0x2;
> +	sil9022_write_reg(client, 0xBC, val);
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: writing level 0 packets to 0xBC\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	val = 0x24;
> +	err = sil9022_write_reg(client, 0xBD, val);
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: writing level 0 packets to 0xBD\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	val = 0x2;
> +	err = sil9022_write_reg(client, 0xBE, val);
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: writing level 0 packets to 0xBE\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	/* Disable Mute */
> +	val = TPI_AUDIO_INTERFACE_I2S |
> +		  TPI_AUDIO_MUTE_DISABLE |
> +		  TPI_AUDIO_CODING_PCM;
> +	err = sil9022_write_reg(client, HDMI_TPI_AUDIO_CONFIG_BYTE2_REG, val);
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: Disabling mute\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	dev_info(&client->dev, "<%s> hdmi audio enabled\n",
> +		__func__);
> +	return 0;
> +
> +}
> +
> +static int
> +sil9022_disable_audio(struct i2c_client *client)
> +{
> +	u8 val = 0;
> +	int err = 0;
> +	/* Disable Audio */
> +	val = TPI_AUDIO_INTERFACE_DISABLE;
> +	err = sil9022_write_reg(client, HDMI_TPI_AUDIO_CONFIG_BYTE2_REG, val);
> +	if (err < 0)
> +		dev_err(&client->dev,
> +			"<%s> ERROR: Disisable audio interface", __func__);
> +
> +	dev_info(&client->dev, "<%s> hdmi audio disabled\n", __func__);
> +	return err;
> +}
> +
> +static int
> +sil9022_enable(struct omap_dss_device *dssdev)
> +{
> +	int		err;
> +	u8		val, vals[14];
> +	int		i;
> +	u16		out_len = 0;
> +	u8		edid[HDMI_EDID_MAX_LENGTH];
> +	u16		horizontal_res;
> +	u16		vertical_res;
> +	u16		pixel_clk;
> +
> +	memset(edid, 0, HDMI_EDID_MAX_LENGTH);
> +	memset(vals, 0, 14);
> +
> +	err = sil9022_read_edid(sil9022_client, HDMI_EDID_MAX_LENGTH,
> +			     edid, &out_len);
> +	if (err < 0 || out_len == 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> Unable to read EDID for monitor\n", __func__);
> +		return err;
> +	}
> +
> +	get_edid_timing_data(edid,
> +			     &pixel_clk,
> +			     &horizontal_res,
> +			     &vertical_res
> +			     );
> +
> +	/*  Fill the TPI Video Mode Data structure */
> +	vals[0] = (pixel_clk & 0xFF);                  /* Pixel clock */
> +	vals[1] = ((pixel_clk & 0xFF00) >> 8);
> +	vals[2] = VERTICAL_FREQ;                    /* Vertical freq */
> +	vals[3] = 0x00;
> +	vals[4] = (horizontal_res & 0xFF);         /* Horizontal pixels*/
> +	vals[5] = ((horizontal_res & 0xFF00) >> 8);
> +	vals[6] = (vertical_res & 0xFF);           /* Vertical pixels */
> +	vals[7] = ((vertical_res & 0xFF00) >> 8);
> +
> +	dev_info(&sil9022_client->dev, "<%s>\nHDMI Monitor E-EDID Timing Data\n"
> +				       "horizontal_res	= %d\n"
> +				       "vertical_res	= %d\n"
> +				       "pixel_clk	= %d\n"
> +				       "hfp		= %d\n"
> +				       "hsw		= %d\n"
> +				       "hbp		= %d\n"
> +				       "vfp		= %d\n"
> +				       "vsw		= %d\n"
> +				       "vbp		= %d\n",
> +		 __func__,
> +		 omap_dss_hdmi_timings.x_res,
> +		 omap_dss_hdmi_timings.y_res,
> +		 omap_dss_hdmi_timings.pixel_clock,
> +		 omap_dss_hdmi_timings.hfp,
> +		 omap_dss_hdmi_timings.hsw,
> +		 omap_dss_hdmi_timings.hbp,
> +		 omap_dss_hdmi_timings.vfp,
> +		 omap_dss_hdmi_timings.vsw,
> +		 omap_dss_hdmi_timings.vbp
> +		 );
> +
> +	dssdev->panel.timings = omap_dss_hdmi_timings;
> +	/*  Write out the TPI Video Mode Data */
> +	out_len = 0;
> +	err = sil9022_blockwrite_reg(sil9022_client,
> +				     HDMI_TPI_VIDEO_DATA_BASE_REG,
> +				     8, vals, &out_len);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: writing TPI video mode data\n", __func__);
> +		return err;
> +	}
> +
> +	/* Write out the TPI Pixel Repetition Data (24 bit wide bus,
> +	falling edge, no pixel replication) */
> +	val = TPI_AVI_PIXEL_REP_BUS_24BIT |
> +		TPI_AVI_PIXEL_REP_FALLING_EDGE |
> +		TPI_AVI_PIXEL_REP_NONE;
> +	err = sil9022_write_reg(sil9022_client,
> +				HDMI_TPI_PIXEL_REPETITION_REG,
> +				val);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: writing TPI pixel repetition data\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	 /*  Write out the TPI AVI Input Format */
> +	val = TPI_AVI_INPUT_BITMODE_8BIT |
> +		TPI_AVI_INPUT_RANGE_AUTO |
> +		TPI_AVI_INPUT_COLORSPACE_RGB;
> +	err = sil9022_write_reg(sil9022_client,
> +				HDMI_TPI_AVI_IN_FORMAT_REG,
> +				val);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: writing TPI AVI Input format\n", __func__);
> +		return err;
> +	}
> +
> +	/*  Write out the TPI AVI Output Format */
> +	val = TPI_AVI_OUTPUT_CONV_BT709 |
> +		TPI_AVI_OUTPUT_RANGE_AUTO |
> +		TPI_AVI_OUTPUT_COLORSPACE_RGBHDMI;
> +	err = sil9022_write_reg(sil9022_client,
> +				HDMI_TPI_AVI_OUT_FORMAT_REG, val);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: writing TPI AVI output format\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	/* Write out the TPI System Control Data to power down */
> +	val = TPI_SYS_CTRL_POWER_DOWN;
> +	err = sil9022_write_reg(sil9022_client, HDMI_SYS_CTRL_DATA_REG, val);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: writing TPI power down control data\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	/* Write out the TPI AVI InfoFrame Data (all defaults) */
> +	/* Compute CRC*/
> +	val = 0x82 + 0x02 + 13;
> +
> +	for (i = 0; i < sizeof(avi_info_frame_data); i++)
> +		val += avi_info_frame_data[i];
> +
> +	avi_info_frame_data[0] = 0x100 - val;
> +
> +	out_len = 0;
> +	err = sil9022_blockwrite_reg(sil9022_client,
> +				     HDMI_TPI_AVI_DBYTE_BASE_REG,
> +				     sizeof(avi_info_frame_data),
> +				     avi_info_frame_data, &out_len);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: writing TPI AVI infoframe data\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	/*  Audio Configuration  */
> +	err = sil9022_enable_audio(sil9022_client);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: Unable set audio configuration\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	/*  Write out the TPI Device Power State (D0) */
> +	val = TPI_AVI_POWER_STATE_D0;
> +	err = sil9022_write_reg(sil9022_client,
> +				HDMI_TPI_POWER_STATE_CTRL_REG, val);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: Setting device power state to D0\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	/* Write out the TPI System Control Data to power up and
> +	 * select output mode
> +	 */
> +	val = TPI_SYS_CTRL_POWER_ACTIVE | TPI_SYS_CTRL_OUTPUT_MODE_HDMI;
> +	err = sil9022_write_reg(sil9022_client, HDMI_SYS_CTRL_DATA_REG, val);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: Writing system control data\n", __func__);
> +		return err;
> +	}
> +
> +	/*  Read back TPI System Control Data to latch settings */
> +	msleep(20);
> +	err = sil9022_read_reg(sil9022_client, 1, HDMI_SYS_CTRL_DATA_REG, &val);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: Writing system control data\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	/* HDCP Enable - Disable */
> +	val = 0;
> +	err = sil9022_write_reg(sil9022_client,
> +				HDMI_TPI_HDCP_CONTROLDATA_REG, val);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: Enable (1) / Disable (0) => HDCP: %d\n",
> +			__func__, val);
> +		return err;
> +	}
> +
> +	dev_info(&sil9022_client->dev, "<%s> hdmi enabled\n", __func__);
> +	return 0;
> +
> +}
> +
> +static int
> +sil9022_disable(void)
> +{
> +	u8 val = 0;
> +	int err = 0;
> +
> +	err = sil9022_disable_audio(sil9022_client);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: failed to disable audio\n", __func__);
> +		return err;
> +	}
> +
> +	/*  Write out the TPI System Control Data to power down  */
> +	val = TPI_SYS_CTRL_POWER_DOWN;
> +	err = sil9022_write_reg(sil9022_client, HDMI_SYS_CTRL_DATA_REG, val);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: writing control data - power down\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	/*  Write out the TPI Device Power State (D2) */
> +	val = TPI_AVI_POWER_STATE_D2;
> +	err = sil9022_write_reg(sil9022_client,
> +			  HDMI_TPI_DEVICE_POWER_STATE_DATA, val);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR: Setting device power state to D2\n",
> +			__func__);
> +		return err;
> +	}
> +
> +	/*  Read back TPI System Control Data to latch settings */
> +	mdelay(10);
> +	err = sil9022_read_reg(sil9022_client, 1, HDMI_SYS_CTRL_DATA_REG, &val);
> +	if (err < 0) {
> +		dev_err(&sil9022_client->dev,
> +			"<%s> ERROR:  Reading System control data "
> +			"- latch settings\n", __func__);
> +		return err;
> +	}
> +
> +	dev_info(&sil9022_client->dev, "<%s> hdmi disabled\n", __func__);
> +	return 0;
> +
> +}
> +
> +static int sil9022_set_reg_read_ctrl(struct i2c_client *client)
> +{
> +	int err = 0;
> +	u8 ver;
> +
> +	/* probe for sil9022 chip version*/
> +	err = sil9022_write_reg(client, SI9022_REG_TPI_RQB, 0x00);
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: Writing HDMI configuration to "
> +			"reg - SI9022_REG_TPI_RQB\n", __func__);
> +		err = -ENODEV;
> +		goto ERROR1;
> +	}
> +
> +	err = sil9022_read_reg(client, 1, SI9022_REG_CHIPID0, &ver);
> +	if (err < 0) {
> +		dev_err(&client->dev,
> +			"<%s> ERROR: Reading HDMI version Id\n", __func__);
> +		err = -ENODEV;
> +		goto ERROR1;
> +	} else if (ver != SI9022_CHIPID_902x) {
> +		dev_err(&client->dev,
> +			"<%s> Not a valid verId: 0x%x\n", __func__, ver);
> +		err = -ENODEV;
> +		goto ERROR1;
> +	} else
> +		dev_info(&client->dev,
> +			 "<%s> sil9022 HDMI Chip version = %x\n",
> +			 __func__, ver);
> +
> +	return 0;
> +ERROR1:
> +	return err;
> +}
> +
> +static inline struct sil9022_platform_data
> +*get_panel_data(const struct omap_dss_device *dssdev)
> +{
> +	return (struct sil9022_platform_data *) dssdev->data;
> +}
> +
> +
> +static int sil9022_panel_probe(struct omap_dss_device *dssdev)
> +{
> +	struct sil9022_platform_data *sidata = get_panel_data(dssdev);
> +	int r;
> +	if (!sidata)
> +		return -EINVAL;
> +
> +	dssdev->panel.timings = omap_dss_hdmi_timings;
> +
> +	if (gpio_is_valid(sidata->res_gpio)) {
> +		r = devm_gpio_request_one(&dssdev->dev, sidata->res_gpio,
> +				GPIOF_OUT_INIT_HIGH, "HDMI");
> +		if (r)
> +			return r;
> +	}
> +
> +	return 0;
> +}
> +
> +static void sil9022_panel_remove(struct omap_dss_device *dssdev)
> +{
> +	omap_dss_unregister_driver(dssdev->driver);
> +}
> +
> +
> +static int sil9022_panel_power_on(struct omap_dss_device *dssdev)
> +{
> +	int r = 0;
> +	struct sil9022_platform_data *sidata = get_panel_data(dssdev);
> +
> +	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
> +		return 0;
> +
> +	if (gpio_is_valid(sidata->res_gpio))
> +		gpio_set_value_cansleep(sidata->res_gpio, 1);
> +
> +	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
> +	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
> +	r = omapdss_dpi_display_enable(dssdev);
> +	return r;
> +
> +}
> +
> +static void sil9022_panel_power_off(struct omap_dss_device *dssdev)
> +{
> +	struct sil9022_platform_data *sidata = get_panel_data(dssdev);
> +
> +	if (gpio_is_valid(sidata->res_gpio))
> +		gpio_set_value_cansleep(sidata->res_gpio, 0);
> +	return;
> +
> +}
> +
> +static int sil9022_panel_enable(struct omap_dss_device *dssdev)
> +{
> +	int r = 0;
> +
> +	r = sil9022_panel_power_on(dssdev);
> +	if (r)
> +			goto ERROR0;
> +	r = sil9022_set_reg_read_ctrl(sil9022_client);
> +	if (r)
> +		goto ERROR0;
> +
> +	r = sil9022_enable(dssdev);
> +	if (r)
> +		goto ERROR0;
> +	/* wait couple of vsyncs until enabling the LCD */
> +	msleep(50);
> +	return 0;
> +
> +ERROR0:
> +	return r;
> +}
> +
> +static void sil9022_panel_disable(struct omap_dss_device *dssdev)
> +{
> +	sil9022_disable();
> +	/* wait couple of vsyncs until enabling the hdmi */
> +	msleep(50);
> +	sil9022_panel_power_off(dssdev);
> +	return;
> +}
> +
> +static struct omap_dss_driver hdmi_driver = {
> +	.probe		= sil9022_panel_probe,
> +	.remove		= sil9022_panel_remove,
> +
> +	.enable		= sil9022_panel_enable,
> +	.disable		= sil9022_panel_disable,
> +
> +	.driver         = {
> +		.name   = "sil9022_panel",
> +		.owner  = THIS_MODULE,
> +	},
> +};
> +
> +static int
> +sil9022_probe(struct i2c_client *client, const struct i2c_device_id *id)
> +{
> +	int err = 0;
> +
> +	sil9022_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
> +	if (!sil9022_client) {
> +		err = -ENOMEM;
> +		goto ERROR0;
> +	}
> +	memset(sil9022_client, 0, sizeof(struct i2c_client));
> +
> +	strncpy(sil9022_client->name, client->name, I2C_NAME_SIZE);
> +	sil9022_client->addr = client->addr;
> +	sil9022_client->adapter = client->adapter;
> +
> +	err = sil9022_set_reg_read_ctrl(client);
> +	if (err)
> +		goto ERROR1;
> +
> +	omap_dss_register_driver(&hdmi_driver);
> +	return 0;
> +
> +ERROR1:
> +	kfree(sil9022_client);
> +ERROR0:
> +	return err;
> +}
> +
> +
> +static int
> +sil9022_remove(struct i2c_client *client)
> +
> +{
> +	int err = 0;
> +
> +	if (!client->adapter) {
> +		dev_err(&sil9022_client->dev, "<%s> No HDMI Device\n",
> +			__func__);
> +		return -ENODEV;
> +	}
> +	kfree(sil9022_client);
> +
> +	return err;
> +}
> +
> +static const struct i2c_device_id sil9022_id[] = {
> +	{ SIL9022_DRV_NAME, 0 },
> +	{ },
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, sil9022_id);
> +
> +static struct i2c_driver sil9022_driver = {
> +	.driver = {
> +		.name  = SIL9022_DRV_NAME,
> +		.owner = THIS_MODULE,
> +		},
> +	.probe		= sil9022_probe,
> +	.remove		= sil9022_remove,
> +	.id_table	= sil9022_id,
> +};
> +
> +static int __init
> +sil9022_init(void)
> +{
> +	int err = 0;
> +	err = i2c_add_driver(&sil9022_driver);
> +	if (err < 0) {
> +		printk(KERN_ERR "<%s> Driver registration failed\n", __func__);
> +		err = -ENODEV;
> +		goto ERROR0;
> +	}
> +
> +	if (sil9022_client == NULL) {
> +		printk(KERN_ERR "<%s> sil9022_client not allocated\n"
> +				"<%s> No HDMI Device\n", __func__, __func__);
> +		err = -ENODEV;
> +		goto ERROR0;
> +	}
> +	return 0;
> +
> +ERROR0:
> +	return err;
> +}
> +
> +static void __exit
> +sil9022_exit(void)
> +{
> +	i2c_del_driver(&sil9022_driver);
> +}
> +
> +late_initcall(sil9022_init);
> +module_exit(sil9022_exit);
> +
> +MODULE_AUTHOR("Texas Instruments");
> +MODULE_DESCRIPTION("SIL9022 HDMI Driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/video/omap2/displays/panel-sil9022.h b/drivers/video/omap2/displays/panel-sil9022.h
> new file mode 100644
> index 0000000..7c920c0
> --- /dev/null
> +++ b/drivers/video/omap2/displays/panel-sil9022.h
> @@ -0,0 +1,527 @@
> +/*
> + * drivers/video/omap2/displays/panel-sil9022.c
> + *
> + * Copyright (C) 2009 Texas Instruments
> + *
> + * This file is licensed under the terms of the GNU General Public License
> + * version 2. This program is licensed "as is" without any warranty of any
> + * kind, whether express or implied.
> + *
> + * sil9022 hdmi driver
> + */
> +#ifndef _SI9022_H_
> +#define _SI9022_H_
> +
> +#define SIL9022_DRV_NAME		"sil9022"
> +
> +#define CLKOUT2_EN		(0x1 << 7)
> +#define CLKOUT2_DIV		(0x4 << 3)
> +#define CLKOUT2SOURCE		(0x2 << 0)
> +#define CM_CLKOUT_CTRL		0x48004D70
> +
> +#define HDMI_XRES			1280
> +#define HDMI_YRES			720
> +#define HDMI_PIXCLOCK_MAX		74250
> +#define VERTICAL_FREQ			0x3C
> +
> +#define I2C_M_WR			0
> +
> +#define SI9022_USERST_PIN		1
> +
> +#define SI9022_REG_PIX_CLK_LSB		0x00
> +#define SI9022_REG_PIX_CLK_MSB		0x01
> +
> +#define SI9022_REG_PIX_REPETITION	0x08
> +#define SI9022_REG_INPUT_FORMAT		0x09
> +#define SI9022_REG_OUTPUT_FORMAT	0x0A
> +#define SI9022_REG_SYNC_GEN_CTRL	0x60
> +
> +#define SI9022_REG_DE_CTRL		0x63
> +#define DE_DLY_MSB_BITPOS		0
> +#define HSYNCPOL_INVERT_BITPOS		4
> +#define VSYNCPOL_INVERT_BITPOS		5
> +#define DE_GENERATOR_EN_BITPOS		6
> +
> +#define SI9022_REG_PWR_STATE		0x1E
> +
> +#define SI9022_REG_TPI_RQB		0xC7
> +
> +#define SI9022_REG_INT_PAGE		0xBC
> +#define SI9022_REG_OFFSET		0xBD
> +#define	SI9022_REG_VALUE		0xBE
> +
> +#define SI9022_PLLMULT_BITPOS		0x05
> +
> +#define SI9022_REG_TPI_SYSCTRL		0x1A
> +#define I2DDCREQ_BITPOS			2
> +#define TMDS_ENABLE_BITPOS		4
> +#define HDMI_ENABLE_BITPOS		0
> +
> +#define SI9022_REG_CHIPID0		0x1B
> +#define SI9022_REG_CHIPID1		0x1C
> +#define SI9022_REG_CHIPID2		0x1D
> +#define SI9022_REG_HDCPVER		0x30
> +
> +#define SI9022_REG_INTSTATUS		0x3D
> +#define HOTPLUG_PENDING_BITPOS		0
> +#define RCV_SENSE_PENDING_BITPOS	1
> +#define HOTPLUG_SENSE_BITPOS		2
> +#define RX_SENSE_BITPOS			3
> +#define AUDIO_ERR_PENDING_BITPOS	4
> +
> +
> +#define SI9022_I2CSLAVEADDRESS		0x39
> +
> +#define SI9022_CHIPID_902x		0xB0
> +
> +#define SI9022_MAXRETRY			100
> +
> +#define SI9022_EDID_DETAILED_TIMING_OFFSET	0x36 /*EDID Detailed Timing */
> +						/*Info 0 begin offset*/
> +#define SI9022_EDID_PIX_CLK_OFFSET		0
> +#define SI9022_EDID_H_ACTIVE_OFFSET		2
> +#define SI9022_EDID_H_BLANKING_OFFSET		3
> +#define SI9022_EDID_V_ACTIVE_OFFSET		5
> +#define SI9022_EDID_V_BLANKING_OFFSET		6
> +#define SI9022_EDID_H_SYNC_OFFSET		8
> +#define SI9022_EDID_H_SYNC_PW_OFFSET		9
> +#define SI9022_EDID_V_SYNC_OFFSET		10
> +#define SI9022_EDID_V_SYNC_PW_OFFSET		10
> +#define SI9022_EDID_H_IMAGE_SIZE_OFFSET		12
> +#define SI9022_EDID_V_IMAGE_SIZE_OFFSET		13
> +#define SI9022_EDID_H_BORDER_OFFSET		15
> +#define SI9022_EDID_V_BORDER_OFFSET		16
> +#define SI9022_EDID_FLAGS_OFFSET		17
> +
> +#define SI9022_PLUG_DETECTED			0xF0
> +#define SI9022_UNPLUG_DETECTED			0xF1
> +
> +
> +/* ---------------------------------------------------------------------  */
> +#define EDID_TIMING_DESCRIPTOR_SIZE		0x12
> +#define EDID_DESCRIPTOR_BLOCK0_ADDRESS		0x36
> +#define EDID_DESCRIPTOR_BLOCK1_ADDRESS		0x80
> +#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR	4
> +#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR	4
> +
> +/* HDMI Connected States  */
> +#define HDMI_STATE_NOMONITOR	0	/* NOT CONNECTED */
> +#define HDMI_STATE_CONNECTED	1	/* CONNECTED */
> +#define HDMI_STATE_ON		2	/* CONNECTED AND POWERED ON */
> +
> +
> +/* HDMI EDID Length  */
> +#define HDMI_EDID_MAX_LENGTH	256
> +
> +/* HDMI EDID DTDs  */
> +#define HDMI_EDID_MAX_DTDS	4
> +
> +/* HDMI EDID DTD Tags  */
> +#define HDMI_EDID_DTD_TAG_MONITOR_NAME		0xFC
> +#define HDMI_EDID_DTD_TAG_MONITOR_SERIALNUM	0xFF
> +#define HDMI_EDID_DTD_TAG_MONITOR_LIMITS	0xFD
> +
> +
> +/* HDMI EDID Extension Data Block Tags  */
> +#define HDMI_EDID_EX_DATABLOCK_TAG_MASK		0xE0
> +#define HDMI_EDID_EX_DATABLOCK_LEN_MASK		0x1F
> +
> +#define HDMI_EDID_EX_DATABLOCK_AUDIO		0x20
> +#define HDMI_EDID_EX_DATABLOCK_VIDEO		0x40
> +#define HDMI_EDID_EX_DATABLOCK_VENDOR		0x60
> +#define HDMI_EDID_EX_DATABLOCK_SPEAKERS		0x80
> +
> +/* HDMI EDID Extenion Data Block Values: Video  */
> +#define HDMI_EDID_EX_VIDEO_NATIVE		0x80
> +#define HDMI_EDID_EX_VIDEO_MASK			0x7F
> +#define HDMI_EDID_EX_VIDEO_MAX			35
> +
> +#define HDMI_EDID_EX_VIDEO_640x480p_60Hz_4_3		1
> +#define HDMI_EDID_EX_VIDEO_720x480p_60Hz_4_3		2
> +#define HDMI_EDID_EX_VIDEO_720x480p_60Hz_16_9		3
> +#define HDMI_EDID_EX_VIDEO_1280x720p_60Hz_16_9		4
> +#define HDMI_EDID_EX_VIDEO_1920x1080i_60Hz_16_9		5
> +#define HDMI_EDID_EX_VIDEO_720x480i_60Hz_4_3		6
> +#define HDMI_EDID_EX_VIDEO_720x480i_60Hz_16_9		7
> +#define HDMI_EDID_EX_VIDEO_720x240p_60Hz_4_3		8
> +#define HDMI_EDID_EX_VIDEO_720x240p_60Hz_16_9		9
> +#define HDMI_EDID_EX_VIDEO_2880x480i_60Hz_4_3		10
> +#define HDMI_EDID_EX_VIDEO_2880x480i_60Hz_16_9		11
> +#define HDMI_EDID_EX_VIDEO_2880x480p_60Hz_4_3		12
> +#define HDMI_EDID_EX_VIDEO_2880x480p_60Hz_16_9		13
> +#define HDMI_EDID_EX_VIDEO_1440x480p_60Hz_4_3		14
> +#define HDMI_EDID_EX_VIDEO_1440x480p_60Hz_16_9		15
> +#define HDMI_EDID_EX_VIDEO_1920x1080p_60Hz_16_9		16
> +#define HDMI_EDID_EX_VIDEO_720x576p_50Hz_4_3		17
> +#define HDMI_EDID_EX_VIDEO_720x576p_50Hz_16_9		18
> +#define HDMI_EDID_EX_VIDEO_1280x720p_50Hz_16_9		19
> +#define HDMI_EDID_EX_VIDEO_1920x1080i_50Hz_16_9		20
> +#define HDMI_EDID_EX_VIDEO_720x576i_50Hz_4_3		21
> +#define HDMI_EDID_EX_VIDEO_720x576i_50Hz_16_9		22
> +#define HDMI_EDID_EX_VIDEO_720x288p_50Hz_4_3		23
> +#define HDMI_EDID_EX_VIDEO_720x288p_50Hz_16_9		24
> +#define HDMI_EDID_EX_VIDEO_2880x576i_50Hz_4_3		25
> +#define HDMI_EDID_EX_VIDEO_2880x576i_50Hz_16_9		26
> +#define HDMI_EDID_EX_VIDEO_2880x288p_50Hz_4_3		27
> +#define HDMI_EDID_EX_VIDEO_2880x288p_50Hz_16_9		28
> +#define HDMI_EDID_EX_VIDEO_1440x576p_50Hz_4_3		29
> +#define HDMI_EDID_EX_VIDEO_1440x576p_50Hz_16_9		30
> +#define HDMI_EDID_EX_VIDEO_1920x1080p_50Hz_16_9		31
> +#define HDMI_EDID_EX_VIDEO_1920x1080p_24Hz_16_9		32
> +#define HDMI_EDID_EX_VIDEO_1920x1080p_25Hz_16_9		33
> +#define HDMI_EDID_EX_VIDEO_1920x1080p_30Hz_16_9		34
> +
> +/*  HDMI TPI Registers  */
> +#define HDMI_TPI_VIDEO_DATA_BASE_REG	0x00
> +#define HDMI_TPI_PIXEL_CLK_LSB_REG	 (HDMI_TPI_VIDEO_DATA_BASE_REG + 0x00)
> +#define HDMI_TPI_PIXEL_CLK_MSB_REG (HDMI_TPI_VIDEO_DATA_BASE_REG + 0x01)
> +#define HDMI_TPI_VFREQ_LSB_REG	(HDMI_TPI_VIDEO_DATA_BASE_REG + 0x02)
> +#define HDMI_TPI_VFREQ_MSB_REG	(HDMI_TPI_VIDEO_DATA_BASE_REG + 0x03)
> +#define HDMI_TPI_PIXELS_LSB_REG	(HDMI_TPI_VIDEO_DATA_BASE_REG + 0x04)
> +#define HDMI_TPI_PIXELS_MSB_REG	(HDMI_TPI_VIDEO_DATA_BASE_REG + 0x05)
> +#define HDMI_TPI_LINES_LSB_REG		(HDMI_TPI_VIDEO_DATA_BASE_REG + 0x06)
> +#define HDMI_TPI_LINES_MSB_REG		(HDMI_TPI_VIDEO_DATA_BASE_REG + 0x07)
> +
> +#define HDMI_TPI_PIXEL_REPETITION_REG	0x08
> +
> +#define HDMI_TPI_AVI_INOUT_BASE_REG	0x09
> +#define HDMI_TPI_AVI_IN_FORMAT_REG	(HDMI_TPI_AVI_INOUT_BASE_REG + 0x00)
> +#define HDMI_TPI_AVI_OUT_FORMAT_REG	(HDMI_TPI_AVI_INOUT_BASE_REG + 0x01)
> +
> +#define HDMI_SYS_CTRL_DATA_REG		0x1A
> +
> +#define HDMI_TPI_SYN_GENERATOR_REG	0x60
> +
> +#define HDMI_TPI_VIDEO_SYN_POLARITY_REG	0x61
> +
> +#define HDMI_TPI_DE_BASE_REG			0x62
> +#define HDMI_TPI_DE_DLY_LSB_REG		(HDMI_TPI_DE_BASE_REG + 0x0)
> +#define HDMI_TPI_DE_DLY_MSB_REG		(HDMI_TPI_DE_BASE_REG + 0x1)
> +#define HDMI_TPI_DE_TOP_REG			(HDMI_TPI_DE_BASE_REG + 0x2)
> +#define HDMI_TPI_DE_RSVD_REG			(HDMI_TPI_DE_BASE_REG + 0x3)
> +#define HDMI_TPI_DE_CNT_LSB_REG		(HDMI_TPI_DE_BASE_REG + 0x4)
> +#define HDMI_TPI_DE_CNT_MSB_REG		(HDMI_TPI_DE_BASE_REG + 0x5)
> +#define HDMI_TPI_DE_LIN_LSB_REG		(HDMI_TPI_DE_BASE_REG + 0x6)
> +#define HDMI_TPI_DE_LIN_MSB_REG		(HDMI_TPI_DE_BASE_REG + 0x7)
> +
> +#define HDMI_TPI_HRES_LSB_REG		0x6A
> +#define HDMI_TPI_HRES_MSB_REG		0x6B
> +
> +#define HDMI_TPI_VRES_LSB_REG		0x6C
> +#define HDMI_TPI_VRES_MSB_REG		0x6D
> +
> +#define HDMI_TPI_RQB_REG		0xC7
> +#define HDMI_TPI_DEVID_REG		0x1B
> +#define HDMI_TPI_DEVREV_REG		0x1C
> +
> +#define HDMI_TPI_DEVICE_POWER_STATE_DATA	0x1E
> +#define HDMI_REQ_GRANT_BMODE_REG		0xC7
> +#define HDMI_TPI_DEVICE_ID_REG			0x1B
> +#define HDMI_TPI_REVISION_REG			0x1C
> +#define HDMI_TPI_ID_BYTE2_REG			0x1D
> +#define HDMI_TPI_POWER_STATE_CTRL_REG		0x1E
> +
> +#define HDMI_TPI_INTERRUPT_ENABLE_REG		0x3C
> +#define HDMI_TPI_INTERRUPT_STATUS_REG		0x3D
> +
> +
> +/* AVI InfoFrames can be readed byte by byte but must be write in a burst  */
> +#define HDMI_TPI_AVI_DBYTE_BASE_REG      0x0C
> +#define HDMI_TPI_AVI_DBYTE0_CHKSUM_REG   (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x00)
> +#define HDMI_TPI_AVI_DBYTE1_REG          (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x01)
> +#define HDMI_TPI_AVI_DBYTE2_REG          (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x02)
> +#define HDMI_TPI_AVI_DBYTE3_REG          (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x03)
> +#define HDMI_TPI_AVI_DBYTE4_REG          (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x04)
> +#define HDMI_TPI_AVI_DBYTE5_REG          (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x05)
> +#define HDMI_TPI_AVI_ETB_LSB_REG         (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x06)
> +#define HDMI_TPI_AVI_ETB_MSB_REG         (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x07)
> +#define HDMI_TPI_AVI_SBB_LSB_REG         (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x08)
> +#define HDMI_TPI_AVI_SBB_MSB_REG         (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x09)
> +#define HDMI_TPI_AVI_ELB_LSB_REG         (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x0A)
> +#define HDMI_TPI_AVI_ELB_MSB_REG         (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x0B)
> +#define HDMI_TPI_AVI_SRB_LSB_REG         (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x0C)
> +#define HDMI_TPI_AVI_SRB_MSB_REG         (HDMI_TPI_AVI_DBYTE_BASE_REG +  0x0D)
> +
> +#define HDMI_CPI_MISC_IF_SELECT_REG         0xBF
> +#define HDMI_CPI_MISC_IF_OFFSET             0xC0
> +
> +#define MISC_INFOFRAME_SIZE_MEMORY          14
> +#define MISC_INFOFRAME_TYPE_SUBOFFSET       0
> +#define MISC_INFOFRAME_VERSION_SUBOFFSET    1
> +#define MISC_INFOFRAME_LENGTH_SUBOFFSET     2
> +#define MISC_INFOFRAME_CHECKSUM_SUBOFFSET   3
> +#define MISC_INFOFRAME_DBYTE1_SUBOFFSET     4
> +#define MISC_INFOFRAME_DBYTE2_SUBOFFSET     5
> +#define MISC_INFOFRAME_DBYTE3_SUBOFFSET     6
> +#define MISC_INFOFRAME_DBYTE4_SUBOFFSET     7
> +#define MISC_INFOFRAME_DBYTE5_SUBOFFSET     8
> +#define MISC_INFOFRAME_DBYTE6_SUBOFFSET     9
> +#define MISC_INFOFRAME_DBYTE7_SUBOFFSET     10
> +#define MISC_INFOFRAME_DBYTE8_SUBOFFSET     11
> +#define MISC_INFOFRAME_DBYTE9_SUBOFFSET     12
> +#define MISC_INFOFRAME_DBYTE10_SUBOFFSET    13
> +
> +#define HDMI_CPI_MISC_TYPE_REG		(HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_TYPE_SUBOFFSET)
> +#define HDMI_CPI_MISC_VERSION_REG	(HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_VERSION_SUBOFFSET)
> +#define HDMI_CPI_MISC_LENGTH_REG	(HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_LENGTH_SUBOFFSET)
> +#define HDMI_CPI_MISC_CHECKSUM_REG	(HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_CHECKSUM_SUBOFFSET)
> +#define HDMI_CPI_MISC_DBYTE1_REG        (HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_DBYTE1_SUBOFFSET)
> +#define HDMI_CPI_MISC_DBYTE2_REG        (HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_DBYTE2_SUBOFFSET)
> +#define HDMI_CPI_MISC_DBYTE3_REG        (HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_DBYTE3_SUBOFFSET)
> +#define HDMI_CPI_MISC_DBYTE4_REG        (HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_DBYTE4_SUBOFFSET)
> +#define HDMI_CPI_MISC_DBYTE5_REG        (HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_DBYTE5_SUBOFFSET)
> +#define HDMI_CPI_MISC_DBYTE6_REG        (HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_DBYTE6_SUBOFFSET)
> +#define HDMI_CPI_MISC_DBYTE7_REG        (HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_DBYTE7_SUBOFFSET)
> +#define HDMI_CPI_MISC_DBYTE8_REG        (HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_DBYTE8_SUBOFFSET)
> +#define HDMI_CPI_MISC_DBYTE9_REG        (HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_DBYTE9_SUBOFFSET)
> +#define HDMI_CPI_MISC_DBYTE10_REG       (HDMI_CPI_MISC_IF_OFFSET\
> +					+  MISC_INFOFRAME_DBYTE10_SUBOFFSET)
> +
> +/* Audio  */
> +#define HDMI_TPI_I2S_ENABLE_MAPPING_REG     0x1F
> +#define HDMI_TPI_I2S_INPUT_CONFIG_REG       0x20
> +#define HDMI_TPI_I2S_STRM_HDR_BASE          0x21
> +#define HDMI_TPI_I2S_STRM_HDR_0_REG         (HDMI_TPI_I2S_STRM_HDR_BASE + 0)
> +#define HDMI_TPI_I2S_STRM_HDR_1_REG         (HDMI_TPI_I2S_STRM_HDR_BASE + 1)
> +#define HDMI_TPI_I2S_STRM_HDR_2_REG         (HDMI_TPI_I2S_STRM_HDR_BASE + 2)
> +#define HDMI_TPI_I2S_STRM_HDR_3_REG         (HDMI_TPI_I2S_STRM_HDR_BASE + 3)
> +#define HDMI_TPI_I2S_STRM_HDR_4_REG         (HDMI_TPI_I2S_STRM_HDR_BASE + 4)
> +#define HDMI_TPI_AUDIO_CONFIG_BYTE2_REG     0x26
> +#define HDMI_TPI_AUDIO_CONFIG_BYTE3_REG     0x27
> +#define HDMI_TPI_AUDIO_CONFIG_BYTE4_REG     0x28
> +
> +/* HDCP */
> +#define HDMI_TPI_HDCP_QUERYDATA_REG         0x29
> +#define HDMI_TPI_HDCP_CONTROLDATA_REG       0x2A
> +
> +/* HDMI_TPI_DEVICE_ID_REG  */
> +#define TPI_DEVICE_ID                       0xB0
> +
> +/* HDMI_TPI_REVISION_REG  */
> +#define TPI_REVISION                        0x00
> +
> +/* HDMI_TPI_ID_BYTE2_REG  */
> +#define TPI_ID_BYTE2_VALUE                  0x00
> +
> +/* HDMI_SYS_CTRL_DATA_REG  */
> +#define TPI_SYS_CTRL_POWER_DOWN             (1 << 4)
> +#define TPI_SYS_CTRL_POWER_ACTIVE           (0 << 4)
> +#define TPI_SYS_CTRL_AV_MUTE                (1 << 3)
> +#define TPI_SYS_CTRL_DDC_BUS_REQUEST        (1 << 2)
> +#define TPI_SYS_CTRL_DDC_BUS_GRANTED        (1 << 1)
> +#define TPI_SYS_CTRL_OUTPUT_MODE_HDMI       (1 << 0)
> +#define TPI_SYS_CTRL_OUTPUT_MODE_DVI        (0 << 0)
> +
> +
> +/* HDMI Monitor I2C default address  */
> +#define HDMI_I2C_MONITOR_ADDRESS            0x50
> +
> +
> +/* HDMI_TPI_INTR_ENABLE  */
> +#define TPI_INTR_ENABLE_SECURITY_EVENT      (1 << 5)
> +#define TPI_INTR_ENABLE_AUDIO_EVENT         (1 << 4)
> +#define TPI_INTR_ENABLE_CPI_EVENT           (1 << 3)
> +#define TPI_INTR_ENABLE_RECEIVER_EVENT      (1 << 1)
> +#define TPI_INTR_ENABLE_HOTPLUG_EVENT       (1 << 0)
> +
> +/* HDMI_TPI_INTR_STATUS  */
> +#define TPI_INTR_STATUS_SECURITY_EVENT      (1 << 5)
> +#define TPI_INTR_STATUS_AUDIO_EVENT         (1 << 4)
> +#define TPI_INTR_STATUS_POWERED_EVENT       (1 << 3)
> +#define TPI_INTR_STATUS_HOTPLUG_STATE       (1 << 2)
> +#define TPI_INTR_STATUS_RECEIVER_EVENT      (1 << 1)
> +#define TPI_INTR_STATUS_HOTPLUG_EVENT       (1 << 0)
> +
> +
> +/* HDMI_TPI_PIXEL_REPETITION  */
> +#define TPI_AVI_PIXEL_REP_BUS_24BIT         (1 << 5)
> +#define TPI_AVI_PIXEL_REP_BUS_12BIT         (0 << 5)
> +#define TPI_AVI_PIXEL_REP_RISING_EDGE       (1 << 4)
> +#define TPI_AVI_PIXEL_REP_FALLING_EDGE      (0 << 4)
> +#define TPI_AVI_PIXEL_REP_4X                (3 << 0)
> +#define TPI_AVI_PIXEL_REP_2X                (1 << 0)
> +#define TPI_AVI_PIXEL_REP_NONE              (0 << 0)
> +
> +/* HDMI_TPI_AVI_INPUT_FORMAT  */
> +#define TPI_AVI_INPUT_BITMODE_12BIT         (1 << 7)
> +#define TPI_AVI_INPUT_BITMODE_8BIT          (0 << 7)
> +#define TPI_AVI_INPUT_DITHER                (1 << 6)
> +#define TPI_AVI_INPUT_RANGE_LIMITED         (2 << 2)
> +#define TPI_AVI_INPUT_RANGE_FULL            (1 << 2)
> +#define TPI_AVI_INPUT_RANGE_AUTO            (0 << 2)
> +#define TPI_AVI_INPUT_COLORSPACE_BLACK      (3 << 0)
> +#define TPI_AVI_INPUT_COLORSPACE_YUV422     (2 << 0)
> +#define TPI_AVI_INPUT_COLORSPACE_YUV444     (1 << 0)
> +#define TPI_AVI_INPUT_COLORSPACE_RGB        (0 << 0)
> +
> +
> +/* HDMI_TPI_AVI_OUTPUT_FORMAT  */
> +#define TPI_AVI_OUTPUT_CONV_BT709           (1 << 4)
> +#define TPI_AVI_OUTPUT_CONV_BT601           (0 << 4)
> +#define TPI_AVI_OUTPUT_RANGE_LIMITED        (2 << 2)
> +#define TPI_AVI_OUTPUT_RANGE_FULL           (1 << 2)
> +#define TPI_AVI_OUTPUT_RANGE_AUTO           (0 << 2)
> +#define TPI_AVI_OUTPUT_COLORSPACE_RGBDVI    (3 << 0)
> +#define TPI_AVI_OUTPUT_COLORSPACE_YUV422    (2 << 0)
> +#define TPI_AVI_OUTPUT_COLORSPACE_YUV444    (1 << 0)
> +#define TPI_AVI_OUTPUT_COLORSPACE_RGBHDMI   (0 << 0)
> +
> +
> +/* HDMI_TPI_DEVICE_POWER_STATE  */
> +#define TPI_AVI_POWER_STATE_D3              (3 << 0)
> +#define TPI_AVI_POWER_STATE_D2              (2 << 0)
> +#define TPI_AVI_POWER_STATE_D0              (0 << 0)
> +
> +/* HDMI_TPI_AUDIO_CONFIG_BYTE2_REG  */
> +#define TPI_AUDIO_CODING_STREAM_HEADER      (0 << 0)
> +#define TPI_AUDIO_CODING_PCM                (1 << 0)
> +#define TPI_AUDIO_CODING_AC3                (2 << 0)
> +#define TPI_AUDIO_CODING_MPEG1              (3 << 0)
> +#define TPI_AUDIO_CODING_MP3                (4 << 0)
> +#define TPI_AUDIO_CODING_MPEG2              (5 << 0)
> +#define TPI_AUDIO_CODING_AAC                (6 << 0)
> +#define TPI_AUDIO_CODING_DTS                (7 << 0)
> +#define TPI_AUDIO_CODING_ATRAC              (8 << 0)
> +#define TPI_AUDIO_MUTE_DISABLE              (0 << 4)
> +#define TPI_AUDIO_MUTE_ENABLE               (1 << 4)
> +#define TPI_AUDIO_INTERFACE_DISABLE         (0 << 6)
> +#define TPI_AUDIO_INTERFACE_SPDIF           (1 << 6)
> +#define TPI_AUDIO_INTERFACE_I2S             (2 << 6)
> +
> +/* HDMI_TPI_AUDIO_CONFIG_BYTE3_REG  */
> +#define TPI_AUDIO_CHANNEL_STREAM            (0 << 0)
> +#define TPI_AUDIO_2_CHANNEL                 (1 << 0)
> +#define TPI_AUDIO_8_CHANNEL                 (7 << 0)
> +#define TPI_AUDIO_FREQ_STREAM               (0 << 3)
> +#define TPI_AUDIO_FREQ_32KHZ                (1 << 3)
> +#define TPI_AUDIO_FREQ_44KHZ                (2 << 3)
> +#define TPI_AUDIO_FREQ_48KHZ                (3 << 3)
> +#define TPI_AUDIO_FREQ_88KHZ                (4 << 3)
> +#define TPI_AUDIO_FREQ_96KHZ                (5 << 3)
> +#define TPI_AUDIO_FREQ_176KHZ               (6 << 3)
> +#define TPI_AUDIO_FREQ_192KHZ               (7 << 3)
> +#define TPI_AUDIO_SAMPLE_SIZE_STREAM        (0 << 6)
> +#define TPI_AUDIO_SAMPLE_SIZE_16            (1 << 6)
> +#define TPI_AUDIO_SAMPLE_SIZE_20            (2 << 6)
> +#define TPI_AUDIO_SAMPLE_SIZE_24            (3 << 6)
> +
> +/* HDMI_TPI_I2S_ENABLE_MAPPING_REG  */
> +#define TPI_I2S_SD_CONFIG_SELECT_SD0        (0 << 0)
> +#define TPI_I2S_SD_CONFIG_SELECT_SD1        (1 << 0)
> +#define TPI_I2S_SD_CONFIG_SELECT_SD2        (2 << 0)
> +#define TPI_I2S_SD_CONFIG_SELECT_SD3        (3 << 0)
> +#define TPI_I2S_LF_RT_SWAP_NO               (0 << 2)
> +#define TPI_I2S_LF_RT_SWAP_YES              (1 << 2)
> +#define TPI_I2S_DOWNSAMPLE_DISABLE          (0 << 3)
> +#define TPI_I2S_DOWNSAMPLE_ENABLE           (1 << 3)
> +#define TPI_I2S_SD_FIFO_0                   (0 << 4)
> +#define TPI_I2S_SD_FIFO_1                   (1 << 4)
> +#define TPI_I2S_SD_FIFO_2                   (2 << 4)
> +#define TPI_I2S_SD_FIFO_3                   (3 << 4)
> +#define TPI_I2S_SD_CHANNEL_DISABLE          (0 << 7)
> +#define TPI_I2S_SD_CHANNEL_ENABLE           (1 << 7)
> +
> +
> +/* HDMI_TPI_I2S_INPUT_CONFIG_REG  */
> +#define TPI_I2S_FIRST_BIT_SHIFT_YES         (0 << 0)
> +#define TPI_I2S_FIRST_BIT_SHIFT_NO          (1 << 0)
> +#define TPI_I2S_SD_DIRECTION_MSB_FIRST      (0 << 1)
> +#define TPI_I2S_SD_DIRECTION_LSB_FIRST      (1 << 1)
> +#define TPI_I2S_SD_JUSTIFY_LEFT             (0 << 2)
> +#define TPI_I2S_SD_JUSTIFY_RIGHT            (1 << 2)
> +#define TPI_I2S_WS_POLARITY_LOW             (0 << 3)
> +#define TPI_I2S_WS_POLARITY_HIGH            (1 << 3)
> +#define TPI_I2S_MCLK_MULTIPLIER_128         (0 << 4)
> +#define TPI_I2S_MCLK_MULTIPLIER_256         (1 << 4)
> +#define TPI_I2S_MCLK_MULTIPLIER_384         (2 << 4)
> +#define TPI_I2S_MCLK_MULTIPLIER_512         (3 << 4)
> +#define TPI_I2S_MCLK_MULTIPLIER_768         (4 << 4)
> +#define TPI_I2S_MCLK_MULTIPLIER_1024        (5 << 4)
> +#define TPI_I2S_MCLK_MULTIPLIER_1152        (6 << 4)
> +#define TPI_I2S_MCLK_MULTIPLIER_192         (7 << 4)
> +#define TPI_I2S_SCK_EDGE_FALLING            (0 << 7)
> +#define TPI_I2S_SCK_EDGE_RISING             (1 << 7)
> +
> +/* HDMI_TPI_I2S_STRM_HDR_REG                       */
> +/* the reference of this values is in IEC 60958-3  */
> +#define I2S_CHAN_STATUS_MODE                0x00
> +#define I2S_CHAN_STATUS_CAT_CODE            0x00
> +#define I2S_CHAN_SOURCE_CHANNEL_NUM         0x00
> +#define I2S_CHAN_ACCURACY_N_44_SAMPLING_FS  0x20
> +#define I2S_CHAN_ACCURACY_N_48_SAMPLING_FS  0x22
> +#define I2S_CHAN_ORIGIN_FS_N_SAMP_LENGTH    0xD2
> +
> +
> +/* MISCELLANOUS INFOFRAME VALUES  */
> +
> +#define HDMI_INFOFRAME_TX_ENABLE            (0x1 << 7)
> +#define HDMI_INFOFRAME_TX_REPEAT            (0x1 << 6)
> +#define HDMI_AUDIO_INFOFRAME                (0x2 << 0)
> +
> +/* Stream Header Data  */
> +#define HDMI_SH_PCM                         (0x1 << 4)
> +#define HDMI_SH_TWO_CHANNELS                (0x1 << 0)
> +#define HDMI_SH_44KHz                       (0x2 << 2)
> +#define HDMI_SH_48KHz                       (0x3 << 2)
> +#define HDMI_SH_16BIT                       (0x1 << 0)
> +#define HDMI_SH_SPKR_FLFR                   0x0
> +#define HDMI_SH_0dB_ATUN                    0x0
> +
> +/* MISC_TYPE  */
> +#define MISC_INFOFRAME_TYPE                 0x04  /* for Audio */
> +#define MISC_INFOFRAME_ALWAYS_SET           0x80
> +
> +/* MISC_VERSION  */
> +#define MISC_INFOFRAME_VERSION              0x01
> +
> +/* MISC_LENGTH  */
> +#define MISC_INFOFRAME_LENGTH               0x0A /*length for Audio infoframe*/
> +#define MISC_INFOFRAME_LENGTH_RSVD_BITS     0xE0
> +
> +/* MISC_DBYTE1                */
> +/* Type, Encoding, Trandport  */
> +#define MISC_DBYTE1_CT_CHK_HEADER_STREAM    0x00
> +
> +/* audio channel count  */
> +#define MISC_DBYTE1_CC_CHK_HEADER_STREAM    0x00
> +#define MISC_DBYTE1_CC_2_CHANNELS           0x01
> +
> +/* MISC_DBYTE2  */
> +/*Sample Size   */
> +#define MISC_DBYTE2_SS_CHK_HEADER_STREAM    0x00  /* for hdmi by default */
> +
> +/* Sampling Frequency  */
> +#define MISC_DBYTE2_SF_CHK_HEADER_STREAM    0x00  /* for hdmi by default */
> +
> +/* MISC_DBYTE3     */
> +/* Code Extention  */
> +#define MISC_DBYTE3_CTX_TAKE_DBYTE1         0x00  /* for hdmi by default */
> +
> +/* MISC_DBYTE4  */
> +#define MISC_DBYTE4                         0x00 /*for no multichannel( */
> +						 /* multichannel means more*/
> +						/* than 2 channels */
> +
> +/* MISC_DBYTE5  */
> +#define MISC_DBYTE5           0x00  /* for no multichannel(multichannel  */
> +					/* means more than 2 channels */
> +
> +struct hdmi_reg_data {
> +	u8 reg_offset;
> +	u8 value;
> +};
> +
> +#endif
> -- 
> 1.7.9.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux