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 <drm/drmP.h>
23 #include <drm/drm_panel.h>
24 
25 #include <linux/of_device.h>
26 #include <linux/bitops.h>
27 #include <linux/gpio/consumer.h>
28 #include <linux/module.h>
29 #include <linux/regmap.h>
30 #include <linux/regulator/consumer.h>
31 #include <linux/spi/spi.h>
32 
33 #include <video/mipi_display.h>
34 #include <video/of_videomode.h>
35 #include <video/videomode.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 	struct drm_connector *connector = panel->connector;
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 	if (ili->conf->dclk_active_high) {
410 		reg = ILI9322_POL_DCLK;
411 		connector->display_info.bus_flags |=
412 			DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
413 	} else {
414 		reg = 0;
415 		connector->display_info.bus_flags |=
416 			DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
417 	}
418 	if (ili->conf->de_active_high) {
419 		reg |= ILI9322_POL_DE;
420 		connector->display_info.bus_flags |=
421 			DRM_BUS_FLAG_DE_HIGH;
422 	} else {
423 		connector->display_info.bus_flags |=
424 			DRM_BUS_FLAG_DE_LOW;
425 	}
426 	if (ili->conf->hsync_active_high)
427 		reg |= ILI9322_POL_HSYNC;
428 	if (ili->conf->vsync_active_high)
429 		reg |= ILI9322_POL_VSYNC;
430 	ret = regmap_write(ili->regmap, ILI9322_POL, reg);
431 	if (ret) {
432 		dev_err(ili->dev, "can't write POL register (%d)\n", ret);
433 		return ret;
434 	}
435 
436 	/*
437 	 * Set up interface control.
438 	 * This is not used in the BT.656 mode (no H/Vsync or DE signals).
439 	 */
440 	reg = ili->conf->syncmode;
441 	reg |= ILI9322_IF_CTRL_LINE_INVERSION;
442 	ret = regmap_write(ili->regmap, ILI9322_IF_CTRL, reg);
443 	if (ret) {
444 		dev_err(ili->dev, "can't write IF CTRL register (%d)\n", ret);
445 		return ret;
446 	}
447 
448 	/* Set up the input mode */
449 	reg = (ili->input << 4);
450 	/* These are inverted, setting to 1 is the default, clearing flips */
451 	if (!ili->conf->flip_horizontal)
452 		reg |= ILI9322_ENTRY_HDIR;
453 	if (!ili->conf->flip_vertical)
454 		reg |= ILI9322_ENTRY_VDIR;
455 	reg |= ILI9322_ENTRY_AUTODETECT;
456 	ret = regmap_write(ili->regmap, ILI9322_ENTRY, reg);
457 	if (ret) {
458 		dev_err(ili->dev, "can't write ENTRY reg (%d)\n", ret);
459 		return ret;
460 	}
461 	dev_info(ili->dev, "display is in %s mode, syncmode %02x\n",
462 		 ili9322_inputs[ili->input],
463 		 ili->conf->syncmode);
464 
465 	dev_info(ili->dev, "initialized display\n");
466 
467 	return 0;
468 }
469 
470 /*
471  * This power-on sequence if from the datasheet, page 57.
472  */
473 static int ili9322_power_on(struct ili9322 *ili)
474 {
475 	int ret;
476 
477 	/* Assert RESET */
478 	gpiod_set_value(ili->reset_gpio, 1);
479 
480 	ret = regulator_bulk_enable(ARRAY_SIZE(ili->supplies), ili->supplies);
481 	if (ret < 0) {
482 		dev_err(ili->dev, "unable to enable regulators\n");
483 		return ret;
484 	}
485 	msleep(20);
486 
487 	/* De-assert RESET */
488 	gpiod_set_value(ili->reset_gpio, 0);
489 
490 	msleep(10);
491 
492 	return 0;
493 }
494 
495 static int ili9322_power_off(struct ili9322 *ili)
496 {
497 	return regulator_bulk_disable(ARRAY_SIZE(ili->supplies), ili->supplies);
498 }
499 
500 static int ili9322_disable(struct drm_panel *panel)
501 {
502 	struct ili9322 *ili = panel_to_ili9322(panel);
503 	int ret;
504 
505 	ret = regmap_write(ili->regmap, ILI9322_POW_CTRL,
506 			   ILI9322_POW_CTRL_STANDBY);
507 	if (ret) {
508 		dev_err(ili->dev, "unable to go to standby mode\n");
509 		return ret;
510 	}
511 
512 	return 0;
513 }
514 
515 static int ili9322_unprepare(struct drm_panel *panel)
516 {
517 	struct ili9322 *ili = panel_to_ili9322(panel);
518 
519 	return ili9322_power_off(ili);
520 }
521 
522 static int ili9322_prepare(struct drm_panel *panel)
523 {
524 	struct ili9322 *ili = panel_to_ili9322(panel);
525 	int ret;
526 
527 	ret = ili9322_power_on(ili);
528 	if (ret < 0)
529 		return ret;
530 
531 	ret = ili9322_init(panel, ili);
532 	if (ret < 0)
533 		ili9322_unprepare(panel);
534 
535 	return ret;
536 }
537 
538 static int ili9322_enable(struct drm_panel *panel)
539 {
540 	struct ili9322 *ili = panel_to_ili9322(panel);
541 	int ret;
542 
543 	ret = regmap_write(ili->regmap, ILI9322_POW_CTRL,
544 			   ILI9322_POW_CTRL_DEFAULT);
545 	if (ret) {
546 		dev_err(ili->dev, "unable to enable panel\n");
547 		return ret;
548 	}
549 
550 	return 0;
551 }
552 
553 /* Serial RGB modes */
554 static const struct drm_display_mode srgb_320x240_mode = {
555 	.clock = 2453500,
556 	.hdisplay = 320,
557 	.hsync_start = 320 + 359,
558 	.hsync_end = 320 + 359 + 1,
559 	.htotal = 320 + 359 + 1 + 241,
560 	.vdisplay = 240,
561 	.vsync_start = 240 + 4,
562 	.vsync_end = 240 + 4 + 1,
563 	.vtotal = 262,
564 	.vrefresh = 60,
565 	.flags = 0,
566 };
567 
568 static const struct drm_display_mode srgb_360x240_mode = {
569 	.clock = 2700000,
570 	.hdisplay = 360,
571 	.hsync_start = 360 + 35,
572 	.hsync_end = 360 + 35 + 1,
573 	.htotal = 360 + 35 + 1 + 241,
574 	.vdisplay = 240,
575 	.vsync_start = 240 + 21,
576 	.vsync_end = 240 + 21 + 1,
577 	.vtotal = 262,
578 	.vrefresh = 60,
579 	.flags = 0,
580 };
581 
582 /* This is the only mode listed for parallel RGB in the datasheet */
583 static const struct drm_display_mode prgb_320x240_mode = {
584 	.clock = 6400000,
585 	.hdisplay = 320,
586 	.hsync_start = 320 + 38,
587 	.hsync_end = 320 + 38 + 1,
588 	.htotal = 320 + 38 + 1 + 50,
589 	.vdisplay = 240,
590 	.vsync_start = 240 + 4,
591 	.vsync_end = 240 + 4 + 1,
592 	.vtotal = 262,
593 	.vrefresh = 60,
594 	.flags = 0,
595 };
596 
597 /* YUV modes */
598 static const struct drm_display_mode yuv_640x320_mode = {
599 	.clock = 2454000,
600 	.hdisplay = 640,
601 	.hsync_start = 640 + 252,
602 	.hsync_end = 640 + 252 + 1,
603 	.htotal = 640 + 252 + 1 + 28,
604 	.vdisplay = 320,
605 	.vsync_start = 320 + 4,
606 	.vsync_end = 320 + 4 + 1,
607 	.vtotal = 320 + 4 + 1 + 18,
608 	.vrefresh = 60,
609 	.flags = 0,
610 };
611 
612 static const struct drm_display_mode yuv_720x360_mode = {
613 	.clock = 2700000,
614 	.hdisplay = 720,
615 	.hsync_start = 720 + 252,
616 	.hsync_end = 720 + 252 + 1,
617 	.htotal = 720 + 252 + 1 + 24,
618 	.vdisplay = 360,
619 	.vsync_start = 360 + 4,
620 	.vsync_end = 360 + 4 + 1,
621 	.vtotal = 360 + 4 + 1 + 18,
622 	.vrefresh = 60,
623 	.flags = 0,
624 };
625 
626 /* BT.656 VGA mode, 640x480 */
627 static const struct drm_display_mode itu_r_bt_656_640_mode = {
628 	.clock = 2454000,
629 	.hdisplay = 640,
630 	.hsync_start = 640 + 3,
631 	.hsync_end = 640 + 3 + 1,
632 	.htotal = 640 + 3 + 1 + 272,
633 	.vdisplay = 480,
634 	.vsync_start = 480 + 4,
635 	.vsync_end = 480 + 4 + 1,
636 	.vtotal = 500,
637 	.vrefresh = 60,
638 	.flags = 0,
639 };
640 
641 /* BT.656 D1 mode 720x480 */
642 static const struct drm_display_mode itu_r_bt_656_720_mode = {
643 	.clock = 2700000,
644 	.hdisplay = 720,
645 	.hsync_start = 720 + 3,
646 	.hsync_end = 720 + 3 + 1,
647 	.htotal = 720 + 3 + 1 + 272,
648 	.vdisplay = 480,
649 	.vsync_start = 480 + 4,
650 	.vsync_end = 480 + 4 + 1,
651 	.vtotal = 500,
652 	.vrefresh = 60,
653 	.flags = 0,
654 };
655 
656 static int ili9322_get_modes(struct drm_panel *panel)
657 {
658 	struct drm_connector *connector = panel->connector;
659 	struct ili9322 *ili = panel_to_ili9322(panel);
660 	struct drm_display_mode *mode;
661 
662 	connector->display_info.width_mm = ili->conf->width_mm;
663 	connector->display_info.height_mm = ili->conf->height_mm;
664 
665 	switch (ili->input) {
666 	case ILI9322_INPUT_SRGB_DUMMY_320X240:
667 		mode = drm_mode_duplicate(panel->drm, &srgb_320x240_mode);
668 		break;
669 	case ILI9322_INPUT_SRGB_DUMMY_360X240:
670 		mode = drm_mode_duplicate(panel->drm, &srgb_360x240_mode);
671 		break;
672 	case ILI9322_INPUT_PRGB_THROUGH:
673 	case ILI9322_INPUT_PRGB_ALIGNED:
674 		mode = drm_mode_duplicate(panel->drm, &prgb_320x240_mode);
675 		break;
676 	case ILI9322_INPUT_YUV_640X320_YCBCR:
677 		mode = drm_mode_duplicate(panel->drm, &yuv_640x320_mode);
678 		break;
679 	case ILI9322_INPUT_YUV_720X360_YCBCR:
680 		mode = drm_mode_duplicate(panel->drm, &yuv_720x360_mode);
681 		break;
682 	case ILI9322_INPUT_ITU_R_BT656_720X360_YCBCR:
683 		mode = drm_mode_duplicate(panel->drm, &itu_r_bt_656_720_mode);
684 		break;
685 	case ILI9322_INPUT_ITU_R_BT656_640X320_YCBCR:
686 		mode = drm_mode_duplicate(panel->drm, &itu_r_bt_656_640_mode);
687 		break;
688 	default:
689 		mode = NULL;
690 		break;
691 	}
692 	if (!mode) {
693 		DRM_ERROR("bad mode or failed to add mode\n");
694 		return -EINVAL;
695 	}
696 	drm_mode_set_name(mode);
697 	/*
698 	 * This is the preferred mode because most people are going
699 	 * to want to use the display with VGA type graphics.
700 	 */
701 	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
702 
703 	/* Set up the polarity */
704 	if (ili->conf->hsync_active_high)
705 		mode->flags |= DRM_MODE_FLAG_PHSYNC;
706 	else
707 		mode->flags |= DRM_MODE_FLAG_NHSYNC;
708 	if (ili->conf->vsync_active_high)
709 		mode->flags |= DRM_MODE_FLAG_PVSYNC;
710 	else
711 		mode->flags |= DRM_MODE_FLAG_NVSYNC;
712 
713 	mode->width_mm = ili->conf->width_mm;
714 	mode->height_mm = ili->conf->height_mm;
715 	drm_mode_probed_add(connector, mode);
716 
717 	return 1; /* Number of modes */
718 }
719 
720 static const struct drm_panel_funcs ili9322_drm_funcs = {
721 	.disable = ili9322_disable,
722 	.unprepare = ili9322_unprepare,
723 	.prepare = ili9322_prepare,
724 	.enable = ili9322_enable,
725 	.get_modes = ili9322_get_modes,
726 };
727 
728 static int ili9322_probe(struct spi_device *spi)
729 {
730 	struct device *dev = &spi->dev;
731 	struct ili9322 *ili;
732 	const struct regmap_config *regmap_config;
733 	u8 gamma;
734 	u32 val;
735 	int ret;
736 	int i;
737 
738 	ili = devm_kzalloc(dev, sizeof(struct ili9322), GFP_KERNEL);
739 	if (!ili)
740 		return -ENOMEM;
741 
742 	spi_set_drvdata(spi, ili);
743 
744 	ili->dev = dev;
745 
746 	/*
747 	 * Every new incarnation of this display must have a unique
748 	 * data entry for the system in this driver.
749 	 */
750 	ili->conf = of_device_get_match_data(dev);
751 	if (!ili->conf) {
752 		dev_err(dev, "missing device configuration\n");
753 		return -ENODEV;
754 	}
755 
756 	val = ili->conf->vreg1out_mv;
757 	if (!val) {
758 		/* Default HW value, do not touch (should be 4.5V) */
759 		ili->vreg1out = U8_MAX;
760 	} else {
761 		if (val < 3600) {
762 			dev_err(dev, "too low VREG1OUT\n");
763 			return -EINVAL;
764 		}
765 		if (val > 6000) {
766 			dev_err(dev, "too high VREG1OUT\n");
767 			return -EINVAL;
768 		}
769 		if ((val % 100) != 0) {
770 			dev_err(dev, "VREG1OUT is no even 100 microvolt\n");
771 			return -EINVAL;
772 		}
773 		val -= 3600;
774 		val /= 100;
775 		dev_dbg(dev, "VREG1OUT = 0x%02x\n", val);
776 		ili->vreg1out = val;
777 	}
778 
779 	val = ili->conf->vcom_high_percent;
780 	if (!val) {
781 		/* Default HW value, do not touch (should be 91%) */
782 		ili->vcom_high = U8_MAX;
783 	} else {
784 		if (val < 37) {
785 			dev_err(dev, "too low VCOM high\n");
786 			return -EINVAL;
787 		}
788 		if (val > 100) {
789 			dev_err(dev, "too high VCOM high\n");
790 			return -EINVAL;
791 		}
792 		val -= 37;
793 		dev_dbg(dev, "VCOM high = 0x%02x\n", val);
794 		ili->vcom_high = val;
795 	}
796 
797 	val = ili->conf->vcom_amplitude_percent;
798 	if (!val) {
799 		/* Default HW value, do not touch (should be 114%) */
800 		ili->vcom_high = U8_MAX;
801 	} else {
802 		if (val < 70) {
803 			dev_err(dev, "too low VCOM amplitude\n");
804 			return -EINVAL;
805 		}
806 		if (val > 132) {
807 			dev_err(dev, "too high VCOM amplitude\n");
808 			return -EINVAL;
809 		}
810 		val -= 70;
811 		val >>= 1; /* Increments of 2% */
812 		dev_dbg(dev, "VCOM amplitude = 0x%02x\n", val);
813 		ili->vcom_amplitude = val;
814 	}
815 
816 	for (i = 0; i < ARRAY_SIZE(ili->gamma); i++) {
817 		val = ili->conf->gamma_corr_neg[i];
818 		if (val > 15) {
819 			dev_err(dev, "negative gamma %u > 15, capping\n", val);
820 			val = 15;
821 		}
822 		gamma = val << 4;
823 		val = ili->conf->gamma_corr_pos[i];
824 		if (val > 15) {
825 			dev_err(dev, "positive gamma %u > 15, capping\n", val);
826 			val = 15;
827 		}
828 		gamma |= val;
829 		ili->gamma[i] = gamma;
830 		dev_dbg(dev, "gamma V%d: 0x%02x\n", i + 1, gamma);
831 	}
832 
833 	ili->supplies[0].supply = "vcc"; /* 2.7-3.6 V */
834 	ili->supplies[1].supply = "iovcc"; /* 1.65-3.6V */
835 	ili->supplies[2].supply = "vci"; /* 2.7-3.6V */
836 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ili->supplies),
837 				      ili->supplies);
838 	if (ret < 0)
839 		return ret;
840 	ret = regulator_set_voltage(ili->supplies[0].consumer,
841 				    2700000, 3600000);
842 	if (ret)
843 		return ret;
844 	ret = regulator_set_voltage(ili->supplies[1].consumer,
845 				    1650000, 3600000);
846 	if (ret)
847 		return ret;
848 	ret = regulator_set_voltage(ili->supplies[2].consumer,
849 				    2700000, 3600000);
850 	if (ret)
851 		return ret;
852 
853 	ili->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
854 	if (IS_ERR(ili->reset_gpio)) {
855 		dev_err(dev, "failed to get RESET GPIO\n");
856 		return PTR_ERR(ili->reset_gpio);
857 	}
858 
859 	spi->bits_per_word = 8;
860 	ret = spi_setup(spi);
861 	if (ret < 0) {
862 		dev_err(dev, "spi setup failed.\n");
863 		return ret;
864 	}
865 	regmap_config = &ili9322_regmap_config;
866 	ili->regmap = devm_regmap_init(dev, &ili9322_regmap_bus, dev,
867 				       regmap_config);
868 	if (IS_ERR(ili->regmap)) {
869 		dev_err(dev, "failed to allocate register map\n");
870 		return PTR_ERR(ili->regmap);
871 	}
872 
873 	ret = regmap_read(ili->regmap, ILI9322_CHIP_ID, &val);
874 	if (ret) {
875 		dev_err(dev, "can't get chip ID (%d)\n", ret);
876 		return ret;
877 	}
878 	if (val != ILI9322_CHIP_ID_MAGIC) {
879 		dev_err(dev, "chip ID 0x%0x2, expected 0x%02x\n", val,
880 			ILI9322_CHIP_ID_MAGIC);
881 		return -ENODEV;
882 	}
883 
884 	/* Probe the system to find the display setting */
885 	if (ili->conf->input == ILI9322_INPUT_UNKNOWN) {
886 		ret = regmap_read(ili->regmap, ILI9322_ENTRY, &val);
887 		if (ret) {
888 			dev_err(dev, "can't get entry setting (%d)\n", ret);
889 			return ret;
890 		}
891 		/* Input enum corresponds to HW setting */
892 		ili->input = (val >> 4) & 0x0f;
893 		if (ili->input >= ILI9322_INPUT_UNKNOWN)
894 			ili->input = ILI9322_INPUT_UNKNOWN;
895 	} else {
896 		ili->input = ili->conf->input;
897 	}
898 
899 	drm_panel_init(&ili->panel);
900 	ili->panel.dev = dev;
901 	ili->panel.funcs = &ili9322_drm_funcs;
902 
903 	return drm_panel_add(&ili->panel);
904 }
905 
906 static int ili9322_remove(struct spi_device *spi)
907 {
908 	struct ili9322 *ili = spi_get_drvdata(spi);
909 
910 	ili9322_power_off(ili);
911 	drm_panel_remove(&ili->panel);
912 
913 	return 0;
914 }
915 
916 /*
917  * The D-Link DIR-685 panel is marked LM918A01-1A SY-B4-091116-E0199
918  */
919 static const struct ili9322_config ili9322_dir_685 = {
920 	.width_mm = 65,
921 	.height_mm = 50,
922 	.input = ILI9322_INPUT_ITU_R_BT656_640X320_YCBCR,
923 	.vreg1out_mv = 4600,
924 	.vcom_high_percent = 91,
925 	.vcom_amplitude_percent = 114,
926 	.syncmode = ILI9322_IF_CTRL_SYNC_DISABLED,
927 	.dclk_active_high = true,
928 	.gamma_corr_neg = { 0xa, 0x5, 0x7, 0x7, 0x7, 0x5, 0x1, 0x6 },
929 	.gamma_corr_pos = { 0x7, 0x7, 0x3, 0x2, 0x3, 0x5, 0x7, 0x2 },
930 };
931 
932 static const struct of_device_id ili9322_of_match[] = {
933 	{
934 		.compatible = "dlink,dir-685-panel",
935 		.data = &ili9322_dir_685,
936 	},
937 	{
938 		.compatible = "ilitek,ili9322",
939 		.data = NULL,
940 	},
941 	{ }
942 };
943 MODULE_DEVICE_TABLE(of, ili9322_of_match);
944 
945 static struct spi_driver ili9322_driver = {
946 	.probe = ili9322_probe,
947 	.remove = ili9322_remove,
948 	.driver = {
949 		.name = "panel-ilitek-ili9322",
950 		.of_match_table = ili9322_of_match,
951 	},
952 };
953 module_spi_driver(ili9322_driver);
954 
955 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
956 MODULE_DESCRIPTION("ILI9322 LCD panel driver");
957 MODULE_LICENSE("GPL v2");
958