21 #include <linux/device.h>
23 #include <linux/slab.h>
26 #include <linux/module.h>
32 #define MIPID_MODULE_NAME "lcd_mipid"
34 #define MIPID_CMD_READ_DISP_ID 0x04
35 #define MIPID_CMD_READ_RED 0x06
36 #define MIPID_CMD_READ_GREEN 0x07
37 #define MIPID_CMD_READ_BLUE 0x08
38 #define MIPID_CMD_READ_DISP_STATUS 0x09
39 #define MIPID_CMD_RDDSDR 0x0F
40 #define MIPID_CMD_SLEEP_IN 0x10
41 #define MIPID_CMD_SLEEP_OUT 0x11
42 #define MIPID_CMD_DISP_OFF 0x28
43 #define MIPID_CMD_DISP_ON 0x29
45 #define MIPID_ESD_CHECK_PERIOD msecs_to_jiffies(5000)
47 #define to_mipid_device(p) container_of(p, struct mipid_device, \
69 int wlen,
u8 *rbuf,
int rlen)
80 memset(xfer, 0,
sizeof(xfer));
87 spi_message_add_tail(x, &m);
94 spi_message_add_tail(x, &m);
101 spi_message_add_tail(x, &m);
113 spi_message_add_tail(x, &m);
125 static inline void mipid_cmd(
struct mipid_device *md,
int cmd)
127 mipid_transfer(md, cmd,
NULL, 0,
NULL, 0);
133 mipid_transfer(md, reg, buf, len,
NULL, 0);
139 mipid_transfer(md, reg,
NULL, 0, buf, len);
146 switch (data_lines) {
157 mipid_write(md, 0x3a, (
u8 *)&par, 2);
162 u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
164 mipid_write(md, 0xc2, (
u8 *)initpar,
sizeof(initpar));
165 set_data_lines(md, md->
panel.data_lines);
168 static void hw_guard_start(
struct mipid_device *md,
int guard_msec)
178 if ((
long)wait > 0 && wait <= md->hw_guard_wait) {
184 static void set_sleep_mode(
struct mipid_device *md,
int on)
186 int cmd, sleep_time = 50;
194 hw_guard_start(md, 120);
213 static int mipid_set_bklight_level(
struct lcd_panel *panel,
unsigned int level)
216 struct mipid_platform_data *
pd = md->
spi->dev.platform_data;
218 if (pd->get_bklight_max ==
NULL || pd->set_bklight_level ==
NULL)
220 if (level > pd->get_bklight_max(pd))
226 pd->set_bklight_level(pd, level);
231 static unsigned int mipid_get_bklight_level(
struct lcd_panel *panel)
234 struct mipid_platform_data *pd = md->
spi->dev.platform_data;
236 if (pd->get_bklight_level ==
NULL)
238 return pd->get_bklight_level(pd);
241 static unsigned int mipid_get_bklight_max(
struct lcd_panel *panel)
244 struct mipid_platform_data *pd = md->
spi->dev.platform_data;
246 if (pd->get_bklight_max ==
NULL)
249 return pd->get_bklight_max(pd);
252 static unsigned long mipid_get_caps(
struct lcd_panel *panel)
268 switch (md->
panel.data_lines) {
270 pixel = ((red >> 1) << 11) | (green << 5) | (blue >> 1);
274 pixel = ((red >> 3) << 11) | ((green >> 2) << 5) |
285 static int mipid_run_test(
struct lcd_panel *panel,
int test_num)
288 static const u16 test_values[4] = {
289 0x0000, 0xffff, 0xaaaa, 0x5555,
296 for (i = 0; i <
ARRAY_SIZE(test_values); i++) {
307 pixel = read_first_pixel(md);
308 if (pixel == test_values[i])
312 "MIPI LCD RGB I/F test failed: "
313 "expecting %04x, got %04x\n",
314 test_values[i], pixel);
324 static void ls041y3_esd_recover(
struct mipid_device *md)
326 dev_err(&md->
spi->dev,
"performing LCD ESD recovery\n");
327 set_sleep_mode(md, 1);
328 set_sleep_mode(md, 0);
331 static void ls041y3_esd_check_mode1(
struct mipid_device *md)
336 set_sleep_mode(md, 0);
338 dev_dbg(&md->
spi->dev,
"ESD mode 1 state1 %02x state2 %02x\n",
343 if (!((state1 ^ state2) & (1 << 6)))
344 ls041y3_esd_recover(md);
347 static void ls041y3_esd_check_mode2(
struct mipid_device *md)
351 static const struct {
355 } *
rd, rd_ctrl[7] = {
356 { 0xb0, 4, { 0x0101, 0x01fe, } },
357 { 0xb1, 4, { 0x01de, 0x0121, } },
358 { 0xc2, 4, { 0x0100, 0x0100, } },
359 { 0xbd, 2, { 0x0100, } },
360 { 0xc2, 4, { 0x01fc, 0x0103, } },
366 for (i = 0; i < 3; i++,
rd++)
367 mipid_write(md,
rd->cmd, (
u8 *)
rd->wbuf,
rd->wlen);
370 mipid_read(md,
rd->cmd, rbuf, 2);
373 for (i = 0; i < 3; i++,
rd++) {
375 mipid_write(md,
rd->cmd, (
u8 *)
rd->wbuf,
rd->wlen);
378 dev_dbg(&md->
spi->dev,
"ESD mode 2 state %02x\n", rbuf[1]);
380 ls041y3_esd_recover(md);
385 ls041y3_esd_check_mode1(md);
387 ls041y3_esd_check_mode2(md);
390 static void mipid_esd_start_check(
struct mipid_device *md)
397 static void mipid_esd_stop_check(
struct mipid_device *md)
411 mipid_esd_start_check(md);
414 static int mipid_enable(
struct lcd_panel *panel)
424 set_sleep_mode(md, 0);
426 send_init_string(md);
427 set_display_state(md, 1);
429 mipid_esd_start_check(md);
435 static void mipid_disable(
struct lcd_panel *panel)
443 mipid_esd_stop_check(md);
451 mipid_set_bklight_level(panel, 0);
452 set_display_state(md, 0);
453 set_sleep_mode(md, 1);
466 enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10));
468 "LCD panel %senabled by bootloader (status 0x%04x)\n",
469 enabled ?
"" :
"not ", disp_status);
473 static int mipid_init(
struct lcd_panel *panel,
481 dev_err(&md->
spi->dev,
"can't create ESD workqueue\n");
487 md->
enabled = panel_enabled(md);
490 mipid_esd_start_check(md);
497 static void mipid_cleanup(
struct lcd_panel *panel)
502 mipid_esd_stop_check(md);
512 .pixel_clock = 21940,
521 .cleanup = mipid_cleanup,
522 .enable = mipid_enable,
523 .disable = mipid_disable,
524 .get_caps = mipid_get_caps,
525 .set_bklight_level = mipid_set_bklight_level,
526 .get_bklight_level = mipid_get_bklight_level,
527 .get_bklight_max = mipid_get_bklight_max,
528 .run_test = mipid_run_test,
533 struct mipid_platform_data *
pdata;
536 pdata = md->
spi->dev.platform_data;
538 dev_err(&md->
spi->dev,
"missing platform data\n");
543 dev_dbg(&md->
spi->dev,
"MIPI display ID: %02x%02x%02x\n",
544 display_id[0], display_id[1], display_id[2]);
546 switch (display_id[0]) {
548 md->
panel.name =
"lph8923";
551 md->
panel.name =
"ls041y3";
555 md->
panel.name =
"unknown";
556 dev_err(&md->
spi->dev,
"invalid display ID\n");
561 md->
panel.data_lines = pdata->data_lines;
562 pr_info(
"omapfb: %s rev %02x LCD detected, %d data lines\n",
582 md->
panel = mipid_panel;
584 r = mipid_detect(md);
593 static int mipid_spi_remove(
struct spi_device *spi)
597 mipid_disable(&md->
panel);
608 .probe = mipid_spi_probe,