cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ili922x.c (14656B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * (C) Copyright 2008
      4 * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
      5 *
      6 * This driver implements a lcd device for the ILITEK 922x display
      7 * controller. The interface to the display is SPI and the display's
      8 * 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			0x00
     25#define REG_DRIVER_CODE_READ			0x00
     26#define REG_DRIVER_OUTPUT_CONTROL		0x01
     27#define REG_LCD_AC_DRIVEING_CONTROL		0x02
     28#define REG_ENTRY_MODE				0x03
     29#define REG_COMPARE_1				0x04
     30#define REG_COMPARE_2				0x05
     31#define REG_DISPLAY_CONTROL_1			0x07
     32#define REG_DISPLAY_CONTROL_2			0x08
     33#define REG_DISPLAY_CONTROL_3			0x09
     34#define REG_FRAME_CYCLE_CONTROL			0x0B
     35#define REG_EXT_INTF_CONTROL			0x0C
     36#define REG_POWER_CONTROL_1			0x10
     37#define REG_POWER_CONTROL_2			0x11
     38#define REG_POWER_CONTROL_3			0x12
     39#define REG_POWER_CONTROL_4			0x13
     40#define REG_RAM_ADDRESS_SET			0x21
     41#define REG_WRITE_DATA_TO_GRAM			0x22
     42#define REG_RAM_WRITE_MASK1			0x23
     43#define REG_RAM_WRITE_MASK2			0x24
     44#define REG_GAMMA_CONTROL_1			0x30
     45#define REG_GAMMA_CONTROL_2			0x31
     46#define REG_GAMMA_CONTROL_3			0x32
     47#define REG_GAMMA_CONTROL_4			0x33
     48#define REG_GAMMA_CONTROL_5			0x34
     49#define REG_GAMMA_CONTROL_6			0x35
     50#define REG_GAMMA_CONTROL_7			0x36
     51#define REG_GAMMA_CONTROL_8			0x37
     52#define REG_GAMMA_CONTROL_9			0x38
     53#define REG_GAMMA_CONTROL_10			0x39
     54#define REG_GATE_SCAN_CONTROL			0x40
     55#define REG_VERT_SCROLL_CONTROL			0x41
     56#define REG_FIRST_SCREEN_DRIVE_POS		0x42
     57#define REG_SECOND_SCREEN_DRIVE_POS		0x43
     58#define REG_RAM_ADDR_POS_H			0x44
     59#define REG_RAM_ADDR_POS_V			0x45
     60#define REG_OSCILLATOR_CONTROL			0x4F
     61#define REG_GPIO				0x60
     62#define REG_OTP_VCM_PROGRAMMING			0x61
     63#define REG_OTP_VCM_STATUS_ENABLE		0x62
     64#define REG_OTP_PROGRAMMING_ID_KEY		0x65
     65
     66/*
     67 * maximum frequency for register access
     68 * (not for the GRAM access)
     69 */
     70#define ILITEK_MAX_FREQ_REG	4000000
     71
     72/*
     73 * Device ID as found in the datasheet (supports 9221 and 9222)
     74 */
     75#define ILITEK_DEVICE_ID	0x9220
     76#define ILITEK_DEVICE_ID_MASK	0xFFF0
     77
     78/* Last two bits in the START BYTE */
     79#define START_RS_INDEX		0
     80#define START_RS_REG		1
     81#define START_RW_WRITE		0
     82#define START_RW_READ		1
     83
     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 manufacturer
     93 * @rs: operation type bit, one of:
     94 *	  - START_RS_INDEX	set the index register
     95 *	  - START_RS_REG	write/read registers/GRAM
     96 * @rw: read/write operation
     97 *	 - START_RW_WRITE	write
     98 *	 - START_RW_READ	read
     99 */
    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 frequency
    105 *	for the SPI transfer. According to the datasheet, the controller
    106 *	accept higher frequency for the GRAM transfer, but it requires
    107 *	lower frequency when the registers are read/written.
    108 *	The macro sets the frequency in the spi_transfer structure if
    109 *	the frequency exceeds the maximum value.
    110 * @s: pointer to an SPI device
    111 * @x: pointer to the read/write buffer pair
    112 */
    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		16
    121
    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 manufacturer
    128 */
    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 structure
    137 */
    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 display
    146 * @spi: spi device
    147 * @rs:  output value
    148 */
    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 byte
    168	 * received after start byte
    169	 */
    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 display
    188 * @spi: spi device
    189 * @reg: offset of the register to be read
    190 * @rx:  output value
    191 */
    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 register
    242 * @spi: struct spi_device *
    243 * @reg: offset of the register to be written
    244 * @value: value to be written
    245 */
    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
    273	spi_message_init(&msg);
    274	tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_REG,
    275					 START_RW_WRITE));
    276	tbuf[1] = set_tx_byte((value & 0xFF00) >> 8);
    277	tbuf[2] = set_tx_byte(value & 0x00FF);
    278
    279	xfer_regvalue.cs_change = 1;
    280	xfer_regvalue.len = 3;
    281	xfer_regvalue.tx_buf = tbuf;
    282	xfer_regvalue.rx_buf = rbuf;
    283	CHECK_FREQ_REG(spi, &xfer_regvalue);
    284
    285	spi_message_add_tail(&xfer_regvalue, &msg);
    286
    287	ret = spi_sync(spi, &msg);
    288	if (ret < 0) {
    289		dev_err(&spi->dev, "Error sending SPI message 0x%x", ret);
    290		return ret;
    291	}
    292	return 0;
    293}
    294
    295#ifdef DEBUG
    296/**
    297 * ili922x_reg_dump - dump all registers
    298 *
    299 * @spi: pointer to an SPI device
    300 */
    301static void ili922x_reg_dump(struct spi_device *spi)
    302{
    303	u8 reg;
    304	u16 rx;
    305
    306	dev_dbg(&spi->dev, "ILI922x configuration registers:\n");
    307	for (reg = REG_START_OSCILLATION;
    308	     reg <= REG_OTP_PROGRAMMING_ID_KEY; reg++) {
    309		ili922x_read(spi, reg, &rx);
    310		dev_dbg(&spi->dev, "reg @ 0x%02X: 0x%04X\n", reg, rx);
    311	}
    312}
    313#else
    314static inline void ili922x_reg_dump(struct spi_device *spi) {}
    315#endif
    316
    317/**
    318 * set_write_to_gram_reg - initialize the display to write the GRAM
    319 * @spi: spi device
    320 */
    321static void set_write_to_gram_reg(struct spi_device *spi)
    322{
    323	struct spi_message msg;
    324	struct spi_transfer xfer;
    325	unsigned char tbuf[CMD_BUFSIZE];
    326
    327	memset(&xfer, 0, sizeof(struct spi_transfer));
    328
    329	spi_message_init(&msg);
    330	xfer.tx_buf = tbuf;
    331	xfer.rx_buf = NULL;
    332	xfer.cs_change = 1;
    333
    334	tbuf[0] = START_BYTE(ili922x_id, START_RS_INDEX, START_RW_WRITE);
    335	tbuf[1] = 0;
    336	tbuf[2] = REG_WRITE_DATA_TO_GRAM;
    337
    338	xfer.bits_per_word = 8;
    339	xfer.len = 3;
    340	spi_message_add_tail(&xfer, &msg);
    341	spi_sync(spi, &msg);
    342}
    343
    344/**
    345 * ili922x_poweron - turn the display on
    346 * @spi: spi device
    347 *
    348 * The sequence to turn on the display is taken from
    349 * the datasheet and/or the example code provided by the
    350 * manufacturer.
    351 */
    352static int ili922x_poweron(struct spi_device *spi)
    353{
    354	int ret;
    355
    356	/* Power on */
    357	ret = ili922x_write(spi, REG_POWER_CONTROL_1, 0x0000);
    358	usleep_range(10000, 10500);
    359	ret += ili922x_write(spi, REG_POWER_CONTROL_2, 0x0000);
    360	ret += ili922x_write(spi, REG_POWER_CONTROL_3, 0x0000);
    361	msleep(40);
    362	ret += ili922x_write(spi, REG_POWER_CONTROL_4, 0x0000);
    363	msleep(40);
    364	/* register 0x56 is not documented in the datasheet */
    365	ret += ili922x_write(spi, 0x56, 0x080F);
    366	ret += ili922x_write(spi, REG_POWER_CONTROL_1, 0x4240);
    367	usleep_range(10000, 10500);
    368	ret += ili922x_write(spi, REG_POWER_CONTROL_2, 0x0000);
    369	ret += ili922x_write(spi, REG_POWER_CONTROL_3, 0x0014);
    370	msleep(40);
    371	ret += ili922x_write(spi, REG_POWER_CONTROL_4, 0x1319);
    372	msleep(40);
    373
    374	return ret;
    375}
    376
    377/**
    378 * ili922x_poweroff - turn the display off
    379 * @spi: spi device
    380 */
    381static int ili922x_poweroff(struct spi_device *spi)
    382{
    383	int ret;
    384
    385	/* Power off */
    386	ret = ili922x_write(spi, REG_POWER_CONTROL_1, 0x0000);
    387	usleep_range(10000, 10500);
    388	ret += ili922x_write(spi, REG_POWER_CONTROL_2, 0x0000);
    389	ret += ili922x_write(spi, REG_POWER_CONTROL_3, 0x0000);
    390	msleep(40);
    391	ret += ili922x_write(spi, REG_POWER_CONTROL_4, 0x0000);
    392	msleep(40);
    393
    394	return ret;
    395}
    396
    397/**
    398 * ili922x_display_init - initialize the display by setting
    399 *			  the configuration registers
    400 * @spi: spi device
    401 */
    402static void ili922x_display_init(struct spi_device *spi)
    403{
    404	ili922x_write(spi, REG_START_OSCILLATION, 1);
    405	usleep_range(10000, 10500);
    406	ili922x_write(spi, REG_DRIVER_OUTPUT_CONTROL, 0x691B);
    407	ili922x_write(spi, REG_LCD_AC_DRIVEING_CONTROL, 0x0700);
    408	ili922x_write(spi, REG_ENTRY_MODE, 0x1030);
    409	ili922x_write(spi, REG_COMPARE_1, 0x0000);
    410	ili922x_write(spi, REG_COMPARE_2, 0x0000);
    411	ili922x_write(spi, REG_DISPLAY_CONTROL_1, 0x0037);
    412	ili922x_write(spi, REG_DISPLAY_CONTROL_2, 0x0202);
    413	ili922x_write(spi, REG_DISPLAY_CONTROL_3, 0x0000);
    414	ili922x_write(spi, REG_FRAME_CYCLE_CONTROL, 0x0000);
    415
    416	/* Set RGB interface */
    417	ili922x_write(spi, REG_EXT_INTF_CONTROL, 0x0110);
    418
    419	ili922x_poweron(spi);
    420
    421	ili922x_write(spi, REG_GAMMA_CONTROL_1, 0x0302);
    422	ili922x_write(spi, REG_GAMMA_CONTROL_2, 0x0407);
    423	ili922x_write(spi, REG_GAMMA_CONTROL_3, 0x0304);
    424	ili922x_write(spi, REG_GAMMA_CONTROL_4, 0x0203);
    425	ili922x_write(spi, REG_GAMMA_CONTROL_5, 0x0706);
    426	ili922x_write(spi, REG_GAMMA_CONTROL_6, 0x0407);
    427	ili922x_write(spi, REG_GAMMA_CONTROL_7, 0x0706);
    428	ili922x_write(spi, REG_GAMMA_CONTROL_8, 0x0000);
    429	ili922x_write(spi, REG_GAMMA_CONTROL_9, 0x0C06);
    430	ili922x_write(spi, REG_GAMMA_CONTROL_10, 0x0F00);
    431	ili922x_write(spi, REG_RAM_ADDRESS_SET, 0x0000);
    432	ili922x_write(spi, REG_GATE_SCAN_CONTROL, 0x0000);
    433	ili922x_write(spi, REG_VERT_SCROLL_CONTROL, 0x0000);
    434	ili922x_write(spi, REG_FIRST_SCREEN_DRIVE_POS, 0xDB00);
    435	ili922x_write(spi, REG_SECOND_SCREEN_DRIVE_POS, 0xDB00);
    436	ili922x_write(spi, REG_RAM_ADDR_POS_H, 0xAF00);
    437	ili922x_write(spi, REG_RAM_ADDR_POS_V, 0xDB00);
    438	ili922x_reg_dump(spi);
    439	set_write_to_gram_reg(spi);
    440}
    441
    442static int ili922x_lcd_power(struct ili922x *lcd, int power)
    443{
    444	int ret = 0;
    445
    446	if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
    447		ret = ili922x_poweron(lcd->spi);
    448	else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
    449		ret = ili922x_poweroff(lcd->spi);
    450
    451	if (!ret)
    452		lcd->power = power;
    453
    454	return ret;
    455}
    456
    457static int ili922x_set_power(struct lcd_device *ld, int power)
    458{
    459	struct ili922x *ili = lcd_get_data(ld);
    460
    461	return ili922x_lcd_power(ili, power);
    462}
    463
    464static int ili922x_get_power(struct lcd_device *ld)
    465{
    466	struct ili922x *ili = lcd_get_data(ld);
    467
    468	return ili->power;
    469}
    470
    471static struct lcd_ops ili922x_ops = {
    472	.get_power = ili922x_get_power,
    473	.set_power = ili922x_set_power,
    474};
    475
    476static int ili922x_probe(struct spi_device *spi)
    477{
    478	struct ili922x *ili;
    479	struct lcd_device *lcd;
    480	int ret;
    481	u16 reg = 0;
    482
    483	ili = devm_kzalloc(&spi->dev, sizeof(*ili), GFP_KERNEL);
    484	if (!ili)
    485		return -ENOMEM;
    486
    487	ili->spi = spi;
    488	spi_set_drvdata(spi, ili);
    489
    490	/* check if the device is connected */
    491	ret = ili922x_read(spi, REG_DRIVER_CODE_READ, &reg);
    492	if (ret || ((reg & ILITEK_DEVICE_ID_MASK) != ILITEK_DEVICE_ID)) {
    493		dev_err(&spi->dev,
    494			"no LCD found: Chip ID 0x%x, ret %d\n",
    495			reg, ret);
    496		return -ENODEV;
    497	}
    498
    499	dev_info(&spi->dev, "ILI%x found, SPI freq %d, mode %d\n",
    500		 reg, spi->max_speed_hz, spi->mode);
    501
    502	ret = ili922x_read_status(spi, &reg);
    503	if (ret) {
    504		dev_err(&spi->dev, "reading RS failed...\n");
    505		return ret;
    506	}
    507
    508	dev_dbg(&spi->dev, "status: 0x%x\n", reg);
    509
    510	ili922x_display_init(spi);
    511
    512	ili->power = FB_BLANK_POWERDOWN;
    513
    514	lcd = devm_lcd_device_register(&spi->dev, "ili922xlcd", &spi->dev, ili,
    515					&ili922x_ops);
    516	if (IS_ERR(lcd)) {
    517		dev_err(&spi->dev, "cannot register LCD\n");
    518		return PTR_ERR(lcd);
    519	}
    520
    521	ili->ld = lcd;
    522	spi_set_drvdata(spi, ili);
    523
    524	ili922x_lcd_power(ili, FB_BLANK_UNBLANK);
    525
    526	return 0;
    527}
    528
    529static void ili922x_remove(struct spi_device *spi)
    530{
    531	ili922x_poweroff(spi);
    532}
    533
    534static struct spi_driver ili922x_driver = {
    535	.driver = {
    536		.name = "ili922x",
    537	},
    538	.probe = ili922x_probe,
    539	.remove = ili922x_remove,
    540};
    541
    542module_spi_driver(ili922x_driver);
    543
    544MODULE_AUTHOR("Stefano Babic <sbabic@denx.de>");
    545MODULE_DESCRIPTION("ILI9221/9222 LCD driver");
    546MODULE_LICENSE("GPL");
    547MODULE_PARM_DESC(ili922x_id, "set controller identifier (default=1)");
    548MODULE_PARM_DESC(tx_invert, "invert bytes before sending");