Linux 6.13-rc6
[linux.git] / drivers / video / backlight / hx8357.c
blob61a57d38700fe610d4ff629bc9b155010e8a6961
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Driver for the Himax HX-8357 LCD Controller
5 * Copyright 2012 Free Electrons
6 */
8 #include <linux/delay.h>
9 #include <linux/gpio/consumer.h>
10 #include <linux/lcd.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/module.h>
13 #include <linux/property.h>
14 #include <linux/spi/spi.h>
16 #define HX8357_NUM_IM_PINS 3
18 #define HX8357_SWRESET 0x01
19 #define HX8357_GET_RED_CHANNEL 0x06
20 #define HX8357_GET_GREEN_CHANNEL 0x07
21 #define HX8357_GET_BLUE_CHANNEL 0x08
22 #define HX8357_GET_POWER_MODE 0x0a
23 #define HX8357_GET_MADCTL 0x0b
24 #define HX8357_GET_PIXEL_FORMAT 0x0c
25 #define HX8357_GET_DISPLAY_MODE 0x0d
26 #define HX8357_GET_SIGNAL_MODE 0x0e
27 #define HX8357_GET_DIAGNOSTIC_RESULT 0x0f
28 #define HX8357_ENTER_SLEEP_MODE 0x10
29 #define HX8357_EXIT_SLEEP_MODE 0x11
30 #define HX8357_ENTER_PARTIAL_MODE 0x12
31 #define HX8357_ENTER_NORMAL_MODE 0x13
32 #define HX8357_EXIT_INVERSION_MODE 0x20
33 #define HX8357_ENTER_INVERSION_MODE 0x21
34 #define HX8357_SET_DISPLAY_OFF 0x28
35 #define HX8357_SET_DISPLAY_ON 0x29
36 #define HX8357_SET_COLUMN_ADDRESS 0x2a
37 #define HX8357_SET_PAGE_ADDRESS 0x2b
38 #define HX8357_WRITE_MEMORY_START 0x2c
39 #define HX8357_READ_MEMORY_START 0x2e
40 #define HX8357_SET_PARTIAL_AREA 0x30
41 #define HX8357_SET_SCROLL_AREA 0x33
42 #define HX8357_SET_TEAR_OFF 0x34
43 #define HX8357_SET_TEAR_ON 0x35
44 #define HX8357_SET_ADDRESS_MODE 0x36
45 #define HX8357_SET_SCROLL_START 0x37
46 #define HX8357_EXIT_IDLE_MODE 0x38
47 #define HX8357_ENTER_IDLE_MODE 0x39
48 #define HX8357_SET_PIXEL_FORMAT 0x3a
49 #define HX8357_SET_PIXEL_FORMAT_DBI_3BIT (0x1)
50 #define HX8357_SET_PIXEL_FORMAT_DBI_16BIT (0x5)
51 #define HX8357_SET_PIXEL_FORMAT_DBI_18BIT (0x6)
52 #define HX8357_SET_PIXEL_FORMAT_DPI_3BIT (0x1 << 4)
53 #define HX8357_SET_PIXEL_FORMAT_DPI_16BIT (0x5 << 4)
54 #define HX8357_SET_PIXEL_FORMAT_DPI_18BIT (0x6 << 4)
55 #define HX8357_WRITE_MEMORY_CONTINUE 0x3c
56 #define HX8357_READ_MEMORY_CONTINUE 0x3e
57 #define HX8357_SET_TEAR_SCAN_LINES 0x44
58 #define HX8357_GET_SCAN_LINES 0x45
59 #define HX8357_READ_DDB_START 0xa1
60 #define HX8357_SET_DISPLAY_MODE 0xb4
61 #define HX8357_SET_DISPLAY_MODE_RGB_THROUGH (0x3)
62 #define HX8357_SET_DISPLAY_MODE_RGB_INTERFACE (1 << 4)
63 #define HX8357_SET_PANEL_DRIVING 0xc0
64 #define HX8357_SET_DISPLAY_FRAME 0xc5
65 #define HX8357_SET_RGB 0xc6
66 #define HX8357_SET_RGB_ENABLE_HIGH (1 << 1)
67 #define HX8357_SET_GAMMA 0xc8
68 #define HX8357_SET_POWER 0xd0
69 #define HX8357_SET_VCOM 0xd1
70 #define HX8357_SET_POWER_NORMAL 0xd2
71 #define HX8357_SET_PANEL_RELATED 0xe9
73 #define HX8369_SET_DISPLAY_BRIGHTNESS 0x51
74 #define HX8369_WRITE_CABC_DISPLAY_VALUE 0x53
75 #define HX8369_WRITE_CABC_BRIGHT_CTRL 0x55
76 #define HX8369_WRITE_CABC_MIN_BRIGHTNESS 0x5e
77 #define HX8369_SET_POWER 0xb1
78 #define HX8369_SET_DISPLAY_MODE 0xb2
79 #define HX8369_SET_DISPLAY_WAVEFORM_CYC 0xb4
80 #define HX8369_SET_VCOM 0xb6
81 #define HX8369_SET_EXTENSION_COMMAND 0xb9
82 #define HX8369_SET_GIP 0xd5
83 #define HX8369_SET_GAMMA_CURVE_RELATED 0xe0
85 struct hx8357_data {
86 struct gpio_descs *im_pins;
87 struct gpio_desc *reset;
88 struct spi_device *spi;
89 int state;
92 static u8 hx8357_seq_power[] = {
93 HX8357_SET_POWER, 0x44, 0x41, 0x06,
96 static u8 hx8357_seq_vcom[] = {
97 HX8357_SET_VCOM, 0x40, 0x10,
100 static u8 hx8357_seq_power_normal[] = {
101 HX8357_SET_POWER_NORMAL, 0x05, 0x12,
104 static u8 hx8357_seq_panel_driving[] = {
105 HX8357_SET_PANEL_DRIVING, 0x14, 0x3b, 0x00, 0x02, 0x11,
108 static u8 hx8357_seq_display_frame[] = {
109 HX8357_SET_DISPLAY_FRAME, 0x0c,
112 static u8 hx8357_seq_panel_related[] = {
113 HX8357_SET_PANEL_RELATED, 0x01,
116 static u8 hx8357_seq_undefined1[] = {
117 0xea, 0x03, 0x00, 0x00,
120 static u8 hx8357_seq_undefined2[] = {
121 0xeb, 0x40, 0x54, 0x26, 0xdb,
124 static u8 hx8357_seq_gamma[] = {
125 HX8357_SET_GAMMA, 0x00, 0x15, 0x00, 0x22, 0x00,
126 0x08, 0x77, 0x26, 0x77, 0x22, 0x04, 0x00,
129 static u8 hx8357_seq_address_mode[] = {
130 HX8357_SET_ADDRESS_MODE, 0xc0,
133 static u8 hx8357_seq_pixel_format[] = {
134 HX8357_SET_PIXEL_FORMAT,
135 HX8357_SET_PIXEL_FORMAT_DPI_18BIT |
136 HX8357_SET_PIXEL_FORMAT_DBI_18BIT,
139 static u8 hx8357_seq_column_address[] = {
140 HX8357_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x01, 0x3f,
143 static u8 hx8357_seq_page_address[] = {
144 HX8357_SET_PAGE_ADDRESS, 0x00, 0x00, 0x01, 0xdf,
147 static u8 hx8357_seq_rgb[] = {
148 HX8357_SET_RGB, 0x02,
151 static u8 hx8357_seq_display_mode[] = {
152 HX8357_SET_DISPLAY_MODE,
153 HX8357_SET_DISPLAY_MODE_RGB_THROUGH |
154 HX8357_SET_DISPLAY_MODE_RGB_INTERFACE,
157 static u8 hx8369_seq_write_CABC_min_brightness[] = {
158 HX8369_WRITE_CABC_MIN_BRIGHTNESS, 0x00,
161 static u8 hx8369_seq_write_CABC_control[] = {
162 HX8369_WRITE_CABC_DISPLAY_VALUE, 0x24,
165 static u8 hx8369_seq_set_display_brightness[] = {
166 HX8369_SET_DISPLAY_BRIGHTNESS, 0xFF,
169 static u8 hx8369_seq_write_CABC_control_setting[] = {
170 HX8369_WRITE_CABC_BRIGHT_CTRL, 0x02,
173 static u8 hx8369_seq_extension_command[] = {
174 HX8369_SET_EXTENSION_COMMAND, 0xff, 0x83, 0x69,
177 static u8 hx8369_seq_display_related[] = {
178 HX8369_SET_DISPLAY_MODE, 0x00, 0x2b, 0x03, 0x03, 0x70, 0x00,
179 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x01,
182 static u8 hx8369_seq_panel_waveform_cycle[] = {
183 HX8369_SET_DISPLAY_WAVEFORM_CYC, 0x0a, 0x1d, 0x80, 0x06, 0x02,
186 static u8 hx8369_seq_set_address_mode[] = {
187 HX8357_SET_ADDRESS_MODE, 0x00,
190 static u8 hx8369_seq_vcom[] = {
191 HX8369_SET_VCOM, 0x3e, 0x3e,
194 static u8 hx8369_seq_gip[] = {
195 HX8369_SET_GIP, 0x00, 0x01, 0x03, 0x25, 0x01, 0x02, 0x28, 0x70,
196 0x11, 0x13, 0x00, 0x00, 0x40, 0x26, 0x51, 0x37, 0x00, 0x00, 0x71,
197 0x35, 0x60, 0x24, 0x07, 0x0f, 0x04, 0x04,
200 static u8 hx8369_seq_power[] = {
201 HX8369_SET_POWER, 0x01, 0x00, 0x34, 0x03, 0x00, 0x11, 0x11, 0x32,
202 0x2f, 0x3f, 0x3f, 0x01, 0x3a, 0x01, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
205 static u8 hx8369_seq_gamma_curve_related[] = {
206 HX8369_SET_GAMMA_CURVE_RELATED, 0x00, 0x0d, 0x19, 0x2f, 0x3b, 0x3d,
207 0x2e, 0x4a, 0x08, 0x0e, 0x0f, 0x14, 0x16, 0x14, 0x14, 0x14, 0x1e,
208 0x00, 0x0d, 0x19, 0x2f, 0x3b, 0x3d, 0x2e, 0x4a, 0x08, 0x0e, 0x0f,
209 0x14, 0x16, 0x14, 0x14, 0x14, 0x1e,
212 static int hx8357_spi_write_then_read(struct lcd_device *lcdev,
213 u8 *txbuf, u16 txlen,
214 u8 *rxbuf, u16 rxlen)
216 struct hx8357_data *lcd = lcd_get_data(lcdev);
217 struct spi_message msg;
218 struct spi_transfer xfer[2];
219 u16 *local_txbuf = NULL;
220 int ret = 0;
222 memset(xfer, 0, sizeof(xfer));
223 spi_message_init(&msg);
225 if (txlen) {
226 int i;
228 local_txbuf = kcalloc(txlen, sizeof(*local_txbuf), GFP_KERNEL);
230 if (!local_txbuf)
231 return -ENOMEM;
233 for (i = 0; i < txlen; i++) {
234 local_txbuf[i] = txbuf[i];
235 if (i > 0)
236 local_txbuf[i] |= 1 << 8;
239 xfer[0].len = 2 * txlen;
240 xfer[0].bits_per_word = 9;
241 xfer[0].tx_buf = local_txbuf;
242 spi_message_add_tail(&xfer[0], &msg);
245 if (rxlen) {
246 xfer[1].len = rxlen;
247 xfer[1].bits_per_word = 8;
248 xfer[1].rx_buf = rxbuf;
249 spi_message_add_tail(&xfer[1], &msg);
252 ret = spi_sync(lcd->spi, &msg);
253 if (ret < 0)
254 dev_err(&lcdev->dev, "Couldn't send SPI data\n");
256 if (txlen)
257 kfree(local_txbuf);
259 return ret;
262 static inline int hx8357_spi_write_array(struct lcd_device *lcdev,
263 u8 *value, u8 len)
265 return hx8357_spi_write_then_read(lcdev, value, len, NULL, 0);
268 static inline int hx8357_spi_write_byte(struct lcd_device *lcdev,
269 u8 value)
271 return hx8357_spi_write_then_read(lcdev, &value, 1, NULL, 0);
274 static int hx8357_enter_standby(struct lcd_device *lcdev)
276 int ret;
278 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_OFF);
279 if (ret < 0)
280 return ret;
282 usleep_range(10000, 12000);
284 ret = hx8357_spi_write_byte(lcdev, HX8357_ENTER_SLEEP_MODE);
285 if (ret < 0)
286 return ret;
289 * The controller needs 120ms when entering in sleep mode before we can
290 * send the command to go off sleep mode
292 msleep(120);
294 return 0;
297 static int hx8357_exit_standby(struct lcd_device *lcdev)
299 int ret;
301 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
302 if (ret < 0)
303 return ret;
306 * The controller needs 120ms when exiting from sleep mode before we
307 * can send the command to enter in sleep mode
309 msleep(120);
311 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
312 if (ret < 0)
313 return ret;
315 return 0;
318 static void hx8357_lcd_reset(struct lcd_device *lcdev)
320 struct hx8357_data *lcd = lcd_get_data(lcdev);
322 /* Reset the screen */
323 gpiod_set_value(lcd->reset, 0);
324 usleep_range(10000, 12000);
325 gpiod_set_value(lcd->reset, 1);
326 usleep_range(10000, 12000);
327 gpiod_set_value(lcd->reset, 0);
329 /* The controller needs 120ms to recover from reset */
330 msleep(120);
333 static int hx8357_lcd_init(struct lcd_device *lcdev)
335 struct hx8357_data *lcd = lcd_get_data(lcdev);
336 int ret;
339 * Set the interface selection pins to SPI mode, with three
340 * wires
342 if (lcd->im_pins) {
343 gpiod_set_value_cansleep(lcd->im_pins->desc[0], 1);
344 gpiod_set_value_cansleep(lcd->im_pins->desc[1], 0);
345 gpiod_set_value_cansleep(lcd->im_pins->desc[2], 1);
348 ret = hx8357_spi_write_array(lcdev, hx8357_seq_power,
349 ARRAY_SIZE(hx8357_seq_power));
350 if (ret < 0)
351 return ret;
353 ret = hx8357_spi_write_array(lcdev, hx8357_seq_vcom,
354 ARRAY_SIZE(hx8357_seq_vcom));
355 if (ret < 0)
356 return ret;
358 ret = hx8357_spi_write_array(lcdev, hx8357_seq_power_normal,
359 ARRAY_SIZE(hx8357_seq_power_normal));
360 if (ret < 0)
361 return ret;
363 ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_driving,
364 ARRAY_SIZE(hx8357_seq_panel_driving));
365 if (ret < 0)
366 return ret;
368 ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_frame,
369 ARRAY_SIZE(hx8357_seq_display_frame));
370 if (ret < 0)
371 return ret;
373 ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_related,
374 ARRAY_SIZE(hx8357_seq_panel_related));
375 if (ret < 0)
376 return ret;
378 ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined1,
379 ARRAY_SIZE(hx8357_seq_undefined1));
380 if (ret < 0)
381 return ret;
383 ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined2,
384 ARRAY_SIZE(hx8357_seq_undefined2));
385 if (ret < 0)
386 return ret;
388 ret = hx8357_spi_write_array(lcdev, hx8357_seq_gamma,
389 ARRAY_SIZE(hx8357_seq_gamma));
390 if (ret < 0)
391 return ret;
393 ret = hx8357_spi_write_array(lcdev, hx8357_seq_address_mode,
394 ARRAY_SIZE(hx8357_seq_address_mode));
395 if (ret < 0)
396 return ret;
398 ret = hx8357_spi_write_array(lcdev, hx8357_seq_pixel_format,
399 ARRAY_SIZE(hx8357_seq_pixel_format));
400 if (ret < 0)
401 return ret;
403 ret = hx8357_spi_write_array(lcdev, hx8357_seq_column_address,
404 ARRAY_SIZE(hx8357_seq_column_address));
405 if (ret < 0)
406 return ret;
408 ret = hx8357_spi_write_array(lcdev, hx8357_seq_page_address,
409 ARRAY_SIZE(hx8357_seq_page_address));
410 if (ret < 0)
411 return ret;
413 ret = hx8357_spi_write_array(lcdev, hx8357_seq_rgb,
414 ARRAY_SIZE(hx8357_seq_rgb));
415 if (ret < 0)
416 return ret;
418 ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_mode,
419 ARRAY_SIZE(hx8357_seq_display_mode));
420 if (ret < 0)
421 return ret;
423 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
424 if (ret < 0)
425 return ret;
428 * The controller needs 120ms to fully recover from exiting sleep mode
430 msleep(120);
432 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
433 if (ret < 0)
434 return ret;
436 usleep_range(5000, 7000);
438 ret = hx8357_spi_write_byte(lcdev, HX8357_WRITE_MEMORY_START);
439 if (ret < 0)
440 return ret;
442 return 0;
445 static int hx8369_lcd_init(struct lcd_device *lcdev)
447 int ret;
449 ret = hx8357_spi_write_array(lcdev, hx8369_seq_extension_command,
450 ARRAY_SIZE(hx8369_seq_extension_command));
451 if (ret < 0)
452 return ret;
453 usleep_range(10000, 12000);
455 ret = hx8357_spi_write_array(lcdev, hx8369_seq_display_related,
456 ARRAY_SIZE(hx8369_seq_display_related));
457 if (ret < 0)
458 return ret;
460 ret = hx8357_spi_write_array(lcdev, hx8369_seq_panel_waveform_cycle,
461 ARRAY_SIZE(hx8369_seq_panel_waveform_cycle));
462 if (ret < 0)
463 return ret;
465 ret = hx8357_spi_write_array(lcdev, hx8369_seq_set_address_mode,
466 ARRAY_SIZE(hx8369_seq_set_address_mode));
467 if (ret < 0)
468 return ret;
470 ret = hx8357_spi_write_array(lcdev, hx8369_seq_vcom,
471 ARRAY_SIZE(hx8369_seq_vcom));
472 if (ret < 0)
473 return ret;
475 ret = hx8357_spi_write_array(lcdev, hx8369_seq_gip,
476 ARRAY_SIZE(hx8369_seq_gip));
477 if (ret < 0)
478 return ret;
480 ret = hx8357_spi_write_array(lcdev, hx8369_seq_power,
481 ARRAY_SIZE(hx8369_seq_power));
482 if (ret < 0)
483 return ret;
485 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
486 if (ret < 0)
487 return ret;
490 * The controller needs 120ms to fully recover from exiting sleep mode
492 msleep(120);
494 ret = hx8357_spi_write_array(lcdev, hx8369_seq_gamma_curve_related,
495 ARRAY_SIZE(hx8369_seq_gamma_curve_related));
496 if (ret < 0)
497 return ret;
499 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
500 if (ret < 0)
501 return ret;
502 usleep_range(1000, 1200);
504 ret = hx8357_spi_write_array(lcdev, hx8369_seq_write_CABC_control,
505 ARRAY_SIZE(hx8369_seq_write_CABC_control));
506 if (ret < 0)
507 return ret;
508 usleep_range(10000, 12000);
510 ret = hx8357_spi_write_array(lcdev,
511 hx8369_seq_write_CABC_control_setting,
512 ARRAY_SIZE(hx8369_seq_write_CABC_control_setting));
513 if (ret < 0)
514 return ret;
516 ret = hx8357_spi_write_array(lcdev,
517 hx8369_seq_write_CABC_min_brightness,
518 ARRAY_SIZE(hx8369_seq_write_CABC_min_brightness));
519 if (ret < 0)
520 return ret;
521 usleep_range(10000, 12000);
523 ret = hx8357_spi_write_array(lcdev, hx8369_seq_set_display_brightness,
524 ARRAY_SIZE(hx8369_seq_set_display_brightness));
525 if (ret < 0)
526 return ret;
528 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
529 if (ret < 0)
530 return ret;
532 return 0;
535 #define POWER_IS_ON(pwr) ((pwr) <= LCD_POWER_REDUCED)
537 static int hx8357_set_power(struct lcd_device *lcdev, int power)
539 struct hx8357_data *lcd = lcd_get_data(lcdev);
540 int ret = 0;
542 if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->state))
543 ret = hx8357_exit_standby(lcdev);
544 else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->state))
545 ret = hx8357_enter_standby(lcdev);
547 if (ret == 0)
548 lcd->state = power;
549 else
550 dev_warn(&lcdev->dev, "failed to set power mode %d\n", power);
552 return ret;
555 static int hx8357_get_power(struct lcd_device *lcdev)
557 struct hx8357_data *lcd = lcd_get_data(lcdev);
559 return lcd->state;
562 static const struct lcd_ops hx8357_ops = {
563 .set_power = hx8357_set_power,
564 .get_power = hx8357_get_power,
567 typedef int (*hx8357_init_fn)(struct lcd_device *);
569 static int hx8357_probe(struct spi_device *spi)
571 struct device *dev = &spi->dev;
572 struct lcd_device *lcdev;
573 struct hx8357_data *lcd;
574 hx8357_init_fn init_fn;
575 int i, ret;
577 lcd = devm_kzalloc(dev, sizeof(*lcd), GFP_KERNEL);
578 if (!lcd)
579 return -ENOMEM;
581 ret = spi_setup(spi);
582 if (ret < 0)
583 return dev_err_probe(dev, ret, "SPI setup failed.\n");
585 lcd->spi = spi;
587 init_fn = device_get_match_data(dev);
588 if (!init_fn)
589 return -EINVAL;
591 lcd->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
592 if (IS_ERR(lcd->reset))
593 return dev_err_probe(dev, PTR_ERR(lcd->reset), "failed to request reset GPIO\n");
594 gpiod_set_consumer_name(lcd->reset, "hx8357-reset");
596 lcd->im_pins = devm_gpiod_get_array_optional(dev, "im", GPIOD_OUT_LOW);
597 if (IS_ERR(lcd->im_pins))
598 return dev_err_probe(dev, PTR_ERR(lcd->im_pins), "failed to request im GPIOs\n");
599 if (lcd->im_pins) {
600 if (lcd->im_pins->ndescs < HX8357_NUM_IM_PINS)
601 return dev_err_probe(dev, -EINVAL, "not enough im GPIOs\n");
603 for (i = 0; i < HX8357_NUM_IM_PINS; i++)
604 gpiod_set_consumer_name(lcd->im_pins->desc[i], "im_pins");
607 lcdev = devm_lcd_device_register(dev, "mxsfb", dev, lcd, &hx8357_ops);
608 if (IS_ERR(lcdev)) {
609 ret = PTR_ERR(lcdev);
610 return ret;
612 spi_set_drvdata(spi, lcdev);
614 hx8357_lcd_reset(lcdev);
616 ret = init_fn(lcdev);
617 if (ret)
618 return dev_err_probe(dev, ret, "Couldn't initialize panel\n");
620 dev_info(dev, "Panel probed\n");
622 return 0;
625 static const struct of_device_id hx8357_dt_ids[] = {
627 .compatible = "himax,hx8357",
628 .data = hx8357_lcd_init,
631 .compatible = "himax,hx8369",
632 .data = hx8369_lcd_init,
636 MODULE_DEVICE_TABLE(of, hx8357_dt_ids);
638 static struct spi_driver hx8357_driver = {
639 .probe = hx8357_probe,
640 .driver = {
641 .name = "hx8357",
642 .of_match_table = hx8357_dt_ids,
646 module_spi_driver(hx8357_driver);
648 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
649 MODULE_DESCRIPTION("Himax HX-8357 LCD Driver");
650 MODULE_LICENSE("GPL");