]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
drm/omap: Merge omap_dss_device type and output_type fields
[linux.git] / drivers / gpu / drm / omapdrm / displays / panel-tpo-td043mtea1.c
1 /*
2  * TPO TD043MTEA1 Panel driver
3  *
4  * Author: Gražvydas Ignotas <notasas@gmail.com>
5  * Converted to new DSS device model: Tomi Valkeinen <tomi.valkeinen@ti.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  */
12
13 #include <linux/delay.h>
14 #include <linux/err.h>
15 #include <linux/gpio/consumer.h>
16 #include <linux/module.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/slab.h>
19 #include <linux/spi/spi.h>
20
21 #include "../dss/omapdss.h"
22
23 #define TPO_R02_MODE(x)         ((x) & 7)
24 #define TPO_R02_MODE_800x480    7
25 #define TPO_R02_NCLK_RISING     BIT(3)
26 #define TPO_R02_HSYNC_HIGH      BIT(4)
27 #define TPO_R02_VSYNC_HIGH      BIT(5)
28
29 #define TPO_R03_NSTANDBY        BIT(0)
30 #define TPO_R03_EN_CP_CLK       BIT(1)
31 #define TPO_R03_EN_VGL_PUMP     BIT(2)
32 #define TPO_R03_EN_PWM          BIT(3)
33 #define TPO_R03_DRIVING_CAP_100 BIT(4)
34 #define TPO_R03_EN_PRE_CHARGE   BIT(6)
35 #define TPO_R03_SOFTWARE_CTL    BIT(7)
36
37 #define TPO_R04_NFLIP_H         BIT(0)
38 #define TPO_R04_NFLIP_V         BIT(1)
39 #define TPO_R04_CP_CLK_FREQ_1H  BIT(2)
40 #define TPO_R04_VGL_FREQ_1H     BIT(4)
41
42 #define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \
43                         TPO_R03_EN_VGL_PUMP |  TPO_R03_EN_PWM | \
44                         TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
45                         TPO_R03_SOFTWARE_CTL)
46
47 #define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \
48                         TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
49
50 static const u16 tpo_td043_def_gamma[12] = {
51         105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
52 };
53
54 struct panel_drv_data {
55         struct omap_dss_device  dssdev;
56
57         struct videomode vm;
58
59         struct spi_device *spi;
60         struct regulator *vcc_reg;
61         struct gpio_desc *reset_gpio;
62         u16 gamma[12];
63         u32 mode;
64         u32 vmirror:1;
65         u32 powered_on:1;
66         u32 spi_suspended:1;
67         u32 power_on_resume:1;
68 };
69
70 static const struct videomode tpo_td043_vm = {
71         .hactive        = 800,
72         .vactive        = 480,
73
74         .pixelclock     = 36000000,
75
76         .hsync_len      = 1,
77         .hfront_porch   = 68,
78         .hback_porch    = 214,
79
80         .vsync_len      = 1,
81         .vfront_porch   = 39,
82         .vback_porch    = 34,
83
84         .flags          = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
85 };
86
87 #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
88
89 static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
90 {
91         struct spi_message      m;
92         struct spi_transfer     xfer;
93         u16                     w;
94         int                     r;
95
96         spi_message_init(&m);
97
98         memset(&xfer, 0, sizeof(xfer));
99
100         w = ((u16)addr << 10) | (1 << 8) | data;
101         xfer.tx_buf = &w;
102         xfer.bits_per_word = 16;
103         xfer.len = 2;
104         spi_message_add_tail(&xfer, &m);
105
106         r = spi_sync(spi, &m);
107         if (r < 0)
108                 dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r);
109         return r;
110 }
111
112 static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12])
113 {
114         u8 i, val;
115
116         /* gamma bits [9:8] */
117         for (val = i = 0; i < 4; i++)
118                 val |= (gamma[i] & 0x300) >> ((i + 1) * 2);
119         tpo_td043_write(spi, 0x11, val);
120
121         for (val = i = 0; i < 4; i++)
122                 val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2);
123         tpo_td043_write(spi, 0x12, val);
124
125         for (val = i = 0; i < 4; i++)
126                 val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2);
127         tpo_td043_write(spi, 0x13, val);
128
129         /* gamma bits [7:0] */
130         for (val = i = 0; i < 12; i++)
131                 tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff);
132 }
133
134 static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v)
135 {
136         u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V |
137                 TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H;
138         if (h)
139                 reg4 &= ~TPO_R04_NFLIP_H;
140         if (v)
141                 reg4 &= ~TPO_R04_NFLIP_V;
142
143         return tpo_td043_write(spi, 4, reg4);
144 }
145
146 static ssize_t tpo_td043_vmirror_show(struct device *dev,
147         struct device_attribute *attr, char *buf)
148 {
149         struct panel_drv_data *ddata = dev_get_drvdata(dev);
150
151         return snprintf(buf, PAGE_SIZE, "%d\n", ddata->vmirror);
152 }
153
154 static ssize_t tpo_td043_vmirror_store(struct device *dev,
155         struct device_attribute *attr, const char *buf, size_t count)
156 {
157         struct panel_drv_data *ddata = dev_get_drvdata(dev);
158         int val;
159         int ret;
160
161         ret = kstrtoint(buf, 0, &val);
162         if (ret < 0)
163                 return ret;
164
165         val = !!val;
166
167         ret = tpo_td043_write_mirror(ddata->spi, false, val);
168         if (ret < 0)
169                 return ret;
170
171         ddata->vmirror = val;
172
173         return count;
174 }
175
176 static ssize_t tpo_td043_mode_show(struct device *dev,
177         struct device_attribute *attr, char *buf)
178 {
179         struct panel_drv_data *ddata = dev_get_drvdata(dev);
180
181         return snprintf(buf, PAGE_SIZE, "%d\n", ddata->mode);
182 }
183
184 static ssize_t tpo_td043_mode_store(struct device *dev,
185         struct device_attribute *attr, const char *buf, size_t count)
186 {
187         struct panel_drv_data *ddata = dev_get_drvdata(dev);
188         long val;
189         int ret;
190
191         ret = kstrtol(buf, 0, &val);
192         if (ret != 0 || val & ~7)
193                 return -EINVAL;
194
195         ddata->mode = val;
196
197         val |= TPO_R02_NCLK_RISING;
198         tpo_td043_write(ddata->spi, 2, val);
199
200         return count;
201 }
202
203 static ssize_t tpo_td043_gamma_show(struct device *dev,
204         struct device_attribute *attr, char *buf)
205 {
206         struct panel_drv_data *ddata = dev_get_drvdata(dev);
207         ssize_t len = 0;
208         int ret;
209         int i;
210
211         for (i = 0; i < ARRAY_SIZE(ddata->gamma); i++) {
212                 ret = snprintf(buf + len, PAGE_SIZE - len, "%u ",
213                                 ddata->gamma[i]);
214                 if (ret < 0)
215                         return ret;
216                 len += ret;
217         }
218         buf[len - 1] = '\n';
219
220         return len;
221 }
222
223 static ssize_t tpo_td043_gamma_store(struct device *dev,
224         struct device_attribute *attr, const char *buf, size_t count)
225 {
226         struct panel_drv_data *ddata = dev_get_drvdata(dev);
227         unsigned int g[12];
228         int ret;
229         int i;
230
231         ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u",
232                         &g[0], &g[1], &g[2], &g[3], &g[4], &g[5],
233                         &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]);
234
235         if (ret != 12)
236                 return -EINVAL;
237
238         for (i = 0; i < 12; i++)
239                 ddata->gamma[i] = g[i];
240
241         tpo_td043_write_gamma(ddata->spi, ddata->gamma);
242
243         return count;
244 }
245
246 static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR,
247                 tpo_td043_vmirror_show, tpo_td043_vmirror_store);
248 static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
249                 tpo_td043_mode_show, tpo_td043_mode_store);
250 static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR,
251                 tpo_td043_gamma_show, tpo_td043_gamma_store);
252
253 static struct attribute *tpo_td043_attrs[] = {
254         &dev_attr_vmirror.attr,
255         &dev_attr_mode.attr,
256         &dev_attr_gamma.attr,
257         NULL,
258 };
259
260 static const struct attribute_group tpo_td043_attr_group = {
261         .attrs = tpo_td043_attrs,
262 };
263
264 static int tpo_td043_power_on(struct panel_drv_data *ddata)
265 {
266         int r;
267
268         if (ddata->powered_on)
269                 return 0;
270
271         r = regulator_enable(ddata->vcc_reg);
272         if (r != 0)
273                 return r;
274
275         /* wait for panel to stabilize */
276         msleep(160);
277
278         gpiod_set_value(ddata->reset_gpio, 0);
279
280         tpo_td043_write(ddata->spi, 2,
281                         TPO_R02_MODE(ddata->mode) | TPO_R02_NCLK_RISING);
282         tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_NORMAL);
283         tpo_td043_write(ddata->spi, 0x20, 0xf0);
284         tpo_td043_write(ddata->spi, 0x21, 0xf0);
285         tpo_td043_write_mirror(ddata->spi, false, ddata->vmirror);
286         tpo_td043_write_gamma(ddata->spi, ddata->gamma);
287
288         ddata->powered_on = 1;
289         return 0;
290 }
291
292 static void tpo_td043_power_off(struct panel_drv_data *ddata)
293 {
294         if (!ddata->powered_on)
295                 return;
296
297         tpo_td043_write(ddata->spi, 3,
298                         TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
299
300         gpiod_set_value(ddata->reset_gpio, 1);
301
302         /* wait for at least 2 vsyncs before cutting off power */
303         msleep(50);
304
305         tpo_td043_write(ddata->spi, 3, TPO_R03_VAL_STANDBY);
306
307         regulator_disable(ddata->vcc_reg);
308
309         ddata->powered_on = 0;
310 }
311
312 static int tpo_td043_connect(struct omap_dss_device *src,
313                              struct omap_dss_device *dst)
314 {
315         return 0;
316 }
317
318 static void tpo_td043_disconnect(struct omap_dss_device *src,
319                                  struct omap_dss_device *dst)
320 {
321 }
322
323 static void tpo_td043_enable(struct omap_dss_device *dssdev)
324 {
325         struct panel_drv_data *ddata = to_panel_data(dssdev);
326         int r;
327
328         /*
329          * If we are resuming from system suspend, SPI clocks might not be
330          * enabled yet, so we'll program the LCD from SPI PM resume callback.
331          */
332         if (!ddata->spi_suspended) {
333                 r = tpo_td043_power_on(ddata);
334                 if (r) {
335                         dev_err(&ddata->spi->dev, "%s: power on failed (%d)\n",
336                                 __func__, r);
337                         return;
338                 }
339         }
340 }
341
342 static void tpo_td043_disable(struct omap_dss_device *dssdev)
343 {
344         struct panel_drv_data *ddata = to_panel_data(dssdev);
345
346         if (!ddata->spi_suspended)
347                 tpo_td043_power_off(ddata);
348 }
349
350 static int tpo_td043_get_modes(struct omap_dss_device *dssdev,
351                                struct drm_connector *connector)
352 {
353         struct panel_drv_data *ddata = to_panel_data(dssdev);
354
355         return omapdss_display_get_modes(connector, &ddata->vm);
356 }
357
358 static const struct omap_dss_device_ops tpo_td043_ops = {
359         .connect        = tpo_td043_connect,
360         .disconnect     = tpo_td043_disconnect,
361
362         .enable         = tpo_td043_enable,
363         .disable        = tpo_td043_disable,
364
365         .get_modes      = tpo_td043_get_modes,
366 };
367
368 static int tpo_td043_probe(struct spi_device *spi)
369 {
370         struct panel_drv_data *ddata;
371         struct omap_dss_device *dssdev;
372         struct gpio_desc *gpio;
373         int r;
374
375         dev_dbg(&spi->dev, "%s\n", __func__);
376
377         spi->bits_per_word = 16;
378         spi->mode = SPI_MODE_0;
379
380         r = spi_setup(spi);
381         if (r < 0) {
382                 dev_err(&spi->dev, "spi_setup failed: %d\n", r);
383                 return r;
384         }
385
386         ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
387         if (ddata == NULL)
388                 return -ENOMEM;
389
390         dev_set_drvdata(&spi->dev, ddata);
391
392         ddata->spi = spi;
393
394         ddata->mode = TPO_R02_MODE_800x480;
395         memcpy(ddata->gamma, tpo_td043_def_gamma, sizeof(ddata->gamma));
396
397         ddata->vcc_reg = devm_regulator_get(&spi->dev, "vcc");
398         if (IS_ERR(ddata->vcc_reg)) {
399                 dev_err(&spi->dev, "failed to get LCD VCC regulator\n");
400                 return PTR_ERR(ddata->vcc_reg);
401         }
402
403         gpio = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_HIGH);
404         if (IS_ERR(gpio)) {
405                 dev_err(&spi->dev, "failed to get reset gpio\n");
406                 return PTR_ERR(gpio);
407         }
408
409         ddata->reset_gpio = gpio;
410
411         r = sysfs_create_group(&spi->dev.kobj, &tpo_td043_attr_group);
412         if (r) {
413                 dev_err(&spi->dev, "failed to create sysfs files\n");
414                 return r;
415         }
416
417         ddata->vm = tpo_td043_vm;
418
419         dssdev = &ddata->dssdev;
420         dssdev->dev = &spi->dev;
421         dssdev->ops = &tpo_td043_ops;
422         dssdev->type = OMAP_DISPLAY_TYPE_DPI;
423         dssdev->display = true;
424         dssdev->owner = THIS_MODULE;
425         dssdev->of_ports = BIT(0);
426         dssdev->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
427
428         /*
429          * Note: According to the panel documentation:
430          * SYNC needs to be driven on the FALLING edge
431          */
432         dssdev->bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_SYNC_POSEDGE
433                           | DRM_BUS_FLAG_PIXDATA_NEGEDGE;
434
435         omapdss_display_init(dssdev);
436         omapdss_device_register(dssdev);
437
438         return 0;
439 }
440
441 static int tpo_td043_remove(struct spi_device *spi)
442 {
443         struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
444         struct omap_dss_device *dssdev = &ddata->dssdev;
445
446         dev_dbg(&ddata->spi->dev, "%s\n", __func__);
447
448         omapdss_device_unregister(dssdev);
449
450         if (omapdss_device_is_enabled(dssdev))
451                 tpo_td043_disable(dssdev);
452
453         sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);
454
455         return 0;
456 }
457
458 #ifdef CONFIG_PM_SLEEP
459 static int tpo_td043_spi_suspend(struct device *dev)
460 {
461         struct panel_drv_data *ddata = dev_get_drvdata(dev);
462
463         dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", ddata);
464
465         ddata->power_on_resume = ddata->powered_on;
466         tpo_td043_power_off(ddata);
467         ddata->spi_suspended = 1;
468
469         return 0;
470 }
471
472 static int tpo_td043_spi_resume(struct device *dev)
473 {
474         struct panel_drv_data *ddata = dev_get_drvdata(dev);
475         int ret;
476
477         dev_dbg(dev, "tpo_td043_spi_resume\n");
478
479         if (ddata->power_on_resume) {
480                 ret = tpo_td043_power_on(ddata);
481                 if (ret)
482                         return ret;
483         }
484         ddata->spi_suspended = 0;
485
486         return 0;
487 }
488 #endif
489
490 static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,
491         tpo_td043_spi_suspend, tpo_td043_spi_resume);
492
493 static const struct of_device_id tpo_td043_of_match[] = {
494         { .compatible = "omapdss,tpo,td043mtea1", },
495         {},
496 };
497
498 MODULE_DEVICE_TABLE(of, tpo_td043_of_match);
499
500 static struct spi_driver tpo_td043_spi_driver = {
501         .driver = {
502                 .name   = "panel-tpo-td043mtea1",
503                 .pm     = &tpo_td043_spi_pm,
504                 .of_match_table = tpo_td043_of_match,
505                 .suppress_bind_attrs = true,
506         },
507         .probe  = tpo_td043_probe,
508         .remove = tpo_td043_remove,
509 };
510
511 module_spi_driver(tpo_td043_spi_driver);
512
513 MODULE_ALIAS("spi:tpo,td043mtea1");
514 MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
515 MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
516 MODULE_LICENSE("GPL");