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 | */ |
129 | static int ili922x_id = 1; |
130 | module_param(ili922x_id, int, 0); |
131 | |
132 | static int tx_invert; |
133 | module_param(tx_invert, int, 0); |
134 | |
135 | /* |
136 | * driver's private structure |
137 | */ |
138 | struct 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 | */ |
149 | static 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(m: &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(t: &xfer, m: &msg); |
176 | ret = spi_sync(spi, message: &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 | */ |
192 | static 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(m: &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(t: &xfer_regindex, m: &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(t: &xfer_regvalue, m: &msg); |
230 | ret = spi_sync(spi, message: &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 | */ |
246 | static 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(m: &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(t: &xfer_regindex, m: &msg); |
270 | |
271 | ret = spi_sync(spi, message: &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(m: &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(t: &xfer_regvalue, m: &msg); |
290 | |
291 | ret = spi_sync(spi, message: &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 DEBUG |
300 | /** |
301 | * ili922x_reg_dump - dump all registers |
302 | * |
303 | * @spi: pointer to an SPI device |
304 | */ |
305 | static 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 | #else |
318 | static inline void ili922x_reg_dump(struct spi_device *spi) {} |
319 | #endif |
320 | |
321 | /** |
322 | * set_write_to_gram_reg - initialize the display to write the GRAM |
323 | * @spi: spi device |
324 | */ |
325 | static 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(m: &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(t: &xfer, m: &msg); |
345 | spi_sync(spi, message: &msg); |
346 | } |
347 | |
348 | /** |
349 | * ili922x_poweron - turn the display on |
350 | * @spi: spi device |
351 | * |
352 | * The sequence to turn on the display is taken from |
353 | * the datasheet and/or the example code provided by the |
354 | * manufacturer. |
355 | */ |
356 | static int ili922x_poweron(struct spi_device *spi) |
357 | { |
358 | int ret; |
359 | |
360 | /* Power on */ |
361 | ret = ili922x_write(spi, REG_POWER_CONTROL_1, value: 0x0000); |
362 | usleep_range(min: 10000, max: 10500); |
363 | ret += ili922x_write(spi, REG_POWER_CONTROL_2, value: 0x0000); |
364 | ret += ili922x_write(spi, REG_POWER_CONTROL_3, value: 0x0000); |
365 | msleep(msecs: 40); |
366 | ret += ili922x_write(spi, REG_POWER_CONTROL_4, value: 0x0000); |
367 | msleep(msecs: 40); |
368 | /* register 0x56 is not documented in the datasheet */ |
369 | ret += ili922x_write(spi, reg: 0x56, value: 0x080F); |
370 | ret += ili922x_write(spi, REG_POWER_CONTROL_1, value: 0x4240); |
371 | usleep_range(min: 10000, max: 10500); |
372 | ret += ili922x_write(spi, REG_POWER_CONTROL_2, value: 0x0000); |
373 | ret += ili922x_write(spi, REG_POWER_CONTROL_3, value: 0x0014); |
374 | msleep(msecs: 40); |
375 | ret += ili922x_write(spi, REG_POWER_CONTROL_4, value: 0x1319); |
376 | msleep(msecs: 40); |
377 | |
378 | return ret; |
379 | } |
380 | |
381 | /** |
382 | * ili922x_poweroff - turn the display off |
383 | * @spi: spi device |
384 | */ |
385 | static int ili922x_poweroff(struct spi_device *spi) |
386 | { |
387 | int ret; |
388 | |
389 | /* Power off */ |
390 | ret = ili922x_write(spi, REG_POWER_CONTROL_1, value: 0x0000); |
391 | usleep_range(min: 10000, max: 10500); |
392 | ret += ili922x_write(spi, REG_POWER_CONTROL_2, value: 0x0000); |
393 | ret += ili922x_write(spi, REG_POWER_CONTROL_3, value: 0x0000); |
394 | msleep(msecs: 40); |
395 | ret += ili922x_write(spi, REG_POWER_CONTROL_4, value: 0x0000); |
396 | msleep(msecs: 40); |
397 | |
398 | return ret; |
399 | } |
400 | |
401 | /** |
402 | * ili922x_display_init - initialize the display by setting |
403 | * the configuration registers |
404 | * @spi: spi device |
405 | */ |
406 | static void ili922x_display_init(struct spi_device *spi) |
407 | { |
408 | ili922x_write(spi, REG_START_OSCILLATION, value: 1); |
409 | usleep_range(min: 10000, max: 10500); |
410 | ili922x_write(spi, REG_DRIVER_OUTPUT_CONTROL, value: 0x691B); |
411 | ili922x_write(spi, REG_LCD_AC_DRIVEING_CONTROL, value: 0x0700); |
412 | ili922x_write(spi, REG_ENTRY_MODE, value: 0x1030); |
413 | ili922x_write(spi, REG_COMPARE_1, value: 0x0000); |
414 | ili922x_write(spi, REG_COMPARE_2, value: 0x0000); |
415 | ili922x_write(spi, REG_DISPLAY_CONTROL_1, value: 0x0037); |
416 | ili922x_write(spi, REG_DISPLAY_CONTROL_2, value: 0x0202); |
417 | ili922x_write(spi, REG_DISPLAY_CONTROL_3, value: 0x0000); |
418 | ili922x_write(spi, REG_FRAME_CYCLE_CONTROL, value: 0x0000); |
419 | |
420 | /* Set RGB interface */ |
421 | ili922x_write(spi, REG_EXT_INTF_CONTROL, value: 0x0110); |
422 | |
423 | ili922x_poweron(spi); |
424 | |
425 | ili922x_write(spi, REG_GAMMA_CONTROL_1, value: 0x0302); |
426 | ili922x_write(spi, REG_GAMMA_CONTROL_2, value: 0x0407); |
427 | ili922x_write(spi, REG_GAMMA_CONTROL_3, value: 0x0304); |
428 | ili922x_write(spi, REG_GAMMA_CONTROL_4, value: 0x0203); |
429 | ili922x_write(spi, REG_GAMMA_CONTROL_5, value: 0x0706); |
430 | ili922x_write(spi, REG_GAMMA_CONTROL_6, value: 0x0407); |
431 | ili922x_write(spi, REG_GAMMA_CONTROL_7, value: 0x0706); |
432 | ili922x_write(spi, REG_GAMMA_CONTROL_8, value: 0x0000); |
433 | ili922x_write(spi, REG_GAMMA_CONTROL_9, value: 0x0C06); |
434 | ili922x_write(spi, REG_GAMMA_CONTROL_10, value: 0x0F00); |
435 | ili922x_write(spi, REG_RAM_ADDRESS_SET, value: 0x0000); |
436 | ili922x_write(spi, REG_GATE_SCAN_CONTROL, value: 0x0000); |
437 | ili922x_write(spi, REG_VERT_SCROLL_CONTROL, value: 0x0000); |
438 | ili922x_write(spi, REG_FIRST_SCREEN_DRIVE_POS, value: 0xDB00); |
439 | ili922x_write(spi, REG_SECOND_SCREEN_DRIVE_POS, value: 0xDB00); |
440 | ili922x_write(spi, REG_RAM_ADDR_POS_H, value: 0xAF00); |
441 | ili922x_write(spi, REG_RAM_ADDR_POS_V, value: 0xDB00); |
442 | ili922x_reg_dump(spi); |
443 | set_write_to_gram_reg(spi); |
444 | } |
445 | |
446 | static 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(spi: lcd->spi); |
452 | else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power)) |
453 | ret = ili922x_poweroff(spi: lcd->spi); |
454 | |
455 | if (!ret) |
456 | lcd->power = power; |
457 | |
458 | return ret; |
459 | } |
460 | |
461 | static int ili922x_set_power(struct lcd_device *ld, int power) |
462 | { |
463 | struct ili922x *ili = lcd_get_data(ld_dev: ld); |
464 | |
465 | return ili922x_lcd_power(lcd: ili, power); |
466 | } |
467 | |
468 | static int ili922x_get_power(struct lcd_device *ld) |
469 | { |
470 | struct ili922x *ili = lcd_get_data(ld_dev: ld); |
471 | |
472 | return ili->power; |
473 | } |
474 | |
475 | static struct lcd_ops ili922x_ops = { |
476 | .get_power = ili922x_get_power, |
477 | .set_power = ili922x_set_power, |
478 | }; |
479 | |
480 | static 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(dev: &spi->dev, size: sizeof(*ili), GFP_KERNEL); |
488 | if (!ili) |
489 | return -ENOMEM; |
490 | |
491 | ili->spi = spi; |
492 | spi_set_drvdata(spi, data: ili); |
493 | |
494 | /* check if the device is connected */ |
495 | ret = ili922x_read(spi, REG_DRIVER_CODE_READ, rx: ®); |
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, rs: ®); |
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(dev: &spi->dev, name: "ili922xlcd" , parent: &spi->dev, devdata: ili, |
519 | ops: &ili922x_ops); |
520 | if (IS_ERR(ptr: lcd)) { |
521 | dev_err(&spi->dev, "cannot register LCD\n" ); |
522 | return PTR_ERR(ptr: lcd); |
523 | } |
524 | |
525 | ili->ld = lcd; |
526 | spi_set_drvdata(spi, data: ili); |
527 | |
528 | ili922x_lcd_power(lcd: ili, power: FB_BLANK_UNBLANK); |
529 | |
530 | return 0; |
531 | } |
532 | |
533 | static void ili922x_remove(struct spi_device *spi) |
534 | { |
535 | ili922x_poweroff(spi); |
536 | } |
537 | |
538 | static struct spi_driver ili922x_driver = { |
539 | .driver = { |
540 | .name = "ili922x" , |
541 | }, |
542 | .probe = ili922x_probe, |
543 | .remove = ili922x_remove, |
544 | }; |
545 | |
546 | module_spi_driver(ili922x_driver); |
547 | |
548 | MODULE_AUTHOR("Stefano Babic <sbabic@denx.de>" ); |
549 | MODULE_DESCRIPTION("ILI9221/9222 LCD driver" ); |
550 | MODULE_LICENSE("GPL" ); |
551 | MODULE_PARM_DESC(ili922x_id, "set controller identifier (default=1)" ); |
552 | MODULE_PARM_DESC(tx_invert, "invert bytes before sending" ); |
553 | |