Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / video / backlight / hx8357.c
1 /*
2  * Driver for the Himax HX-8357 LCD Controller
3  *
4  * Copyright 2012 Free Electrons
5  *
6  * Licensed under the GPLv2 or later.
7  */
8
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>
16
17 #define HX8357_NUM_IM_PINS      3
18
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
73
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
85
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;
92 };
93
94 static u8 hx8357_seq_power[] = {
95         HX8357_SET_POWER, 0x44, 0x41, 0x06,
96 };
97
98 static u8 hx8357_seq_vcom[] = {
99         HX8357_SET_VCOM, 0x40, 0x10,
100 };
101
102 static u8 hx8357_seq_power_normal[] = {
103         HX8357_SET_POWER_NORMAL, 0x05, 0x12,
104 };
105
106 static u8 hx8357_seq_panel_driving[] = {
107         HX8357_SET_PANEL_DRIVING, 0x14, 0x3b, 0x00, 0x02, 0x11,
108 };
109
110 static u8 hx8357_seq_display_frame[] = {
111         HX8357_SET_DISPLAY_FRAME, 0x0c,
112 };
113
114 static u8 hx8357_seq_panel_related[] = {
115         HX8357_SET_PANEL_RELATED, 0x01,
116 };
117
118 static u8 hx8357_seq_undefined1[] = {
119         0xea, 0x03, 0x00, 0x00,
120 };
121
122 static u8 hx8357_seq_undefined2[] = {
123         0xeb, 0x40, 0x54, 0x26, 0xdb,
124 };
125
126 static u8 hx8357_seq_gamma[] = {
127         HX8357_SET_GAMMA, 0x00, 0x15, 0x00, 0x22, 0x00,
128         0x08, 0x77, 0x26, 0x77, 0x22, 0x04, 0x00,
129 };
130
131 static u8 hx8357_seq_address_mode[] = {
132         HX8357_SET_ADDRESS_MODE, 0xc0,
133 };
134
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,
139 };
140
141 static u8 hx8357_seq_column_address[] = {
142         HX8357_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x01, 0x3f,
143 };
144
145 static u8 hx8357_seq_page_address[] = {
146         HX8357_SET_PAGE_ADDRESS, 0x00, 0x00, 0x01, 0xdf,
147 };
148
149 static u8 hx8357_seq_rgb[] = {
150         HX8357_SET_RGB, 0x02,
151 };
152
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,
157 };
158
159 static u8 hx8369_seq_write_CABC_min_brightness[] = {
160         HX8369_WRITE_CABC_MIN_BRIGHTNESS, 0x00,
161 };
162
163 static u8 hx8369_seq_write_CABC_control[] = {
164         HX8369_WRITE_CABC_DISPLAY_VALUE, 0x24,
165 };
166
167 static u8 hx8369_seq_set_display_brightness[] = {
168         HX8369_SET_DISPLAY_BRIGHTNESS, 0xFF,
169 };
170
171 static u8 hx8369_seq_write_CABC_control_setting[] = {
172         HX8369_WRITE_CABC_BRIGHT_CTRL, 0x02,
173 };
174
175 static u8 hx8369_seq_extension_command[] = {
176         HX8369_SET_EXTENSION_COMMAND, 0xff, 0x83, 0x69,
177 };
178
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,
182 };
183
184 static u8 hx8369_seq_panel_waveform_cycle[] = {
185         HX8369_SET_DISPLAY_WAVEFORM_CYC, 0x0a, 0x1d, 0x80, 0x06, 0x02,
186 };
187
188 static u8 hx8369_seq_set_address_mode[] = {
189         HX8357_SET_ADDRESS_MODE, 0x00,
190 };
191
192 static u8 hx8369_seq_vcom[] = {
193         HX8369_SET_VCOM, 0x3e, 0x3e,
194 };
195
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,
200 };
201
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,
205 };
206
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,
212 };
213
214 static int hx8357_spi_write_then_read(struct lcd_device *lcdev,
215                                 u8 *txbuf, u16 txlen,
216                                 u8 *rxbuf, u16 rxlen)
217 {
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;
223
224         memset(xfer, 0, sizeof(xfer));
225         spi_message_init(&msg);
226
227         if (txlen) {
228                 int i;
229
230                 local_txbuf = kcalloc(txlen, sizeof(*local_txbuf), GFP_KERNEL);
231
232                 if (!local_txbuf)
233                         return -ENOMEM;
234
235                 for (i = 0; i < txlen; i++) {
236                         local_txbuf[i] = txbuf[i];
237                         if (i > 0)
238                                 local_txbuf[i] |= 1 << 8;
239                 }
240
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);
245         }
246
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);
252         }
253
254         ret = spi_sync(lcd->spi, &msg);
255         if (ret < 0)
256                 dev_err(&lcdev->dev, "Couldn't send SPI data\n");
257
258         if (txlen)
259                 kfree(local_txbuf);
260
261         return ret;
262 }
263
264 static inline int hx8357_spi_write_array(struct lcd_device *lcdev,
265                                         u8 *value, u8 len)
266 {
267         return hx8357_spi_write_then_read(lcdev, value, len, NULL, 0);
268 }
269
270 static inline int hx8357_spi_write_byte(struct lcd_device *lcdev,
271                                         u8 value)
272 {
273         return hx8357_spi_write_then_read(lcdev, &value, 1, NULL, 0);
274 }
275
276 static int hx8357_enter_standby(struct lcd_device *lcdev)
277 {
278         int ret;
279
280         ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_OFF);
281         if (ret < 0)
282                 return ret;
283
284         usleep_range(10000, 12000);
285
286         ret = hx8357_spi_write_byte(lcdev, HX8357_ENTER_SLEEP_MODE);
287         if (ret < 0)
288                 return ret;
289
290         /*
291          * The controller needs 120ms when entering in sleep mode before we can
292          * send the command to go off sleep mode
293          */
294         msleep(120);
295
296         return 0;
297 }
298
299 static int hx8357_exit_standby(struct lcd_device *lcdev)
300 {
301         int ret;
302
303         ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
304         if (ret < 0)
305                 return ret;
306
307         /*
308          * The controller needs 120ms when exiting from sleep mode before we
309          * can send the command to enter in sleep mode
310          */
311         msleep(120);
312
313         ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
314         if (ret < 0)
315                 return ret;
316
317         return 0;
318 }
319
320 static void hx8357_lcd_reset(struct lcd_device *lcdev)
321 {
322         struct hx8357_data *lcd = lcd_get_data(lcdev);
323
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);
330
331         /* The controller needs 120ms to recover from reset */
332         msleep(120);
333 }
334
335 static int hx8357_lcd_init(struct lcd_device *lcdev)
336 {
337         struct hx8357_data *lcd = lcd_get_data(lcdev);
338         int ret;
339
340         /*
341          * Set the interface selection pins to SPI mode, with three
342          * wires
343          */
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);
348         }
349
350         ret = hx8357_spi_write_array(lcdev, hx8357_seq_power,
351                                 ARRAY_SIZE(hx8357_seq_power));
352         if (ret < 0)
353                 return ret;
354
355         ret = hx8357_spi_write_array(lcdev, hx8357_seq_vcom,
356                                 ARRAY_SIZE(hx8357_seq_vcom));
357         if (ret < 0)
358                 return ret;
359
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;
364
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;
369
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;
374
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;
379
380         ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined1,
381                                 ARRAY_SIZE(hx8357_seq_undefined1));
382         if (ret < 0)
383                 return ret;
384
385         ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined2,
386                                 ARRAY_SIZE(hx8357_seq_undefined2));
387         if (ret < 0)
388                 return ret;
389
390         ret = hx8357_spi_write_array(lcdev, hx8357_seq_gamma,
391                                 ARRAY_SIZE(hx8357_seq_gamma));
392         if (ret < 0)
393                 return ret;
394
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;
399
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;
404
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;
409
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;
414
415         ret = hx8357_spi_write_array(lcdev, hx8357_seq_rgb,
416                                 ARRAY_SIZE(hx8357_seq_rgb));
417         if (ret < 0)
418                 return ret;
419
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;
424
425         ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
426         if (ret < 0)
427                 return ret;
428
429         /*
430          * The controller needs 120ms to fully recover from exiting sleep mode
431          */
432         msleep(120);
433
434         ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
435         if (ret < 0)
436                 return ret;
437
438         usleep_range(5000, 7000);
439
440         ret = hx8357_spi_write_byte(lcdev, HX8357_WRITE_MEMORY_START);
441         if (ret < 0)
442                 return ret;
443
444         return 0;
445 }
446
447 static int hx8369_lcd_init(struct lcd_device *lcdev)
448 {
449         int ret;
450
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);
456
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;
461
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;
466
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;
471
472         ret = hx8357_spi_write_array(lcdev, hx8369_seq_vcom,
473                                 ARRAY_SIZE(hx8369_seq_vcom));
474         if (ret < 0)
475                 return ret;
476
477         ret = hx8357_spi_write_array(lcdev, hx8369_seq_gip,
478                                 ARRAY_SIZE(hx8369_seq_gip));
479         if (ret < 0)
480                 return ret;
481
482         ret = hx8357_spi_write_array(lcdev, hx8369_seq_power,
483                                 ARRAY_SIZE(hx8369_seq_power));
484         if (ret < 0)
485                 return ret;
486
487         ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
488         if (ret < 0)
489                 return ret;
490
491         /*
492          * The controller needs 120ms to fully recover from exiting sleep mode
493          */
494         msleep(120);
495
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;
500
501         ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
502         if (ret < 0)
503                 return ret;
504         usleep_range(1000, 1200);
505
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);
511
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;
517
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);
524
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;
529
530         ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
531         if (ret < 0)
532                 return ret;
533
534         return 0;
535 }
536
537 #define POWER_IS_ON(pwr)        ((pwr) <= FB_BLANK_NORMAL)
538
539 static int hx8357_set_power(struct lcd_device *lcdev, int power)
540 {
541         struct hx8357_data *lcd = lcd_get_data(lcdev);
542         int ret = 0;
543
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);
548
549         if (ret == 0)
550                 lcd->state = power;
551         else
552                 dev_warn(&lcdev->dev, "failed to set power mode %d\n", power);
553
554         return ret;
555 }
556
557 static int hx8357_get_power(struct lcd_device *lcdev)
558 {
559         struct hx8357_data *lcd = lcd_get_data(lcdev);
560
561         return lcd->state;
562 }
563
564 static struct lcd_ops hx8357_ops = {
565         .set_power      = hx8357_set_power,
566         .get_power      = hx8357_get_power,
567 };
568
569 static const struct of_device_id hx8357_dt_ids[] = {
570         {
571                 .compatible = "himax,hx8357",
572                 .data = hx8357_lcd_init,
573         },
574         {
575                 .compatible = "himax,hx8369",
576                 .data = hx8369_lcd_init,
577         },
578         {},
579 };
580 MODULE_DEVICE_TABLE(of, hx8357_dt_ids);
581
582 static int hx8357_probe(struct spi_device *spi)
583 {
584         struct lcd_device *lcdev;
585         struct hx8357_data *lcd;
586         const struct of_device_id *match;
587         int i, ret;
588
589         lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL);
590         if (!lcd)
591                 return -ENOMEM;
592
593         ret = spi_setup(spi);
594         if (ret < 0) {
595                 dev_err(&spi->dev, "SPI setup failed.\n");
596                 return ret;
597         }
598
599         lcd->spi = spi;
600
601         match = of_match_device(hx8357_dt_ids, &spi->dev);
602         if (!match || !match->data)
603                 return -EINVAL;
604
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;
609         }
610
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;
619         }
620
621         if (of_find_property(spi->dev.of_node, "im-gpios", NULL)) {
622                 lcd->use_im_pins = 1;
623
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;
630                         }
631                         if (!gpio_is_valid(lcd->im_pins[i])) {
632                                 dev_err(&spi->dev, "Missing dt property: im-gpios\n");
633                                 return -EINVAL;
634                         }
635
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;
643                         }
644                 }
645         } else {
646                 lcd->use_im_pins = 0;
647         }
648
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;
654         }
655         spi_set_drvdata(spi, lcdev);
656
657         hx8357_lcd_reset(lcdev);
658
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;
663         }
664
665         dev_info(&spi->dev, "Panel probed\n");
666
667         return 0;
668 }
669
670 static struct spi_driver hx8357_driver = {
671         .probe  = hx8357_probe,
672         .driver = {
673                 .name = "hx8357",
674                 .of_match_table = hx8357_dt_ids,
675         },
676 };
677
678 module_spi_driver(hx8357_driver);
679
680 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
681 MODULE_DESCRIPTION("Himax HX-8357 LCD Driver");
682 MODULE_LICENSE("GPL");