GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / gpu / drm / panel / panel-ilitek-ili9322.c
1 /*
2  * Ilitek ILI9322 TFT LCD drm_panel driver.
3  *
4  * This panel can be configured to support:
5  * - 8-bit serial RGB interface
6  * - 24-bit parallel RGB interface
7  * - 8-bit ITU-R BT.601 interface
8  * - 8-bit ITU-R BT.656 interface
9  * - Up to 320RGBx240 dots resolution TFT LCD displays
10  * - Scaling, brightness and contrast
11  *
12  * The scaling means that the display accepts a 640x480 or 720x480
13  * input and rescales it to fit to the 320x240 display. So what we
14  * present to the system is something else than what comes out on the
15  * actual display.
16  *
17  * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
18  * Derived from drivers/drm/gpu/panel/panel-samsung-ld9040.c
19  *
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License version 2 as
22  * published by the Free Software Foundation.
23  */
24
25 #include <drm/drmP.h>
26 #include <drm/drm_panel.h>
27
28 #include <linux/of_device.h>
29 #include <linux/bitops.h>
30 #include <linux/gpio/consumer.h>
31 #include <linux/module.h>
32 #include <linux/regmap.h>
33 #include <linux/regulator/consumer.h>
34 #include <linux/spi/spi.h>
35
36 #include <video/mipi_display.h>
37 #include <video/of_videomode.h>
38 #include <video/videomode.h>
39
40 #define ILI9322_CHIP_ID                 0x00
41 #define ILI9322_CHIP_ID_MAGIC           0x96
42
43 /*
44  * Voltage on the communication interface, from 0.7 (0x00)
45  * to 1.32 (0x1f) times the VREG1OUT voltage in 2% increments.
46  * 1.00 (0x0f) is the default.
47  */
48 #define ILI9322_VCOM_AMP                0x01
49
50 /*
51  * High voltage on the communication signals, from 0.37 (0x00) to
52  * 1.0 (0x3f) times the VREGOUT1 voltage in 1% increments.
53  * 0.83 (0x2e) is the default.
54  */
55 #define ILI9322_VCOM_HIGH               0x02
56
57 /*
58  * VREG1 voltage regulator from 3.6V (0x00) to 6.0V (0x18) in 0.1V
59  * increments. 5.4V (0x12) is the default. This is the reference
60  * voltage for the VCOM levels and the greyscale level.
61  */
62 #define ILI9322_VREG1_VOLTAGE           0x03
63
64 /* Describes the incoming signal */
65 #define ILI9322_ENTRY                   0x06
66 /* 0 = right-to-left, 1 = left-to-right (default), horizontal flip */
67 #define ILI9322_ENTRY_HDIR              BIT(0)
68 /* 0 = down-to-up, 1 = up-to-down (default), vertical flip  */
69 #define ILI9322_ENTRY_VDIR              BIT(1)
70 /* NTSC, PAL or autodetect */
71 #define ILI9322_ENTRY_NTSC              (0 << 2)
72 #define ILI9322_ENTRY_PAL               (1 << 2)
73 #define ILI9322_ENTRY_AUTODETECT        (3 << 2)
74 /* Input format */
75 #define ILI9322_ENTRY_SERIAL_RGB_THROUGH (0 << 4)
76 #define ILI9322_ENTRY_SERIAL_RGB_ALIGNED (1 << 4)
77 #define ILI9322_ENTRY_SERIAL_RGB_DUMMY_320X240 (2 << 4)
78 #define ILI9322_ENTRY_SERIAL_RGB_DUMMY_360X240 (3 << 4)
79 #define ILI9322_ENTRY_DISABLE_1         (4 << 4)
80 #define ILI9322_ENTRY_PARALLEL_RGB_THROUGH (5 << 4)
81 #define ILI9322_ENTRY_PARALLEL_RGB_ALIGNED (6 << 4)
82 #define ILI9322_ENTRY_YUV_640Y_320CBCR_25_54_MHZ (7 << 4)
83 #define ILI9322_ENTRY_YUV_720Y_360CBCR_27_MHZ (8 << 4)
84 #define ILI9322_ENTRY_DISABLE_2         (9 << 4)
85 #define ILI9322_ENTRY_ITU_R_BT_656_720X360 (10 << 4)
86 #define ILI9322_ENTRY_ITU_R_BT_656_640X320 (11 << 4)
87
88 /* Power control */
89 #define ILI9322_POW_CTRL                0x07
90 #define ILI9322_POW_CTRL_STB            BIT(0) /* 0 = standby, 1 = normal */
91 #define ILI9322_POW_CTRL_VGL            BIT(1) /* 0 = off, 1 = on  */
92 #define ILI9322_POW_CTRL_VGH            BIT(2) /* 0 = off, 1 = on  */
93 #define ILI9322_POW_CTRL_DDVDH          BIT(3) /* 0 = off, 1 = on  */
94 #define ILI9322_POW_CTRL_VCOM           BIT(4) /* 0 = off, 1 = on  */
95 #define ILI9322_POW_CTRL_VCL            BIT(5) /* 0 = off, 1 = on  */
96 #define ILI9322_POW_CTRL_AUTO           BIT(6) /* 0 = interactive, 1 = auto */
97 #define ILI9322_POW_CTRL_STANDBY        (ILI9322_POW_CTRL_VGL | \
98                                          ILI9322_POW_CTRL_VGH | \
99                                          ILI9322_POW_CTRL_DDVDH | \
100                                          ILI9322_POW_CTRL_VCL | \
101                                          ILI9322_POW_CTRL_AUTO | \
102                                          BIT(7))
103 #define ILI9322_POW_CTRL_DEFAULT        (ILI9322_POW_CTRL_STANDBY | \
104                                          ILI9322_POW_CTRL_STB)
105
106 /* Vertical back porch bits 0..5 */
107 #define ILI9322_VBP                     0x08
108
109 /* Horizontal back porch, 8 bits */
110 #define ILI9322_HBP                     0x09
111
112 /*
113  * Polarity settings:
114  * 1 = positive polarity
115  * 0 = negative polarity
116  */
117 #define ILI9322_POL                     0x0a
118 #define ILI9322_POL_DCLK                BIT(0) /* 1 default */
119 #define ILI9322_POL_HSYNC               BIT(1) /* 0 default */
120 #define ILI9322_POL_VSYNC               BIT(2) /* 0 default */
121 #define ILI9322_POL_DE                  BIT(3) /* 1 default */
122 /*
123  * 0 means YCBCR are ordered Cb0,Y0,Cr0,Y1,Cb2,Y2,Cr2,Y3 (default)
124  *   in RGB mode this means RGB comes in RGBRGB
125  * 1 means YCBCR are ordered Cr0,Y0,Cb0,Y1,Cr2,Y2,Cb2,Y3
126  *   in RGB mode this means RGB comes in BGRBGR
127  */
128 #define ILI9322_POL_YCBCR_MODE          BIT(4)
129 /* Formula A for YCbCR->RGB = 0, Formula B = 1 */
130 #define ILI9322_POL_FORMULA             BIT(5)
131 /* Reverse polarity: 0 = 0..255, 1 = 255..0 */
132 #define ILI9322_POL_REV                 BIT(6)
133
134 #define ILI9322_IF_CTRL                 0x0b
135 #define ILI9322_IF_CTRL_HSYNC_VSYNC     0x00
136 #define ILI9322_IF_CTRL_HSYNC_VSYNC_DE  BIT(2)
137 #define ILI9322_IF_CTRL_DE_ONLY         BIT(3)
138 #define ILI9322_IF_CTRL_SYNC_DISABLED   (BIT(2) | BIT(3))
139 #define ILI9322_IF_CTRL_LINE_INVERSION  BIT(0) /* Not set means frame inv */
140
141 #define ILI9322_GLOBAL_RESET            0x04
142 #define ILI9322_GLOBAL_RESET_ASSERT     0x00 /* bit 0 = 0 -> reset */
143
144 /*
145  * 4+4 bits of negative and positive gamma correction
146  * Upper nybble, bits 4-7 are negative gamma
147  * Lower nybble, bits 0-3 are positive gamma
148  */
149 #define ILI9322_GAMMA_1                 0x10
150 #define ILI9322_GAMMA_2                 0x11
151 #define ILI9322_GAMMA_3                 0x12
152 #define ILI9322_GAMMA_4                 0x13
153 #define ILI9322_GAMMA_5                 0x14
154 #define ILI9322_GAMMA_6                 0x15
155 #define ILI9322_GAMMA_7                 0x16
156 #define ILI9322_GAMMA_8                 0x17
157
158 /**
159  * enum ili9322_input - the format of the incoming signal to the panel
160  *
161  * The panel can be connected to various input streams and four of them can
162  * be selected by electronic straps on the display. However it is possible
163  * to select another mode or override the electronic default with this
164  * setting.
165  */
166 enum ili9322_input {
167         ILI9322_INPUT_SRGB_THROUGH = 0x0,
168         ILI9322_INPUT_SRGB_ALIGNED = 0x1,
169         ILI9322_INPUT_SRGB_DUMMY_320X240 = 0x2,
170         ILI9322_INPUT_SRGB_DUMMY_360X240 = 0x3,
171         ILI9322_INPUT_DISABLED_1 = 0x4,
172         ILI9322_INPUT_PRGB_THROUGH = 0x5,
173         ILI9322_INPUT_PRGB_ALIGNED = 0x6,
174         ILI9322_INPUT_YUV_640X320_YCBCR = 0x7,
175         ILI9322_INPUT_YUV_720X360_YCBCR = 0x8,
176         ILI9322_INPUT_DISABLED_2 = 0x9,
177         ILI9322_INPUT_ITU_R_BT656_720X360_YCBCR = 0xa,
178         ILI9322_INPUT_ITU_R_BT656_640X320_YCBCR = 0xb,
179         ILI9322_INPUT_UNKNOWN = 0xc,
180 };
181
182 static const char * const ili9322_inputs[] = {
183         "8 bit serial RGB through",
184         "8 bit serial RGB aligned",
185         "8 bit serial RGB dummy 320x240",
186         "8 bit serial RGB dummy 360x240",
187         "disabled 1",
188         "24 bit parallel RGB through",
189         "24 bit parallel RGB aligned",
190         "24 bit YUV 640Y 320CbCr",
191         "24 bit YUV 720Y 360CbCr",
192         "disabled 2",
193         "8 bit ITU-R BT.656 720Y 360CbCr",
194         "8 bit ITU-R BT.656 640Y 320CbCr",
195 };
196
197 /**
198  * struct ili9322_config - the system specific ILI9322 configuration
199  * @width_mm: physical panel width [mm]
200  * @height_mm: physical panel height [mm]
201  * @flip_horizontal: flip the image horizontally (right-to-left scan)
202  * (only in RGB and YUV modes)
203  * @flip_vertical: flip the image vertically (down-to-up scan)
204  * (only in RGB and YUV modes)
205  * @input: the input/entry type used in this system, if this is set to
206  * ILI9322_INPUT_UNKNOWN the driver will try to figure it out by probing
207  * the hardware
208  * @vreg1out_mv: the output in microvolts for the VREGOUT1 regulator used
209  * to drive the physical display. Valid ranges are 3600 thru 6000 in 100
210  * microvolt increments. If not specified, hardware defaults will be
211  * used (4.5V).
212  * @vcom_high_percent: the percentage of VREGOUT1 used for the peak
213  * voltage on the communications link. Valid ranges are 37 thru 100
214  * percent. If not specified, hardware defaults will be used (91%).
215  * @vcom_amplitude_percent: the percentage of VREGOUT1 used for the
216  * peak-to-peak amplitude of the communcation signals to the physical
217  * display. Valid ranges are 70 thru 132 percent in increments if two
218  * percent. Odd percentages will be truncated. If not specified, hardware
219  * defaults will be used (114%).
220  * @dclk_active_high: data/pixel clock active high, data will be clocked
221  * in on the rising edge of the DCLK (this is usually the case).
222  * @syncmode: The synchronization mode, what sync signals are emitted.
223  * See the enum for details.
224  * @de_active_high: DE (data entry) is active high
225  * @hsync_active_high: HSYNC is active high
226  * @vsync_active_high: VSYNC is active high
227  * @gamma_corr_pos: a set of 8 nybbles describing positive
228  * gamma correction for voltages V1 thru V8. Valid range 0..15
229  * @gamma_corr_neg: a set of 8 nybbles describing negative
230  * gamma correction for voltages V1 thru V8. Valid range 0..15
231  *
232  * These adjust what grayscale voltage will be output for input data V1 = 0,
233  * V2 = 16, V3 = 48, V4 = 96, V5 = 160, V6 = 208, V7 = 240 and V8 = 255.
234  * The curve is shaped like this:
235  *
236  *  ^
237  *  |                                                        V8
238  *  |                                                   V7
239  *  |                                          V6
240  *  |                               V5
241  *  |                    V4
242  *  |            V3
243  *  |     V2
244  *  | V1
245  *  +----------------------------------------------------------->
246  *    0   16     48      96         160        208      240  255
247  *
248  * The negative and postive gamma values adjust the V1 thru V8 up/down
249  * according to the datasheet specifications. This is a property of the
250  * physical display connected to the display controller and may vary.
251  * If defined, both arrays must be supplied in full. If the properties
252  * are not supplied, hardware defaults will be used.
253  */
254 struct ili9322_config {
255         u32 width_mm;
256         u32 height_mm;
257         bool flip_horizontal;
258         bool flip_vertical;
259         enum ili9322_input input;
260         u32 vreg1out_mv;
261         u32 vcom_high_percent;
262         u32 vcom_amplitude_percent;
263         bool dclk_active_high;
264         bool de_active_high;
265         bool hsync_active_high;
266         bool vsync_active_high;
267         u8 syncmode;
268         u8 gamma_corr_pos[8];
269         u8 gamma_corr_neg[8];
270 };
271
272 struct ili9322 {
273         struct device *dev;
274         const struct ili9322_config *conf;
275         struct drm_panel panel;
276         struct regmap *regmap;
277         struct regulator_bulk_data supplies[3];
278         struct gpio_desc *reset_gpio;
279         enum ili9322_input input;
280         struct videomode vm;
281         u8 gamma[8];
282         u8 vreg1out;
283         u8 vcom_high;
284         u8 vcom_amplitude;
285 };
286
287 static inline struct ili9322 *panel_to_ili9322(struct drm_panel *panel)
288 {
289         return container_of(panel, struct ili9322, panel);
290 }
291
292 static int ili9322_regmap_spi_write(void *context, const void *data,
293                                     size_t count)
294 {
295         struct device *dev = context;
296         struct spi_device *spi = to_spi_device(dev);
297         u8 buf[2];
298
299         /* Clear bit 7 to write */
300         memcpy(buf, data, 2);
301         buf[0] &= ~0x80;
302
303         dev_dbg(dev, "WRITE: %02x %02x\n", buf[0], buf[1]);
304         return spi_write_then_read(spi, buf, 2, NULL, 0);
305 }
306
307 static int ili9322_regmap_spi_read(void *context, const void *reg,
308                                    size_t reg_size, void *val, size_t val_size)
309 {
310         struct device *dev = context;
311         struct spi_device *spi = to_spi_device(dev);
312         u8 buf[1];
313
314         /* Set bit 7 to 1 to read */
315         memcpy(buf, reg, 1);
316         dev_dbg(dev, "READ: %02x reg size = %zu, val size = %zu\n",
317                 buf[0], reg_size, val_size);
318         buf[0] |= 0x80;
319
320         return spi_write_then_read(spi, buf, 1, val, 1);
321 }
322
323 static struct regmap_bus ili9322_regmap_bus = {
324         .write = ili9322_regmap_spi_write,
325         .read = ili9322_regmap_spi_read,
326         .reg_format_endian_default = REGMAP_ENDIAN_BIG,
327         .val_format_endian_default = REGMAP_ENDIAN_BIG,
328 };
329
330 static bool ili9322_volatile_reg(struct device *dev, unsigned int reg)
331 {
332         return false;
333 }
334
335 static bool ili9322_writeable_reg(struct device *dev, unsigned int reg)
336 {
337         /* Just register 0 is read-only */
338         if (reg == 0x00)
339                 return false;
340         return true;
341 }
342
343 static const struct regmap_config ili9322_regmap_config = {
344         .reg_bits = 8,
345         .val_bits = 8,
346         .max_register = 0x44,
347         .cache_type = REGCACHE_RBTREE,
348         .volatile_reg = ili9322_volatile_reg,
349         .writeable_reg = ili9322_writeable_reg,
350 };
351
352 static int ili9322_init(struct drm_panel *panel, struct ili9322 *ili)
353 {
354         struct drm_connector *connector = panel->connector;
355         u8 reg;
356         int ret;
357         int i;
358
359         /* Reset display */
360         ret = regmap_write(ili->regmap, ILI9322_GLOBAL_RESET,
361                            ILI9322_GLOBAL_RESET_ASSERT);
362         if (ret) {
363                 dev_err(ili->dev, "can't issue GRESET (%d)\n", ret);
364                 return ret;
365         }
366
367         /* Set up the main voltage regulator */
368         if (ili->vreg1out != U8_MAX) {
369                 ret = regmap_write(ili->regmap, ILI9322_VREG1_VOLTAGE,
370                                    ili->vreg1out);
371                 if (ret) {
372                         dev_err(ili->dev, "can't set up VREG1OUT (%d)\n", ret);
373                         return ret;
374                 }
375         }
376
377         if (ili->vcom_amplitude != U8_MAX) {
378                 ret = regmap_write(ili->regmap, ILI9322_VCOM_AMP,
379                                    ili->vcom_amplitude);
380                 if (ret) {
381                         dev_err(ili->dev,
382                                 "can't set up VCOM amplitude (%d)\n", ret);
383                         return ret;
384                 }
385         };
386
387         if (ili->vcom_high != U8_MAX) {
388                 ret = regmap_write(ili->regmap, ILI9322_VCOM_HIGH,
389                                    ili->vcom_high);
390                 if (ret) {
391                         dev_err(ili->dev, "can't set up VCOM high (%d)\n", ret);
392                         return ret;
393                 }
394         };
395
396         /* Set up gamma correction */
397         for (i = 0; i < ARRAY_SIZE(ili->gamma); i++) {
398                 ret = regmap_write(ili->regmap, ILI9322_GAMMA_1 + i,
399                                    ili->gamma[i]);
400                 if (ret) {
401                         dev_err(ili->dev,
402                                 "can't write gamma V%d to 0x%02x (%d)\n",
403                                 i + 1, ILI9322_GAMMA_1 + i, ret);
404                         return ret;
405                 }
406         }
407
408         /*
409          * Polarity and inverted color order for RGB input.
410          * None of this applies in the BT.656 mode.
411          */
412         if (ili->conf->dclk_active_high) {
413                 reg = ILI9322_POL_DCLK;
414                 connector->display_info.bus_flags |=
415                         DRM_BUS_FLAG_PIXDATA_POSEDGE;
416         } else {
417                 reg = 0;
418                 connector->display_info.bus_flags |=
419                         DRM_BUS_FLAG_PIXDATA_NEGEDGE;
420         }
421         if (ili->conf->de_active_high) {
422                 reg |= ILI9322_POL_DE;
423                 connector->display_info.bus_flags |=
424                         DRM_BUS_FLAG_DE_HIGH;
425         } else {
426                 connector->display_info.bus_flags |=
427                         DRM_BUS_FLAG_DE_LOW;
428         }
429         if (ili->conf->hsync_active_high)
430                 reg |= ILI9322_POL_HSYNC;
431         if (ili->conf->vsync_active_high)
432                 reg |= ILI9322_POL_VSYNC;
433         ret = regmap_write(ili->regmap, ILI9322_POL, reg);
434         if (ret) {
435                 dev_err(ili->dev, "can't write POL register (%d)\n", ret);
436                 return ret;
437         }
438
439         /*
440          * Set up interface control.
441          * This is not used in the BT.656 mode (no H/Vsync or DE signals).
442          */
443         reg = ili->conf->syncmode;
444         reg |= ILI9322_IF_CTRL_LINE_INVERSION;
445         ret = regmap_write(ili->regmap, ILI9322_IF_CTRL, reg);
446         if (ret) {
447                 dev_err(ili->dev, "can't write IF CTRL register (%d)\n", ret);
448                 return ret;
449         }
450
451         /* Set up the input mode */
452         reg = (ili->input << 4);
453         /* These are inverted, setting to 1 is the default, clearing flips */
454         if (!ili->conf->flip_horizontal)
455                 reg |= ILI9322_ENTRY_HDIR;
456         if (!ili->conf->flip_vertical)
457                 reg |= ILI9322_ENTRY_VDIR;
458         reg |= ILI9322_ENTRY_AUTODETECT;
459         ret = regmap_write(ili->regmap, ILI9322_ENTRY, reg);
460         if (ret) {
461                 dev_err(ili->dev, "can't write ENTRY reg (%d)\n", ret);
462                 return ret;
463         }
464         dev_info(ili->dev, "display is in %s mode, syncmode %02x\n",
465                  ili9322_inputs[ili->input],
466                  ili->conf->syncmode);
467
468         dev_info(ili->dev, "initialized display\n");
469
470         return 0;
471 }
472
473 /*
474  * This power-on sequence if from the datasheet, page 57.
475  */
476 static int ili9322_power_on(struct ili9322 *ili)
477 {
478         int ret;
479
480         /* Assert RESET */
481         gpiod_set_value(ili->reset_gpio, 1);
482
483         ret = regulator_bulk_enable(ARRAY_SIZE(ili->supplies), ili->supplies);
484         if (ret < 0) {
485                 dev_err(ili->dev, "unable to enable regulators\n");
486                 return ret;
487         }
488         msleep(20);
489
490         /* De-assert RESET */
491         gpiod_set_value(ili->reset_gpio, 0);
492
493         msleep(10);
494
495         return 0;
496 }
497
498 static int ili9322_power_off(struct ili9322 *ili)
499 {
500         return regulator_bulk_disable(ARRAY_SIZE(ili->supplies), ili->supplies);
501 }
502
503 static int ili9322_disable(struct drm_panel *panel)
504 {
505         struct ili9322 *ili = panel_to_ili9322(panel);
506         int ret;
507
508         ret = regmap_write(ili->regmap, ILI9322_POW_CTRL,
509                            ILI9322_POW_CTRL_STANDBY);
510         if (ret) {
511                 dev_err(ili->dev, "unable to go to standby mode\n");
512                 return ret;
513         }
514
515         return 0;
516 }
517
518 static int ili9322_unprepare(struct drm_panel *panel)
519 {
520         struct ili9322 *ili = panel_to_ili9322(panel);
521
522         return ili9322_power_off(ili);
523 }
524
525 static int ili9322_prepare(struct drm_panel *panel)
526 {
527         struct ili9322 *ili = panel_to_ili9322(panel);
528         int ret;
529
530         ret = ili9322_power_on(ili);
531         if (ret < 0)
532                 return ret;
533
534         ret = ili9322_init(panel, ili);
535         if (ret < 0)
536                 ili9322_unprepare(panel);
537
538         return ret;
539 }
540
541 static int ili9322_enable(struct drm_panel *panel)
542 {
543         struct ili9322 *ili = panel_to_ili9322(panel);
544         int ret;
545
546         ret = regmap_write(ili->regmap, ILI9322_POW_CTRL,
547                            ILI9322_POW_CTRL_DEFAULT);
548         if (ret) {
549                 dev_err(ili->dev, "unable to enable panel\n");
550                 return ret;
551         }
552
553         return 0;
554 }
555
556 /* Serial RGB modes */
557 static const struct drm_display_mode srgb_320x240_mode = {
558         .clock = 2453500,
559         .hdisplay = 320,
560         .hsync_start = 320 + 359,
561         .hsync_end = 320 + 359 + 1,
562         .htotal = 320 + 359 + 1 + 241,
563         .vdisplay = 240,
564         .vsync_start = 240 + 4,
565         .vsync_end = 240 + 4 + 1,
566         .vtotal = 262,
567         .vrefresh = 60,
568         .flags = 0,
569 };
570
571 static const struct drm_display_mode srgb_360x240_mode = {
572         .clock = 2700000,
573         .hdisplay = 360,
574         .hsync_start = 360 + 35,
575         .hsync_end = 360 + 35 + 1,
576         .htotal = 360 + 35 + 1 + 241,
577         .vdisplay = 240,
578         .vsync_start = 240 + 21,
579         .vsync_end = 240 + 21 + 1,
580         .vtotal = 262,
581         .vrefresh = 60,
582         .flags = 0,
583 };
584
585 /* This is the only mode listed for parallel RGB in the datasheet */
586 static const struct drm_display_mode prgb_320x240_mode = {
587         .clock = 6400000,
588         .hdisplay = 320,
589         .hsync_start = 320 + 38,
590         .hsync_end = 320 + 38 + 1,
591         .htotal = 320 + 38 + 1 + 50,
592         .vdisplay = 240,
593         .vsync_start = 240 + 4,
594         .vsync_end = 240 + 4 + 1,
595         .vtotal = 262,
596         .vrefresh = 60,
597         .flags = 0,
598 };
599
600 /* YUV modes */
601 static const struct drm_display_mode yuv_640x320_mode = {
602         .clock = 2454000,
603         .hdisplay = 640,
604         .hsync_start = 640 + 252,
605         .hsync_end = 640 + 252 + 1,
606         .htotal = 640 + 252 + 1 + 28,
607         .vdisplay = 320,
608         .vsync_start = 320 + 4,
609         .vsync_end = 320 + 4 + 1,
610         .vtotal = 320 + 4 + 1 + 18,
611         .vrefresh = 60,
612         .flags = 0,
613 };
614
615 static const struct drm_display_mode yuv_720x360_mode = {
616         .clock = 2700000,
617         .hdisplay = 720,
618         .hsync_start = 720 + 252,
619         .hsync_end = 720 + 252 + 1,
620         .htotal = 720 + 252 + 1 + 24,
621         .vdisplay = 360,
622         .vsync_start = 360 + 4,
623         .vsync_end = 360 + 4 + 1,
624         .vtotal = 360 + 4 + 1 + 18,
625         .vrefresh = 60,
626         .flags = 0,
627 };
628
629 /* BT.656 VGA mode, 640x480 */
630 static const struct drm_display_mode itu_r_bt_656_640_mode = {
631         .clock = 2454000,
632         .hdisplay = 640,
633         .hsync_start = 640 + 3,
634         .hsync_end = 640 + 3 + 1,
635         .htotal = 640 + 3 + 1 + 272,
636         .vdisplay = 480,
637         .vsync_start = 480 + 4,
638         .vsync_end = 480 + 4 + 1,
639         .vtotal = 500,
640         .vrefresh = 60,
641         .flags = 0,
642 };
643
644 /* BT.656 D1 mode 720x480 */
645 static const struct drm_display_mode itu_r_bt_656_720_mode = {
646         .clock = 2700000,
647         .hdisplay = 720,
648         .hsync_start = 720 + 3,
649         .hsync_end = 720 + 3 + 1,
650         .htotal = 720 + 3 + 1 + 272,
651         .vdisplay = 480,
652         .vsync_start = 480 + 4,
653         .vsync_end = 480 + 4 + 1,
654         .vtotal = 500,
655         .vrefresh = 60,
656         .flags = 0,
657 };
658
659 static int ili9322_get_modes(struct drm_panel *panel)
660 {
661         struct drm_connector *connector = panel->connector;
662         struct ili9322 *ili = panel_to_ili9322(panel);
663         struct drm_display_mode *mode;
664
665         strncpy(connector->display_info.name, "ILI9322 TFT LCD driver\0",
666                 DRM_DISPLAY_INFO_LEN);
667         connector->display_info.width_mm = ili->conf->width_mm;
668         connector->display_info.height_mm = ili->conf->height_mm;
669
670         switch (ili->input) {
671         case ILI9322_INPUT_SRGB_DUMMY_320X240:
672                 mode = drm_mode_duplicate(panel->drm, &srgb_320x240_mode);
673                 break;
674         case ILI9322_INPUT_SRGB_DUMMY_360X240:
675                 mode = drm_mode_duplicate(panel->drm, &srgb_360x240_mode);
676                 break;
677         case ILI9322_INPUT_PRGB_THROUGH:
678         case ILI9322_INPUT_PRGB_ALIGNED:
679                 mode = drm_mode_duplicate(panel->drm, &prgb_320x240_mode);
680                 break;
681         case ILI9322_INPUT_YUV_640X320_YCBCR:
682                 mode = drm_mode_duplicate(panel->drm, &yuv_640x320_mode);
683                 break;
684         case ILI9322_INPUT_YUV_720X360_YCBCR:
685                 mode = drm_mode_duplicate(panel->drm, &yuv_720x360_mode);
686                 break;
687         case ILI9322_INPUT_ITU_R_BT656_720X360_YCBCR:
688                 mode = drm_mode_duplicate(panel->drm, &itu_r_bt_656_720_mode);
689                 break;
690         case ILI9322_INPUT_ITU_R_BT656_640X320_YCBCR:
691                 mode = drm_mode_duplicate(panel->drm, &itu_r_bt_656_640_mode);
692                 break;
693         default:
694                 mode = NULL;
695                 break;
696         }
697         if (!mode) {
698                 DRM_ERROR("bad mode or failed to add mode\n");
699                 return -EINVAL;
700         }
701         drm_mode_set_name(mode);
702         /*
703          * This is the preferred mode because most people are going
704          * to want to use the display with VGA type graphics.
705          */
706         mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
707
708         /* Set up the polarity */
709         if (ili->conf->hsync_active_high)
710                 mode->flags |= DRM_MODE_FLAG_PHSYNC;
711         else
712                 mode->flags |= DRM_MODE_FLAG_NHSYNC;
713         if (ili->conf->vsync_active_high)
714                 mode->flags |= DRM_MODE_FLAG_PVSYNC;
715         else
716                 mode->flags |= DRM_MODE_FLAG_NVSYNC;
717
718         mode->width_mm = ili->conf->width_mm;
719         mode->height_mm = ili->conf->height_mm;
720         drm_mode_probed_add(connector, mode);
721
722         return 1; /* Number of modes */
723 }
724
725 static const struct drm_panel_funcs ili9322_drm_funcs = {
726         .disable = ili9322_disable,
727         .unprepare = ili9322_unprepare,
728         .prepare = ili9322_prepare,
729         .enable = ili9322_enable,
730         .get_modes = ili9322_get_modes,
731 };
732
733 static int ili9322_probe(struct spi_device *spi)
734 {
735         struct device *dev = &spi->dev;
736         struct ili9322 *ili;
737         const struct regmap_config *regmap_config;
738         u8 gamma;
739         u32 val;
740         int ret;
741         int i;
742
743         ili = devm_kzalloc(dev, sizeof(struct ili9322), GFP_KERNEL);
744         if (!ili)
745                 return -ENOMEM;
746
747         spi_set_drvdata(spi, ili);
748
749         ili->dev = dev;
750
751         /*
752          * Every new incarnation of this display must have a unique
753          * data entry for the system in this driver.
754          */
755         ili->conf = of_device_get_match_data(dev);
756         if (!ili->conf) {
757                 dev_err(dev, "missing device configuration\n");
758                 return -ENODEV;
759         }
760
761         val = ili->conf->vreg1out_mv;
762         if (!val) {
763                 /* Default HW value, do not touch (should be 4.5V) */
764                 ili->vreg1out = U8_MAX;
765         } else {
766                 if (val < 3600) {
767                         dev_err(dev, "too low VREG1OUT\n");
768                         return -EINVAL;
769                 }
770                 if (val > 6000) {
771                         dev_err(dev, "too high VREG1OUT\n");
772                         return -EINVAL;
773                 }
774                 if ((val % 100) != 0) {
775                         dev_err(dev, "VREG1OUT is no even 100 microvolt\n");
776                         return -EINVAL;
777                 }
778                 val -= 3600;
779                 val /= 100;
780                 dev_dbg(dev, "VREG1OUT = 0x%02x\n", val);
781                 ili->vreg1out = val;
782         }
783
784         val = ili->conf->vcom_high_percent;
785         if (!val) {
786                 /* Default HW value, do not touch (should be 91%) */
787                 ili->vcom_high = U8_MAX;
788         } else {
789                 if (val < 37) {
790                         dev_err(dev, "too low VCOM high\n");
791                         return -EINVAL;
792                 }
793                 if (val > 100) {
794                         dev_err(dev, "too high VCOM high\n");
795                         return -EINVAL;
796                 }
797                 val -= 37;
798                 dev_dbg(dev, "VCOM high = 0x%02x\n", val);
799                 ili->vcom_high = val;
800         }
801
802         val = ili->conf->vcom_amplitude_percent;
803         if (!val) {
804                 /* Default HW value, do not touch (should be 114%) */
805                 ili->vcom_high = U8_MAX;
806         } else {
807                 if (val < 70) {
808                         dev_err(dev, "too low VCOM amplitude\n");
809                         return -EINVAL;
810                 }
811                 if (val > 132) {
812                         dev_err(dev, "too high VCOM amplitude\n");
813                         return -EINVAL;
814                 }
815                 val -= 70;
816                 val >>= 1; /* Increments of 2% */
817                 dev_dbg(dev, "VCOM amplitude = 0x%02x\n", val);
818                 ili->vcom_amplitude = val;
819         }
820
821         for (i = 0; i < ARRAY_SIZE(ili->gamma); i++) {
822                 val = ili->conf->gamma_corr_neg[i];
823                 if (val > 15) {
824                         dev_err(dev, "negative gamma %u > 15, capping\n", val);
825                         val = 15;
826                 }
827                 gamma = val << 4;
828                 val = ili->conf->gamma_corr_pos[i];
829                 if (val > 15) {
830                         dev_err(dev, "positive gamma %u > 15, capping\n", val);
831                         val = 15;
832                 }
833                 gamma |= val;
834                 ili->gamma[i] = gamma;
835                 dev_dbg(dev, "gamma V%d: 0x%02x\n", i + 1, gamma);
836         }
837
838         ili->supplies[0].supply = "vcc"; /* 2.7-3.6 V */
839         ili->supplies[1].supply = "iovcc"; /* 1.65-3.6V */
840         ili->supplies[2].supply = "vci"; /* 2.7-3.6V */
841         ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ili->supplies),
842                                       ili->supplies);
843         if (ret < 0)
844                 return ret;
845         ret = regulator_set_voltage(ili->supplies[0].consumer,
846                                     2700000, 3600000);
847         if (ret)
848                 return ret;
849         ret = regulator_set_voltage(ili->supplies[1].consumer,
850                                     1650000, 3600000);
851         if (ret)
852                 return ret;
853         ret = regulator_set_voltage(ili->supplies[2].consumer,
854                                     2700000, 3600000);
855         if (ret)
856                 return ret;
857
858         ili->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
859         if (IS_ERR(ili->reset_gpio)) {
860                 dev_err(dev, "failed to get RESET GPIO\n");
861                 return PTR_ERR(ili->reset_gpio);
862         }
863
864         spi->bits_per_word = 8;
865         ret = spi_setup(spi);
866         if (ret < 0) {
867                 dev_err(dev, "spi setup failed.\n");
868                 return ret;
869         }
870         regmap_config = &ili9322_regmap_config;
871         ili->regmap = devm_regmap_init(dev, &ili9322_regmap_bus, dev,
872                                        regmap_config);
873         if (IS_ERR(ili->regmap)) {
874                 dev_err(dev, "failed to allocate register map\n");
875                 return PTR_ERR(ili->regmap);
876         }
877
878         ret = regmap_read(ili->regmap, ILI9322_CHIP_ID, &val);
879         if (ret) {
880                 dev_err(dev, "can't get chip ID (%d)\n", ret);
881                 return ret;
882         }
883         if (val != ILI9322_CHIP_ID_MAGIC) {
884                 dev_err(dev, "chip ID 0x%0x2, expected 0x%02x\n", val,
885                         ILI9322_CHIP_ID_MAGIC);
886                 return -ENODEV;
887         }
888
889         /* Probe the system to find the display setting */
890         if (ili->conf->input == ILI9322_INPUT_UNKNOWN) {
891                 ret = regmap_read(ili->regmap, ILI9322_ENTRY, &val);
892                 if (ret) {
893                         dev_err(dev, "can't get entry setting (%d)\n", ret);
894                         return ret;
895                 }
896                 /* Input enum corresponds to HW setting */
897                 ili->input = (val >> 4) & 0x0f;
898                 if (ili->input >= ILI9322_INPUT_UNKNOWN)
899                         ili->input = ILI9322_INPUT_UNKNOWN;
900         } else {
901                 ili->input = ili->conf->input;
902         }
903
904         drm_panel_init(&ili->panel);
905         ili->panel.dev = dev;
906         ili->panel.funcs = &ili9322_drm_funcs;
907
908         return drm_panel_add(&ili->panel);
909 }
910
911 static int ili9322_remove(struct spi_device *spi)
912 {
913         struct ili9322 *ili = spi_get_drvdata(spi);
914
915         ili9322_power_off(ili);
916         drm_panel_remove(&ili->panel);
917
918         return 0;
919 }
920
921 /*
922  * The D-Link DIR-685 panel is marked LM918A01-1A SY-B4-091116-E0199
923  */
924 static const struct ili9322_config ili9322_dir_685 = {
925         .width_mm = 65,
926         .height_mm = 50,
927         .input = ILI9322_INPUT_ITU_R_BT656_640X320_YCBCR,
928         .vreg1out_mv = 4600,
929         .vcom_high_percent = 91,
930         .vcom_amplitude_percent = 114,
931         .syncmode = ILI9322_IF_CTRL_SYNC_DISABLED,
932         .dclk_active_high = true,
933         .gamma_corr_neg = { 0xa, 0x5, 0x7, 0x7, 0x7, 0x5, 0x1, 0x6 },
934         .gamma_corr_pos = { 0x7, 0x7, 0x3, 0x2, 0x3, 0x5, 0x7, 0x2 },
935 };
936
937 static const struct of_device_id ili9322_of_match[] = {
938         {
939                 .compatible = "dlink,dir-685-panel",
940                 .data = &ili9322_dir_685,
941         },
942         {
943                 .compatible = "ilitek,ili9322",
944                 .data = NULL,
945         },
946         { }
947 };
948 MODULE_DEVICE_TABLE(of, ili9322_of_match);
949
950 static struct spi_driver ili9322_driver = {
951         .probe = ili9322_probe,
952         .remove = ili9322_remove,
953         .driver = {
954                 .name = "panel-ilitek-ili9322",
955                 .of_match_table = ili9322_of_match,
956         },
957 };
958 module_spi_driver(ili9322_driver);
959
960 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
961 MODULE_DESCRIPTION("ILI9322 LCD panel driver");
962 MODULE_LICENSE("GPL v2");