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