]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/video/omap/lcd_mipid.c
30261d248e4042a6a4825fcd057b292e99df52db
[linux-2.6-omap-h63xx.git] / drivers / video / omap / lcd_mipid.c
1 /*
2  * File: drivers/video/omap/lcd_mipid.c
3  *
4  * LCD driver for MIPI DBI-C / DCS compatible LCDs
5  *
6  * Copyright (C) 2006 Nokia Corporation
7  * Author: Imre Deak <imre.deak@nokia.com>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by the
11  * Free Software Foundation; either version 2 of the License, or (at your
12  * option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  */
23 #include <linux/device.h>
24 #include <linux/delay.h>
25 #include <linux/spi/spi.h>
26
27 #include <asm/arch/omapfb.h>
28 #include <asm/arch/lcd_mipid.h>
29
30 #include "../../cbus/tahvo.h"
31
32 #define MIPID_MODULE_NAME               "lcd_mipid"
33
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
44
45 #define MIPID_VER_LPH8923               3
46 #define MIPID_VER_LS041Y3               4
47
48 #define MIPID_ESD_CHECK_PERIOD          msecs_to_jiffies(5000)
49
50 #define to_mipid_device(p)              container_of(p, struct mipid_device, \
51                                                 panel)
52 struct mipid_device {
53         int             enabled;
54         int             model;
55         int             revision;
56         u8              display_id[3];
57         unsigned int    saved_bklight_level;
58         unsigned long   hw_guard_end;           /* next value of jiffies
59                                                    when we can issue the
60                                                    next sleep in/out command */
61         unsigned long   hw_guard_wait;          /* max guard time in jiffies */
62
63         struct omapfb_device    *fbdev;
64         struct spi_device       *spi;
65         struct mutex            mutex;
66         struct lcd_panel        panel;
67
68         struct work_struct      esd_work;
69         void                    (*esd_check)(struct mipid_device *m);
70 };
71
72 static void mipid_transfer(struct mipid_device *md, int cmd, const u8 *wbuf,
73                            int wlen, u8 *rbuf, int rlen)
74 {
75         struct spi_message      m;
76         struct spi_transfer     *x, xfer[4];
77         u16                     w;
78         int                     r;
79
80         BUG_ON(md->spi == NULL);
81
82         spi_message_init(&m);
83
84         memset(xfer, 0, sizeof(xfer));
85         x = &xfer[0];
86
87         cmd &=  0xff;
88         x->tx_buf       = &cmd;
89         x->bits_per_word= 9;
90         x->len          = 2;
91         spi_message_add_tail(x, &m);
92
93         if (wlen) {
94                 x++;
95                 x->tx_buf       = wbuf;
96                 x->len          = wlen;
97                 x->bits_per_word= 9;
98                 spi_message_add_tail(x, &m);
99         }
100
101         if (rlen) {
102                 x++;
103                 x->rx_buf       = &w;
104                 x->len          = 1;
105                 spi_message_add_tail(x, &m);
106
107                 if (rlen > 1) {
108                         /* Arrange for the extra clock before the first
109                          * data bit.
110                          */
111                         x->bits_per_word = 9;
112                         x->len           = 2;
113
114                         x++;
115                         x->rx_buf        = &rbuf[1];
116                         x->len           = rlen - 1;
117                         spi_message_add_tail(x, &m);
118                 }
119         }
120
121         r = spi_sync(md->spi, &m);
122         if (r < 0)
123                 dev_dbg(md->spi->dev, "spi_sync %d\n", r);
124
125         if (rlen)
126                 rbuf[0] = w & 0xff;
127 }
128
129 static inline void mipid_cmd(struct mipid_device *md, int cmd)
130 {
131         mipid_transfer(md, cmd, NULL, 0, NULL, 0);
132 }
133
134 static inline void mipid_write(struct mipid_device *md,
135                                int reg, const u8 *buf, int len)
136 {
137         mipid_transfer(md, reg, buf, len, NULL, 0);
138 }
139
140 static inline void mipid_read(struct mipid_device *md,
141                               int reg, u8 *buf, int len)
142 {
143         mipid_transfer(md, reg, NULL, 0, buf, len);
144 }
145
146 static void set_data_lines(struct mipid_device *md, int data_lines)
147 {
148         u16 par;
149
150         switch (data_lines) {
151         case 16:
152                 par = 0x150;
153                 break;
154         case 18:
155                 par = 0x160;
156                 break;
157         case 24:
158                 par = 0x170;
159                 break;
160         }
161         mipid_write(md, 0x3a, (u8 *)&par, 2);
162 }
163
164 static void send_init_string(struct mipid_device *md)
165 {
166         u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
167
168         mipid_write(md, 0xc2, (u8 *)initpar, sizeof(initpar));
169         set_data_lines(md, md->panel.data_lines);
170 }
171
172 static void hw_guard_start(struct mipid_device *md, int guard_msec)
173 {
174         md->hw_guard_wait = msecs_to_jiffies(guard_msec);
175         md->hw_guard_end = jiffies + md->hw_guard_wait;
176 }
177
178 static void hw_guard_wait(struct mipid_device *md)
179 {
180         unsigned long wait = md->hw_guard_end - jiffies;
181
182         if ((long)wait > 0 && wait <= md->hw_guard_wait) {
183                 set_current_state(TASK_UNINTERRUPTIBLE);
184                 schedule_timeout(wait);
185         }
186 }
187
188 static void set_sleep_mode(struct mipid_device *md, int on)
189 {
190         int cmd, sleep_time = 5;
191
192         if (on)
193                 cmd = MIPID_CMD_SLEEP_IN;
194         else
195                 cmd = MIPID_CMD_SLEEP_OUT;
196         hw_guard_wait(md);
197         mipid_cmd(md, cmd);
198         hw_guard_start(md, 120);
199         /* When we enable the panel, it seems we _have_ to sleep
200          * 120 ms before sending the init string */
201         if (!on)
202                 sleep_time = 120;
203         msleep(sleep_time);
204 }
205
206 static void set_display_state(struct mipid_device *md, int enabled)
207 {
208         int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF;
209
210         mipid_cmd(md, cmd);
211 }
212
213 static int mipid_set_bklight_level(struct lcd_panel *panel, unsigned int level)
214 {
215         struct mipid_device *md = to_mipid_device(panel);
216
217         if (level > tahvo_get_max_backlight_level())
218                 return -EINVAL;
219         if (!md->enabled) {
220                 md->saved_bklight_level = level;
221                 return 0;
222         }
223         tahvo_set_backlight_level(level);
224
225         return 0;
226 }
227
228 static unsigned int mipid_get_bklight_level(struct lcd_panel *panel)
229 {
230         return tahvo_get_backlight_level();
231 }
232
233 static unsigned int mipid_get_bklight_max(struct lcd_panel *panel)
234 {
235         return tahvo_get_max_backlight_level();
236 }
237
238
239 static unsigned long mipid_get_caps(struct lcd_panel *panel)
240 {
241         return OMAPFB_CAPS_SET_BACKLIGHT;
242 }
243
244 static u16 read_first_pixel(struct mipid_device *md)
245 {
246         u16 pixel;
247         u8 red, green, blue;
248
249         mutex_lock(&md->mutex);
250         mipid_read(md, MIPID_CMD_READ_RED, &red, 1);
251         mipid_read(md, MIPID_CMD_READ_GREEN, &green, 1);
252         mipid_read(md, MIPID_CMD_READ_BLUE, &blue, 1);
253         mutex_unlock(&md->mutex);
254
255         switch (md->panel.data_lines) {
256         case 16:
257                 pixel = ((red >> 1) << 11) | (green << 5) | (blue >> 1);
258                 break;
259         case 24:
260                 /* 24 bit -> 16 bit */
261                 pixel = ((red >> 3) << 11) | ((green >> 2) << 5) |
262                         (blue >> 3);
263                 break;
264         default:
265                 BUG();
266         }
267
268         return pixel;
269 }
270
271 static int mipid_run_test(struct lcd_panel *panel, int test_num)
272 {
273         struct mipid_device *md = to_mipid_device(panel);
274         static const u16 test_values[4] = {
275                 0x0000, 0xffff, 0xaaaa, 0x5555,
276         };
277         int i;
278
279         if (test_num != MIPID_TEST_RGB_LINES)
280                 return MIPID_TEST_INVALID;
281
282         for (i = 0; i < ARRAY_SIZE(test_values); i++) {
283                 int delay;
284                 unsigned long tmo;
285
286                 omapfb_write_first_pixel(md->fbdev, test_values[i]);
287                 tmo = jiffies + msecs_to_jiffies(100);
288                 delay = 25;
289                 while (1) {
290                         u16 pixel;
291
292                         msleep(delay);
293                         pixel = read_first_pixel(md);
294                         if (pixel == test_values[i])
295                                 break;
296                         if (time_after(jiffies, tmo)) {
297                                 dev_err(&md->spi->dev,
298                                         "MIPI LCD RGB I/F test failed: "
299                                         "expecting %04x, got %04x\n",
300                                         test_values[i], pixel);
301                                 return MIPID_TEST_FAILED;
302                         }
303                         delay = 10;
304                 }
305         }
306
307         return 0;
308 }
309
310 static void ls041y3_esd_recover(struct mipid_device *md)
311 {
312         dev_err(&md->spi->dev, "performing LCD ESD recovery\n");
313         set_sleep_mode(md, 1);
314         set_sleep_mode(md, 0);
315 }
316
317 static void ls041y3_esd_check_mode1(struct mipid_device *md)
318 {
319         u8 state1, state2;
320
321         mipid_read(md, MIPID_CMD_RDDSDR, &state1, 1);
322         set_sleep_mode(md, 0);
323         mipid_read(md, MIPID_CMD_RDDSDR, &state2, 1);
324         dev_dbg(&md->spi->dev, "ESD mode 1 state1 %02x state2 %02x\n",
325                 state1, state2);
326         /* Each sleep out command will trigger a self diagnostic and flip
327         * Bit6 if the test passes.
328         */
329         if (!((state1 ^ state2) & (1 << 6)))
330                 ls041y3_esd_recover(md);
331 }
332
333 static void ls041y3_esd_check_mode2(struct mipid_device *md)
334 {
335         int i;
336         u8 rbuf[2];
337         static const struct {
338                 int     cmd;
339                 int     wlen;
340                 u16     wbuf[3];
341         } *rd, rd_ctrl[7] = {
342                 { 0xb0, 4, { 0x0101, 0x01fe, } },
343                 { 0xb1, 4, { 0x01de, 0x0121, } },
344                 { 0xc2, 4, { 0x0100, 0x0100, } },
345                 { 0xbd, 2, { 0x0100, } },
346                 { 0xc2, 4, { 0x01fc, 0x0103, } },
347                 { 0xb4, 0, },
348                 { 0x00, 0, },
349         };
350
351         rd = rd_ctrl;
352         for (i = 0; i < 3; i++, rd++)
353                 mipid_write(md, rd->cmd, (u8 *)rd->wbuf, rd->wlen);
354
355         udelay(10);
356         mipid_read(md, rd->cmd, rbuf, 2);
357         rd++;
358
359         for (i = 0; i < 3; i++, rd++) {
360                 udelay(10);
361                 mipid_write(md, rd->cmd, (u8 *)rd->wbuf, rd->wlen);
362         }
363
364         dev_dbg(&md->spi->dev, "ESD mode 2 state %02x\n", rbuf[1]);
365         if (rbuf[1] == 0x00)
366                 ls041y3_esd_recover(md);
367 }
368
369 static void ls041y3_esd_check(struct mipid_device *md)
370 {
371         ls041y3_esd_check_mode1(md);
372         if (md->revision >= 0x88)
373                 ls041y3_esd_check_mode2(md);
374 }
375
376 static void mipid_esd_start_check(struct mipid_device *md)
377 {
378         if (md->esd_check != NULL)
379                 schedule_delayed_work(&md->esd_work, MIPID_ESD_CHECK_PERIOD);
380 }
381
382 static void mipid_esd_stop_check(struct mipid_device *md)
383 {
384         cancel_rearming_delayed_work(&md->esd_work);
385 }
386
387 static void mipid_esd_work(void *data)
388 {
389         struct mipid_device *md = data;
390
391         mutex_lock(&md->mutex);
392         md->esd_check(md);
393         mutex_unlock(&md->mutex);
394         mipid_esd_start_check(md);
395 }
396
397 static int mipid_enable(struct lcd_panel *panel)
398 {
399         struct mipid_device *md = to_mipid_device(panel);
400
401         mutex_lock(&md->mutex);
402
403         if (md->enabled) {
404                 mutex_unlock(&md->mutex);
405                 return 0;
406         }
407         set_sleep_mode(md, 0);
408         md->enabled = 1;
409         send_init_string(md);
410         set_display_state(md, 1);
411         mipid_set_bklight_level(panel, md->saved_bklight_level);
412         mipid_esd_start_check(md);
413
414         mutex_unlock(&md->mutex);
415         return 0;
416 }
417
418 static void mipid_disable(struct lcd_panel *panel)
419 {
420         struct mipid_device *md = to_mipid_device(panel);
421
422         /* A final ESD work might be called before returning,
423          * so do this without holding the lock. */
424         mipid_esd_stop_check(md);
425         mutex_lock(&md->mutex);
426
427         if (!md->enabled) {
428                 mutex_unlock(&md->mutex);
429                 return;
430         }
431         md->saved_bklight_level = mipid_get_bklight_level(panel);
432         mipid_set_bklight_level(panel, 0);
433         set_display_state(md, 0);
434         set_sleep_mode(md, 1);
435         md->enabled = 0;
436
437         mutex_unlock(&md->mutex);
438 }
439
440 static int panel_enabled(struct mipid_device *md)
441 {
442         u32 disp_status;
443         int enabled;
444
445         mipid_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4);
446         disp_status = __be32_to_cpu(disp_status);
447         enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10));
448         dev_dbg(&md->spi->dev,
449                 "LCD panel %s enabled by bootloader (status 0x%04x)\n",
450                 enabled ? "" : "not ", disp_status);
451         return enabled;
452 }
453
454 static int mipid_init(struct lcd_panel *panel,
455                             struct omapfb_device *fbdev)
456 {
457         struct mipid_device *md = to_mipid_device(panel);
458
459         md->fbdev = fbdev;
460         INIT_WORK(&md->esd_work, mipid_esd_work, md);
461         mutex_init(&md->mutex);
462
463         md->enabled = panel_enabled(md);
464
465         if (md->enabled)
466                 mipid_esd_start_check(md);
467         else
468                 md->saved_bklight_level = mipid_get_bklight_level(panel);
469
470         return 0;
471 }
472
473 static void mipid_cleanup(struct lcd_panel *panel)
474 {
475         struct mipid_device *md = to_mipid_device(panel);
476
477         mipid_esd_stop_check(md);
478 }
479
480 static struct lcd_panel mipid_panel = {
481         .config         = OMAP_LCDC_PANEL_TFT,
482
483         .bpp            = 16,
484         .x_res          = 800,
485         .y_res          = 480,
486         .pixel_clock    = 21940,
487         .hsw            = 50,
488         .hfp            = 20,
489         .hbp            = 15,
490         .vsw            = 2,
491         .vfp            = 1,
492         .vbp            = 3,
493
494         .init           = mipid_init,
495         .cleanup        = mipid_cleanup,
496         .enable         = mipid_enable,
497         .disable        = mipid_disable,
498         .get_caps       = mipid_get_caps,
499         .set_bklight_level= mipid_set_bklight_level,
500         .get_bklight_level= mipid_get_bklight_level,
501         .get_bklight_max= mipid_get_bklight_max,
502         .run_test       = mipid_run_test,
503 };
504
505 static int mipid_detect(struct mipid_device *md)
506 {
507         struct mipid_platform_data *pdata;
508
509         pdata = md->spi->dev.platform_data;
510         if (pdata == NULL) {
511                 dev_err(&md->spi->dev, "missing platform data\n");
512                 return -ENOENT;
513         }
514
515         mipid_read(md, MIPID_CMD_READ_DISP_ID, md->display_id, 3);
516         dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n",
517                 md->display_id[0], md->display_id[1], md->display_id[2]);
518
519         switch (md->display_id[0]) {
520         case 0x45:
521                 md->model = MIPID_VER_LPH8923;
522                 md->panel.name = "lph8923";
523                 break;
524         case 0x83:
525                 md->model = MIPID_VER_LS041Y3;
526                 md->panel.name = "ls041y3";
527                 md->esd_check = ls041y3_esd_check;
528                 break;
529         default:
530                 md->panel.name = "unknown";
531                 dev_err(&md->spi->dev, "invalid display ID\n");
532                 return -ENODEV;
533         }
534
535         md->revision = md->display_id[1];
536         md->panel.data_lines = pdata->data_lines;
537         pr_info("omapfb: %s rev %02x LCD detected\n",
538                         md->panel.name, md->revision);
539
540         return 0;
541 }
542
543 static int mipid_spi_probe(struct spi_device *spi)
544 {
545         struct mipid_device *md;
546         int r;
547
548         md = kzalloc(sizeof(*md), SLAB_KERNEL);
549         if (md == NULL) {
550                 dev_err(&md->spi->dev, "out of memory\n");
551                 return -ENOMEM;
552         }
553
554         spi->mode = SPI_MODE_1;
555         md->spi = spi;
556         dev_set_drvdata(&spi->dev, md);
557         md->panel = mipid_panel;
558
559         r = mipid_detect(md);
560         if (r < 0)
561                 return r;
562
563         omapfb_register_panel(&md->panel);
564
565         return 0;
566 }
567
568 static int mipid_spi_remove(struct spi_device *spi)
569 {
570         struct mipid_device *md = dev_get_drvdata(&spi->dev);
571
572         mipid_disable(&md->panel);
573         kfree(md);
574
575         return 0;
576 }
577
578 static struct spi_driver mipid_spi_driver = {
579         .driver = {
580                 .name   = MIPID_MODULE_NAME,
581                 .bus    = &spi_bus_type,
582                 .owner  = THIS_MODULE,
583         },
584         .probe  = mipid_spi_probe,
585         .remove = __devexit_p(mipid_spi_remove),
586 };
587
588 static int mipid_drv_init(void)
589 {
590         spi_register_driver(&mipid_spi_driver);
591
592         return 0;
593 }
594 module_init(mipid_drv_init);
595
596 static void mipid_drv_cleanup(void)
597 {
598         spi_unregister_driver(&mipid_spi_driver);
599 }
600 module_exit(mipid_drv_cleanup);
601
602 MODULE_DESCRIPTION("MIPI display driver");
603 MODULE_LICENSE("GPL");