scsi: use per-cpu buffer for formatting scsi_print_result()
[linux/fpc-iii.git] / drivers / video / backlight / hx8357.c
blob23f50b92a930b25f80986a529f2bad3fb5d6c877
1 /*
2 * Driver for the Himax HX-8357 LCD Controller
4 * Copyright 2012 Free Electrons
6 * Licensed under the GPLv2 or later.
7 */
9 #include <linux/delay.h>
10 #include <linux/lcd.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/of_device.h>
14 #include <linux/of_gpio.h>
15 #include <linux/spi/spi.h>
17 #define HX8357_NUM_IM_PINS 3
19 #define HX8357_SWRESET 0x01
20 #define HX8357_GET_RED_CHANNEL 0x06
21 #define HX8357_GET_GREEN_CHANNEL 0x07
22 #define HX8357_GET_BLUE_CHANNEL 0x08
23 #define HX8357_GET_POWER_MODE 0x0a
24 #define HX8357_GET_MADCTL 0x0b
25 #define HX8357_GET_PIXEL_FORMAT 0x0c
26 #define HX8357_GET_DISPLAY_MODE 0x0d
27 #define HX8357_GET_SIGNAL_MODE 0x0e
28 #define HX8357_GET_DIAGNOSTIC_RESULT 0x0f
29 #define HX8357_ENTER_SLEEP_MODE 0x10
30 #define HX8357_EXIT_SLEEP_MODE 0x11
31 #define HX8357_ENTER_PARTIAL_MODE 0x12
32 #define HX8357_ENTER_NORMAL_MODE 0x13
33 #define HX8357_EXIT_INVERSION_MODE 0x20
34 #define HX8357_ENTER_INVERSION_MODE 0x21
35 #define HX8357_SET_DISPLAY_OFF 0x28
36 #define HX8357_SET_DISPLAY_ON 0x29
37 #define HX8357_SET_COLUMN_ADDRESS 0x2a
38 #define HX8357_SET_PAGE_ADDRESS 0x2b
39 #define HX8357_WRITE_MEMORY_START 0x2c
40 #define HX8357_READ_MEMORY_START 0x2e
41 #define HX8357_SET_PARTIAL_AREA 0x30
42 #define HX8357_SET_SCROLL_AREA 0x33
43 #define HX8357_SET_TEAR_OFF 0x34
44 #define HX8357_SET_TEAR_ON 0x35
45 #define HX8357_SET_ADDRESS_MODE 0x36
46 #define HX8357_SET_SCROLL_START 0x37
47 #define HX8357_EXIT_IDLE_MODE 0x38
48 #define HX8357_ENTER_IDLE_MODE 0x39
49 #define HX8357_SET_PIXEL_FORMAT 0x3a
50 #define HX8357_SET_PIXEL_FORMAT_DBI_3BIT (0x1)
51 #define HX8357_SET_PIXEL_FORMAT_DBI_16BIT (0x5)
52 #define HX8357_SET_PIXEL_FORMAT_DBI_18BIT (0x6)
53 #define HX8357_SET_PIXEL_FORMAT_DPI_3BIT (0x1 << 4)
54 #define HX8357_SET_PIXEL_FORMAT_DPI_16BIT (0x5 << 4)
55 #define HX8357_SET_PIXEL_FORMAT_DPI_18BIT (0x6 << 4)
56 #define HX8357_WRITE_MEMORY_CONTINUE 0x3c
57 #define HX8357_READ_MEMORY_CONTINUE 0x3e
58 #define HX8357_SET_TEAR_SCAN_LINES 0x44
59 #define HX8357_GET_SCAN_LINES 0x45
60 #define HX8357_READ_DDB_START 0xa1
61 #define HX8357_SET_DISPLAY_MODE 0xb4
62 #define HX8357_SET_DISPLAY_MODE_RGB_THROUGH (0x3)
63 #define HX8357_SET_DISPLAY_MODE_RGB_INTERFACE (1 << 4)
64 #define HX8357_SET_PANEL_DRIVING 0xc0
65 #define HX8357_SET_DISPLAY_FRAME 0xc5
66 #define HX8357_SET_RGB 0xc6
67 #define HX8357_SET_RGB_ENABLE_HIGH (1 << 1)
68 #define HX8357_SET_GAMMA 0xc8
69 #define HX8357_SET_POWER 0xd0
70 #define HX8357_SET_VCOM 0xd1
71 #define HX8357_SET_POWER_NORMAL 0xd2
72 #define HX8357_SET_PANEL_RELATED 0xe9
74 #define HX8369_SET_DISPLAY_BRIGHTNESS 0x51
75 #define HX8369_WRITE_CABC_DISPLAY_VALUE 0x53
76 #define HX8369_WRITE_CABC_BRIGHT_CTRL 0x55
77 #define HX8369_WRITE_CABC_MIN_BRIGHTNESS 0x5e
78 #define HX8369_SET_POWER 0xb1
79 #define HX8369_SET_DISPLAY_MODE 0xb2
80 #define HX8369_SET_DISPLAY_WAVEFORM_CYC 0xb4
81 #define HX8369_SET_VCOM 0xb6
82 #define HX8369_SET_EXTENSION_COMMAND 0xb9
83 #define HX8369_SET_GIP 0xd5
84 #define HX8369_SET_GAMMA_CURVE_RELATED 0xe0
86 struct hx8357_data {
87 unsigned im_pins[HX8357_NUM_IM_PINS];
88 unsigned reset;
89 struct spi_device *spi;
90 int state;
91 bool use_im_pins;
94 static u8 hx8357_seq_power[] = {
95 HX8357_SET_POWER, 0x44, 0x41, 0x06,
98 static u8 hx8357_seq_vcom[] = {
99 HX8357_SET_VCOM, 0x40, 0x10,
102 static u8 hx8357_seq_power_normal[] = {
103 HX8357_SET_POWER_NORMAL, 0x05, 0x12,
106 static u8 hx8357_seq_panel_driving[] = {
107 HX8357_SET_PANEL_DRIVING, 0x14, 0x3b, 0x00, 0x02, 0x11,
110 static u8 hx8357_seq_display_frame[] = {
111 HX8357_SET_DISPLAY_FRAME, 0x0c,
114 static u8 hx8357_seq_panel_related[] = {
115 HX8357_SET_PANEL_RELATED, 0x01,
118 static u8 hx8357_seq_undefined1[] = {
119 0xea, 0x03, 0x00, 0x00,
122 static u8 hx8357_seq_undefined2[] = {
123 0xeb, 0x40, 0x54, 0x26, 0xdb,
126 static u8 hx8357_seq_gamma[] = {
127 HX8357_SET_GAMMA, 0x00, 0x15, 0x00, 0x22, 0x00,
128 0x08, 0x77, 0x26, 0x77, 0x22, 0x04, 0x00,
131 static u8 hx8357_seq_address_mode[] = {
132 HX8357_SET_ADDRESS_MODE, 0xc0,
135 static u8 hx8357_seq_pixel_format[] = {
136 HX8357_SET_PIXEL_FORMAT,
137 HX8357_SET_PIXEL_FORMAT_DPI_18BIT |
138 HX8357_SET_PIXEL_FORMAT_DBI_18BIT,
141 static u8 hx8357_seq_column_address[] = {
142 HX8357_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x01, 0x3f,
145 static u8 hx8357_seq_page_address[] = {
146 HX8357_SET_PAGE_ADDRESS, 0x00, 0x00, 0x01, 0xdf,
149 static u8 hx8357_seq_rgb[] = {
150 HX8357_SET_RGB, 0x02,
153 static u8 hx8357_seq_display_mode[] = {
154 HX8357_SET_DISPLAY_MODE,
155 HX8357_SET_DISPLAY_MODE_RGB_THROUGH |
156 HX8357_SET_DISPLAY_MODE_RGB_INTERFACE,
159 static u8 hx8369_seq_write_CABC_min_brightness[] = {
160 HX8369_WRITE_CABC_MIN_BRIGHTNESS, 0x00,
163 static u8 hx8369_seq_write_CABC_control[] = {
164 HX8369_WRITE_CABC_DISPLAY_VALUE, 0x24,
167 static u8 hx8369_seq_set_display_brightness[] = {
168 HX8369_SET_DISPLAY_BRIGHTNESS, 0xFF,
171 static u8 hx8369_seq_write_CABC_control_setting[] = {
172 HX8369_WRITE_CABC_BRIGHT_CTRL, 0x02,
175 static u8 hx8369_seq_extension_command[] = {
176 HX8369_SET_EXTENSION_COMMAND, 0xff, 0x83, 0x69,
179 static u8 hx8369_seq_display_related[] = {
180 HX8369_SET_DISPLAY_MODE, 0x00, 0x2b, 0x03, 0x03, 0x70, 0x00,
181 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x01,
184 static u8 hx8369_seq_panel_waveform_cycle[] = {
185 HX8369_SET_DISPLAY_WAVEFORM_CYC, 0x0a, 0x1d, 0x80, 0x06, 0x02,
188 static u8 hx8369_seq_set_address_mode[] = {
189 HX8357_SET_ADDRESS_MODE, 0x00,
192 static u8 hx8369_seq_vcom[] = {
193 HX8369_SET_VCOM, 0x3e, 0x3e,
196 static u8 hx8369_seq_gip[] = {
197 HX8369_SET_GIP, 0x00, 0x01, 0x03, 0x25, 0x01, 0x02, 0x28, 0x70,
198 0x11, 0x13, 0x00, 0x00, 0x40, 0x26, 0x51, 0x37, 0x00, 0x00, 0x71,
199 0x35, 0x60, 0x24, 0x07, 0x0f, 0x04, 0x04,
202 static u8 hx8369_seq_power[] = {
203 HX8369_SET_POWER, 0x01, 0x00, 0x34, 0x03, 0x00, 0x11, 0x11, 0x32,
204 0x2f, 0x3f, 0x3f, 0x01, 0x3a, 0x01, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
207 static u8 hx8369_seq_gamma_curve_related[] = {
208 HX8369_SET_GAMMA_CURVE_RELATED, 0x00, 0x0d, 0x19, 0x2f, 0x3b, 0x3d,
209 0x2e, 0x4a, 0x08, 0x0e, 0x0f, 0x14, 0x16, 0x14, 0x14, 0x14, 0x1e,
210 0x00, 0x0d, 0x19, 0x2f, 0x3b, 0x3d, 0x2e, 0x4a, 0x08, 0x0e, 0x0f,
211 0x14, 0x16, 0x14, 0x14, 0x14, 0x1e,
214 static int hx8357_spi_write_then_read(struct lcd_device *lcdev,
215 u8 *txbuf, u16 txlen,
216 u8 *rxbuf, u16 rxlen)
218 struct hx8357_data *lcd = lcd_get_data(lcdev);
219 struct spi_message msg;
220 struct spi_transfer xfer[2];
221 u16 *local_txbuf = NULL;
222 int ret = 0;
224 memset(xfer, 0, sizeof(xfer));
225 spi_message_init(&msg);
227 if (txlen) {
228 int i;
230 local_txbuf = kcalloc(txlen, sizeof(*local_txbuf), GFP_KERNEL);
232 if (!local_txbuf)
233 return -ENOMEM;
235 for (i = 0; i < txlen; i++) {
236 local_txbuf[i] = txbuf[i];
237 if (i > 0)
238 local_txbuf[i] |= 1 << 8;
241 xfer[0].len = 2 * txlen;
242 xfer[0].bits_per_word = 9;
243 xfer[0].tx_buf = local_txbuf;
244 spi_message_add_tail(&xfer[0], &msg);
247 if (rxlen) {
248 xfer[1].len = rxlen;
249 xfer[1].bits_per_word = 8;
250 xfer[1].rx_buf = rxbuf;
251 spi_message_add_tail(&xfer[1], &msg);
254 ret = spi_sync(lcd->spi, &msg);
255 if (ret < 0)
256 dev_err(&lcdev->dev, "Couldn't send SPI data\n");
258 if (txlen)
259 kfree(local_txbuf);
261 return ret;
264 static inline int hx8357_spi_write_array(struct lcd_device *lcdev,
265 u8 *value, u8 len)
267 return hx8357_spi_write_then_read(lcdev, value, len, NULL, 0);
270 static inline int hx8357_spi_write_byte(struct lcd_device *lcdev,
271 u8 value)
273 return hx8357_spi_write_then_read(lcdev, &value, 1, NULL, 0);
276 static int hx8357_enter_standby(struct lcd_device *lcdev)
278 int ret;
280 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_OFF);
281 if (ret < 0)
282 return ret;
284 usleep_range(10000, 12000);
286 ret = hx8357_spi_write_byte(lcdev, HX8357_ENTER_SLEEP_MODE);
287 if (ret < 0)
288 return ret;
291 * The controller needs 120ms when entering in sleep mode before we can
292 * send the command to go off sleep mode
294 msleep(120);
296 return 0;
299 static int hx8357_exit_standby(struct lcd_device *lcdev)
301 int ret;
303 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
304 if (ret < 0)
305 return ret;
308 * The controller needs 120ms when exiting from sleep mode before we
309 * can send the command to enter in sleep mode
311 msleep(120);
313 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
314 if (ret < 0)
315 return ret;
317 return 0;
320 static void hx8357_lcd_reset(struct lcd_device *lcdev)
322 struct hx8357_data *lcd = lcd_get_data(lcdev);
324 /* Reset the screen */
325 gpio_set_value(lcd->reset, 1);
326 usleep_range(10000, 12000);
327 gpio_set_value(lcd->reset, 0);
328 usleep_range(10000, 12000);
329 gpio_set_value(lcd->reset, 1);
331 /* The controller needs 120ms to recover from reset */
332 msleep(120);
335 static int hx8357_lcd_init(struct lcd_device *lcdev)
337 struct hx8357_data *lcd = lcd_get_data(lcdev);
338 int ret;
341 * Set the interface selection pins to SPI mode, with three
342 * wires
344 if (lcd->use_im_pins) {
345 gpio_set_value_cansleep(lcd->im_pins[0], 1);
346 gpio_set_value_cansleep(lcd->im_pins[1], 0);
347 gpio_set_value_cansleep(lcd->im_pins[2], 1);
350 ret = hx8357_spi_write_array(lcdev, hx8357_seq_power,
351 ARRAY_SIZE(hx8357_seq_power));
352 if (ret < 0)
353 return ret;
355 ret = hx8357_spi_write_array(lcdev, hx8357_seq_vcom,
356 ARRAY_SIZE(hx8357_seq_vcom));
357 if (ret < 0)
358 return ret;
360 ret = hx8357_spi_write_array(lcdev, hx8357_seq_power_normal,
361 ARRAY_SIZE(hx8357_seq_power_normal));
362 if (ret < 0)
363 return ret;
365 ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_driving,
366 ARRAY_SIZE(hx8357_seq_panel_driving));
367 if (ret < 0)
368 return ret;
370 ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_frame,
371 ARRAY_SIZE(hx8357_seq_display_frame));
372 if (ret < 0)
373 return ret;
375 ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_related,
376 ARRAY_SIZE(hx8357_seq_panel_related));
377 if (ret < 0)
378 return ret;
380 ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined1,
381 ARRAY_SIZE(hx8357_seq_undefined1));
382 if (ret < 0)
383 return ret;
385 ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined2,
386 ARRAY_SIZE(hx8357_seq_undefined2));
387 if (ret < 0)
388 return ret;
390 ret = hx8357_spi_write_array(lcdev, hx8357_seq_gamma,
391 ARRAY_SIZE(hx8357_seq_gamma));
392 if (ret < 0)
393 return ret;
395 ret = hx8357_spi_write_array(lcdev, hx8357_seq_address_mode,
396 ARRAY_SIZE(hx8357_seq_address_mode));
397 if (ret < 0)
398 return ret;
400 ret = hx8357_spi_write_array(lcdev, hx8357_seq_pixel_format,
401 ARRAY_SIZE(hx8357_seq_pixel_format));
402 if (ret < 0)
403 return ret;
405 ret = hx8357_spi_write_array(lcdev, hx8357_seq_column_address,
406 ARRAY_SIZE(hx8357_seq_column_address));
407 if (ret < 0)
408 return ret;
410 ret = hx8357_spi_write_array(lcdev, hx8357_seq_page_address,
411 ARRAY_SIZE(hx8357_seq_page_address));
412 if (ret < 0)
413 return ret;
415 ret = hx8357_spi_write_array(lcdev, hx8357_seq_rgb,
416 ARRAY_SIZE(hx8357_seq_rgb));
417 if (ret < 0)
418 return ret;
420 ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_mode,
421 ARRAY_SIZE(hx8357_seq_display_mode));
422 if (ret < 0)
423 return ret;
425 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
426 if (ret < 0)
427 return ret;
430 * The controller needs 120ms to fully recover from exiting sleep mode
432 msleep(120);
434 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
435 if (ret < 0)
436 return ret;
438 usleep_range(5000, 7000);
440 ret = hx8357_spi_write_byte(lcdev, HX8357_WRITE_MEMORY_START);
441 if (ret < 0)
442 return ret;
444 return 0;
447 static int hx8369_lcd_init(struct lcd_device *lcdev)
449 int ret;
451 ret = hx8357_spi_write_array(lcdev, hx8369_seq_extension_command,
452 ARRAY_SIZE(hx8369_seq_extension_command));
453 if (ret < 0)
454 return ret;
455 usleep_range(10000, 12000);
457 ret = hx8357_spi_write_array(lcdev, hx8369_seq_display_related,
458 ARRAY_SIZE(hx8369_seq_display_related));
459 if (ret < 0)
460 return ret;
462 ret = hx8357_spi_write_array(lcdev, hx8369_seq_panel_waveform_cycle,
463 ARRAY_SIZE(hx8369_seq_panel_waveform_cycle));
464 if (ret < 0)
465 return ret;
467 ret = hx8357_spi_write_array(lcdev, hx8369_seq_set_address_mode,
468 ARRAY_SIZE(hx8369_seq_set_address_mode));
469 if (ret < 0)
470 return ret;
472 ret = hx8357_spi_write_array(lcdev, hx8369_seq_vcom,
473 ARRAY_SIZE(hx8369_seq_vcom));
474 if (ret < 0)
475 return ret;
477 ret = hx8357_spi_write_array(lcdev, hx8369_seq_gip,
478 ARRAY_SIZE(hx8369_seq_gip));
479 if (ret < 0)
480 return ret;
482 ret = hx8357_spi_write_array(lcdev, hx8369_seq_power,
483 ARRAY_SIZE(hx8369_seq_power));
484 if (ret < 0)
485 return ret;
487 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
488 if (ret < 0)
489 return ret;
492 * The controller needs 120ms to fully recover from exiting sleep mode
494 msleep(120);
496 ret = hx8357_spi_write_array(lcdev, hx8369_seq_gamma_curve_related,
497 ARRAY_SIZE(hx8369_seq_gamma_curve_related));
498 if (ret < 0)
499 return ret;
501 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
502 if (ret < 0)
503 return ret;
504 usleep_range(1000, 1200);
506 ret = hx8357_spi_write_array(lcdev, hx8369_seq_write_CABC_control,
507 ARRAY_SIZE(hx8369_seq_write_CABC_control));
508 if (ret < 0)
509 return ret;
510 usleep_range(10000, 12000);
512 ret = hx8357_spi_write_array(lcdev,
513 hx8369_seq_write_CABC_control_setting,
514 ARRAY_SIZE(hx8369_seq_write_CABC_control_setting));
515 if (ret < 0)
516 return ret;
518 ret = hx8357_spi_write_array(lcdev,
519 hx8369_seq_write_CABC_min_brightness,
520 ARRAY_SIZE(hx8369_seq_write_CABC_min_brightness));
521 if (ret < 0)
522 return ret;
523 usleep_range(10000, 12000);
525 ret = hx8357_spi_write_array(lcdev, hx8369_seq_set_display_brightness,
526 ARRAY_SIZE(hx8369_seq_set_display_brightness));
527 if (ret < 0)
528 return ret;
530 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
531 if (ret < 0)
532 return ret;
534 return 0;
537 #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
539 static int hx8357_set_power(struct lcd_device *lcdev, int power)
541 struct hx8357_data *lcd = lcd_get_data(lcdev);
542 int ret = 0;
544 if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->state))
545 ret = hx8357_exit_standby(lcdev);
546 else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->state))
547 ret = hx8357_enter_standby(lcdev);
549 if (ret == 0)
550 lcd->state = power;
551 else
552 dev_warn(&lcdev->dev, "failed to set power mode %d\n", power);
554 return ret;
557 static int hx8357_get_power(struct lcd_device *lcdev)
559 struct hx8357_data *lcd = lcd_get_data(lcdev);
561 return lcd->state;
564 static struct lcd_ops hx8357_ops = {
565 .set_power = hx8357_set_power,
566 .get_power = hx8357_get_power,
569 static const struct of_device_id hx8357_dt_ids[] = {
571 .compatible = "himax,hx8357",
572 .data = hx8357_lcd_init,
575 .compatible = "himax,hx8369",
576 .data = hx8369_lcd_init,
580 MODULE_DEVICE_TABLE(of, hx8357_dt_ids);
582 static int hx8357_probe(struct spi_device *spi)
584 struct lcd_device *lcdev;
585 struct hx8357_data *lcd;
586 const struct of_device_id *match;
587 int i, ret;
589 lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL);
590 if (!lcd)
591 return -ENOMEM;
593 ret = spi_setup(spi);
594 if (ret < 0) {
595 dev_err(&spi->dev, "SPI setup failed.\n");
596 return ret;
599 lcd->spi = spi;
601 match = of_match_device(hx8357_dt_ids, &spi->dev);
602 if (!match || !match->data)
603 return -EINVAL;
605 lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0);
606 if (!gpio_is_valid(lcd->reset)) {
607 dev_err(&spi->dev, "Missing dt property: gpios-reset\n");
608 return -EINVAL;
611 ret = devm_gpio_request_one(&spi->dev, lcd->reset,
612 GPIOF_OUT_INIT_HIGH,
613 "hx8357-reset");
614 if (ret) {
615 dev_err(&spi->dev,
616 "failed to request gpio %d: %d\n",
617 lcd->reset, ret);
618 return -EINVAL;
621 if (of_find_property(spi->dev.of_node, "im-gpios", NULL)) {
622 lcd->use_im_pins = 1;
624 for (i = 0; i < HX8357_NUM_IM_PINS; i++) {
625 lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node,
626 "im-gpios", i);
627 if (lcd->im_pins[i] == -EPROBE_DEFER) {
628 dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n");
629 return -EPROBE_DEFER;
631 if (!gpio_is_valid(lcd->im_pins[i])) {
632 dev_err(&spi->dev, "Missing dt property: im-gpios\n");
633 return -EINVAL;
636 ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i],
637 GPIOF_OUT_INIT_LOW,
638 "im_pins");
639 if (ret) {
640 dev_err(&spi->dev, "failed to request gpio %d: %d\n",
641 lcd->im_pins[i], ret);
642 return -EINVAL;
645 } else {
646 lcd->use_im_pins = 0;
649 lcdev = devm_lcd_device_register(&spi->dev, "mxsfb", &spi->dev, lcd,
650 &hx8357_ops);
651 if (IS_ERR(lcdev)) {
652 ret = PTR_ERR(lcdev);
653 return ret;
655 spi_set_drvdata(spi, lcdev);
657 hx8357_lcd_reset(lcdev);
659 ret = ((int (*)(struct lcd_device *))match->data)(lcdev);
660 if (ret) {
661 dev_err(&spi->dev, "Couldn't initialize panel\n");
662 return ret;
665 dev_info(&spi->dev, "Panel probed\n");
667 return 0;
670 static struct spi_driver hx8357_driver = {
671 .probe = hx8357_probe,
672 .driver = {
673 .name = "hx8357",
674 .of_match_table = hx8357_dt_ids,
678 module_spi_driver(hx8357_driver);
680 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
681 MODULE_DESCRIPTION("Himax HX-8357 LCD Driver");
682 MODULE_LICENSE("GPL");