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