1 // SPDX-License-Identifier: GPL-2.0+
3 * Toppoly TD043MTEA1 Panel Driver
5 * Copyright (C) 2019 Texas Instruments Incorporated
7 * Based on the omapdrm-specific panel-tpo-td043mtea1 driver
9 * Author: Gražvydas Ignotas <notasas@gmail.com>
12 #include <linux/delay.h>
13 #include <linux/module.h>
14 #include <linux/regulator/consumer.h>
15 #include <linux/spi/spi.h>
17 #include <drm/drm_connector.h>
18 #include <drm/drm_modes.h>
19 #include <drm/drm_panel.h>
21 #define TPO_R02_MODE(x) ((x) & 7)
22 #define TPO_R02_MODE_800x480 7
23 #define TPO_R02_NCLK_RISING BIT(3)
24 #define TPO_R02_HSYNC_HIGH BIT(4)
25 #define TPO_R02_VSYNC_HIGH BIT(5)
27 #define TPO_R03_NSTANDBY BIT(0)
28 #define TPO_R03_EN_CP_CLK BIT(1)
29 #define TPO_R03_EN_VGL_PUMP BIT(2)
30 #define TPO_R03_EN_PWM BIT(3)
31 #define TPO_R03_DRIVING_CAP_100 BIT(4)
32 #define TPO_R03_EN_PRE_CHARGE BIT(6)
33 #define TPO_R03_SOFTWARE_CTL BIT(7)
35 #define TPO_R04_NFLIP_H BIT(0)
36 #define TPO_R04_NFLIP_V BIT(1)
37 #define TPO_R04_CP_CLK_FREQ_1H BIT(2)
38 #define TPO_R04_VGL_FREQ_1H BIT(4)
40 #define TPO_R03_VAL_NORMAL \
41 (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | TPO_R03_EN_VGL_PUMP | \
42 TPO_R03_EN_PWM | TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
45 #define TPO_R03_VAL_STANDBY \
46 (TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
49 static const u16 td043mtea1_def_gamma
[12] = {
50 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
53 struct td043mtea1_panel
{
54 struct drm_panel panel
;
56 struct spi_device
*spi
;
57 struct regulator
*vcc_reg
;
58 struct gpio_desc
*reset_gpio
;
68 #define to_td043mtea1_device(p) container_of(p, struct td043mtea1_panel, panel)
70 /* -----------------------------------------------------------------------------
74 static int td043mtea1_write(struct td043mtea1_panel
*lcd
, u8 addr
, u8 value
)
76 struct spi_message msg
;
77 struct spi_transfer xfer
;
81 spi_message_init(&msg
);
83 memset(&xfer
, 0, sizeof(xfer
));
85 data
= ((u16
)addr
<< 10) | (1 << 8) | value
;
87 xfer
.bits_per_word
= 16;
89 spi_message_add_tail(&xfer
, &msg
);
91 ret
= spi_sync(lcd
->spi
, &msg
);
93 dev_warn(&lcd
->spi
->dev
, "failed to write to LCD reg (%d)\n",
99 static void td043mtea1_write_gamma(struct td043mtea1_panel
*lcd
)
101 const u16
*gamma
= lcd
->gamma
;
105 /* gamma bits [9:8] */
106 for (val
= i
= 0; i
< 4; i
++)
107 val
|= (gamma
[i
] & 0x300) >> ((i
+ 1) * 2);
108 td043mtea1_write(lcd
, 0x11, val
);
110 for (val
= i
= 0; i
< 4; i
++)
111 val
|= (gamma
[i
+ 4] & 0x300) >> ((i
+ 1) * 2);
112 td043mtea1_write(lcd
, 0x12, val
);
114 for (val
= i
= 0; i
< 4; i
++)
115 val
|= (gamma
[i
+ 8] & 0x300) >> ((i
+ 1) * 2);
116 td043mtea1_write(lcd
, 0x13, val
);
118 /* gamma bits [7:0] */
119 for (i
= 0; i
< 12; i
++)
120 td043mtea1_write(lcd
, 0x14 + i
, gamma
[i
] & 0xff);
123 static int td043mtea1_write_mirror(struct td043mtea1_panel
*lcd
)
125 u8 reg4
= TPO_R04_NFLIP_H
| TPO_R04_NFLIP_V
|
126 TPO_R04_CP_CLK_FREQ_1H
| TPO_R04_VGL_FREQ_1H
;
128 reg4
&= ~TPO_R04_NFLIP_V
;
130 return td043mtea1_write(lcd
, 4, reg4
);
133 static int td043mtea1_power_on(struct td043mtea1_panel
*lcd
)
140 ret
= regulator_enable(lcd
->vcc_reg
);
144 /* Wait for the panel to stabilize. */
147 gpiod_set_value(lcd
->reset_gpio
, 0);
149 td043mtea1_write(lcd
, 2, TPO_R02_MODE(lcd
->mode
) | TPO_R02_NCLK_RISING
);
150 td043mtea1_write(lcd
, 3, TPO_R03_VAL_NORMAL
);
151 td043mtea1_write(lcd
, 0x20, 0xf0);
152 td043mtea1_write(lcd
, 0x21, 0xf0);
153 td043mtea1_write_mirror(lcd
);
154 td043mtea1_write_gamma(lcd
);
156 lcd
->powered_on
= true;
161 static void td043mtea1_power_off(struct td043mtea1_panel
*lcd
)
163 if (!lcd
->powered_on
)
166 td043mtea1_write(lcd
, 3, TPO_R03_VAL_STANDBY
| TPO_R03_EN_PWM
);
168 gpiod_set_value(lcd
->reset_gpio
, 1);
170 /* wait for at least 2 vsyncs before cutting off power */
173 td043mtea1_write(lcd
, 3, TPO_R03_VAL_STANDBY
);
175 regulator_disable(lcd
->vcc_reg
);
177 lcd
->powered_on
= false;
180 /* -----------------------------------------------------------------------------
184 static ssize_t
vmirror_show(struct device
*dev
, struct device_attribute
*attr
,
187 struct td043mtea1_panel
*lcd
= dev_get_drvdata(dev
);
189 return snprintf(buf
, PAGE_SIZE
, "%d\n", lcd
->vmirror
);
192 static ssize_t
vmirror_store(struct device
*dev
, struct device_attribute
*attr
,
193 const char *buf
, size_t count
)
195 struct td043mtea1_panel
*lcd
= dev_get_drvdata(dev
);
199 ret
= kstrtoint(buf
, 0, &val
);
203 lcd
->vmirror
= !!val
;
205 ret
= td043mtea1_write_mirror(lcd
);
212 static ssize_t
mode_show(struct device
*dev
, struct device_attribute
*attr
,
215 struct td043mtea1_panel
*lcd
= dev_get_drvdata(dev
);
217 return snprintf(buf
, PAGE_SIZE
, "%d\n", lcd
->mode
);
220 static ssize_t
mode_store(struct device
*dev
, struct device_attribute
*attr
,
221 const char *buf
, size_t count
)
223 struct td043mtea1_panel
*lcd
= dev_get_drvdata(dev
);
227 ret
= kstrtol(buf
, 0, &val
);
228 if (ret
!= 0 || val
& ~7)
233 val
|= TPO_R02_NCLK_RISING
;
234 td043mtea1_write(lcd
, 2, val
);
239 static ssize_t
gamma_show(struct device
*dev
, struct device_attribute
*attr
,
242 struct td043mtea1_panel
*lcd
= dev_get_drvdata(dev
);
247 for (i
= 0; i
< ARRAY_SIZE(lcd
->gamma
); i
++) {
248 ret
= snprintf(buf
+ len
, PAGE_SIZE
- len
, "%u ",
259 static ssize_t
gamma_store(struct device
*dev
, struct device_attribute
*attr
,
260 const char *buf
, size_t count
)
262 struct td043mtea1_panel
*lcd
= dev_get_drvdata(dev
);
267 ret
= sscanf(buf
, "%u %u %u %u %u %u %u %u %u %u %u %u",
268 &g
[0], &g
[1], &g
[2], &g
[3], &g
[4], &g
[5],
269 &g
[6], &g
[7], &g
[8], &g
[9], &g
[10], &g
[11]);
273 for (i
= 0; i
< 12; i
++)
274 lcd
->gamma
[i
] = g
[i
];
276 td043mtea1_write_gamma(lcd
);
281 static DEVICE_ATTR_RW(vmirror
);
282 static DEVICE_ATTR_RW(mode
);
283 static DEVICE_ATTR_RW(gamma
);
285 static struct attribute
*td043mtea1_attrs
[] = {
286 &dev_attr_vmirror
.attr
,
288 &dev_attr_gamma
.attr
,
292 static const struct attribute_group td043mtea1_attr_group
= {
293 .attrs
= td043mtea1_attrs
,
296 /* -----------------------------------------------------------------------------
300 static int td043mtea1_unprepare(struct drm_panel
*panel
)
302 struct td043mtea1_panel
*lcd
= to_td043mtea1_device(panel
);
304 if (!lcd
->spi_suspended
)
305 td043mtea1_power_off(lcd
);
310 static int td043mtea1_prepare(struct drm_panel
*panel
)
312 struct td043mtea1_panel
*lcd
= to_td043mtea1_device(panel
);
316 * If we are resuming from system suspend, SPI might not be enabled
317 * yet, so we'll program the LCD from SPI PM resume callback.
319 if (lcd
->spi_suspended
)
322 ret
= td043mtea1_power_on(lcd
);
324 dev_err(&lcd
->spi
->dev
, "%s: power on failed (%d)\n",
332 static const struct drm_display_mode td043mtea1_mode
= {
335 .hsync_start
= 800 + 68,
336 .hsync_end
= 800 + 68 + 1,
337 .htotal
= 800 + 68 + 1 + 214,
339 .vsync_start
= 480 + 39,
340 .vsync_end
= 480 + 39 + 1,
341 .vtotal
= 480 + 39 + 1 + 34,
342 .type
= DRM_MODE_TYPE_DRIVER
| DRM_MODE_TYPE_PREFERRED
,
343 .flags
= DRM_MODE_FLAG_NHSYNC
| DRM_MODE_FLAG_NVSYNC
,
348 static int td043mtea1_get_modes(struct drm_panel
*panel
,
349 struct drm_connector
*connector
)
351 struct drm_display_mode
*mode
;
353 mode
= drm_mode_duplicate(connector
->dev
, &td043mtea1_mode
);
357 drm_mode_set_name(mode
);
358 drm_mode_probed_add(connector
, mode
);
360 connector
->display_info
.width_mm
= td043mtea1_mode
.width_mm
;
361 connector
->display_info
.height_mm
= td043mtea1_mode
.height_mm
;
363 * FIXME: According to the datasheet sync signals are sampled on the
364 * rising edge of the clock, but the code running on the OMAP3 Pandora
365 * indicates sampling on the falling edge. This should be tested on a
368 connector
->display_info
.bus_flags
= DRM_BUS_FLAG_DE_HIGH
369 | DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE
370 | DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE
;
375 static const struct drm_panel_funcs td043mtea1_funcs
= {
376 .unprepare
= td043mtea1_unprepare
,
377 .prepare
= td043mtea1_prepare
,
378 .get_modes
= td043mtea1_get_modes
,
381 /* -----------------------------------------------------------------------------
382 * Power Management, Probe and Remove
385 static int __maybe_unused
td043mtea1_suspend(struct device
*dev
)
387 struct td043mtea1_panel
*lcd
= dev_get_drvdata(dev
);
389 if (lcd
->powered_on
) {
390 td043mtea1_power_off(lcd
);
391 lcd
->powered_on
= true;
394 lcd
->spi_suspended
= true;
399 static int __maybe_unused
td043mtea1_resume(struct device
*dev
)
401 struct td043mtea1_panel
*lcd
= dev_get_drvdata(dev
);
404 lcd
->spi_suspended
= false;
406 if (lcd
->powered_on
) {
407 lcd
->powered_on
= false;
408 ret
= td043mtea1_power_on(lcd
);
416 static SIMPLE_DEV_PM_OPS(td043mtea1_pm_ops
, td043mtea1_suspend
,
419 static int td043mtea1_probe(struct spi_device
*spi
)
421 struct td043mtea1_panel
*lcd
;
424 lcd
= devm_kzalloc(&spi
->dev
, sizeof(*lcd
), GFP_KERNEL
);
428 spi_set_drvdata(spi
, lcd
);
430 lcd
->mode
= TPO_R02_MODE_800x480
;
431 memcpy(lcd
->gamma
, td043mtea1_def_gamma
, sizeof(lcd
->gamma
));
433 lcd
->vcc_reg
= devm_regulator_get(&spi
->dev
, "vcc");
434 if (IS_ERR(lcd
->vcc_reg
)) {
435 dev_err(&spi
->dev
, "failed to get VCC regulator\n");
436 return PTR_ERR(lcd
->vcc_reg
);
439 lcd
->reset_gpio
= devm_gpiod_get(&spi
->dev
, "reset", GPIOD_OUT_HIGH
);
440 if (IS_ERR(lcd
->reset_gpio
)) {
441 dev_err(&spi
->dev
, "failed to get reset GPIO\n");
442 return PTR_ERR(lcd
->reset_gpio
);
445 spi
->bits_per_word
= 16;
446 spi
->mode
= SPI_MODE_0
;
448 ret
= spi_setup(spi
);
450 dev_err(&spi
->dev
, "failed to setup SPI: %d\n", ret
);
454 ret
= sysfs_create_group(&spi
->dev
.kobj
, &td043mtea1_attr_group
);
456 dev_err(&spi
->dev
, "failed to create sysfs files\n");
460 drm_panel_init(&lcd
->panel
, &lcd
->spi
->dev
, &td043mtea1_funcs
,
461 DRM_MODE_CONNECTOR_DPI
);
463 drm_panel_add(&lcd
->panel
);
468 static int td043mtea1_remove(struct spi_device
*spi
)
470 struct td043mtea1_panel
*lcd
= spi_get_drvdata(spi
);
472 drm_panel_remove(&lcd
->panel
);
473 drm_panel_disable(&lcd
->panel
);
474 drm_panel_unprepare(&lcd
->panel
);
476 sysfs_remove_group(&spi
->dev
.kobj
, &td043mtea1_attr_group
);
481 static const struct of_device_id td043mtea1_of_match
[] = {
482 { .compatible
= "tpo,td043mtea1", },
486 MODULE_DEVICE_TABLE(of
, td043mtea1_of_match
);
488 static const struct spi_device_id td043mtea1_ids
[] = {
493 MODULE_DEVICE_TABLE(spi
, td043mtea1_ids
);
495 static struct spi_driver td043mtea1_driver
= {
496 .probe
= td043mtea1_probe
,
497 .remove
= td043mtea1_remove
,
498 .id_table
= td043mtea1_ids
,
500 .name
= "panel-tpo-td043mtea1",
501 .pm
= &td043mtea1_pm_ops
,
502 .of_match_table
= td043mtea1_of_match
,
506 module_spi_driver(td043mtea1_driver
);
508 MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
509 MODULE_DESCRIPTION("TPO TD043MTEA1 Panel Driver");
510 MODULE_LICENSE("GPL");