2 * LCD panel driver for TPO TD043MTEA1
4 * Author: Gražvydas Ignotas <notasas@gmail.com>
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.
12 #include <linux/module.h>
13 #include <linux/delay.h>
14 #include <linux/spi/spi.h>
15 #include <linux/regulator/consumer.h>
16 #include <linux/gpio.h>
17 #include <linux/err.h>
18 #include <linux/slab.h>
20 #include <video/omapdss.h>
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)
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)
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)
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 | \
46 #define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \
47 TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
49 static const u16 tpo_td043_def_gamma[12] = {
50 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
53 struct tpo_td043_device {
54 struct spi_device *spi;
55 struct regulator *vcc_reg;
63 u32 power_on_resume:1;
66 static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
69 struct spi_transfer xfer;
75 memset(&xfer, 0, sizeof(xfer));
77 w = ((u16)addr << 10) | (1 << 8) | data;
79 xfer.bits_per_word = 16;
81 spi_message_add_tail(&xfer, &m);
83 r = spi_sync(spi, &m);
85 dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r);
89 static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12])
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);
98 for (val = i = 0; i < 4; i++)
99 val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2);
100 tpo_td043_write(spi, 0x12, val);
102 for (val = i = 0; i < 4; i++)
103 val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2);
104 tpo_td043_write(spi, 0x13, val);
106 /* gamma bits [7:0] */
107 for (val = i = 0; i < 12; i++)
108 tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff);
111 static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v)
113 u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V | \
114 TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H;
116 reg4 &= ~TPO_R04_NFLIP_H;
118 reg4 &= ~TPO_R04_NFLIP_V;
120 return tpo_td043_write(spi, 4, reg4);
123 static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
125 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
127 tpo_td043->hmirror = enable;
128 return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
132 static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev)
134 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
136 return tpo_td043->hmirror;
139 static ssize_t tpo_td043_vmirror_show(struct device *dev,
140 struct device_attribute *attr, char *buf)
142 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
144 return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->vmirror);
147 static ssize_t tpo_td043_vmirror_store(struct device *dev,
148 struct device_attribute *attr, const char *buf, size_t count)
150 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
154 ret = kstrtoint(buf, 0, &val);
160 ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val);
164 tpo_td043->vmirror = val;
169 static ssize_t tpo_td043_mode_show(struct device *dev,
170 struct device_attribute *attr, char *buf)
172 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
174 return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->mode);
177 static ssize_t tpo_td043_mode_store(struct device *dev,
178 struct device_attribute *attr, const char *buf, size_t count)
180 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
184 ret = kstrtol(buf, 0, &val);
185 if (ret != 0 || val & ~7)
188 tpo_td043->mode = val;
190 val |= TPO_R02_NCLK_RISING;
191 tpo_td043_write(tpo_td043->spi, 2, val);
196 static ssize_t tpo_td043_gamma_show(struct device *dev,
197 struct device_attribute *attr, char *buf)
199 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
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]);
216 static ssize_t tpo_td043_gamma_store(struct device *dev,
217 struct device_attribute *attr, const char *buf, size_t count)
219 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
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]);
231 for (i = 0; i < 12; i++)
232 tpo_td043->gamma[i] = g[i];
234 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
239 static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR,
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);
246 static struct attribute *tpo_td043_attrs[] = {
247 &dev_attr_vmirror.attr,
249 &dev_attr_gamma.attr,
253 static struct attribute_group tpo_td043_attr_group = {
254 .attrs = tpo_td043_attrs,
257 static const struct omap_video_timings tpo_td043_timings = {
261 .pixel_clock = 36000,
264 * hbp+hsw must be 215
265 * if vbp+vsw < 32, the panel tears at the bottom
266 * if vbp+vsw > 35, it wraps from the top */
276 static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
278 int nreset_gpio = tpo_td043->nreset_gpio;
280 if (tpo_td043->powered_on)
283 regulator_enable(tpo_td043->vcc_reg);
285 /* wait for regulator to stabilize */
288 if (gpio_is_valid(nreset_gpio))
289 gpio_set_value(nreset_gpio, 1);
291 tpo_td043_write(tpo_td043->spi, 2,
292 TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING);
293 tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_NORMAL);
294 tpo_td043_write(tpo_td043->spi, 0x20, 0xf0);
295 tpo_td043_write(tpo_td043->spi, 0x21, 0xf0);
296 tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
298 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
300 tpo_td043->powered_on = 1;
304 static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
306 int nreset_gpio = tpo_td043->nreset_gpio;
308 if (!tpo_td043->powered_on)
311 tpo_td043_write(tpo_td043->spi, 3,
312 TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
314 if (gpio_is_valid(nreset_gpio))
315 gpio_set_value(nreset_gpio, 0);
317 /* wait for at least 2 vsyncs before cutting off power */
320 tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY);
322 regulator_disable(tpo_td043->vcc_reg);
324 tpo_td043->powered_on = 0;
327 static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
329 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
332 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
335 r = omapdss_dpi_display_enable(dssdev);
339 if (dssdev->platform_enable) {
340 r = dssdev->platform_enable(dssdev);
346 * If we are resuming from system suspend, SPI clocks might not be
347 * enabled yet, so we'll program the LCD from SPI PM resume callback.
349 if (!tpo_td043->spi_suspended) {
350 r = tpo_td043_power_on(tpo_td043);
355 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
359 omapdss_dpi_display_disable(dssdev);
364 static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
366 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
368 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
371 if (dssdev->platform_disable)
372 dssdev->platform_disable(dssdev);
374 omapdss_dpi_display_disable(dssdev);
376 if (!tpo_td043->spi_suspended)
377 tpo_td043_power_off(tpo_td043);
380 static int tpo_td043_enable(struct omap_dss_device *dssdev)
382 dev_dbg(&dssdev->dev, "enable\n");
384 return tpo_td043_enable_dss(dssdev);
387 static void tpo_td043_disable(struct omap_dss_device *dssdev)
389 dev_dbg(&dssdev->dev, "disable\n");
391 tpo_td043_disable_dss(dssdev);
393 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
396 static int tpo_td043_suspend(struct omap_dss_device *dssdev)
398 dev_dbg(&dssdev->dev, "suspend\n");
400 tpo_td043_disable_dss(dssdev);
402 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
407 static int tpo_td043_resume(struct omap_dss_device *dssdev)
409 dev_dbg(&dssdev->dev, "resume\n");
411 return tpo_td043_enable_dss(dssdev);
414 static int tpo_td043_probe(struct omap_dss_device *dssdev)
416 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
417 int nreset_gpio = dssdev->reset_gpio;
420 dev_dbg(&dssdev->dev, "probe\n");
422 if (tpo_td043 == NULL) {
423 dev_err(&dssdev->dev, "missing tpo_td043_device\n");
427 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS |
428 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IPC;
429 dssdev->panel.timings = tpo_td043_timings;
430 dssdev->ctrl.pixel_size = 24;
432 tpo_td043->mode = TPO_R02_MODE_800x480;
433 memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma));
435 tpo_td043->vcc_reg = regulator_get(&dssdev->dev, "vcc");
436 if (IS_ERR(tpo_td043->vcc_reg)) {
437 dev_err(&dssdev->dev, "failed to get LCD VCC regulator\n");
438 ret = PTR_ERR(tpo_td043->vcc_reg);
442 if (gpio_is_valid(nreset_gpio)) {
443 ret = gpio_request(nreset_gpio, "lcd reset");
445 dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
449 ret = gpio_direction_output(nreset_gpio, 0);
451 dev_err(&dssdev->dev, "couldn't set GPIO direction\n");
452 goto fail_gpio_direction;
456 ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
458 dev_warn(&dssdev->dev, "failed to create sysfs files\n");
463 gpio_free(nreset_gpio);
465 regulator_put(tpo_td043->vcc_reg);
471 static void tpo_td043_remove(struct omap_dss_device *dssdev)
473 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
474 int nreset_gpio = dssdev->reset_gpio;
476 dev_dbg(&dssdev->dev, "remove\n");
478 sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
479 regulator_put(tpo_td043->vcc_reg);
480 if (gpio_is_valid(nreset_gpio))
481 gpio_free(nreset_gpio);
484 static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
485 struct omap_video_timings *timings)
487 dpi_set_timings(dssdev, timings);
490 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
491 struct omap_video_timings *timings)
493 return dpi_check_timings(dssdev, timings);
496 static struct omap_dss_driver tpo_td043_driver = {
497 .probe = tpo_td043_probe,
498 .remove = tpo_td043_remove,
500 .enable = tpo_td043_enable,
501 .disable = tpo_td043_disable,
502 .suspend = tpo_td043_suspend,
503 .resume = tpo_td043_resume,
504 .set_mirror = tpo_td043_set_hmirror,
505 .get_mirror = tpo_td043_get_hmirror,
507 .set_timings = tpo_td043_set_timings,
508 .check_timings = tpo_td043_check_timings,
511 .name = "tpo_td043mtea1_panel",
512 .owner = THIS_MODULE,
516 static int tpo_td043_spi_probe(struct spi_device *spi)
518 struct omap_dss_device *dssdev = spi->dev.platform_data;
519 struct tpo_td043_device *tpo_td043;
522 if (dssdev == NULL) {
523 dev_err(&spi->dev, "missing dssdev\n");
527 spi->bits_per_word = 16;
528 spi->mode = SPI_MODE_0;
530 ret = spi_setup(spi);
532 dev_err(&spi->dev, "spi_setup failed: %d\n", ret);
536 tpo_td043 = kzalloc(sizeof(*tpo_td043), GFP_KERNEL);
537 if (tpo_td043 == NULL)
540 tpo_td043->spi = spi;
541 tpo_td043->nreset_gpio = dssdev->reset_gpio;
542 dev_set_drvdata(&spi->dev, tpo_td043);
543 dev_set_drvdata(&dssdev->dev, tpo_td043);
545 omap_dss_register_driver(&tpo_td043_driver);
550 static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
552 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev);
554 omap_dss_unregister_driver(&tpo_td043_driver);
560 #ifdef CONFIG_PM_SLEEP
561 static int tpo_td043_spi_suspend(struct device *dev)
563 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
565 dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043);
567 tpo_td043->power_on_resume = tpo_td043->powered_on;
568 tpo_td043_power_off(tpo_td043);
569 tpo_td043->spi_suspended = 1;
574 static int tpo_td043_spi_resume(struct device *dev)
576 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
579 dev_dbg(dev, "tpo_td043_spi_resume\n");
581 if (tpo_td043->power_on_resume) {
582 ret = tpo_td043_power_on(tpo_td043);
586 tpo_td043->spi_suspended = 0;
592 static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,
593 tpo_td043_spi_suspend, tpo_td043_spi_resume);
595 static struct spi_driver tpo_td043_spi_driver = {
597 .name = "tpo_td043mtea1_panel_spi",
598 .bus = &spi_bus_type,
599 .owner = THIS_MODULE,
600 .pm = &tpo_td043_spi_pm,
602 .probe = tpo_td043_spi_probe,
603 .remove = __devexit_p(tpo_td043_spi_remove),
606 static int __init tpo_td043_init(void)
608 return spi_register_driver(&tpo_td043_spi_driver);
611 static void __exit tpo_td043_exit(void)
613 spi_unregister_driver(&tpo_td043_spi_driver);
616 module_init(tpo_td043_init);
617 module_exit(tpo_td043_exit);
619 MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
620 MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
621 MODULE_LICENSE("GPL");