Merge tag 'v5.15.57' into rpi-5.15.y
[platform/kernel/linux-rpi.git] / drivers / gpu / drm / panel / panel-ilitek-ili9806e.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Ilitek ILI9806E TFT LCD drm_panel driver.
4  *
5  * Copyright (C) 2022 Raspberry Pi Ltd
6  *
7  * Derived from drivers/drm/gpu/panel/panel-sitronix-st7789v.c
8  * Copyright (C) 2017 Free Electrons
9  */
10
11 #include <drm/drm_modes.h>
12 #include <drm/drm_panel.h>
13
14 #include <linux/bitops.h>
15 #include <linux/gpio/consumer.h>
16 #include <linux/media-bus-format.h>
17 #include <linux/module.h>
18 #include <linux/of_device.h>
19 #include <linux/regmap.h>
20 #include <linux/regulator/consumer.h>
21 #include <linux/spi/spi.h>
22
23 #include <video/mipi_display.h>
24 #include <video/of_videomode.h>
25 #include <video/videomode.h>
26
27 struct ili9806 {
28         struct drm_panel panel;
29         struct spi_device *spi;
30         struct gpio_desc *reset;
31         struct regulator *power;
32         u32 bus_format;
33 };
34
35 #define ILI9806_DATA            BIT(8)
36
37 #define ILI9806_MAX_MSG_LEN     6
38
39 struct ili9806e_msg {
40         unsigned int len;
41         u16 msg[ILI9806_MAX_MSG_LEN];
42 };
43
44 #define ILI9806_SET_PAGE(page)  \
45         {                               \
46                 .len = 6,               \
47                 .msg = {                \
48                         0xFF,                   \
49                         ILI9806_DATA | 0xFF,    \
50                         ILI9806_DATA | 0x98,    \
51                         ILI9806_DATA | 0x06,    \
52                         ILI9806_DATA | 0x04,    \
53                         ILI9806_DATA | (page)   \
54                 },                              \
55         }
56
57 #define ILI9806_SET_REG_PARAM(reg, data)        \
58         {                                       \
59                 .len = 2,                       \
60                 .msg = {                        \
61                         (reg),                  \
62                         ILI9806_DATA | (data),  \
63                 },                              \
64         }
65
66 #define ILI9806_SET_REG(reg)    \
67         {                               \
68                 .len = 1,               \
69                 .msg = { (reg) },               \
70         }
71
72 static const struct ili9806e_msg panel_init[] = {
73         ILI9806_SET_PAGE(1),
74
75         /* interface mode
76          *   SEPT_SDIO = 0 (spi interface transfer through SDA pin)
77          *   SDO_STATUS = 1 (always output, but without output tri-state)
78          */
79         ILI9806_SET_REG_PARAM(0x08, 0x10),
80         /* display control
81          * VSPL = 1 (vertical sync polarity)
82          * HSPL = 0 (horizontal sync polarity)
83          * DPL = 0 (PCLK polarity)
84          * EPL = 1 (data enable polarity)
85          */
86         ILI9806_SET_REG_PARAM(0x21, 0x0d),
87         /* resolution control (0x02 = 480x800) */
88         ILI9806_SET_REG_PARAM(0x30, 0x02),
89         /* display inversion control (0x00 = column inversion) */
90         ILI9806_SET_REG_PARAM(0x31, 0x00),
91         /* power control
92          *  EXB1T = 0 (internal charge pump)
93          *  EXT_CPCK_SEL = 1 (pump clock control signal = output 2 x waveform)
94          *  BT = 0 (DDVDH / DDVDL voltage = VCI x 2 / VCI x -2)
95          */
96         ILI9806_SET_REG_PARAM(0x40, 0x10),
97         /* power control
98          *  DDVDH_CLP = 5.6 (DDVDH clamp leve)
99          *  DDVDL_CLP = -5.6 (DDVDL clamp leve)
100          */
101         ILI9806_SET_REG_PARAM(0x41, 0x55),
102         /* power control
103          *  VGH_CP = 2DDVDH - DDVDL (step up factor for VGH)
104          *  VGL_CP = DDVDL + VCL - VCIP (step up factor for VGL)
105          */
106         ILI9806_SET_REG_PARAM(0x42, 0x02),
107         /* power control
108          *  VGH_CLPEN = 0 (disable VGH clamp level)
109          *  VGH_CLP = 9 (15.0 VGH clamp level - but this is disabled so not used?)
110          */
111         ILI9806_SET_REG_PARAM(0x43, 0x84),
112         /* power control
113          *  VGL_CLPEN = 0 (disable VGL clamp level)
114          *  VGL_CLP = 9 (-11.0 VGL clamp level - but this is disabled so not used?)
115          */
116         ILI9806_SET_REG_PARAM(0x44, 0x84),
117
118         /* power control
119          *  VREG1OUT voltage for positive gamma?
120          */
121         ILI9806_SET_REG_PARAM(0x50, 0x78),
122         /* power control
123          *  VREG2OUT voltage for negative gamma?
124          */
125         ILI9806_SET_REG_PARAM(0x51, 0x78),
126
127         ILI9806_SET_REG_PARAM(0x52, 0x00),
128         ILI9806_SET_REG_PARAM(0x53, 0x77),
129         ILI9806_SET_REG_PARAM(0x57, 0x60),
130         ILI9806_SET_REG_PARAM(0x60, 0x07),
131         ILI9806_SET_REG_PARAM(0x61, 0x00),
132         ILI9806_SET_REG_PARAM(0x62, 0x08),
133         ILI9806_SET_REG_PARAM(0x63, 0x00),
134         ILI9806_SET_REG_PARAM(0xA0, 0x00),
135         ILI9806_SET_REG_PARAM(0xA1, 0x07),
136         ILI9806_SET_REG_PARAM(0xA2, 0x0C),
137         ILI9806_SET_REG_PARAM(0xA3, 0x0B),
138         ILI9806_SET_REG_PARAM(0xA4, 0x03),
139         ILI9806_SET_REG_PARAM(0xA5, 0x07),
140         ILI9806_SET_REG_PARAM(0xA6, 0x06),
141         ILI9806_SET_REG_PARAM(0xA7, 0x04),
142         ILI9806_SET_REG_PARAM(0xA8, 0x08),
143         ILI9806_SET_REG_PARAM(0xA9, 0x0C),
144         ILI9806_SET_REG_PARAM(0xAA, 0x13),
145         ILI9806_SET_REG_PARAM(0xAB, 0x06),
146         ILI9806_SET_REG_PARAM(0xAC, 0x0D),
147         ILI9806_SET_REG_PARAM(0xAD, 0x19),
148         ILI9806_SET_REG_PARAM(0xAE, 0x10),
149         ILI9806_SET_REG_PARAM(0xAF, 0x00),
150         /* negative gamma control
151          * set the gray scale voltage to adjust the gamma characteristics of the panel
152          */
153         ILI9806_SET_REG_PARAM(0xC0, 0x00),
154         ILI9806_SET_REG_PARAM(0xC1, 0x07),
155         ILI9806_SET_REG_PARAM(0xC2, 0x0C),
156         ILI9806_SET_REG_PARAM(0xC3, 0x0B),
157         ILI9806_SET_REG_PARAM(0xC4, 0x03),
158         ILI9806_SET_REG_PARAM(0xC5, 0x07),
159         ILI9806_SET_REG_PARAM(0xC6, 0x07),
160         ILI9806_SET_REG_PARAM(0xC7, 0x04),
161         ILI9806_SET_REG_PARAM(0xC8, 0x08),
162         ILI9806_SET_REG_PARAM(0xC9, 0x0C),
163         ILI9806_SET_REG_PARAM(0xCA, 0x13),
164         ILI9806_SET_REG_PARAM(0xCB, 0x06),
165         ILI9806_SET_REG_PARAM(0xCC, 0x0D),
166         ILI9806_SET_REG_PARAM(0xCD, 0x18),
167         ILI9806_SET_REG_PARAM(0xCE, 0x10),
168         ILI9806_SET_REG_PARAM(0xCF, 0x00),
169
170         ILI9806_SET_PAGE(6),
171
172         ILI9806_SET_REG_PARAM(0x00, 0x20),
173         ILI9806_SET_REG_PARAM(0x01, 0x0A),
174         ILI9806_SET_REG_PARAM(0x02, 0x00),
175         ILI9806_SET_REG_PARAM(0x03, 0x00),
176         ILI9806_SET_REG_PARAM(0x04, 0x01),
177         ILI9806_SET_REG_PARAM(0x05, 0x01),
178         ILI9806_SET_REG_PARAM(0x06, 0x98),
179         ILI9806_SET_REG_PARAM(0x07, 0x06),
180         ILI9806_SET_REG_PARAM(0x08, 0x01),
181         ILI9806_SET_REG_PARAM(0x09, 0x80),
182         ILI9806_SET_REG_PARAM(0x0A, 0x00),
183         ILI9806_SET_REG_PARAM(0x0B, 0x00),
184         ILI9806_SET_REG_PARAM(0x0C, 0x01),
185         ILI9806_SET_REG_PARAM(0x0D, 0x01),
186         ILI9806_SET_REG_PARAM(0x0E, 0x00),
187         ILI9806_SET_REG_PARAM(0x0F, 0x00),
188         ILI9806_SET_REG_PARAM(0x10, 0xF0),
189         ILI9806_SET_REG_PARAM(0x11, 0xF4),
190         ILI9806_SET_REG_PARAM(0x12, 0x01),
191         ILI9806_SET_REG_PARAM(0x13, 0x00),
192         ILI9806_SET_REG_PARAM(0x14, 0x00),
193         ILI9806_SET_REG_PARAM(0x15, 0xC0),
194         ILI9806_SET_REG_PARAM(0x16, 0x08),
195         ILI9806_SET_REG_PARAM(0x17, 0x00),
196         ILI9806_SET_REG_PARAM(0x18, 0x00),
197         ILI9806_SET_REG_PARAM(0x19, 0x00),
198         ILI9806_SET_REG_PARAM(0x1A, 0x00),
199         ILI9806_SET_REG_PARAM(0x1B, 0x00),
200         ILI9806_SET_REG_PARAM(0x1C, 0x00),
201         ILI9806_SET_REG_PARAM(0x1D, 0x00),
202         ILI9806_SET_REG_PARAM(0x20, 0x01),
203         ILI9806_SET_REG_PARAM(0x21, 0x23),
204         ILI9806_SET_REG_PARAM(0x22, 0x45),
205         ILI9806_SET_REG_PARAM(0x23, 0x67),
206         ILI9806_SET_REG_PARAM(0x24, 0x01),
207         ILI9806_SET_REG_PARAM(0x25, 0x23),
208         ILI9806_SET_REG_PARAM(0x26, 0x45),
209         ILI9806_SET_REG_PARAM(0x27, 0x67),
210         ILI9806_SET_REG_PARAM(0x30, 0x11),
211         ILI9806_SET_REG_PARAM(0x31, 0x11),
212         ILI9806_SET_REG_PARAM(0x32, 0x00),
213         ILI9806_SET_REG_PARAM(0x33, 0xEE),
214         ILI9806_SET_REG_PARAM(0x34, 0xFF),
215         ILI9806_SET_REG_PARAM(0x35, 0xBB),
216         ILI9806_SET_REG_PARAM(0x36, 0xAA),
217         ILI9806_SET_REG_PARAM(0x37, 0xDD),
218         ILI9806_SET_REG_PARAM(0x38, 0xCC),
219         ILI9806_SET_REG_PARAM(0x39, 0x66),
220         ILI9806_SET_REG_PARAM(0x3A, 0x77),
221         ILI9806_SET_REG_PARAM(0x3B, 0x22),
222         ILI9806_SET_REG_PARAM(0x3C, 0x22),
223         ILI9806_SET_REG_PARAM(0x3D, 0x22),
224         ILI9806_SET_REG_PARAM(0x3E, 0x22),
225         ILI9806_SET_REG_PARAM(0x3F, 0x22),
226         ILI9806_SET_REG_PARAM(0x40, 0x22),
227         /* register doesn't exist on page 6? */
228         ILI9806_SET_REG_PARAM(0x52, 0x10),
229         /* doesn't make sense, not valid according to datasheet */
230         ILI9806_SET_REG_PARAM(0x53, 0x10),
231         /* doesn't make sense, not valid according to datasheet */
232         ILI9806_SET_REG_PARAM(0x54, 0x13),
233
234         ILI9806_SET_PAGE(7),
235
236         /* enable VREG */
237         ILI9806_SET_REG_PARAM(0x18, 0x1D),
238         /* enable VGL_REG */
239         ILI9806_SET_REG_PARAM(0x17, 0x22),
240         /* register doesn't exist on page 7? */
241         ILI9806_SET_REG_PARAM(0x02, 0x77),
242         /* register doesn't exist on page 7? */
243         ILI9806_SET_REG_PARAM(0x26, 0xB2),
244         /* register doesn't exist on page 7? */
245         ILI9806_SET_REG_PARAM(0xE1, 0x79),
246
247         ILI9806_SET_PAGE(0),
248
249         ILI9806_SET_REG_PARAM(MIPI_DCS_SET_PIXEL_FORMAT,
250                               MIPI_DCS_PIXEL_FMT_18BIT << 4),
251         ILI9806_SET_REG_PARAM(MIPI_DCS_SET_TEAR_ON, 0x00),
252         ILI9806_SET_REG(MIPI_DCS_EXIT_SLEEP_MODE),
253 };
254
255 #define NUM_INIT_REGS ARRAY_SIZE(panel_init)
256
257 static inline struct ili9806 *panel_to_ili9806(struct drm_panel *panel)
258 {
259         return container_of(panel, struct ili9806, panel);
260 }
261
262 static int ili9806_write_msg(struct ili9806 *ctx, const struct ili9806e_msg *msg)
263 {
264         struct spi_transfer xfer = { };
265         struct spi_message spi;
266         //u16 txbuf[] = { msg->, ILI9806_DATA | data };
267
268         spi_message_init(&spi);
269
270         xfer.tx_buf = msg->msg;
271         xfer.bits_per_word = 9;
272         xfer.len = sizeof(u16) * msg->len;
273
274         spi_message_add_tail(&xfer, &spi);
275         return spi_sync(ctx->spi, &spi);
276 }
277
278 static int ili9806e_write_msg_list(struct ili9806 *ctx,
279                                    const struct ili9806e_msg msgs[],
280                                    unsigned int num_msgs)
281 {
282         int ret, i;
283
284         for (i = 0; i < num_msgs; i++) {
285                 ret = ili9806_write_msg(ctx, &msgs[i]);
286                 if (ret)
287                         break;
288         }
289
290         return ret;
291 }
292
293 static const struct drm_display_mode ili9806e_480x800_mode = {
294         .clock = 32000,
295         .hdisplay = 480,
296         .hsync_start = 480 + 10,
297         .hsync_end = 480 + 10 + 16,
298         .htotal = 480 + 10 + 16 + 59,
299         .vdisplay = 800,
300         .vsync_start = 800 + 15,
301         .vsync_end = 800 + 15 + 113,
302         .vtotal = 800 + 15 + 113 + 15,
303         .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
304 };
305
306 static int ili9806_get_modes(struct drm_panel *panel,
307                              struct drm_connector *connector)
308 {
309         struct ili9806 *ctx = panel_to_ili9806(panel);
310         struct drm_display_mode *mode;
311
312         mode = drm_mode_duplicate(connector->dev, &ili9806e_480x800_mode);
313         if (!mode) {
314                 dev_err(panel->dev, "failed to add mode %ux%ux@%u\n",
315                         ili9806e_480x800_mode.hdisplay,
316                         ili9806e_480x800_mode.vdisplay,
317                         drm_mode_vrefresh(&ili9806e_480x800_mode));
318                 return -ENOMEM;
319         }
320
321         drm_mode_set_name(mode);
322
323         mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
324         drm_mode_probed_add(connector, mode);
325
326         connector->display_info.width_mm = 61;
327         connector->display_info.height_mm = 103;
328         drm_display_info_set_bus_formats(&connector->display_info,
329                                          &ctx->bus_format, 1);
330         connector->display_info.bus_flags =
331                                         DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
332
333         return 1;
334 }
335
336 static int ili9806_prepare(struct drm_panel *panel)
337 {
338         struct ili9806 *ctx = panel_to_ili9806(panel);
339         int ret;
340
341         ret = regulator_enable(ctx->power);
342         if (ret)
343                 return ret;
344
345         ret = ili9806e_write_msg_list(ctx, panel_init, NUM_INIT_REGS);
346
347         return ret;
348 }
349
350 static int ili9806_enable(struct drm_panel *panel)
351 {
352         struct ili9806 *ctx = panel_to_ili9806(panel);
353         const struct ili9806e_msg msg = ILI9806_SET_REG(MIPI_DCS_SET_DISPLAY_ON);
354         int ret;
355
356         ret = ili9806_write_msg(ctx, &msg);
357
358         return ret;
359 }
360
361 static int ili9806_disable(struct drm_panel *panel)
362 {
363         struct ili9806 *ctx = panel_to_ili9806(panel);
364         const struct ili9806e_msg msg = ILI9806_SET_REG(MIPI_DCS_SET_DISPLAY_OFF);
365         int ret;
366
367         ret = ili9806_write_msg(ctx, &msg);
368
369         return ret;
370 }
371
372 static int ili9806_unprepare(struct drm_panel *panel)
373 {
374         struct ili9806 *ctx = panel_to_ili9806(panel);
375         const struct ili9806e_msg msg = ILI9806_SET_REG(MIPI_DCS_ENTER_SLEEP_MODE);
376         int ret;
377
378         ret = ili9806_write_msg(ctx, &msg);
379
380         return ret;
381 }
382
383 static const struct drm_panel_funcs ili9806_drm_funcs = {
384         .disable        = ili9806_disable,
385         .enable         = ili9806_enable,
386         .get_modes      = ili9806_get_modes,
387         .prepare        = ili9806_prepare,
388         .unprepare      = ili9806_unprepare,
389 };
390
391 static const struct of_device_id ili9806_of_match[] = {
392         {       .compatible = "txw,txw397017s2",
393                 .data = (void *)MEDIA_BUS_FMT_RGB888_1X24,
394         }, {
395                 .compatible = "pimoroni,hyperpixel4",
396                 .data = (void *)MEDIA_BUS_FMT_RGB666_1X24_CPADHI,
397         }, {
398                 .compatible = "ilitek,ili9806e",
399                 .data = (void *)MEDIA_BUS_FMT_RGB888_1X24,
400         }, {
401                 /* sentinel */
402         }
403 };
404 MODULE_DEVICE_TABLE(of, ili9806_of_match);
405
406 static int ili9806_probe(struct spi_device *spi)
407 {
408         const struct ili9806e_msg panel_reset[] = {
409                 ILI9806_SET_PAGE(0),
410                 ILI9806_SET_REG_PARAM(0x01, 0x00)
411         };
412         const struct of_device_id *id;
413         struct ili9806 *ctx;
414         int ret;
415
416         ctx = devm_kzalloc(&spi->dev, sizeof(*ctx), GFP_KERNEL);
417         if (!ctx)
418                 return -ENOMEM;
419
420         id = of_match_node(ili9806_of_match, spi->dev.of_node);
421         if (!id)
422                 return -ENODEV;
423
424         ctx->bus_format = (u32)(uintptr_t)id->data;
425
426         spi_set_drvdata(spi, ctx);
427         ctx->spi = spi;
428
429         drm_panel_init(&ctx->panel, &spi->dev, &ili9806_drm_funcs,
430                        DRM_MODE_CONNECTOR_DPI);
431
432         ctx->power = devm_regulator_get(&spi->dev, "power");
433         if (IS_ERR(ctx->power))
434                 return PTR_ERR(ctx->power);
435
436         ctx->reset = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_LOW);
437         if (IS_ERR(ctx->reset)) {
438                 dev_err(&spi->dev, "Couldn't get our reset line\n");
439                 return PTR_ERR(ctx->reset);
440         }
441
442         /* Soft reset */
443         ili9806e_write_msg_list(ctx, panel_reset, ARRAY_SIZE(panel_reset));
444         msleep(200);
445
446         ret = drm_panel_of_backlight(&ctx->panel);
447         if (ret)
448                 return ret;
449
450         drm_panel_add(&ctx->panel);
451
452         return 0;
453 }
454
455 static int ili9806_remove(struct spi_device *spi)
456 {
457         struct ili9806 *ctx = spi_get_drvdata(spi);
458
459         drm_panel_remove(&ctx->panel);
460
461         return 0;
462 }
463
464 static const struct spi_device_id ili9806_ids[] = {
465         { "txw397017s2", 0 },
466         { "ili9806e", 0 },
467         { "hyperpixel4", 0 },
468         { /* sentinel */ }
469 };
470
471 MODULE_DEVICE_TABLE(spi, ili9806_ids);
472
473 static struct spi_driver ili9806_driver = {
474         .probe = ili9806_probe,
475         .remove = ili9806_remove,
476         .driver = {
477                 .name = "ili9806e",
478                 .of_match_table = ili9806_of_match,
479         },
480         .id_table = ili9806_ids,
481 };
482 module_spi_driver(ili9806_driver);
483
484 MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.com>");
485 MODULE_DESCRIPTION("ili9806 LCD panel driver");
486 MODULE_LICENSE("GPL v2");