Merge tag 'drm-misc-next-2019-03-28-1' of git://anongit.freedesktop.org/drm/drm-misc...
[platform/kernel/linux-starfive.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_DRIVE_POSEDGE;
416         } else {
417                 reg = 0;
418                 connector->display_info.bus_flags |=
419                         DRM_BUS_FLAG_PIXDATA_DRIVE_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         connector->display_info.width_mm = ili->conf->width_mm;
666         connector->display_info.height_mm = ili->conf->height_mm;
667
668         switch (ili->input) {
669         case ILI9322_INPUT_SRGB_DUMMY_320X240:
670                 mode = drm_mode_duplicate(panel->drm, &srgb_320x240_mode);
671                 break;
672         case ILI9322_INPUT_SRGB_DUMMY_360X240:
673                 mode = drm_mode_duplicate(panel->drm, &srgb_360x240_mode);
674                 break;
675         case ILI9322_INPUT_PRGB_THROUGH:
676         case ILI9322_INPUT_PRGB_ALIGNED:
677                 mode = drm_mode_duplicate(panel->drm, &prgb_320x240_mode);
678                 break;
679         case ILI9322_INPUT_YUV_640X320_YCBCR:
680                 mode = drm_mode_duplicate(panel->drm, &yuv_640x320_mode);
681                 break;
682         case ILI9322_INPUT_YUV_720X360_YCBCR:
683                 mode = drm_mode_duplicate(panel->drm, &yuv_720x360_mode);
684                 break;
685         case ILI9322_INPUT_ITU_R_BT656_720X360_YCBCR:
686                 mode = drm_mode_duplicate(panel->drm, &itu_r_bt_656_720_mode);
687                 break;
688         case ILI9322_INPUT_ITU_R_BT656_640X320_YCBCR:
689                 mode = drm_mode_duplicate(panel->drm, &itu_r_bt_656_640_mode);
690                 break;
691         default:
692                 mode = NULL;
693                 break;
694         }
695         if (!mode) {
696                 DRM_ERROR("bad mode or failed to add mode\n");
697                 return -EINVAL;
698         }
699         drm_mode_set_name(mode);
700         /*
701          * This is the preferred mode because most people are going
702          * to want to use the display with VGA type graphics.
703          */
704         mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
705
706         /* Set up the polarity */
707         if (ili->conf->hsync_active_high)
708                 mode->flags |= DRM_MODE_FLAG_PHSYNC;
709         else
710                 mode->flags |= DRM_MODE_FLAG_NHSYNC;
711         if (ili->conf->vsync_active_high)
712                 mode->flags |= DRM_MODE_FLAG_PVSYNC;
713         else
714                 mode->flags |= DRM_MODE_FLAG_NVSYNC;
715
716         mode->width_mm = ili->conf->width_mm;
717         mode->height_mm = ili->conf->height_mm;
718         drm_mode_probed_add(connector, mode);
719
720         return 1; /* Number of modes */
721 }
722
723 static const struct drm_panel_funcs ili9322_drm_funcs = {
724         .disable = ili9322_disable,
725         .unprepare = ili9322_unprepare,
726         .prepare = ili9322_prepare,
727         .enable = ili9322_enable,
728         .get_modes = ili9322_get_modes,
729 };
730
731 static int ili9322_probe(struct spi_device *spi)
732 {
733         struct device *dev = &spi->dev;
734         struct ili9322 *ili;
735         const struct regmap_config *regmap_config;
736         u8 gamma;
737         u32 val;
738         int ret;
739         int i;
740
741         ili = devm_kzalloc(dev, sizeof(struct ili9322), GFP_KERNEL);
742         if (!ili)
743                 return -ENOMEM;
744
745         spi_set_drvdata(spi, ili);
746
747         ili->dev = dev;
748
749         /*
750          * Every new incarnation of this display must have a unique
751          * data entry for the system in this driver.
752          */
753         ili->conf = of_device_get_match_data(dev);
754         if (!ili->conf) {
755                 dev_err(dev, "missing device configuration\n");
756                 return -ENODEV;
757         }
758
759         val = ili->conf->vreg1out_mv;
760         if (!val) {
761                 /* Default HW value, do not touch (should be 4.5V) */
762                 ili->vreg1out = U8_MAX;
763         } else {
764                 if (val < 3600) {
765                         dev_err(dev, "too low VREG1OUT\n");
766                         return -EINVAL;
767                 }
768                 if (val > 6000) {
769                         dev_err(dev, "too high VREG1OUT\n");
770                         return -EINVAL;
771                 }
772                 if ((val % 100) != 0) {
773                         dev_err(dev, "VREG1OUT is no even 100 microvolt\n");
774                         return -EINVAL;
775                 }
776                 val -= 3600;
777                 val /= 100;
778                 dev_dbg(dev, "VREG1OUT = 0x%02x\n", val);
779                 ili->vreg1out = val;
780         }
781
782         val = ili->conf->vcom_high_percent;
783         if (!val) {
784                 /* Default HW value, do not touch (should be 91%) */
785                 ili->vcom_high = U8_MAX;
786         } else {
787                 if (val < 37) {
788                         dev_err(dev, "too low VCOM high\n");
789                         return -EINVAL;
790                 }
791                 if (val > 100) {
792                         dev_err(dev, "too high VCOM high\n");
793                         return -EINVAL;
794                 }
795                 val -= 37;
796                 dev_dbg(dev, "VCOM high = 0x%02x\n", val);
797                 ili->vcom_high = val;
798         }
799
800         val = ili->conf->vcom_amplitude_percent;
801         if (!val) {
802                 /* Default HW value, do not touch (should be 114%) */
803                 ili->vcom_high = U8_MAX;
804         } else {
805                 if (val < 70) {
806                         dev_err(dev, "too low VCOM amplitude\n");
807                         return -EINVAL;
808                 }
809                 if (val > 132) {
810                         dev_err(dev, "too high VCOM amplitude\n");
811                         return -EINVAL;
812                 }
813                 val -= 70;
814                 val >>= 1; /* Increments of 2% */
815                 dev_dbg(dev, "VCOM amplitude = 0x%02x\n", val);
816                 ili->vcom_amplitude = val;
817         }
818
819         for (i = 0; i < ARRAY_SIZE(ili->gamma); i++) {
820                 val = ili->conf->gamma_corr_neg[i];
821                 if (val > 15) {
822                         dev_err(dev, "negative gamma %u > 15, capping\n", val);
823                         val = 15;
824                 }
825                 gamma = val << 4;
826                 val = ili->conf->gamma_corr_pos[i];
827                 if (val > 15) {
828                         dev_err(dev, "positive gamma %u > 15, capping\n", val);
829                         val = 15;
830                 }
831                 gamma |= val;
832                 ili->gamma[i] = gamma;
833                 dev_dbg(dev, "gamma V%d: 0x%02x\n", i + 1, gamma);
834         }
835
836         ili->supplies[0].supply = "vcc"; /* 2.7-3.6 V */
837         ili->supplies[1].supply = "iovcc"; /* 1.65-3.6V */
838         ili->supplies[2].supply = "vci"; /* 2.7-3.6V */
839         ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ili->supplies),
840                                       ili->supplies);
841         if (ret < 0)
842                 return ret;
843         ret = regulator_set_voltage(ili->supplies[0].consumer,
844                                     2700000, 3600000);
845         if (ret)
846                 return ret;
847         ret = regulator_set_voltage(ili->supplies[1].consumer,
848                                     1650000, 3600000);
849         if (ret)
850                 return ret;
851         ret = regulator_set_voltage(ili->supplies[2].consumer,
852                                     2700000, 3600000);
853         if (ret)
854                 return ret;
855
856         ili->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
857         if (IS_ERR(ili->reset_gpio)) {
858                 dev_err(dev, "failed to get RESET GPIO\n");
859                 return PTR_ERR(ili->reset_gpio);
860         }
861
862         spi->bits_per_word = 8;
863         ret = spi_setup(spi);
864         if (ret < 0) {
865                 dev_err(dev, "spi setup failed.\n");
866                 return ret;
867         }
868         regmap_config = &ili9322_regmap_config;
869         ili->regmap = devm_regmap_init(dev, &ili9322_regmap_bus, dev,
870                                        regmap_config);
871         if (IS_ERR(ili->regmap)) {
872                 dev_err(dev, "failed to allocate register map\n");
873                 return PTR_ERR(ili->regmap);
874         }
875
876         ret = regmap_read(ili->regmap, ILI9322_CHIP_ID, &val);
877         if (ret) {
878                 dev_err(dev, "can't get chip ID (%d)\n", ret);
879                 return ret;
880         }
881         if (val != ILI9322_CHIP_ID_MAGIC) {
882                 dev_err(dev, "chip ID 0x%0x2, expected 0x%02x\n", val,
883                         ILI9322_CHIP_ID_MAGIC);
884                 return -ENODEV;
885         }
886
887         /* Probe the system to find the display setting */
888         if (ili->conf->input == ILI9322_INPUT_UNKNOWN) {
889                 ret = regmap_read(ili->regmap, ILI9322_ENTRY, &val);
890                 if (ret) {
891                         dev_err(dev, "can't get entry setting (%d)\n", ret);
892                         return ret;
893                 }
894                 /* Input enum corresponds to HW setting */
895                 ili->input = (val >> 4) & 0x0f;
896                 if (ili->input >= ILI9322_INPUT_UNKNOWN)
897                         ili->input = ILI9322_INPUT_UNKNOWN;
898         } else {
899                 ili->input = ili->conf->input;
900         }
901
902         drm_panel_init(&ili->panel);
903         ili->panel.dev = dev;
904         ili->panel.funcs = &ili9322_drm_funcs;
905
906         return drm_panel_add(&ili->panel);
907 }
908
909 static int ili9322_remove(struct spi_device *spi)
910 {
911         struct ili9322 *ili = spi_get_drvdata(spi);
912
913         ili9322_power_off(ili);
914         drm_panel_remove(&ili->panel);
915
916         return 0;
917 }
918
919 /*
920  * The D-Link DIR-685 panel is marked LM918A01-1A SY-B4-091116-E0199
921  */
922 static const struct ili9322_config ili9322_dir_685 = {
923         .width_mm = 65,
924         .height_mm = 50,
925         .input = ILI9322_INPUT_ITU_R_BT656_640X320_YCBCR,
926         .vreg1out_mv = 4600,
927         .vcom_high_percent = 91,
928         .vcom_amplitude_percent = 114,
929         .syncmode = ILI9322_IF_CTRL_SYNC_DISABLED,
930         .dclk_active_high = true,
931         .gamma_corr_neg = { 0xa, 0x5, 0x7, 0x7, 0x7, 0x5, 0x1, 0x6 },
932         .gamma_corr_pos = { 0x7, 0x7, 0x3, 0x2, 0x3, 0x5, 0x7, 0x2 },
933 };
934
935 static const struct of_device_id ili9322_of_match[] = {
936         {
937                 .compatible = "dlink,dir-685-panel",
938                 .data = &ili9322_dir_685,
939         },
940         {
941                 .compatible = "ilitek,ili9322",
942                 .data = NULL,
943         },
944         { }
945 };
946 MODULE_DEVICE_TABLE(of, ili9322_of_match);
947
948 static struct spi_driver ili9322_driver = {
949         .probe = ili9322_probe,
950         .remove = ili9322_remove,
951         .driver = {
952                 .name = "panel-ilitek-ili9322",
953                 .of_match_table = ili9322_of_match,
954         },
955 };
956 module_spi_driver(ili9322_driver);
957
958 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
959 MODULE_DESCRIPTION("ILI9322 LCD panel driver");
960 MODULE_LICENSE("GPL v2");