Merge git://1984.lsi.us.es/nf-next
[cascardo/linux.git] / drivers / video / omap2 / displays / panel-n8x0.c
1 /* #define DEBUG */
2
3 #include <linux/module.h>
4 #include <linux/delay.h>
5 #include <linux/slab.h>
6 #include <linux/gpio.h>
7 #include <linux/spi/spi.h>
8 #include <linux/backlight.h>
9 #include <linux/fb.h>
10
11 #include <video/omapdss.h>
12 #include <video/omap-panel-n8x0.h>
13
14 #define BLIZZARD_REV_CODE                      0x00
15 #define BLIZZARD_CONFIG                        0x02
16 #define BLIZZARD_PLL_DIV                       0x04
17 #define BLIZZARD_PLL_LOCK_RANGE                0x06
18 #define BLIZZARD_PLL_CLOCK_SYNTH_0             0x08
19 #define BLIZZARD_PLL_CLOCK_SYNTH_1             0x0a
20 #define BLIZZARD_PLL_MODE                      0x0c
21 #define BLIZZARD_CLK_SRC                       0x0e
22 #define BLIZZARD_MEM_BANK0_ACTIVATE            0x10
23 #define BLIZZARD_MEM_BANK0_STATUS              0x14
24 #define BLIZZARD_PANEL_CONFIGURATION           0x28
25 #define BLIZZARD_HDISP                         0x2a
26 #define BLIZZARD_HNDP                          0x2c
27 #define BLIZZARD_VDISP0                        0x2e
28 #define BLIZZARD_VDISP1                        0x30
29 #define BLIZZARD_VNDP                          0x32
30 #define BLIZZARD_HSW                           0x34
31 #define BLIZZARD_VSW                           0x38
32 #define BLIZZARD_DISPLAY_MODE                  0x68
33 #define BLIZZARD_INPUT_WIN_X_START_0           0x6c
34 #define BLIZZARD_DATA_SOURCE_SELECT            0x8e
35 #define BLIZZARD_DISP_MEM_DATA_PORT            0x90
36 #define BLIZZARD_DISP_MEM_READ_ADDR0           0x92
37 #define BLIZZARD_POWER_SAVE                    0xE6
38 #define BLIZZARD_NDISP_CTRL_STATUS             0xE8
39
40 /* Data source select */
41 /* For S1D13745 */
42 #define BLIZZARD_SRC_WRITE_LCD_BACKGROUND       0x00
43 #define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE      0x01
44 #define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE       0x04
45 #define BLIZZARD_SRC_DISABLE_OVERLAY            0x05
46 /* For S1D13744 */
47 #define BLIZZARD_SRC_WRITE_LCD                  0x00
48 #define BLIZZARD_SRC_BLT_LCD                    0x06
49
50 #define BLIZZARD_COLOR_RGB565                   0x01
51 #define BLIZZARD_COLOR_YUV420                   0x09
52
53 #define BLIZZARD_VERSION_S1D13745               0x01    /* Hailstorm */
54 #define BLIZZARD_VERSION_S1D13744               0x02    /* Blizzard */
55
56 #define MIPID_CMD_READ_DISP_ID          0x04
57 #define MIPID_CMD_READ_RED              0x06
58 #define MIPID_CMD_READ_GREEN            0x07
59 #define MIPID_CMD_READ_BLUE             0x08
60 #define MIPID_CMD_READ_DISP_STATUS      0x09
61 #define MIPID_CMD_RDDSDR                0x0F
62 #define MIPID_CMD_SLEEP_IN              0x10
63 #define MIPID_CMD_SLEEP_OUT             0x11
64 #define MIPID_CMD_DISP_OFF              0x28
65 #define MIPID_CMD_DISP_ON               0x29
66
67 static struct panel_drv_data {
68         struct mutex lock;
69
70         struct omap_dss_device *dssdev;
71         struct spi_device *spidev;
72         struct backlight_device *bldev;
73
74         int blizzard_ver;
75 } s_drv_data;
76
77
78 static inline
79 struct panel_n8x0_data *get_board_data(const struct omap_dss_device *dssdev)
80 {
81         return dssdev->data;
82 }
83
84 static inline
85 struct panel_drv_data *get_drv_data(const struct omap_dss_device *dssdev)
86 {
87         return &s_drv_data;
88 }
89
90
91 static inline void blizzard_cmd(u8 cmd)
92 {
93         omap_rfbi_write_command(&cmd, 1);
94 }
95
96 static inline void blizzard_write(u8 cmd, const u8 *buf, int len)
97 {
98         omap_rfbi_write_command(&cmd, 1);
99         omap_rfbi_write_data(buf, len);
100 }
101
102 static inline void blizzard_read(u8 cmd, u8 *buf, int len)
103 {
104         omap_rfbi_write_command(&cmd, 1);
105         omap_rfbi_read_data(buf, len);
106 }
107
108 static u8 blizzard_read_reg(u8 cmd)
109 {
110         u8 data;
111         blizzard_read(cmd, &data, 1);
112         return data;
113 }
114
115 static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
116                 int x, int y, int w, int h)
117 {
118         struct panel_drv_data *ddata = get_drv_data(dssdev);
119         u8 tmp[18];
120         int x_end, y_end;
121
122         x_end = x + w - 1;
123         y_end = y + h - 1;
124
125         tmp[0] = x;
126         tmp[1] = x >> 8;
127         tmp[2] = y;
128         tmp[3] = y >> 8;
129         tmp[4] = x_end;
130         tmp[5] = x_end >> 8;
131         tmp[6] = y_end;
132         tmp[7] = y_end >> 8;
133
134         /* scaling? */
135         tmp[8] = x;
136         tmp[9] = x >> 8;
137         tmp[10] = y;
138         tmp[11] = y >> 8;
139         tmp[12] = x_end;
140         tmp[13] = x_end >> 8;
141         tmp[14] = y_end;
142         tmp[15] = y_end >> 8;
143
144         tmp[16] = BLIZZARD_COLOR_RGB565;
145
146         if (ddata->blizzard_ver == BLIZZARD_VERSION_S1D13745)
147                 tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
148         else
149                 tmp[17] = ddata->blizzard_ver == BLIZZARD_VERSION_S1D13744 ?
150                         BLIZZARD_SRC_WRITE_LCD :
151                         BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
152
153         omap_rfbi_configure(dssdev, 16, 8);
154
155         blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
156
157         omap_rfbi_configure(dssdev, 16, 16);
158 }
159
160 static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
161                 int wlen, u8 *rbuf, int rlen)
162 {
163         struct spi_message      m;
164         struct spi_transfer     *x, xfer[4];
165         u16                     w;
166         int                     r;
167
168         spi_message_init(&m);
169
170         memset(xfer, 0, sizeof(xfer));
171         x = &xfer[0];
172
173         cmd &=  0xff;
174         x->tx_buf               = &cmd;
175         x->bits_per_word        = 9;
176         x->len                  = 2;
177         spi_message_add_tail(x, &m);
178
179         if (wlen) {
180                 x++;
181                 x->tx_buf               = wbuf;
182                 x->len                  = wlen;
183                 x->bits_per_word        = 9;
184                 spi_message_add_tail(x, &m);
185         }
186
187         if (rlen) {
188                 x++;
189                 x->rx_buf       = &w;
190                 x->len          = 1;
191                 spi_message_add_tail(x, &m);
192
193                 if (rlen > 1) {
194                         /* Arrange for the extra clock before the first
195                          * data bit.
196                          */
197                         x->bits_per_word = 9;
198                         x->len           = 2;
199
200                         x++;
201                         x->rx_buf        = &rbuf[1];
202                         x->len           = rlen - 1;
203                         spi_message_add_tail(x, &m);
204                 }
205         }
206
207         r = spi_sync(spi, &m);
208         if (r < 0)
209                 dev_dbg(&spi->dev, "spi_sync %d\n", r);
210
211         if (rlen)
212                 rbuf[0] = w & 0xff;
213 }
214
215 static inline void mipid_cmd(struct spi_device *spi, int cmd)
216 {
217         mipid_transfer(spi, cmd, NULL, 0, NULL, 0);
218 }
219
220 static inline void mipid_write(struct spi_device *spi,
221                 int reg, const u8 *buf, int len)
222 {
223         mipid_transfer(spi, reg, buf, len, NULL, 0);
224 }
225
226 static inline void mipid_read(struct spi_device *spi,
227                 int reg, u8 *buf, int len)
228 {
229         mipid_transfer(spi, reg, NULL, 0, buf, len);
230 }
231
232 static void set_data_lines(struct spi_device *spi, int data_lines)
233 {
234         u16 par;
235
236         switch (data_lines) {
237         case 16:
238                 par = 0x150;
239                 break;
240         case 18:
241                 par = 0x160;
242                 break;
243         case 24:
244                 par = 0x170;
245                 break;
246         }
247
248         mipid_write(spi, 0x3a, (u8 *)&par, 2);
249 }
250
251 static void send_init_string(struct spi_device *spi)
252 {
253         u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
254         mipid_write(spi, 0xc2, (u8 *)initpar, sizeof(initpar));
255 }
256
257 static void send_display_on(struct spi_device *spi)
258 {
259         mipid_cmd(spi, MIPID_CMD_DISP_ON);
260 }
261
262 static void send_display_off(struct spi_device *spi)
263 {
264         mipid_cmd(spi, MIPID_CMD_DISP_OFF);
265 }
266
267 static void send_sleep_out(struct spi_device *spi)
268 {
269         mipid_cmd(spi, MIPID_CMD_SLEEP_OUT);
270         msleep(120);
271 }
272
273 static void send_sleep_in(struct spi_device *spi)
274 {
275         mipid_cmd(spi, MIPID_CMD_SLEEP_IN);
276         msleep(50);
277 }
278
279 static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
280 {
281         int r;
282         struct panel_n8x0_data *bdata = get_board_data(dssdev);
283         struct panel_drv_data *ddata = get_drv_data(dssdev);
284         struct spi_device *spi = ddata->spidev;
285         u8 rev, conf;
286         u8 display_id[3];
287         const char *panel_name;
288
289         if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
290                 return 0;
291
292         gpio_direction_output(bdata->ctrl_pwrdown, 1);
293
294         if (bdata->platform_enable) {
295                 r = bdata->platform_enable(dssdev);
296                 if (r)
297                         goto err_plat_en;
298         }
299
300         r = omapdss_rfbi_display_enable(dssdev);
301         if (r)
302                 goto err_rfbi_en;
303
304         rev = blizzard_read_reg(BLIZZARD_REV_CODE);
305         conf = blizzard_read_reg(BLIZZARD_CONFIG);
306
307         switch (rev & 0xfc) {
308         case 0x9c:
309                 ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744;
310                 dev_info(&dssdev->dev, "s1d13744 LCD controller rev %d "
311                         "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
312                 break;
313         case 0xa4:
314                 ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745;
315                 dev_info(&dssdev->dev, "s1d13745 LCD controller rev %d "
316                         "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
317                 break;
318         default:
319                 dev_err(&dssdev->dev, "invalid s1d1374x revision %02x\n", rev);
320                 r = -ENODEV;
321                 goto err_inv_chip;
322         }
323
324         /* panel */
325
326         gpio_direction_output(bdata->panel_reset, 1);
327
328         mipid_read(spi, MIPID_CMD_READ_DISP_ID, display_id, 3);
329         dev_dbg(&spi->dev, "MIPI display ID: %02x%02x%02x\n",
330                         display_id[0], display_id[1], display_id[2]);
331
332         switch (display_id[0]) {
333         case 0x45:
334                 panel_name = "lph8923";
335                 break;
336         case 0x83:
337                 panel_name = "ls041y3";
338                 break;
339         default:
340                 dev_err(&dssdev->dev, "invalid display ID 0x%x\n",
341                                 display_id[0]);
342                 r = -ENODEV;
343                 goto err_inv_panel;
344         }
345
346         dev_info(&dssdev->dev, "%s rev %02x LCD detected\n",
347                         panel_name, display_id[1]);
348
349         send_sleep_out(spi);
350         send_init_string(spi);
351         set_data_lines(spi, 24);
352         send_display_on(spi);
353
354         return 0;
355
356 err_inv_panel:
357         /*
358          * HACK: we should turn off the panel here, but there is some problem
359          * with the initialization sequence, and we fail to init the panel if we
360          * have turned it off
361          */
362         /* gpio_direction_output(bdata->panel_reset, 0); */
363 err_inv_chip:
364         omapdss_rfbi_display_disable(dssdev);
365 err_rfbi_en:
366         if (bdata->platform_disable)
367                 bdata->platform_disable(dssdev);
368 err_plat_en:
369         gpio_direction_output(bdata->ctrl_pwrdown, 0);
370         return r;
371 }
372
373 static void n8x0_panel_power_off(struct omap_dss_device *dssdev)
374 {
375         struct panel_n8x0_data *bdata = get_board_data(dssdev);
376         struct panel_drv_data *ddata = get_drv_data(dssdev);
377         struct spi_device *spi = ddata->spidev;
378
379         if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
380                 return;
381
382         send_display_off(spi);
383         send_sleep_in(spi);
384
385         if (bdata->platform_disable)
386                 bdata->platform_disable(dssdev);
387
388         /*
389          * HACK: we should turn off the panel here, but there is some problem
390          * with the initialization sequence, and we fail to init the panel if we
391          * have turned it off
392          */
393         /* gpio_direction_output(bdata->panel_reset, 0); */
394         gpio_direction_output(bdata->ctrl_pwrdown, 0);
395         omapdss_rfbi_display_disable(dssdev);
396 }
397
398 static const struct rfbi_timings n8x0_panel_timings = {
399         .cs_on_time     = 0,
400
401         .we_on_time     = 9000,
402         .we_off_time    = 18000,
403         .we_cycle_time  = 36000,
404
405         .re_on_time     = 9000,
406         .re_off_time    = 27000,
407         .re_cycle_time  = 36000,
408
409         .access_time    = 27000,
410         .cs_off_time    = 36000,
411
412         .cs_pulse_width = 0,
413 };
414
415 static int n8x0_bl_update_status(struct backlight_device *dev)
416 {
417         struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
418         struct panel_n8x0_data *bdata = get_board_data(dssdev);
419         struct panel_drv_data *ddata = get_drv_data(dssdev);
420         int r;
421         int level;
422
423         mutex_lock(&ddata->lock);
424
425         if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
426                         dev->props.power == FB_BLANK_UNBLANK)
427                 level = dev->props.brightness;
428         else
429                 level = 0;
430
431         dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
432
433         if (!bdata->set_backlight)
434                 r = -EINVAL;
435         else
436                 r = bdata->set_backlight(dssdev, level);
437
438         mutex_unlock(&ddata->lock);
439
440         return r;
441 }
442
443 static int n8x0_bl_get_intensity(struct backlight_device *dev)
444 {
445         if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
446                         dev->props.power == FB_BLANK_UNBLANK)
447                 return dev->props.brightness;
448
449         return 0;
450 }
451
452 static const struct backlight_ops n8x0_bl_ops = {
453         .get_brightness = n8x0_bl_get_intensity,
454         .update_status  = n8x0_bl_update_status,
455 };
456
457 static int n8x0_panel_probe(struct omap_dss_device *dssdev)
458 {
459         struct panel_n8x0_data *bdata = get_board_data(dssdev);
460         struct panel_drv_data *ddata;
461         struct backlight_device *bldev;
462         struct backlight_properties props;
463         int r;
464
465         dev_dbg(&dssdev->dev, "probe\n");
466
467         if (!bdata)
468                 return -EINVAL;
469
470         s_drv_data.dssdev = dssdev;
471
472         ddata = &s_drv_data;
473
474         mutex_init(&ddata->lock);
475
476         dssdev->panel.timings.x_res = 800;
477         dssdev->panel.timings.y_res = 480;
478         dssdev->ctrl.pixel_size = 16;
479         dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
480
481         memset(&props, 0, sizeof(props));
482         props.max_brightness = 127;
483         props.type = BACKLIGHT_PLATFORM;
484         bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
485                         dssdev, &n8x0_bl_ops, &props);
486         if (IS_ERR(bldev)) {
487                 r = PTR_ERR(bldev);
488                 dev_err(&dssdev->dev, "register backlight failed\n");
489                 return r;
490         }
491
492         ddata->bldev = bldev;
493
494         bldev->props.fb_blank = FB_BLANK_UNBLANK;
495         bldev->props.power = FB_BLANK_UNBLANK;
496         bldev->props.brightness = 127;
497
498         n8x0_bl_update_status(bldev);
499
500         return 0;
501 }
502
503 static void n8x0_panel_remove(struct omap_dss_device *dssdev)
504 {
505         struct panel_drv_data *ddata = get_drv_data(dssdev);
506         struct backlight_device *bldev;
507
508         dev_dbg(&dssdev->dev, "remove\n");
509
510         bldev = ddata->bldev;
511         bldev->props.power = FB_BLANK_POWERDOWN;
512         n8x0_bl_update_status(bldev);
513         backlight_device_unregister(bldev);
514
515         dev_set_drvdata(&dssdev->dev, NULL);
516 }
517
518 static int n8x0_panel_enable(struct omap_dss_device *dssdev)
519 {
520         struct panel_drv_data *ddata = get_drv_data(dssdev);
521         int r;
522
523         dev_dbg(&dssdev->dev, "enable\n");
524
525         mutex_lock(&ddata->lock);
526
527         rfbi_bus_lock();
528
529         r = n8x0_panel_power_on(dssdev);
530
531         rfbi_bus_unlock();
532
533         if (r) {
534                 mutex_unlock(&ddata->lock);
535                 return r;
536         }
537
538         dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
539
540         mutex_unlock(&ddata->lock);
541
542         return 0;
543 }
544
545 static void n8x0_panel_disable(struct omap_dss_device *dssdev)
546 {
547         struct panel_drv_data *ddata = get_drv_data(dssdev);
548
549         dev_dbg(&dssdev->dev, "disable\n");
550
551         mutex_lock(&ddata->lock);
552
553         rfbi_bus_lock();
554
555         n8x0_panel_power_off(dssdev);
556
557         rfbi_bus_unlock();
558
559         dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
560
561         mutex_unlock(&ddata->lock);
562 }
563
564 static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
565 {
566         struct panel_drv_data *ddata = get_drv_data(dssdev);
567
568         dev_dbg(&dssdev->dev, "suspend\n");
569
570         mutex_lock(&ddata->lock);
571
572         rfbi_bus_lock();
573
574         n8x0_panel_power_off(dssdev);
575
576         rfbi_bus_unlock();
577
578         dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
579
580         mutex_unlock(&ddata->lock);
581
582         return 0;
583 }
584
585 static int n8x0_panel_resume(struct omap_dss_device *dssdev)
586 {
587         struct panel_drv_data *ddata = get_drv_data(dssdev);
588         int r;
589
590         dev_dbg(&dssdev->dev, "resume\n");
591
592         mutex_lock(&ddata->lock);
593
594         rfbi_bus_lock();
595
596         r = n8x0_panel_power_on(dssdev);
597
598         rfbi_bus_unlock();
599
600         if (r) {
601                 mutex_unlock(&ddata->lock);
602                 return r;
603         }
604
605         dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
606
607         mutex_unlock(&ddata->lock);
608
609         return 0;
610 }
611
612 static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
613                 u16 *xres, u16 *yres)
614 {
615         *xres = dssdev->panel.timings.x_res;
616         *yres = dssdev->panel.timings.y_res;
617 }
618
619 static void update_done(void *data)
620 {
621         rfbi_bus_unlock();
622 }
623
624 static int n8x0_panel_update(struct omap_dss_device *dssdev,
625                 u16 x, u16 y, u16 w, u16 h)
626 {
627         struct panel_drv_data *ddata = get_drv_data(dssdev);
628
629         dev_dbg(&dssdev->dev, "update\n");
630
631         mutex_lock(&ddata->lock);
632         rfbi_bus_lock();
633
634         omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h);
635
636         blizzard_ctrl_setup_update(dssdev, x, y, w, h);
637
638         omap_rfbi_update(dssdev, x, y, w, h, update_done, NULL);
639
640         mutex_unlock(&ddata->lock);
641
642         return 0;
643 }
644
645 static int n8x0_panel_sync(struct omap_dss_device *dssdev)
646 {
647         struct panel_drv_data *ddata = get_drv_data(dssdev);
648
649         dev_dbg(&dssdev->dev, "sync\n");
650
651         mutex_lock(&ddata->lock);
652         rfbi_bus_lock();
653         rfbi_bus_unlock();
654         mutex_unlock(&ddata->lock);
655
656         return 0;
657 }
658
659 static struct omap_dss_driver n8x0_panel_driver = {
660         .probe          = n8x0_panel_probe,
661         .remove         = n8x0_panel_remove,
662
663         .enable         = n8x0_panel_enable,
664         .disable        = n8x0_panel_disable,
665         .suspend        = n8x0_panel_suspend,
666         .resume         = n8x0_panel_resume,
667
668         .update         = n8x0_panel_update,
669         .sync           = n8x0_panel_sync,
670
671         .get_resolution = n8x0_panel_get_resolution,
672         .get_recommended_bpp = omapdss_default_get_recommended_bpp,
673
674         .driver         = {
675                 .name   = "n8x0_panel",
676                 .owner  = THIS_MODULE,
677         },
678 };
679
680 /* PANEL */
681
682 static int mipid_spi_probe(struct spi_device *spi)
683 {
684         dev_dbg(&spi->dev, "mipid_spi_probe\n");
685
686         spi->mode = SPI_MODE_0;
687
688         s_drv_data.spidev = spi;
689
690         return 0;
691 }
692
693 static int mipid_spi_remove(struct spi_device *spi)
694 {
695         dev_dbg(&spi->dev, "mipid_spi_remove\n");
696         return 0;
697 }
698
699 static struct spi_driver mipid_spi_driver = {
700         .driver = {
701                 .name   = "lcd_mipid",
702                 .owner  = THIS_MODULE,
703         },
704         .probe  = mipid_spi_probe,
705         .remove = __devexit_p(mipid_spi_remove),
706 };
707
708 static int __init n8x0_panel_drv_init(void)
709 {
710         int r;
711
712         r = spi_register_driver(&mipid_spi_driver);
713         if (r) {
714                 pr_err("n8x0_panel: spi driver registration failed\n");
715                 return r;
716         }
717
718         r = omap_dss_register_driver(&n8x0_panel_driver);
719         if (r) {
720                 pr_err("n8x0_panel: dss driver registration failed\n");
721                 spi_unregister_driver(&mipid_spi_driver);
722                 return r;
723         }
724
725         return 0;
726 }
727
728 static void __exit n8x0_panel_drv_exit(void)
729 {
730         spi_unregister_driver(&mipid_spi_driver);
731
732         omap_dss_unregister_driver(&n8x0_panel_driver);
733 }
734
735 module_init(n8x0_panel_drv_init);
736 module_exit(n8x0_panel_drv_exit);
737 MODULE_LICENSE("GPL");