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