Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
panel-tpo-td043mtea1.c
Go to the documentation of this file.
1 /*
2  * LCD panel driver for TPO TD043MTEA1
3  *
4  * Author: Gražvydas Ignotas <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11 
12 #include <linux/module.h>
13 #include <linux/delay.h>
14 #include <linux/spi/spi.h>
16 #include <linux/gpio.h>
17 #include <linux/err.h>
18 #include <linux/slab.h>
19 
20 #include <video/omapdss.h>
21 
22 #define TPO_R02_MODE(x) ((x) & 7)
23 #define TPO_R02_MODE_800x480 7
24 #define TPO_R02_NCLK_RISING BIT(3)
25 #define TPO_R02_HSYNC_HIGH BIT(4)
26 #define TPO_R02_VSYNC_HIGH BIT(5)
27 
28 #define TPO_R03_NSTANDBY BIT(0)
29 #define TPO_R03_EN_CP_CLK BIT(1)
30 #define TPO_R03_EN_VGL_PUMP BIT(2)
31 #define TPO_R03_EN_PWM BIT(3)
32 #define TPO_R03_DRIVING_CAP_100 BIT(4)
33 #define TPO_R03_EN_PRE_CHARGE BIT(6)
34 #define TPO_R03_SOFTWARE_CTL BIT(7)
35 
36 #define TPO_R04_NFLIP_H BIT(0)
37 #define TPO_R04_NFLIP_V BIT(1)
38 #define TPO_R04_CP_CLK_FREQ_1H BIT(2)
39 #define TPO_R04_VGL_FREQ_1H BIT(4)
40 
41 #define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \
42  TPO_R03_EN_VGL_PUMP | TPO_R03_EN_PWM | \
43  TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
44  TPO_R03_SOFTWARE_CTL)
45 
46 #define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \
47  TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
48 
49 static const u16 tpo_td043_def_gamma[12] = {
50  105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
51 };
52 
54  struct spi_device *spi;
55  struct regulator *vcc_reg;
57  u16 gamma[12];
64 };
65 
66 static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
67 {
68  struct spi_message m;
69  struct spi_transfer xfer;
70  u16 w;
71  int r;
72 
73  spi_message_init(&m);
74 
75  memset(&xfer, 0, sizeof(xfer));
76 
77  w = ((u16)addr << 10) | (1 << 8) | data;
78  xfer.tx_buf = &w;
79  xfer.bits_per_word = 16;
80  xfer.len = 2;
81  spi_message_add_tail(&xfer, &m);
82 
83  r = spi_sync(spi, &m);
84  if (r < 0)
85  dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r);
86  return r;
87 }
88 
89 static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12])
90 {
91  u8 i, val;
92 
93  /* gamma bits [9:8] */
94  for (val = i = 0; i < 4; i++)
95  val |= (gamma[i] & 0x300) >> ((i + 1) * 2);
96  tpo_td043_write(spi, 0x11, val);
97 
98  for (val = i = 0; i < 4; i++)
99  val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2);
100  tpo_td043_write(spi, 0x12, val);
101 
102  for (val = i = 0; i < 4; i++)
103  val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2);
104  tpo_td043_write(spi, 0x13, val);
105 
106  /* gamma bits [7:0] */
107  for (val = i = 0; i < 12; i++)
108  tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff);
109 }
110 
111 static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v)
112 {
114  TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H;
115  if (h)
116  reg4 &= ~TPO_R04_NFLIP_H;
117  if (v)
118  reg4 &= ~TPO_R04_NFLIP_V;
119 
120  return tpo_td043_write(spi, 4, reg4);
121 }
122 
123 static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
124 {
125  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
126 
127  tpo_td043->hmirror = enable;
128  return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
129  tpo_td043->vmirror);
130 }
131 
132 static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev)
133 {
134  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
135 
136  return tpo_td043->hmirror;
137 }
138 
139 static ssize_t tpo_td043_vmirror_show(struct device *dev,
140  struct device_attribute *attr, char *buf)
141 {
142  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
143 
144  return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->vmirror);
145 }
146 
147 static ssize_t tpo_td043_vmirror_store(struct device *dev,
148  struct device_attribute *attr, const char *buf, size_t count)
149 {
150  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
151  int val;
152  int ret;
153 
154  ret = kstrtoint(buf, 0, &val);
155  if (ret < 0)
156  return ret;
157 
158  val = !!val;
159 
160  ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val);
161  if (ret < 0)
162  return ret;
163 
164  tpo_td043->vmirror = val;
165 
166  return count;
167 }
168 
169 static ssize_t tpo_td043_mode_show(struct device *dev,
170  struct device_attribute *attr, char *buf)
171 {
172  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
173 
174  return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->mode);
175 }
176 
177 static ssize_t tpo_td043_mode_store(struct device *dev,
178  struct device_attribute *attr, const char *buf, size_t count)
179 {
180  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
181  long val;
182  int ret;
183 
184  ret = kstrtol(buf, 0, &val);
185  if (ret != 0 || val & ~7)
186  return -EINVAL;
187 
188  tpo_td043->mode = val;
189 
190  val |= TPO_R02_NCLK_RISING;
191  tpo_td043_write(tpo_td043->spi, 2, val);
192 
193  return count;
194 }
195 
196 static ssize_t tpo_td043_gamma_show(struct device *dev,
197  struct device_attribute *attr, char *buf)
198 {
199  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
200  ssize_t len = 0;
201  int ret;
202  int i;
203 
204  for (i = 0; i < ARRAY_SIZE(tpo_td043->gamma); i++) {
205  ret = snprintf(buf + len, PAGE_SIZE - len, "%u ",
206  tpo_td043->gamma[i]);
207  if (ret < 0)
208  return ret;
209  len += ret;
210  }
211  buf[len - 1] = '\n';
212 
213  return len;
214 }
215 
216 static ssize_t tpo_td043_gamma_store(struct device *dev,
217  struct device_attribute *attr, const char *buf, size_t count)
218 {
219  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
220  unsigned int g[12];
221  int ret;
222  int i;
223 
224  ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u",
225  &g[0], &g[1], &g[2], &g[3], &g[4], &g[5],
226  &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]);
227 
228  if (ret != 12)
229  return -EINVAL;
230 
231  for (i = 0; i < 12; i++)
232  tpo_td043->gamma[i] = g[i];
233 
234  tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
235 
236  return count;
237 }
238 
240  tpo_td043_vmirror_show, tpo_td043_vmirror_store);
241 static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
242  tpo_td043_mode_show, tpo_td043_mode_store);
243 static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR,
244  tpo_td043_gamma_show, tpo_td043_gamma_store);
245 
246 static struct attribute *tpo_td043_attrs[] = {
247  &dev_attr_vmirror.attr,
248  &dev_attr_mode.attr,
249  &dev_attr_gamma.attr,
250  NULL,
251 };
252 
253 static struct attribute_group tpo_td043_attr_group = {
254  .attrs = tpo_td043_attrs,
255 };
256 
257 static const struct omap_video_timings tpo_td043_timings = {
258  .x_res = 800,
259  .y_res = 480,
260 
261  .pixel_clock = 36000,
262 
263  .hsw = 1,
264  .hfp = 68,
265  .hbp = 214,
266 
267  .vsw = 1,
268  .vfp = 39,
269  .vbp = 34,
270 
271  .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
272  .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
273  .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
274  .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
275  .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
276 };
277 
278 static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
279 {
280  int nreset_gpio = tpo_td043->nreset_gpio;
281  int r;
282 
283  if (tpo_td043->powered_on)
284  return 0;
285 
286  r = regulator_enable(tpo_td043->vcc_reg);
287  if (r != 0)
288  return r;
289 
290  /* wait for panel to stabilize */
291  msleep(160);
292 
293  if (gpio_is_valid(nreset_gpio))
294  gpio_set_value(nreset_gpio, 1);
295 
296  tpo_td043_write(tpo_td043->spi, 2,
297  TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING);
298  tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_NORMAL);
299  tpo_td043_write(tpo_td043->spi, 0x20, 0xf0);
300  tpo_td043_write(tpo_td043->spi, 0x21, 0xf0);
301  tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
302  tpo_td043->vmirror);
303  tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
304 
305  tpo_td043->powered_on = 1;
306  return 0;
307 }
308 
309 static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
310 {
311  int nreset_gpio = tpo_td043->nreset_gpio;
312 
313  if (!tpo_td043->powered_on)
314  return;
315 
316  tpo_td043_write(tpo_td043->spi, 3,
318 
319  if (gpio_is_valid(nreset_gpio))
320  gpio_set_value(nreset_gpio, 0);
321 
322  /* wait for at least 2 vsyncs before cutting off power */
323  msleep(50);
324 
325  tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY);
326 
327  regulator_disable(tpo_td043->vcc_reg);
328 
329  tpo_td043->powered_on = 0;
330 }
331 
332 static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
333 {
334  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
335  int r;
336 
337  if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
338  return 0;
339 
340  omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
341  omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
342 
343  r = omapdss_dpi_display_enable(dssdev);
344  if (r)
345  goto err0;
346 
347  if (dssdev->platform_enable) {
348  r = dssdev->platform_enable(dssdev);
349  if (r)
350  goto err1;
351  }
352 
353  /*
354  * If we are resuming from system suspend, SPI clocks might not be
355  * enabled yet, so we'll program the LCD from SPI PM resume callback.
356  */
357  if (!tpo_td043->spi_suspended) {
358  r = tpo_td043_power_on(tpo_td043);
359  if (r)
360  goto err1;
361  }
362 
363  dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
364 
365  return 0;
366 err1:
368 err0:
369  return r;
370 }
371 
372 static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
373 {
374  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
375 
376  if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
377  return;
378 
379  if (dssdev->platform_disable)
380  dssdev->platform_disable(dssdev);
381 
383 
384  if (!tpo_td043->spi_suspended)
385  tpo_td043_power_off(tpo_td043);
386 }
387 
388 static int tpo_td043_enable(struct omap_dss_device *dssdev)
389 {
390  dev_dbg(&dssdev->dev, "enable\n");
391 
392  return tpo_td043_enable_dss(dssdev);
393 }
394 
395 static void tpo_td043_disable(struct omap_dss_device *dssdev)
396 {
397  dev_dbg(&dssdev->dev, "disable\n");
398 
399  tpo_td043_disable_dss(dssdev);
400 
402 }
403 
404 static int tpo_td043_suspend(struct omap_dss_device *dssdev)
405 {
406  dev_dbg(&dssdev->dev, "suspend\n");
407 
408  tpo_td043_disable_dss(dssdev);
409 
411 
412  return 0;
413 }
414 
415 static int tpo_td043_resume(struct omap_dss_device *dssdev)
416 {
417  dev_dbg(&dssdev->dev, "resume\n");
418 
419  return tpo_td043_enable_dss(dssdev);
420 }
421 
422 static int tpo_td043_probe(struct omap_dss_device *dssdev)
423 {
424  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
425  int nreset_gpio = dssdev->reset_gpio;
426  int ret = 0;
427 
428  dev_dbg(&dssdev->dev, "probe\n");
429 
430  if (tpo_td043 == NULL) {
431  dev_err(&dssdev->dev, "missing tpo_td043_device\n");
432  return -ENODEV;
433  }
434 
435  dssdev->panel.timings = tpo_td043_timings;
436  dssdev->ctrl.pixel_size = 24;
437 
438  tpo_td043->mode = TPO_R02_MODE_800x480;
439  memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma));
440 
441  tpo_td043->vcc_reg = regulator_get(&dssdev->dev, "vcc");
442  if (IS_ERR(tpo_td043->vcc_reg)) {
443  dev_err(&dssdev->dev, "failed to get LCD VCC regulator\n");
444  ret = PTR_ERR(tpo_td043->vcc_reg);
445  goto fail_regulator;
446  }
447 
448  if (gpio_is_valid(nreset_gpio)) {
449  ret = gpio_request_one(nreset_gpio, GPIOF_OUT_INIT_LOW,
450  "lcd reset");
451  if (ret < 0) {
452  dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
453  goto fail_gpio_req;
454  }
455  }
456 
457  ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
458  if (ret)
459  dev_warn(&dssdev->dev, "failed to create sysfs files\n");
460 
461  return 0;
462 
463 fail_gpio_req:
464  regulator_put(tpo_td043->vcc_reg);
465 fail_regulator:
466  kfree(tpo_td043);
467  return ret;
468 }
469 
470 static void tpo_td043_remove(struct omap_dss_device *dssdev)
471 {
472  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
473  int nreset_gpio = dssdev->reset_gpio;
474 
475  dev_dbg(&dssdev->dev, "remove\n");
476 
477  sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
478  regulator_put(tpo_td043->vcc_reg);
479  if (gpio_is_valid(nreset_gpio))
480  gpio_free(nreset_gpio);
481 }
482 
483 static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
484  struct omap_video_timings *timings)
485 {
486  omapdss_dpi_set_timings(dssdev, timings);
487 
488  dssdev->panel.timings = *timings;
489 }
490 
491 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
492  struct omap_video_timings *timings)
493 {
494  return dpi_check_timings(dssdev, timings);
495 }
496 
497 static struct omap_dss_driver tpo_td043_driver = {
498  .probe = tpo_td043_probe,
499  .remove = tpo_td043_remove,
500 
501  .enable = tpo_td043_enable,
502  .disable = tpo_td043_disable,
503  .suspend = tpo_td043_suspend,
504  .resume = tpo_td043_resume,
505  .set_mirror = tpo_td043_set_hmirror,
506  .get_mirror = tpo_td043_get_hmirror,
507 
508  .set_timings = tpo_td043_set_timings,
509  .check_timings = tpo_td043_check_timings,
510 
511  .driver = {
512  .name = "tpo_td043mtea1_panel",
513  .owner = THIS_MODULE,
514  },
515 };
516 
517 static int tpo_td043_spi_probe(struct spi_device *spi)
518 {
519  struct omap_dss_device *dssdev = spi->dev.platform_data;
520  struct tpo_td043_device *tpo_td043;
521  int ret;
522 
523  if (dssdev == NULL) {
524  dev_err(&spi->dev, "missing dssdev\n");
525  return -ENODEV;
526  }
527 
528  spi->bits_per_word = 16;
529  spi->mode = SPI_MODE_0;
530 
531  ret = spi_setup(spi);
532  if (ret < 0) {
533  dev_err(&spi->dev, "spi_setup failed: %d\n", ret);
534  return ret;
535  }
536 
537  tpo_td043 = kzalloc(sizeof(*tpo_td043), GFP_KERNEL);
538  if (tpo_td043 == NULL)
539  return -ENOMEM;
540 
541  tpo_td043->spi = spi;
542  tpo_td043->nreset_gpio = dssdev->reset_gpio;
543  dev_set_drvdata(&spi->dev, tpo_td043);
544  dev_set_drvdata(&dssdev->dev, tpo_td043);
545 
546  omap_dss_register_driver(&tpo_td043_driver);
547 
548  return 0;
549 }
550 
551 static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
552 {
553  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev);
554 
555  omap_dss_unregister_driver(&tpo_td043_driver);
556  kfree(tpo_td043);
557 
558  return 0;
559 }
560 
561 #ifdef CONFIG_PM_SLEEP
562 static int tpo_td043_spi_suspend(struct device *dev)
563 {
564  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
565 
566  dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043);
567 
568  tpo_td043->power_on_resume = tpo_td043->powered_on;
569  tpo_td043_power_off(tpo_td043);
570  tpo_td043->spi_suspended = 1;
571 
572  return 0;
573 }
574 
575 static int tpo_td043_spi_resume(struct device *dev)
576 {
577  struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
578  int ret;
579 
580  dev_dbg(dev, "tpo_td043_spi_resume\n");
581 
582  if (tpo_td043->power_on_resume) {
583  ret = tpo_td043_power_on(tpo_td043);
584  if (ret)
585  return ret;
586  }
587  tpo_td043->spi_suspended = 0;
588 
589  return 0;
590 }
591 #endif
592 
593 static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,
594  tpo_td043_spi_suspend, tpo_td043_spi_resume);
595 
596 static struct spi_driver tpo_td043_spi_driver = {
597  .driver = {
598  .name = "tpo_td043mtea1_panel_spi",
599  .owner = THIS_MODULE,
600  .pm = &tpo_td043_spi_pm,
601  },
602  .probe = tpo_td043_spi_probe,
603  .remove = __devexit_p(tpo_td043_spi_remove),
604 };
605 
606 module_spi_driver(tpo_td043_spi_driver);
607 
608 MODULE_AUTHOR("Gražvydas Ignotas <[email protected]>");
609 MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
610 MODULE_LICENSE("GPL");