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