diff mbox

[v2,5/7] OMAP: DSS: Adding initialization routine to picodlp panel

Message ID 1304347971-1504-6-git-send-email-mayur@ti.com (mailing list archive)
State Rejected
Delegated to: Tomi Valkeinen
Headers show

Commit Message

MAYURESH JANORKAR May 2, 2011, 2:52 p.m. UTC
From: Mythri P K <mythripk@ti.com>

picodlp_i2c_client needs to send commands over i2c as a part of initialiazation.
system controller dlp pico processor dpp2600 is used.
It configures the splash screen of picodlp using a sequence of commands.
A programmer's guide is available at:
http://focus.ti.com/lit/ug/dlpu002a/dlpu002a.pdf

API is defined for sending command over i2c as an i2c_write operation.

Signed-off-by: Mythri P K <mythripk@ti.com>
Signed-off-by: Mayuresh Janorkar <mayur@ti.com>
---
Changes since v1:
	1. Removed initial splash screen
	2. i2c_commands regrouped
	3. Removed long msleep
	4. Added try-after-sleep in i2c_write

 drivers/video/omap2/displays/panel-picodlp.c |  212 ++++++++++++++++++++++++++
 1 files changed, 212 insertions(+), 0 deletions(-)

Comments

Tomi Valkeinen May 3, 2011, 6:58 p.m. UTC | #1
On Mon, 2011-05-02 at 20:22 +0530, Mayuresh Janorkar wrote:
> From: Mythri P K <mythripk@ti.com>
> 
> picodlp_i2c_client needs to send commands over i2c as a part of initialiazation.
> system controller dlp pico processor dpp2600 is used.
> It configures the splash screen of picodlp using a sequence of commands.
> A programmer's guide is available at:
> http://focus.ti.com/lit/ug/dlpu002a/dlpu002a.pdf
> 
> API is defined for sending command over i2c as an i2c_write operation.
> 
> Signed-off-by: Mythri P K <mythripk@ti.com>
> Signed-off-by: Mayuresh Janorkar <mayur@ti.com>
> ---
> Changes since v1:
> 	1. Removed initial splash screen
> 	2. i2c_commands regrouped
> 	3. Removed long msleep
> 	4. Added try-after-sleep in i2c_write
> 
>  drivers/video/omap2/displays/panel-picodlp.c |  212 ++++++++++++++++++++++++++
>  1 files changed, 212 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
> index fdbfdcf..493a411 100644
> --- a/drivers/video/omap2/displays/panel-picodlp.c
> +++ b/drivers/video/omap2/displays/panel-picodlp.c
> @@ -32,7 +32,15 @@
>  #include <plat/display.h>
>  #include <plat/panel-picodlp.h>
>  
> +#include "panel-picodlp.h"
> +
>  #define DRIVER_NAME	"picodlp_i2c_driver"
> +
> +/* This defines the minit of data which is allowed into single write block */
> +#define MAX_I2C_WRITE_BLOCK_SIZE	32
> +#define PICO_MAJOR			1 /* 2 bits */
> +#define PICO_MINOR			1 /* 2 bits */
> +
>  struct picodlp_data {
>  	struct mutex lock;
>  	struct i2c_client *picodlp_i2c_client;
> @@ -50,6 +58,11 @@ struct i2c_device_id picodlp_i2c_id[] = {
>  	{ "picodlp_i2c_driver", 0 },
>  };
>  
> +struct picodlp_i2c_command {
> +	u8 reg;
> +	u32 value;
> +};
> +
>  static struct omap_video_timings pico_ls_timings = {
>  	.x_res		= 864,
>  	.y_res		= 480,
> @@ -70,6 +83,197 @@ static inline struct picodlp_panel_data
>  	return (struct picodlp_panel_data *) dssdev->data;
>  }
>  
> +static int picodlp_i2c_write_block(struct i2c_client *client,
> +					u8 *data, int len)
> +{
> +	struct i2c_msg msg;
> +	int i, r, msg_count = 1, trial = 4;
> +
> +	struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
> +
> +	if (len < 1 || len > MAX_I2C_WRITE_BLOCK_SIZE) {
> +		dev_err(&client->dev,
> +			"too long syn_write_block len %d\n", len);
> +		return -EIO;
> +	}
> +retry:
> +	mutex_lock(&picodlp_i2c_data->xfer_lock);
> +
> +	msg.addr = client->addr;
> +	msg.flags = 0;
> +	msg.len = len;
> +	msg.buf = data;
> +	r = i2c_transfer(client->adapter, &msg, msg_count);
> +	mutex_unlock(&picodlp_i2c_data->xfer_lock);
> +
> +	/*
> +	 * i2c_transfer returns:
> +	 * number of messages sent in case of success
> +	 * a negative error number in case of failure
> +	 * i2c controller might timeout, in such a case sleep for sometime
> +	 * and then retry
> +	 */
> +	if (r != msg_count) {
> +		msleep(2);
> +		if (trial--)
> +			goto retry;

This is not good. Hacks like these should only be used as a last option.

I'm still saying that you should find the document mentioned in the
documents you have. I refuse to believe that we (TI) do not know what
our hardware does, especially in a basic issue like this.

I'm 99% sure there is documentation telling the required power-up
sequence. And if that 1% happens, we should find the HW designers and
yell at them until they make the documents.

 Tomi


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
MAYURESH JANORKAR May 4, 2011, 2:31 p.m. UTC | #2
> -----Original Message-----
> From: Valkeinen, Tomi
> Sent: Wednesday, May 04, 2011 12:28 AM
> To: Janorkar, Mayuresh
> Cc: linux-omap@vger.kernel.org; K, Mythri P
> Subject: Re: [PATCH v2 5/7] OMAP: DSS: Adding initialization routine to
> picodlp panel
> 
> On Mon, 2011-05-02 at 20:22 +0530, Mayuresh Janorkar wrote:
> > From: Mythri P K <mythripk@ti.com>
> >
> > picodlp_i2c_client needs to send commands over i2c as a part of
> initialiazation.
> > system controller dlp pico processor dpp2600 is used.
> > It configures the splash screen of picodlp using a sequence of commands.
> > A programmer's guide is available at:
> > http://focus.ti.com/lit/ug/dlpu002a/dlpu002a.pdf
> >
> > API is defined for sending command over i2c as an i2c_write operation.
> >
> > Signed-off-by: Mythri P K <mythripk@ti.com>
> > Signed-off-by: Mayuresh Janorkar <mayur@ti.com>
> > ---
> > Changes since v1:
> > 	1. Removed initial splash screen
> > 	2. i2c_commands regrouped
> > 	3. Removed long msleep
> > 	4. Added try-after-sleep in i2c_write
> >
> >  drivers/video/omap2/displays/panel-picodlp.c |  212
> ++++++++++++++++++++++++++
> >  1 files changed, 212 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/video/omap2/displays/panel-picodlp.c
> b/drivers/video/omap2/displays/panel-picodlp.c
> > index fdbfdcf..493a411 100644
> > --- a/drivers/video/omap2/displays/panel-picodlp.c
> > +++ b/drivers/video/omap2/displays/panel-picodlp.c
> > @@ -32,7 +32,15 @@
> >  #include <plat/display.h>
> >  #include <plat/panel-picodlp.h>
> >
> > +#include "panel-picodlp.h"
> > +
> >  #define DRIVER_NAME	"picodlp_i2c_driver"
> > +
> > +/* This defines the minit of data which is allowed into single write
> block */
> > +#define MAX_I2C_WRITE_BLOCK_SIZE	32
> > +#define PICO_MAJOR			1 /* 2 bits */
> > +#define PICO_MINOR			1 /* 2 bits */
> > +
> >  struct picodlp_data {
> >  	struct mutex lock;
> >  	struct i2c_client *picodlp_i2c_client;
> > @@ -50,6 +58,11 @@ struct i2c_device_id picodlp_i2c_id[] = {
> >  	{ "picodlp_i2c_driver", 0 },
> >  };
> >
> > +struct picodlp_i2c_command {
> > +	u8 reg;
> > +	u32 value;
> > +};
> > +
> >  static struct omap_video_timings pico_ls_timings = {
> >  	.x_res		= 864,
> >  	.y_res		= 480,
> > @@ -70,6 +83,197 @@ static inline struct picodlp_panel_data
> >  	return (struct picodlp_panel_data *) dssdev->data;
> >  }
> >
> > +static int picodlp_i2c_write_block(struct i2c_client *client,
> > +					u8 *data, int len)
> > +{
> > +	struct i2c_msg msg;
> > +	int i, r, msg_count = 1, trial = 4;
> > +
> > +	struct picodlp_i2c_data *picodlp_i2c_data =
> i2c_get_clientdata(client);
> > +
> > +	if (len < 1 || len > MAX_I2C_WRITE_BLOCK_SIZE) {
> > +		dev_err(&client->dev,
> > +			"too long syn_write_block len %d\n", len);
> > +		return -EIO;
> > +	}
> > +retry:
> > +	mutex_lock(&picodlp_i2c_data->xfer_lock);
> > +
> > +	msg.addr = client->addr;
> > +	msg.flags = 0;
> > +	msg.len = len;
> > +	msg.buf = data;
> > +	r = i2c_transfer(client->adapter, &msg, msg_count);
> > +	mutex_unlock(&picodlp_i2c_data->xfer_lock);
> > +
> > +	/*
> > +	 * i2c_transfer returns:
> > +	 * number of messages sent in case of success
> > +	 * a negative error number in case of failure
> > +	 * i2c controller might timeout, in such a case sleep for sometime
> > +	 * and then retry
> > +	 */
> > +	if (r != msg_count) {
> > +		msleep(2);
> > +		if (trial--)
> > +			goto retry;
> 
> This is not good. Hacks like these should only be used as a last option.
> 
> I'm still saying that you should find the document mentioned in the
> documents you have. I refuse to believe that we (TI) do not know what
> our hardware does, especially in a basic issue like this.
> 
> I'm 99% sure there is documentation telling the required power-up
> sequence. And if that 1% happens, we should find the HW designers and
> yell at them until they make the documents.

Yes it is mentioned.
You can check it here:
https://focus.ti.com/myti/docs/extranet.tsp?sectionId=403

A delay is required after i2c client creation and it is 1 second.
So this part of code would be removed.

> 
>  Tomi
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tomi Valkeinen May 5, 2011, 9:35 a.m. UTC | #3
On Wed, 2011-05-04 at 20:01 +0530, Janorkar, Mayuresh wrote:
> 
> > -----Original Message-----
> > From: Valkeinen, Tomi
> > Sent: Wednesday, May 04, 2011 12:28 AM
> > To: Janorkar, Mayuresh
> > Cc: linux-omap@vger.kernel.org; K, Mythri P
> > Subject: Re: [PATCH v2 5/7] OMAP: DSS: Adding initialization routine to
> > picodlp panel
> > 
> > On Mon, 2011-05-02 at 20:22 +0530, Mayuresh Janorkar wrote:
> > > From: Mythri P K <mythripk@ti.com>
> > >
> > > picodlp_i2c_client needs to send commands over i2c as a part of
> > initialiazation.
> > > system controller dlp pico processor dpp2600 is used.
> > > It configures the splash screen of picodlp using a sequence of commands.
> > > A programmer's guide is available at:
> > > http://focus.ti.com/lit/ug/dlpu002a/dlpu002a.pdf
> > >
> > > API is defined for sending command over i2c as an i2c_write operation.
> > >
> > > Signed-off-by: Mythri P K <mythripk@ti.com>
> > > Signed-off-by: Mayuresh Janorkar <mayur@ti.com>
> > > ---
> > > Changes since v1:
> > > 	1. Removed initial splash screen
> > > 	2. i2c_commands regrouped
> > > 	3. Removed long msleep
> > > 	4. Added try-after-sleep in i2c_write
> > >
> > >  drivers/video/omap2/displays/panel-picodlp.c |  212
> > ++++++++++++++++++++++++++
> > >  1 files changed, 212 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/drivers/video/omap2/displays/panel-picodlp.c
> > b/drivers/video/omap2/displays/panel-picodlp.c
> > > index fdbfdcf..493a411 100644
> > > --- a/drivers/video/omap2/displays/panel-picodlp.c
> > > +++ b/drivers/video/omap2/displays/panel-picodlp.c
> > > @@ -32,7 +32,15 @@
> > >  #include <plat/display.h>
> > >  #include <plat/panel-picodlp.h>
> > >
> > > +#include "panel-picodlp.h"
> > > +
> > >  #define DRIVER_NAME	"picodlp_i2c_driver"
> > > +
> > > +/* This defines the minit of data which is allowed into single write
> > block */
> > > +#define MAX_I2C_WRITE_BLOCK_SIZE	32
> > > +#define PICO_MAJOR			1 /* 2 bits */
> > > +#define PICO_MINOR			1 /* 2 bits */
> > > +
> > >  struct picodlp_data {
> > >  	struct mutex lock;
> > >  	struct i2c_client *picodlp_i2c_client;
> > > @@ -50,6 +58,11 @@ struct i2c_device_id picodlp_i2c_id[] = {
> > >  	{ "picodlp_i2c_driver", 0 },
> > >  };
> > >
> > > +struct picodlp_i2c_command {
> > > +	u8 reg;
> > > +	u32 value;
> > > +};
> > > +
> > >  static struct omap_video_timings pico_ls_timings = {
> > >  	.x_res		= 864,
> > >  	.y_res		= 480,
> > > @@ -70,6 +83,197 @@ static inline struct picodlp_panel_data
> > >  	return (struct picodlp_panel_data *) dssdev->data;
> > >  }
> > >
> > > +static int picodlp_i2c_write_block(struct i2c_client *client,
> > > +					u8 *data, int len)
> > > +{
> > > +	struct i2c_msg msg;
> > > +	int i, r, msg_count = 1, trial = 4;
> > > +
> > > +	struct picodlp_i2c_data *picodlp_i2c_data =
> > i2c_get_clientdata(client);
> > > +
> > > +	if (len < 1 || len > MAX_I2C_WRITE_BLOCK_SIZE) {
> > > +		dev_err(&client->dev,
> > > +			"too long syn_write_block len %d\n", len);
> > > +		return -EIO;
> > > +	}
> > > +retry:
> > > +	mutex_lock(&picodlp_i2c_data->xfer_lock);
> > > +
> > > +	msg.addr = client->addr;
> > > +	msg.flags = 0;
> > > +	msg.len = len;
> > > +	msg.buf = data;
> > > +	r = i2c_transfer(client->adapter, &msg, msg_count);
> > > +	mutex_unlock(&picodlp_i2c_data->xfer_lock);
> > > +
> > > +	/*
> > > +	 * i2c_transfer returns:
> > > +	 * number of messages sent in case of success
> > > +	 * a negative error number in case of failure
> > > +	 * i2c controller might timeout, in such a case sleep for sometime
> > > +	 * and then retry
> > > +	 */
> > > +	if (r != msg_count) {
> > > +		msleep(2);
> > > +		if (trial--)
> > > +			goto retry;
> > 
> > This is not good. Hacks like these should only be used as a last option.
> > 
> > I'm still saying that you should find the document mentioned in the
> > documents you have. I refuse to believe that we (TI) do not know what
> > our hardware does, especially in a basic issue like this.
> > 
> > I'm 99% sure there is documentation telling the required power-up
> > sequence. And if that 1% happens, we should find the HW designers and
> > yell at them until they make the documents.
> 
> Yes it is mentioned.
> You can check it here:
> https://focus.ti.com/myti/docs/extranet.tsp?sectionId=403
> 
> A delay is required after i2c client creation and it is 1 second.
> So this part of code would be removed.

The document says that time between when PWRGOOD goes high and when the
first i2c command can be sent is 1 second. (although I have no idea what
PWRGOOD is since the gpio names in the code do not match any documents).

In that case you should probably store the current time when PWRGOOD is
set high, and wait before sending the first i2c commands so that one
second has passed since PWRGOOD.

If that happens in the same function it's most likely just the same to
use msleep(1) there.

 Tomi


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index fdbfdcf..493a411 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -32,7 +32,15 @@ 
 #include <plat/display.h>
 #include <plat/panel-picodlp.h>
 
+#include "panel-picodlp.h"
+
 #define DRIVER_NAME	"picodlp_i2c_driver"
+
+/* This defines the minit of data which is allowed into single write block */
+#define MAX_I2C_WRITE_BLOCK_SIZE	32
+#define PICO_MAJOR			1 /* 2 bits */
+#define PICO_MINOR			1 /* 2 bits */
+
 struct picodlp_data {
 	struct mutex lock;
 	struct i2c_client *picodlp_i2c_client;
@@ -50,6 +58,11 @@  struct i2c_device_id picodlp_i2c_id[] = {
 	{ "picodlp_i2c_driver", 0 },
 };
 
+struct picodlp_i2c_command {
+	u8 reg;
+	u32 value;
+};
+
 static struct omap_video_timings pico_ls_timings = {
 	.x_res		= 864,
 	.y_res		= 480,
@@ -70,6 +83,197 @@  static inline struct picodlp_panel_data
 	return (struct picodlp_panel_data *) dssdev->data;
 }
 
+static int picodlp_i2c_write_block(struct i2c_client *client,
+					u8 *data, int len)
+{
+	struct i2c_msg msg;
+	int i, r, msg_count = 1, trial = 4;
+
+	struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
+
+	if (len < 1 || len > MAX_I2C_WRITE_BLOCK_SIZE) {
+		dev_err(&client->dev,
+			"too long syn_write_block len %d\n", len);
+		return -EIO;
+	}
+retry:
+	mutex_lock(&picodlp_i2c_data->xfer_lock);
+
+	msg.addr = client->addr;
+	msg.flags = 0;
+	msg.len = len;
+	msg.buf = data;
+	r = i2c_transfer(client->adapter, &msg, msg_count);
+	mutex_unlock(&picodlp_i2c_data->xfer_lock);
+
+	/*
+	 * i2c_transfer returns:
+	 * number of messages sent in case of success
+	 * a negative error number in case of failure
+	 * i2c controller might timeout, in such a case sleep for sometime
+	 * and then retry
+	 */
+	if (r != msg_count) {
+		msleep(2);
+		if (trial--)
+			goto retry;
+
+		dev_err(&client->dev, " picodlp_i2c_write error\n");
+		return r;
+	}
+
+	/* In case of success */
+	for (i = 0; i < len; i++)
+		dev_dbg(&client->dev,
+			"addr %x bw 0x%02x[%d]: 0x%02x\n",
+			client->addr, data[0] + i, i, data[i]);
+
+	return 0;
+}
+
+static int picodlp_i2c_write(struct i2c_client *client, u8 reg, u32 value)
+{
+	u8 data[5];
+	int i;
+
+	data[0] = reg;
+	for (i = 1; i < 5; i++)
+		data[i] = (value >> (32 - (i) * 8)) & 0xFF;
+
+	return picodlp_i2c_write_block(client, data, 5);
+}
+
+static int picodlp_i2c_write_array(struct i2c_client *client,
+			const struct picodlp_i2c_command commands[],
+			int count)
+{
+	int i, r = 0;
+	for (i = 0; i < count; i++) {
+		r = picodlp_i2c_write(client, commands[i].reg,
+						commands[i].value);
+		if (r)
+			return r;
+	}
+	return r;
+}
+/**
+ * picodlp_i2c_init:	i2c_initialization routine
+ * client:	i2c_client for communication
+ *
+ * @return
+ *		0	: Success, no error
+ *	error code	: Failure
+ */
+static int picodlp_i2c_init(struct i2c_client *client)
+{
+	int r;
+	static const struct picodlp_i2c_command init_cmd_set1[] = {
+		{SOFT_RESET, 1},
+		{DMD_PARK_TRIGGER, 1},
+		{MISC_REG, (PICO_MAJOR << 2 | PICO_MINOR)},
+		{SEQ_CONTROL, 0},
+		{SEQ_VECTOR, 0x100},
+		{DMD_BLOCK_COUNT, 7},
+		{DMD_VCC_CONTROL, 0x109},
+		{DMD_PARK_PULSE_COUNT, 0xA},
+		{DMD_PARK_PULSE_WIDTH, 0xB},
+		{DMD_PARK_DELAY, 0x2ED},
+		{DMD_SHADOW_ENABLE, 0},
+		{FLASH_OPCODE, 0xB},
+		{FLASH_DUMMY_BYTES, 1},
+		{FLASH_ADDR_BYTES, 3},
+		{PBC_CONTROL, 0},
+		{FLASH_START_ADDR, CMT_LUT_0_START_ADDR},
+		{FLASH_READ_BYTES, CMT_LUT_0_SIZE},
+		{CMT_SPLASH_LUT_START_ADDR, 0},
+		{CMT_SPLASH_LUT_DEST_SELECT, CMT_LUT_ALL},
+		{PBC_CONTROL, 1},
+	};
+
+	static const struct picodlp_i2c_command init_cmd_set2[] = {
+		{PBC_CONTROL, 0},
+		{CMT_SPLASH_LUT_DEST_SELECT, 0},
+		{PBC_CONTROL, 0},
+		{FLASH_START_ADDR, SEQUENCE_0_START_ADDR},
+		{FLASH_READ_BYTES, SEQUENCE_0_SIZE},
+		{SEQ_RESET_LUT_START_ADDR, 0},
+		{SEQ_RESET_LUT_DEST_SELECT, SEQ_SEQ_LUT},
+		{PBC_CONTROL, 1},
+	};
+
+	static const struct picodlp_i2c_command init_cmd_set3[] = {
+		{PBC_CONTROL, 0},
+		{SEQ_RESET_LUT_DEST_SELECT, 0},
+		{PBC_CONTROL, 0},
+		{FLASH_START_ADDR, DRC_TABLE_0_START_ADDR},
+		{FLASH_READ_BYTES, DRC_TABLE_0_SIZE},
+		{SEQ_RESET_LUT_START_ADDR, 0},
+		{SEQ_RESET_LUT_DEST_SELECT, SEQ_DRC_LUT_ALL},
+		{PBC_CONTROL, 1},
+	};
+
+	static const struct picodlp_i2c_command init_cmd_set4[] = {
+		{PBC_CONTROL, 0},
+		{SEQ_RESET_LUT_DEST_SELECT, 0},
+		{SDC_ENABLE, 1},
+		{AGC_CTRL, 7},
+		{CCA_C1A, 0x100},
+		{CCA_C1B, 0x0},
+		{CCA_C1C, 0x0},
+		{CCA_C2A, 0x0},
+		{CCA_C2B, 0x100},
+		{CCA_C2C, 0x0},
+		{CCA_C3A, 0x0},
+		{CCA_C3B, 0x0},
+		{CCA_C3C, 0x100},
+		{CCA_C7A, 0x100},
+		{CCA_C7B, 0x100},
+		{CCA_C7C, 0x100},
+		{CCA_ENABLE, 1},
+		{CPU_IF_MODE, 1},
+		{SHORT_FLIP, 1},
+		{CURTAIN_CONTROL, 0},
+		{DMD_PARK_TRIGGER, 0},
+		{R_DRIVE_CURRENT, 0x298},
+		{G_DRIVE_CURRENT, 0x298},
+		{B_DRIVE_CURRENT, 0x298},
+		{RGB_DRIVER_ENABLE, 7},
+		{SEQ_CONTROL, 0},
+		{ACTGEN_CONTROL, 0x10},
+		{SEQUENCE_MODE, SEQ_LOCK},
+		{DATA_FORMAT, RGB888},
+		{INPUT_RESOLUTION, WVGA_864_LANDSCAPE},
+		{INPUT_SOURCE, PARALLEL_RGB},
+		{CPU_IF_SYNC_METHOD, 1},
+		{SEQ_CONTROL, 1}
+	};
+
+	r = picodlp_i2c_write_array(client, init_cmd_set1,
+						ARRAY_SIZE(init_cmd_set1));
+	if (r)
+		return r;
+	msleep(2);
+
+	r = picodlp_i2c_write_array(client, init_cmd_set2,
+					ARRAY_SIZE(init_cmd_set2));
+	if (r)
+		return r;
+	msleep(2);
+
+	r = picodlp_i2c_write_array(client, init_cmd_set3,
+					ARRAY_SIZE(init_cmd_set3));
+	if (r)
+		return r;
+	msleep(2);
+
+	r = picodlp_i2c_write_array(client, init_cmd_set4,
+					ARRAY_SIZE(init_cmd_set4));
+	if (r)
+		return r;
+
+	return 0;
+}
+
 static int picodlp_i2c_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
@@ -109,6 +313,7 @@  static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 	int r = 0;
 	struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
 	struct picodlp_panel_data *picodlp_pdata;
+	struct picodlp_i2c_data *picodlp_i2c_data;
 
 	picodlp_pdata = get_panel_data(dssdev);
 	gpio_set_value(picodlp_pdata->display_sel_gpio, 1);
@@ -128,6 +333,13 @@  static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 	}
 	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
 
+	picodlp_i2c_data =
+		i2c_get_clientdata(picod->picodlp_i2c_client);
+
+	r = picodlp_i2c_init(picod->picodlp_i2c_client);
+	if (r)
+		goto err;
+
 	return r;
 err:
 	if (dssdev->platform_disable)