Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
panel-n8x0.c
Go to the documentation of this file.
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;
73 
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 
148  else
149  tmp[17] = ddata->blizzard_ver == BLIZZARD_VERSION_S1D13744 ?
152 
153  omapdss_rfbi_set_pixel_size(dssdev, 16);
154  omapdss_rfbi_set_data_lines(dssdev, 8);
155 
156  omap_rfbi_configure(dssdev);
157 
158  blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
159 
160  omapdss_rfbi_set_pixel_size(dssdev, 16);
161  omapdss_rfbi_set_data_lines(dssdev, 16);
162 
163  omap_rfbi_configure(dssdev);
164 }
165 
166 static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
167  int wlen, u8 *rbuf, int rlen)
168 {
169  struct spi_message m;
170  struct spi_transfer *x, xfer[4];
171  u16 w;
172  int r;
173 
174  spi_message_init(&m);
175 
176  memset(xfer, 0, sizeof(xfer));
177  x = &xfer[0];
178 
179  cmd &= 0xff;
180  x->tx_buf = &cmd;
181  x->bits_per_word = 9;
182  x->len = 2;
183  spi_message_add_tail(x, &m);
184 
185  if (wlen) {
186  x++;
187  x->tx_buf = wbuf;
188  x->len = wlen;
189  x->bits_per_word = 9;
190  spi_message_add_tail(x, &m);
191  }
192 
193  if (rlen) {
194  x++;
195  x->rx_buf = &w;
196  x->len = 1;
197  spi_message_add_tail(x, &m);
198 
199  if (rlen > 1) {
200  /* Arrange for the extra clock before the first
201  * data bit.
202  */
203  x->bits_per_word = 9;
204  x->len = 2;
205 
206  x++;
207  x->rx_buf = &rbuf[1];
208  x->len = rlen - 1;
209  spi_message_add_tail(x, &m);
210  }
211  }
212 
213  r = spi_sync(spi, &m);
214  if (r < 0)
215  dev_dbg(&spi->dev, "spi_sync %d\n", r);
216 
217  if (rlen)
218  rbuf[0] = w & 0xff;
219 }
220 
221 static inline void mipid_cmd(struct spi_device *spi, int cmd)
222 {
223  mipid_transfer(spi, cmd, NULL, 0, NULL, 0);
224 }
225 
226 static inline void mipid_write(struct spi_device *spi,
227  int reg, const u8 *buf, int len)
228 {
229  mipid_transfer(spi, reg, buf, len, NULL, 0);
230 }
231 
232 static inline void mipid_read(struct spi_device *spi,
233  int reg, u8 *buf, int len)
234 {
235  mipid_transfer(spi, reg, NULL, 0, buf, len);
236 }
237 
238 static void set_data_lines(struct spi_device *spi, int data_lines)
239 {
240  u16 par;
241 
242  switch (data_lines) {
243  case 16:
244  par = 0x150;
245  break;
246  case 18:
247  par = 0x160;
248  break;
249  case 24:
250  par = 0x170;
251  break;
252  }
253 
254  mipid_write(spi, 0x3a, (u8 *)&par, 2);
255 }
256 
257 static void send_init_string(struct spi_device *spi)
258 {
259  u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
260  mipid_write(spi, 0xc2, (u8 *)initpar, sizeof(initpar));
261 }
262 
263 static void send_display_on(struct spi_device *spi)
264 {
265  mipid_cmd(spi, MIPID_CMD_DISP_ON);
266 }
267 
268 static void send_display_off(struct spi_device *spi)
269 {
270  mipid_cmd(spi, MIPID_CMD_DISP_OFF);
271 }
272 
273 static void send_sleep_out(struct spi_device *spi)
274 {
275  mipid_cmd(spi, MIPID_CMD_SLEEP_OUT);
276  msleep(120);
277 }
278 
279 static void send_sleep_in(struct spi_device *spi)
280 {
281  mipid_cmd(spi, MIPID_CMD_SLEEP_IN);
282  msleep(50);
283 }
284 
285 static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
286 {
287  int r;
288  struct panel_n8x0_data *bdata = get_board_data(dssdev);
289  struct panel_drv_data *ddata = get_drv_data(dssdev);
290  struct spi_device *spi = ddata->spidev;
291  u8 rev, conf;
292  u8 display_id[3];
293  const char *panel_name;
294 
295  if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
296  return 0;
297 
299 
300  if (bdata->platform_enable) {
301  r = bdata->platform_enable(dssdev);
302  if (r)
303  goto err_plat_en;
304  }
305 
306  omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res,
307  dssdev->panel.timings.y_res);
308  omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size);
309  omapdss_rfbi_set_data_lines(dssdev, dssdev->phy.rfbi.data_lines);
310  omapdss_rfbi_set_interface_timings(dssdev, &dssdev->ctrl.rfbi_timings);
311 
312  r = omapdss_rfbi_display_enable(dssdev);
313  if (r)
314  goto err_rfbi_en;
315 
316  rev = blizzard_read_reg(BLIZZARD_REV_CODE);
317  conf = blizzard_read_reg(BLIZZARD_CONFIG);
318 
319  switch (rev & 0xfc) {
320  case 0x9c:
322  dev_info(&dssdev->dev, "s1d13744 LCD controller rev %d "
323  "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
324  break;
325  case 0xa4:
327  dev_info(&dssdev->dev, "s1d13745 LCD controller rev %d "
328  "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
329  break;
330  default:
331  dev_err(&dssdev->dev, "invalid s1d1374x revision %02x\n", rev);
332  r = -ENODEV;
333  goto err_inv_chip;
334  }
335 
336  /* panel */
337 
339 
340  mipid_read(spi, MIPID_CMD_READ_DISP_ID, display_id, 3);
341  dev_dbg(&spi->dev, "MIPI display ID: %02x%02x%02x\n",
342  display_id[0], display_id[1], display_id[2]);
343 
344  switch (display_id[0]) {
345  case 0x45:
346  panel_name = "lph8923";
347  break;
348  case 0x83:
349  panel_name = "ls041y3";
350  break;
351  default:
352  dev_err(&dssdev->dev, "invalid display ID 0x%x\n",
353  display_id[0]);
354  r = -ENODEV;
355  goto err_inv_panel;
356  }
357 
358  dev_info(&dssdev->dev, "%s rev %02x LCD detected\n",
359  panel_name, display_id[1]);
360 
361  send_sleep_out(spi);
362  send_init_string(spi);
363  set_data_lines(spi, 24);
364  send_display_on(spi);
365 
366  return 0;
367 
368 err_inv_panel:
369  /*
370  * HACK: we should turn off the panel here, but there is some problem
371  * with the initialization sequence, and we fail to init the panel if we
372  * have turned it off
373  */
374  /* gpio_direction_output(bdata->panel_reset, 0); */
375 err_inv_chip:
377 err_rfbi_en:
378  if (bdata->platform_disable)
379  bdata->platform_disable(dssdev);
380 err_plat_en:
382  return r;
383 }
384 
385 static void n8x0_panel_power_off(struct omap_dss_device *dssdev)
386 {
387  struct panel_n8x0_data *bdata = get_board_data(dssdev);
388  struct panel_drv_data *ddata = get_drv_data(dssdev);
389  struct spi_device *spi = ddata->spidev;
390 
391  if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
392  return;
393 
394  send_display_off(spi);
395  send_sleep_in(spi);
396 
397  if (bdata->platform_disable)
398  bdata->platform_disable(dssdev);
399 
400  /*
401  * HACK: we should turn off the panel here, but there is some problem
402  * with the initialization sequence, and we fail to init the panel if we
403  * have turned it off
404  */
405  /* gpio_direction_output(bdata->panel_reset, 0); */
408 }
409 
410 static const struct rfbi_timings n8x0_panel_timings = {
411  .cs_on_time = 0,
412 
413  .we_on_time = 9000,
414  .we_off_time = 18000,
415  .we_cycle_time = 36000,
416 
417  .re_on_time = 9000,
418  .re_off_time = 27000,
419  .re_cycle_time = 36000,
420 
421  .access_time = 27000,
422  .cs_off_time = 36000,
423 
424  .cs_pulse_width = 0,
425 };
426 
427 static int n8x0_bl_update_status(struct backlight_device *dev)
428 {
429  struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
430  struct panel_n8x0_data *bdata = get_board_data(dssdev);
431  struct panel_drv_data *ddata = get_drv_data(dssdev);
432  int r;
433  int level;
434 
435  mutex_lock(&ddata->lock);
436 
437  if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
438  dev->props.power == FB_BLANK_UNBLANK)
439  level = dev->props.brightness;
440  else
441  level = 0;
442 
443  dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
444 
445  if (!bdata->set_backlight)
446  r = -EINVAL;
447  else
448  r = bdata->set_backlight(dssdev, level);
449 
450  mutex_unlock(&ddata->lock);
451 
452  return r;
453 }
454 
455 static int n8x0_bl_get_intensity(struct backlight_device *dev)
456 {
457  if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
458  dev->props.power == FB_BLANK_UNBLANK)
459  return dev->props.brightness;
460 
461  return 0;
462 }
463 
464 static const struct backlight_ops n8x0_bl_ops = {
465  .get_brightness = n8x0_bl_get_intensity,
466  .update_status = n8x0_bl_update_status,
467 };
468 
469 static int n8x0_panel_probe(struct omap_dss_device *dssdev)
470 {
471  struct panel_n8x0_data *bdata = get_board_data(dssdev);
472  struct panel_drv_data *ddata;
473  struct backlight_device *bldev;
474  struct backlight_properties props;
475  int r;
476 
477  dev_dbg(&dssdev->dev, "probe\n");
478 
479  if (!bdata)
480  return -EINVAL;
481 
482  s_drv_data.dssdev = dssdev;
483 
484  ddata = &s_drv_data;
485 
486  mutex_init(&ddata->lock);
487 
488  dssdev->panel.timings.x_res = 800;
489  dssdev->panel.timings.y_res = 480;
490  dssdev->ctrl.pixel_size = 16;
491  dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
493 
494  memset(&props, 0, sizeof(props));
495  props.max_brightness = 127;
496  props.type = BACKLIGHT_PLATFORM;
497  bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
498  dssdev, &n8x0_bl_ops, &props);
499  if (IS_ERR(bldev)) {
500  r = PTR_ERR(bldev);
501  dev_err(&dssdev->dev, "register backlight failed\n");
502  return r;
503  }
504 
505  ddata->bldev = bldev;
506 
507  bldev->props.fb_blank = FB_BLANK_UNBLANK;
508  bldev->props.power = FB_BLANK_UNBLANK;
509  bldev->props.brightness = 127;
510 
511  n8x0_bl_update_status(bldev);
512 
513  return 0;
514 }
515 
516 static void n8x0_panel_remove(struct omap_dss_device *dssdev)
517 {
518  struct panel_drv_data *ddata = get_drv_data(dssdev);
519  struct backlight_device *bldev;
520 
521  dev_dbg(&dssdev->dev, "remove\n");
522 
523  bldev = ddata->bldev;
524  bldev->props.power = FB_BLANK_POWERDOWN;
525  n8x0_bl_update_status(bldev);
527 
528  dev_set_drvdata(&dssdev->dev, NULL);
529 }
530 
531 static int n8x0_panel_enable(struct omap_dss_device *dssdev)
532 {
533  struct panel_drv_data *ddata = get_drv_data(dssdev);
534  int r;
535 
536  dev_dbg(&dssdev->dev, "enable\n");
537 
538  mutex_lock(&ddata->lock);
539 
540  rfbi_bus_lock();
541 
542  r = n8x0_panel_power_on(dssdev);
543 
544  rfbi_bus_unlock();
545 
546  if (r) {
547  mutex_unlock(&ddata->lock);
548  return r;
549  }
550 
551  dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
552 
553  mutex_unlock(&ddata->lock);
554 
555  return 0;
556 }
557 
558 static void n8x0_panel_disable(struct omap_dss_device *dssdev)
559 {
560  struct panel_drv_data *ddata = get_drv_data(dssdev);
561 
562  dev_dbg(&dssdev->dev, "disable\n");
563 
564  mutex_lock(&ddata->lock);
565 
566  rfbi_bus_lock();
567 
568  n8x0_panel_power_off(dssdev);
569 
570  rfbi_bus_unlock();
571 
573 
574  mutex_unlock(&ddata->lock);
575 }
576 
577 static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
578 {
579  struct panel_drv_data *ddata = get_drv_data(dssdev);
580 
581  dev_dbg(&dssdev->dev, "suspend\n");
582 
583  mutex_lock(&ddata->lock);
584 
585  rfbi_bus_lock();
586 
587  n8x0_panel_power_off(dssdev);
588 
589  rfbi_bus_unlock();
590 
592 
593  mutex_unlock(&ddata->lock);
594 
595  return 0;
596 }
597 
598 static int n8x0_panel_resume(struct omap_dss_device *dssdev)
599 {
600  struct panel_drv_data *ddata = get_drv_data(dssdev);
601  int r;
602 
603  dev_dbg(&dssdev->dev, "resume\n");
604 
605  mutex_lock(&ddata->lock);
606 
607  rfbi_bus_lock();
608 
609  r = n8x0_panel_power_on(dssdev);
610 
611  rfbi_bus_unlock();
612 
613  if (r) {
614  mutex_unlock(&ddata->lock);
615  return r;
616  }
617 
618  dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
619 
620  mutex_unlock(&ddata->lock);
621 
622  return 0;
623 }
624 
625 static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
626  u16 *xres, u16 *yres)
627 {
628  *xres = dssdev->panel.timings.x_res;
629  *yres = dssdev->panel.timings.y_res;
630 }
631 
632 static void update_done(void *data)
633 {
634  rfbi_bus_unlock();
635 }
636 
637 static int n8x0_panel_update(struct omap_dss_device *dssdev,
638  u16 x, u16 y, u16 w, u16 h)
639 {
640  struct panel_drv_data *ddata = get_drv_data(dssdev);
641  u16 dw, dh;
642 
643  dev_dbg(&dssdev->dev, "update\n");
644 
645  dw = dssdev->panel.timings.x_res;
646  dh = dssdev->panel.timings.y_res;
647 
648  if (x != 0 || y != 0 || w != dw || h != dh) {
649  dev_err(&dssdev->dev, "invaid update region %d, %d, %d, %d\n",
650  x, y, w, h);
651  return -EINVAL;
652  }
653 
654  mutex_lock(&ddata->lock);
655  rfbi_bus_lock();
656 
657  blizzard_ctrl_setup_update(dssdev, x, y, w, h);
658 
659  omap_rfbi_update(dssdev, update_done, NULL);
660 
661  mutex_unlock(&ddata->lock);
662 
663  return 0;
664 }
665 
666 static int n8x0_panel_sync(struct omap_dss_device *dssdev)
667 {
668  struct panel_drv_data *ddata = get_drv_data(dssdev);
669 
670  dev_dbg(&dssdev->dev, "sync\n");
671 
672  mutex_lock(&ddata->lock);
673  rfbi_bus_lock();
674  rfbi_bus_unlock();
675  mutex_unlock(&ddata->lock);
676 
677  return 0;
678 }
679 
680 static struct omap_dss_driver n8x0_panel_driver = {
681  .probe = n8x0_panel_probe,
682  .remove = n8x0_panel_remove,
683 
684  .enable = n8x0_panel_enable,
685  .disable = n8x0_panel_disable,
686  .suspend = n8x0_panel_suspend,
687  .resume = n8x0_panel_resume,
688 
689  .update = n8x0_panel_update,
690  .sync = n8x0_panel_sync,
691 
692  .get_resolution = n8x0_panel_get_resolution,
693  .get_recommended_bpp = omapdss_default_get_recommended_bpp,
694 
695  .driver = {
696  .name = "n8x0_panel",
697  .owner = THIS_MODULE,
698  },
699 };
700 
701 /* PANEL */
702 
703 static int mipid_spi_probe(struct spi_device *spi)
704 {
705  dev_dbg(&spi->dev, "mipid_spi_probe\n");
706 
707  spi->mode = SPI_MODE_0;
708 
709  s_drv_data.spidev = spi;
710 
711  return 0;
712 }
713 
714 static int mipid_spi_remove(struct spi_device *spi)
715 {
716  dev_dbg(&spi->dev, "mipid_spi_remove\n");
717  return 0;
718 }
719 
720 static struct spi_driver mipid_spi_driver = {
721  .driver = {
722  .name = "lcd_mipid",
723  .owner = THIS_MODULE,
724  },
725  .probe = mipid_spi_probe,
726  .remove = __devexit_p(mipid_spi_remove),
727 };
728 
729 static int __init n8x0_panel_drv_init(void)
730 {
731  int r;
732 
733  r = spi_register_driver(&mipid_spi_driver);
734  if (r) {
735  pr_err("n8x0_panel: spi driver registration failed\n");
736  return r;
737  }
738 
739  r = omap_dss_register_driver(&n8x0_panel_driver);
740  if (r) {
741  pr_err("n8x0_panel: dss driver registration failed\n");
742  spi_unregister_driver(&mipid_spi_driver);
743  return r;
744  }
745 
746  return 0;
747 }
748 
749 static void __exit n8x0_panel_drv_exit(void)
750 {
751  spi_unregister_driver(&mipid_spi_driver);
752 
753  omap_dss_unregister_driver(&n8x0_panel_driver);
754 }
755 
756 module_init(n8x0_panel_drv_init);
757 module_exit(n8x0_panel_drv_exit);
758 MODULE_LICENSE("GPL");