553 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * (C) Copyright 20084 * Stefano Babic, DENX Software Engineering, sbabic@denx.de.5 *6 * This driver implements a lcd device for the ILITEK 922x display7 * controller. The interface to the display is SPI and the display's8 * memory is cyclically updated over the RGB interface.9 */10 11#include <linux/fb.h>12#include <linux/delay.h>13#include <linux/errno.h>14#include <linux/init.h>15#include <linux/kernel.h>16#include <linux/lcd.h>17#include <linux/module.h>18#include <linux/of.h>19#include <linux/slab.h>20#include <linux/spi/spi.h>21#include <linux/string.h>22 23/* Register offset, see manual section 8.2 */24#define REG_START_OSCILLATION 0x0025#define REG_DRIVER_CODE_READ 0x0026#define REG_DRIVER_OUTPUT_CONTROL 0x0127#define REG_LCD_AC_DRIVEING_CONTROL 0x0228#define REG_ENTRY_MODE 0x0329#define REG_COMPARE_1 0x0430#define REG_COMPARE_2 0x0531#define REG_DISPLAY_CONTROL_1 0x0732#define REG_DISPLAY_CONTROL_2 0x0833#define REG_DISPLAY_CONTROL_3 0x0934#define REG_FRAME_CYCLE_CONTROL 0x0B35#define REG_EXT_INTF_CONTROL 0x0C36#define REG_POWER_CONTROL_1 0x1037#define REG_POWER_CONTROL_2 0x1138#define REG_POWER_CONTROL_3 0x1239#define REG_POWER_CONTROL_4 0x1340#define REG_RAM_ADDRESS_SET 0x2141#define REG_WRITE_DATA_TO_GRAM 0x2242#define REG_RAM_WRITE_MASK1 0x2343#define REG_RAM_WRITE_MASK2 0x2444#define REG_GAMMA_CONTROL_1 0x3045#define REG_GAMMA_CONTROL_2 0x3146#define REG_GAMMA_CONTROL_3 0x3247#define REG_GAMMA_CONTROL_4 0x3348#define REG_GAMMA_CONTROL_5 0x3449#define REG_GAMMA_CONTROL_6 0x3550#define REG_GAMMA_CONTROL_7 0x3651#define REG_GAMMA_CONTROL_8 0x3752#define REG_GAMMA_CONTROL_9 0x3853#define REG_GAMMA_CONTROL_10 0x3954#define REG_GATE_SCAN_CONTROL 0x4055#define REG_VERT_SCROLL_CONTROL 0x4156#define REG_FIRST_SCREEN_DRIVE_POS 0x4257#define REG_SECOND_SCREEN_DRIVE_POS 0x4358#define REG_RAM_ADDR_POS_H 0x4459#define REG_RAM_ADDR_POS_V 0x4560#define REG_OSCILLATOR_CONTROL 0x4F61#define REG_GPIO 0x6062#define REG_OTP_VCM_PROGRAMMING 0x6163#define REG_OTP_VCM_STATUS_ENABLE 0x6264#define REG_OTP_PROGRAMMING_ID_KEY 0x6565 66/*67 * maximum frequency for register access68 * (not for the GRAM access)69 */70#define ILITEK_MAX_FREQ_REG 400000071 72/*73 * Device ID as found in the datasheet (supports 9221 and 9222)74 */75#define ILITEK_DEVICE_ID 0x922076#define ILITEK_DEVICE_ID_MASK 0xFFF077 78/* Last two bits in the START BYTE */79#define START_RS_INDEX 080#define START_RS_REG 181#define START_RW_WRITE 082#define START_RW_READ 183 84/*85 * START_BYTE(id, rs, rw)86 *87 * Set the start byte according to the required operation.88 * The start byte is defined as:89 * ----------------------------------90 * | 0 | 1 | 1 | 1 | 0 | ID | RS | RW |91 * ----------------------------------92 * @id: display's id as set by the manufacturer93 * @rs: operation type bit, one of:94 * - START_RS_INDEX set the index register95 * - START_RS_REG write/read registers/GRAM96 * @rw: read/write operation97 * - START_RW_WRITE write98 * - START_RW_READ read99 */100#define START_BYTE(id, rs, rw) \101 (0x70 | (((id) & 0x01) << 2) | (((rs) & 0x01) << 1) | ((rw) & 0x01))102 103/*104 * CHECK_FREQ_REG(spi_device s, spi_transfer x) - Check the frequency105 * for the SPI transfer. According to the datasheet, the controller106 * accept higher frequency for the GRAM transfer, but it requires107 * lower frequency when the registers are read/written.108 * The macro sets the frequency in the spi_transfer structure if109 * the frequency exceeds the maximum value.110 * @s: pointer to an SPI device111 * @x: pointer to the read/write buffer pair112 */113#define CHECK_FREQ_REG(s, x) \114 do { \115 if (s->max_speed_hz > ILITEK_MAX_FREQ_REG) \116 ((struct spi_transfer *)x)->speed_hz = \117 ILITEK_MAX_FREQ_REG; \118 } while (0)119 120#define CMD_BUFSIZE 16121 122#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)123 124#define set_tx_byte(b) (tx_invert ? ~(b) : b)125 126/*127 * ili922x_id - id as set by manufacturer128 */129static int ili922x_id = 1;130module_param(ili922x_id, int, 0);131 132static int tx_invert;133module_param(tx_invert, int, 0);134 135/*136 * driver's private structure137 */138struct ili922x {139 struct spi_device *spi;140 struct lcd_device *ld;141 int power;142};143 144/**145 * ili922x_read_status - read status register from display146 * @spi: spi device147 * @rs: output value148 */149static int ili922x_read_status(struct spi_device *spi, u16 *rs)150{151 struct spi_message msg;152 struct spi_transfer xfer;153 unsigned char tbuf[CMD_BUFSIZE];154 unsigned char rbuf[CMD_BUFSIZE];155 int ret, i;156 157 memset(&xfer, 0, sizeof(struct spi_transfer));158 spi_message_init(&msg);159 xfer.tx_buf = tbuf;160 xfer.rx_buf = rbuf;161 xfer.cs_change = 1;162 CHECK_FREQ_REG(spi, &xfer);163 164 tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_INDEX,165 START_RW_READ));166 /*167 * we need 4-byte xfer here due to invalid dummy byte168 * received after start byte169 */170 for (i = 1; i < 4; i++)171 tbuf[i] = set_tx_byte(0); /* dummy */172 173 xfer.bits_per_word = 8;174 xfer.len = 4;175 spi_message_add_tail(&xfer, &msg);176 ret = spi_sync(spi, &msg);177 if (ret < 0) {178 dev_dbg(&spi->dev, "Error sending SPI message 0x%x", ret);179 return ret;180 }181 182 *rs = (rbuf[2] << 8) + rbuf[3];183 return 0;184}185 186/**187 * ili922x_read - read register from display188 * @spi: spi device189 * @reg: offset of the register to be read190 * @rx: output value191 */192static int ili922x_read(struct spi_device *spi, u8 reg, u16 *rx)193{194 struct spi_message msg;195 struct spi_transfer xfer_regindex, xfer_regvalue;196 unsigned char tbuf[CMD_BUFSIZE];197 unsigned char rbuf[CMD_BUFSIZE];198 int ret, len = 0, send_bytes;199 200 memset(&xfer_regindex, 0, sizeof(struct spi_transfer));201 memset(&xfer_regvalue, 0, sizeof(struct spi_transfer));202 spi_message_init(&msg);203 xfer_regindex.tx_buf = tbuf;204 xfer_regindex.rx_buf = rbuf;205 xfer_regindex.cs_change = 1;206 CHECK_FREQ_REG(spi, &xfer_regindex);207 208 tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_INDEX,209 START_RW_WRITE));210 tbuf[1] = set_tx_byte(0);211 tbuf[2] = set_tx_byte(reg);212 xfer_regindex.bits_per_word = 8;213 len = xfer_regindex.len = 3;214 spi_message_add_tail(&xfer_regindex, &msg);215 216 send_bytes = len;217 218 tbuf[len++] = set_tx_byte(START_BYTE(ili922x_id, START_RS_REG,219 START_RW_READ));220 tbuf[len++] = set_tx_byte(0);221 tbuf[len] = set_tx_byte(0);222 223 xfer_regvalue.cs_change = 1;224 xfer_regvalue.len = 3;225 xfer_regvalue.tx_buf = &tbuf[send_bytes];226 xfer_regvalue.rx_buf = &rbuf[send_bytes];227 CHECK_FREQ_REG(spi, &xfer_regvalue);228 229 spi_message_add_tail(&xfer_regvalue, &msg);230 ret = spi_sync(spi, &msg);231 if (ret < 0) {232 dev_dbg(&spi->dev, "Error sending SPI message 0x%x", ret);233 return ret;234 }235 236 *rx = (rbuf[1 + send_bytes] << 8) + rbuf[2 + send_bytes];237 return 0;238}239 240/**241 * ili922x_write - write a controller register242 * @spi: struct spi_device *243 * @reg: offset of the register to be written244 * @value: value to be written245 */246static int ili922x_write(struct spi_device *spi, u8 reg, u16 value)247{248 struct spi_message msg;249 struct spi_transfer xfer_regindex, xfer_regvalue;250 unsigned char tbuf[CMD_BUFSIZE];251 unsigned char rbuf[CMD_BUFSIZE];252 int ret;253 254 memset(&xfer_regindex, 0, sizeof(struct spi_transfer));255 memset(&xfer_regvalue, 0, sizeof(struct spi_transfer));256 257 spi_message_init(&msg);258 xfer_regindex.tx_buf = tbuf;259 xfer_regindex.rx_buf = rbuf;260 xfer_regindex.cs_change = 1;261 CHECK_FREQ_REG(spi, &xfer_regindex);262 263 tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_INDEX,264 START_RW_WRITE));265 tbuf[1] = set_tx_byte(0);266 tbuf[2] = set_tx_byte(reg);267 xfer_regindex.bits_per_word = 8;268 xfer_regindex.len = 3;269 spi_message_add_tail(&xfer_regindex, &msg);270 271 ret = spi_sync(spi, &msg);272 if (ret < 0) {273 dev_err(&spi->dev, "Error sending SPI message 0x%x", ret);274 return ret;275 }276 277 spi_message_init(&msg);278 tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_REG,279 START_RW_WRITE));280 tbuf[1] = set_tx_byte((value & 0xFF00) >> 8);281 tbuf[2] = set_tx_byte(value & 0x00FF);282 283 xfer_regvalue.cs_change = 1;284 xfer_regvalue.len = 3;285 xfer_regvalue.tx_buf = tbuf;286 xfer_regvalue.rx_buf = rbuf;287 CHECK_FREQ_REG(spi, &xfer_regvalue);288 289 spi_message_add_tail(&xfer_regvalue, &msg);290 291 ret = spi_sync(spi, &msg);292 if (ret < 0) {293 dev_err(&spi->dev, "Error sending SPI message 0x%x", ret);294 return ret;295 }296 return 0;297}298 299#ifdef DEBUG300/**301 * ili922x_reg_dump - dump all registers302 *303 * @spi: pointer to an SPI device304 */305static void ili922x_reg_dump(struct spi_device *spi)306{307 u8 reg;308 u16 rx;309 310 dev_dbg(&spi->dev, "ILI922x configuration registers:\n");311 for (reg = REG_START_OSCILLATION;312 reg <= REG_OTP_PROGRAMMING_ID_KEY; reg++) {313 ili922x_read(spi, reg, &rx);314 dev_dbg(&spi->dev, "reg @ 0x%02X: 0x%04X\n", reg, rx);315 }316}317#else318static inline void ili922x_reg_dump(struct spi_device *spi) {}319#endif320 321/**322 * set_write_to_gram_reg - initialize the display to write the GRAM323 * @spi: spi device324 */325static void set_write_to_gram_reg(struct spi_device *spi)326{327 struct spi_message msg;328 struct spi_transfer xfer;329 unsigned char tbuf[CMD_BUFSIZE];330 331 memset(&xfer, 0, sizeof(struct spi_transfer));332 333 spi_message_init(&msg);334 xfer.tx_buf = tbuf;335 xfer.rx_buf = NULL;336 xfer.cs_change = 1;337 338 tbuf[0] = START_BYTE(ili922x_id, START_RS_INDEX, START_RW_WRITE);339 tbuf[1] = 0;340 tbuf[2] = REG_WRITE_DATA_TO_GRAM;341 342 xfer.bits_per_word = 8;343 xfer.len = 3;344 spi_message_add_tail(&xfer, &msg);345 spi_sync(spi, &msg);346}347 348/**349 * ili922x_poweron - turn the display on350 * @spi: spi device351 *352 * The sequence to turn on the display is taken from353 * the datasheet and/or the example code provided by the354 * manufacturer.355 */356static int ili922x_poweron(struct spi_device *spi)357{358 int ret;359 360 /* Power on */361 ret = ili922x_write(spi, REG_POWER_CONTROL_1, 0x0000);362 usleep_range(10000, 10500);363 ret += ili922x_write(spi, REG_POWER_CONTROL_2, 0x0000);364 ret += ili922x_write(spi, REG_POWER_CONTROL_3, 0x0000);365 msleep(40);366 ret += ili922x_write(spi, REG_POWER_CONTROL_4, 0x0000);367 msleep(40);368 /* register 0x56 is not documented in the datasheet */369 ret += ili922x_write(spi, 0x56, 0x080F);370 ret += ili922x_write(spi, REG_POWER_CONTROL_1, 0x4240);371 usleep_range(10000, 10500);372 ret += ili922x_write(spi, REG_POWER_CONTROL_2, 0x0000);373 ret += ili922x_write(spi, REG_POWER_CONTROL_3, 0x0014);374 msleep(40);375 ret += ili922x_write(spi, REG_POWER_CONTROL_4, 0x1319);376 msleep(40);377 378 return ret;379}380 381/**382 * ili922x_poweroff - turn the display off383 * @spi: spi device384 */385static int ili922x_poweroff(struct spi_device *spi)386{387 int ret;388 389 /* Power off */390 ret = ili922x_write(spi, REG_POWER_CONTROL_1, 0x0000);391 usleep_range(10000, 10500);392 ret += ili922x_write(spi, REG_POWER_CONTROL_2, 0x0000);393 ret += ili922x_write(spi, REG_POWER_CONTROL_3, 0x0000);394 msleep(40);395 ret += ili922x_write(spi, REG_POWER_CONTROL_4, 0x0000);396 msleep(40);397 398 return ret;399}400 401/**402 * ili922x_display_init - initialize the display by setting403 * the configuration registers404 * @spi: spi device405 */406static void ili922x_display_init(struct spi_device *spi)407{408 ili922x_write(spi, REG_START_OSCILLATION, 1);409 usleep_range(10000, 10500);410 ili922x_write(spi, REG_DRIVER_OUTPUT_CONTROL, 0x691B);411 ili922x_write(spi, REG_LCD_AC_DRIVEING_CONTROL, 0x0700);412 ili922x_write(spi, REG_ENTRY_MODE, 0x1030);413 ili922x_write(spi, REG_COMPARE_1, 0x0000);414 ili922x_write(spi, REG_COMPARE_2, 0x0000);415 ili922x_write(spi, REG_DISPLAY_CONTROL_1, 0x0037);416 ili922x_write(spi, REG_DISPLAY_CONTROL_2, 0x0202);417 ili922x_write(spi, REG_DISPLAY_CONTROL_3, 0x0000);418 ili922x_write(spi, REG_FRAME_CYCLE_CONTROL, 0x0000);419 420 /* Set RGB interface */421 ili922x_write(spi, REG_EXT_INTF_CONTROL, 0x0110);422 423 ili922x_poweron(spi);424 425 ili922x_write(spi, REG_GAMMA_CONTROL_1, 0x0302);426 ili922x_write(spi, REG_GAMMA_CONTROL_2, 0x0407);427 ili922x_write(spi, REG_GAMMA_CONTROL_3, 0x0304);428 ili922x_write(spi, REG_GAMMA_CONTROL_4, 0x0203);429 ili922x_write(spi, REG_GAMMA_CONTROL_5, 0x0706);430 ili922x_write(spi, REG_GAMMA_CONTROL_6, 0x0407);431 ili922x_write(spi, REG_GAMMA_CONTROL_7, 0x0706);432 ili922x_write(spi, REG_GAMMA_CONTROL_8, 0x0000);433 ili922x_write(spi, REG_GAMMA_CONTROL_9, 0x0C06);434 ili922x_write(spi, REG_GAMMA_CONTROL_10, 0x0F00);435 ili922x_write(spi, REG_RAM_ADDRESS_SET, 0x0000);436 ili922x_write(spi, REG_GATE_SCAN_CONTROL, 0x0000);437 ili922x_write(spi, REG_VERT_SCROLL_CONTROL, 0x0000);438 ili922x_write(spi, REG_FIRST_SCREEN_DRIVE_POS, 0xDB00);439 ili922x_write(spi, REG_SECOND_SCREEN_DRIVE_POS, 0xDB00);440 ili922x_write(spi, REG_RAM_ADDR_POS_H, 0xAF00);441 ili922x_write(spi, REG_RAM_ADDR_POS_V, 0xDB00);442 ili922x_reg_dump(spi);443 set_write_to_gram_reg(spi);444}445 446static int ili922x_lcd_power(struct ili922x *lcd, int power)447{448 int ret = 0;449 450 if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))451 ret = ili922x_poweron(lcd->spi);452 else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))453 ret = ili922x_poweroff(lcd->spi);454 455 if (!ret)456 lcd->power = power;457 458 return ret;459}460 461static int ili922x_set_power(struct lcd_device *ld, int power)462{463 struct ili922x *ili = lcd_get_data(ld);464 465 return ili922x_lcd_power(ili, power);466}467 468static int ili922x_get_power(struct lcd_device *ld)469{470 struct ili922x *ili = lcd_get_data(ld);471 472 return ili->power;473}474 475static const struct lcd_ops ili922x_ops = {476 .get_power = ili922x_get_power,477 .set_power = ili922x_set_power,478};479 480static int ili922x_probe(struct spi_device *spi)481{482 struct ili922x *ili;483 struct lcd_device *lcd;484 int ret;485 u16 reg = 0;486 487 ili = devm_kzalloc(&spi->dev, sizeof(*ili), GFP_KERNEL);488 if (!ili)489 return -ENOMEM;490 491 ili->spi = spi;492 spi_set_drvdata(spi, ili);493 494 /* check if the device is connected */495 ret = ili922x_read(spi, REG_DRIVER_CODE_READ, ®);496 if (ret || ((reg & ILITEK_DEVICE_ID_MASK) != ILITEK_DEVICE_ID)) {497 dev_err(&spi->dev,498 "no LCD found: Chip ID 0x%x, ret %d\n",499 reg, ret);500 return -ENODEV;501 }502 503 dev_info(&spi->dev, "ILI%x found, SPI freq %d, mode %d\n",504 reg, spi->max_speed_hz, spi->mode);505 506 ret = ili922x_read_status(spi, ®);507 if (ret) {508 dev_err(&spi->dev, "reading RS failed...\n");509 return ret;510 }511 512 dev_dbg(&spi->dev, "status: 0x%x\n", reg);513 514 ili922x_display_init(spi);515 516 ili->power = FB_BLANK_POWERDOWN;517 518 lcd = devm_lcd_device_register(&spi->dev, "ili922xlcd", &spi->dev, ili,519 &ili922x_ops);520 if (IS_ERR(lcd)) {521 dev_err(&spi->dev, "cannot register LCD\n");522 return PTR_ERR(lcd);523 }524 525 ili->ld = lcd;526 spi_set_drvdata(spi, ili);527 528 ili922x_lcd_power(ili, FB_BLANK_UNBLANK);529 530 return 0;531}532 533static void ili922x_remove(struct spi_device *spi)534{535 ili922x_poweroff(spi);536}537 538static struct spi_driver ili922x_driver = {539 .driver = {540 .name = "ili922x",541 },542 .probe = ili922x_probe,543 .remove = ili922x_remove,544};545 546module_spi_driver(ili922x_driver);547 548MODULE_AUTHOR("Stefano Babic <sbabic@denx.de>");549MODULE_DESCRIPTION("ILI9221/9222 LCD driver");550MODULE_LICENSE("GPL");551MODULE_PARM_DESC(ili922x_id, "set controller identifier (default=1)");552MODULE_PARM_DESC(tx_invert, "invert bytes before sending");553