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