RE: [PATCH v2 5/7] OMAP: DSS: Adding initialization routine to picodlp panel
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 > > > > > > 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 > > > Signed-off-by: Mayuresh Janorkar > > > --- > > > 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 > > > #include > > > > > > +#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
RE: [PATCH v2 5/7] OMAP: DSS: Adding initialization routine to picodlp panel
> -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 > > > > 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 > > Signed-off-by: Mayuresh Janorkar > > --- > > 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 > > #include > > > > +#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 majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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 > > 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 > Signed-off-by: Mayuresh Janorkar > --- > 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 > #include > > +#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 majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 5/7] OMAP: DSS: Adding initialization routine to picodlp panel
From: Mythri P K 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 Signed-off-by: Mayuresh Janorkar --- 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 #include +#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}, +