blob: 1d525fc84db959894dce439899f1517b7c96b0ac [file] [log] [blame]
Tomi Valkeinen562a0602011-04-21 19:53:59 +03001/* #define DEBUG */
2
3#include <linux/module.h>
4#include <linux/delay.h>
5#include <linux/slab.h>
6#include <linux/gpio.h>
7#include <linux/spi/spi.h>
Tomi Valkeinen562a0602011-04-21 19:53:59 +03008#include <linux/fb.h>
9
10#include <video/omapdss.h>
Archit Tanejaa0d8dde2013-02-12 16:46:46 +053011#include <video/omap-panel-data.h>
Tomi Valkeinen562a0602011-04-21 19:53:59 +030012
13#define BLIZZARD_REV_CODE 0x00
14#define BLIZZARD_CONFIG 0x02
15#define BLIZZARD_PLL_DIV 0x04
16#define BLIZZARD_PLL_LOCK_RANGE 0x06
17#define BLIZZARD_PLL_CLOCK_SYNTH_0 0x08
18#define BLIZZARD_PLL_CLOCK_SYNTH_1 0x0a
19#define BLIZZARD_PLL_MODE 0x0c
20#define BLIZZARD_CLK_SRC 0x0e
21#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10
22#define BLIZZARD_MEM_BANK0_STATUS 0x14
23#define BLIZZARD_PANEL_CONFIGURATION 0x28
24#define BLIZZARD_HDISP 0x2a
25#define BLIZZARD_HNDP 0x2c
26#define BLIZZARD_VDISP0 0x2e
27#define BLIZZARD_VDISP1 0x30
28#define BLIZZARD_VNDP 0x32
29#define BLIZZARD_HSW 0x34
30#define BLIZZARD_VSW 0x38
31#define BLIZZARD_DISPLAY_MODE 0x68
32#define BLIZZARD_INPUT_WIN_X_START_0 0x6c
33#define BLIZZARD_DATA_SOURCE_SELECT 0x8e
34#define BLIZZARD_DISP_MEM_DATA_PORT 0x90
35#define BLIZZARD_DISP_MEM_READ_ADDR0 0x92
36#define BLIZZARD_POWER_SAVE 0xE6
37#define BLIZZARD_NDISP_CTRL_STATUS 0xE8
38
39/* Data source select */
40/* For S1D13745 */
41#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND 0x00
42#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE 0x01
43#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE 0x04
44#define BLIZZARD_SRC_DISABLE_OVERLAY 0x05
45/* For S1D13744 */
46#define BLIZZARD_SRC_WRITE_LCD 0x00
47#define BLIZZARD_SRC_BLT_LCD 0x06
48
49#define BLIZZARD_COLOR_RGB565 0x01
50#define BLIZZARD_COLOR_YUV420 0x09
51
52#define BLIZZARD_VERSION_S1D13745 0x01 /* Hailstorm */
53#define BLIZZARD_VERSION_S1D13744 0x02 /* Blizzard */
54
55#define MIPID_CMD_READ_DISP_ID 0x04
56#define MIPID_CMD_READ_RED 0x06
57#define MIPID_CMD_READ_GREEN 0x07
58#define MIPID_CMD_READ_BLUE 0x08
59#define MIPID_CMD_READ_DISP_STATUS 0x09
60#define MIPID_CMD_RDDSDR 0x0F
61#define MIPID_CMD_SLEEP_IN 0x10
62#define MIPID_CMD_SLEEP_OUT 0x11
63#define MIPID_CMD_DISP_OFF 0x28
64#define MIPID_CMD_DISP_ON 0x29
65
66static struct panel_drv_data {
67 struct mutex lock;
68
69 struct omap_dss_device *dssdev;
70 struct spi_device *spidev;
Tomi Valkeinen562a0602011-04-21 19:53:59 +030071
72 int blizzard_ver;
73} s_drv_data;
74
75
76static inline
77struct panel_n8x0_data *get_board_data(const struct omap_dss_device *dssdev)
78{
79 return dssdev->data;
80}
81
82static inline
83struct panel_drv_data *get_drv_data(const struct omap_dss_device *dssdev)
84{
85 return &s_drv_data;
86}
87
88
89static inline void blizzard_cmd(u8 cmd)
90{
91 omap_rfbi_write_command(&cmd, 1);
92}
93
94static inline void blizzard_write(u8 cmd, const u8 *buf, int len)
95{
96 omap_rfbi_write_command(&cmd, 1);
97 omap_rfbi_write_data(buf, len);
98}
99
100static inline void blizzard_read(u8 cmd, u8 *buf, int len)
101{
102 omap_rfbi_write_command(&cmd, 1);
103 omap_rfbi_read_data(buf, len);
104}
105
106static u8 blizzard_read_reg(u8 cmd)
107{
108 u8 data;
109 blizzard_read(cmd, &data, 1);
110 return data;
111}
112
113static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
114 int x, int y, int w, int h)
115{
116 struct panel_drv_data *ddata = get_drv_data(dssdev);
117 u8 tmp[18];
118 int x_end, y_end;
119
120 x_end = x + w - 1;
121 y_end = y + h - 1;
122
123 tmp[0] = x;
124 tmp[1] = x >> 8;
125 tmp[2] = y;
126 tmp[3] = y >> 8;
127 tmp[4] = x_end;
128 tmp[5] = x_end >> 8;
129 tmp[6] = y_end;
130 tmp[7] = y_end >> 8;
131
132 /* scaling? */
133 tmp[8] = x;
134 tmp[9] = x >> 8;
135 tmp[10] = y;
136 tmp[11] = y >> 8;
137 tmp[12] = x_end;
138 tmp[13] = x_end >> 8;
139 tmp[14] = y_end;
140 tmp[15] = y_end >> 8;
141
142 tmp[16] = BLIZZARD_COLOR_RGB565;
143
144 if (ddata->blizzard_ver == BLIZZARD_VERSION_S1D13745)
145 tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
146 else
147 tmp[17] = ddata->blizzard_ver == BLIZZARD_VERSION_S1D13744 ?
148 BLIZZARD_SRC_WRITE_LCD :
149 BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
150
Archit Tanejab02875b2012-08-13 15:26:49 +0530151 omapdss_rfbi_set_pixel_size(dssdev, 16);
Archit Taneja475989b2012-08-13 15:28:15 +0530152 omapdss_rfbi_set_data_lines(dssdev, 8);
Archit Tanejab02875b2012-08-13 15:26:49 +0530153
Archit Taneja475989b2012-08-13 15:28:15 +0530154 omap_rfbi_configure(dssdev);
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300155
156 blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
157
Archit Tanejab02875b2012-08-13 15:26:49 +0530158 omapdss_rfbi_set_pixel_size(dssdev, 16);
Archit Taneja475989b2012-08-13 15:28:15 +0530159 omapdss_rfbi_set_data_lines(dssdev, 16);
Archit Tanejab02875b2012-08-13 15:26:49 +0530160
Archit Taneja475989b2012-08-13 15:28:15 +0530161 omap_rfbi_configure(dssdev);
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300162}
163
164static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
165 int wlen, u8 *rbuf, int rlen)
166{
167 struct spi_message m;
168 struct spi_transfer *x, xfer[4];
169 u16 w;
170 int r;
171
172 spi_message_init(&m);
173
174 memset(xfer, 0, sizeof(xfer));
175 x = &xfer[0];
176
177 cmd &= 0xff;
178 x->tx_buf = &cmd;
179 x->bits_per_word = 9;
180 x->len = 2;
181 spi_message_add_tail(x, &m);
182
183 if (wlen) {
184 x++;
185 x->tx_buf = wbuf;
186 x->len = wlen;
187 x->bits_per_word = 9;
188 spi_message_add_tail(x, &m);
189 }
190
191 if (rlen) {
192 x++;
193 x->rx_buf = &w;
194 x->len = 1;
195 spi_message_add_tail(x, &m);
196
197 if (rlen > 1) {
198 /* Arrange for the extra clock before the first
199 * data bit.
200 */
201 x->bits_per_word = 9;
202 x->len = 2;
203
204 x++;
205 x->rx_buf = &rbuf[1];
206 x->len = rlen - 1;
207 spi_message_add_tail(x, &m);
208 }
209 }
210
211 r = spi_sync(spi, &m);
212 if (r < 0)
213 dev_dbg(&spi->dev, "spi_sync %d\n", r);
214
215 if (rlen)
216 rbuf[0] = w & 0xff;
217}
218
219static inline void mipid_cmd(struct spi_device *spi, int cmd)
220{
221 mipid_transfer(spi, cmd, NULL, 0, NULL, 0);
222}
223
224static inline void mipid_write(struct spi_device *spi,
225 int reg, const u8 *buf, int len)
226{
227 mipid_transfer(spi, reg, buf, len, NULL, 0);
228}
229
230static inline void mipid_read(struct spi_device *spi,
231 int reg, u8 *buf, int len)
232{
233 mipid_transfer(spi, reg, NULL, 0, buf, len);
234}
235
236static void set_data_lines(struct spi_device *spi, int data_lines)
237{
238 u16 par;
239
240 switch (data_lines) {
241 case 16:
242 par = 0x150;
243 break;
244 case 18:
245 par = 0x160;
246 break;
247 case 24:
248 par = 0x170;
249 break;
250 }
251
252 mipid_write(spi, 0x3a, (u8 *)&par, 2);
253}
254
255static void send_init_string(struct spi_device *spi)
256{
257 u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
258 mipid_write(spi, 0xc2, (u8 *)initpar, sizeof(initpar));
259}
260
261static void send_display_on(struct spi_device *spi)
262{
263 mipid_cmd(spi, MIPID_CMD_DISP_ON);
264}
265
266static void send_display_off(struct spi_device *spi)
267{
268 mipid_cmd(spi, MIPID_CMD_DISP_OFF);
269}
270
271static void send_sleep_out(struct spi_device *spi)
272{
273 mipid_cmd(spi, MIPID_CMD_SLEEP_OUT);
274 msleep(120);
275}
276
277static void send_sleep_in(struct spi_device *spi)
278{
279 mipid_cmd(spi, MIPID_CMD_SLEEP_IN);
280 msleep(50);
281}
282
283static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
284{
285 int r;
286 struct panel_n8x0_data *bdata = get_board_data(dssdev);
287 struct panel_drv_data *ddata = get_drv_data(dssdev);
288 struct spi_device *spi = ddata->spidev;
289 u8 rev, conf;
290 u8 display_id[3];
291 const char *panel_name;
292
293 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
294 return 0;
295
296 gpio_direction_output(bdata->ctrl_pwrdown, 1);
297
Archit Taneja6ff9dd52012-08-13 15:12:10 +0530298 omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res,
299 dssdev->panel.timings.y_res);
Archit Tanejab02875b2012-08-13 15:26:49 +0530300 omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size);
Archit Taneja475989b2012-08-13 15:28:15 +0530301 omapdss_rfbi_set_data_lines(dssdev, dssdev->phy.rfbi.data_lines);
Archit Taneja6e883322012-08-13 22:23:29 +0530302 omapdss_rfbi_set_interface_timings(dssdev, &dssdev->ctrl.rfbi_timings);
Archit Taneja6ff9dd52012-08-13 15:12:10 +0530303
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300304 r = omapdss_rfbi_display_enable(dssdev);
305 if (r)
306 goto err_rfbi_en;
307
308 rev = blizzard_read_reg(BLIZZARD_REV_CODE);
309 conf = blizzard_read_reg(BLIZZARD_CONFIG);
310
311 switch (rev & 0xfc) {
312 case 0x9c:
313 ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744;
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200314 dev_info(dssdev->dev, "s1d13744 LCD controller rev %d "
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300315 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
316 break;
317 case 0xa4:
318 ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745;
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200319 dev_info(dssdev->dev, "s1d13745 LCD controller rev %d "
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300320 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
321 break;
322 default:
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200323 dev_err(dssdev->dev, "invalid s1d1374x revision %02x\n", rev);
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300324 r = -ENODEV;
325 goto err_inv_chip;
326 }
327
328 /* panel */
329
330 gpio_direction_output(bdata->panel_reset, 1);
331
332 mipid_read(spi, MIPID_CMD_READ_DISP_ID, display_id, 3);
333 dev_dbg(&spi->dev, "MIPI display ID: %02x%02x%02x\n",
334 display_id[0], display_id[1], display_id[2]);
335
336 switch (display_id[0]) {
337 case 0x45:
338 panel_name = "lph8923";
339 break;
340 case 0x83:
341 panel_name = "ls041y3";
342 break;
343 default:
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200344 dev_err(dssdev->dev, "invalid display ID 0x%x\n",
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300345 display_id[0]);
346 r = -ENODEV;
347 goto err_inv_panel;
348 }
349
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200350 dev_info(dssdev->dev, "%s rev %02x LCD detected\n",
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300351 panel_name, display_id[1]);
352
353 send_sleep_out(spi);
354 send_init_string(spi);
355 set_data_lines(spi, 24);
356 send_display_on(spi);
357
358 return 0;
359
360err_inv_panel:
361 /*
362 * HACK: we should turn off the panel here, but there is some problem
363 * with the initialization sequence, and we fail to init the panel if we
364 * have turned it off
365 */
366 /* gpio_direction_output(bdata->panel_reset, 0); */
367err_inv_chip:
368 omapdss_rfbi_display_disable(dssdev);
369err_rfbi_en:
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300370 gpio_direction_output(bdata->ctrl_pwrdown, 0);
371 return r;
372}
373
374static void n8x0_panel_power_off(struct omap_dss_device *dssdev)
375{
376 struct panel_n8x0_data *bdata = get_board_data(dssdev);
377 struct panel_drv_data *ddata = get_drv_data(dssdev);
378 struct spi_device *spi = ddata->spidev;
379
380 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
381 return;
382
383 send_display_off(spi);
384 send_sleep_in(spi);
385
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300386 /*
387 * HACK: we should turn off the panel here, but there is some problem
388 * with the initialization sequence, and we fail to init the panel if we
389 * have turned it off
390 */
391 /* gpio_direction_output(bdata->panel_reset, 0); */
392 gpio_direction_output(bdata->ctrl_pwrdown, 0);
393 omapdss_rfbi_display_disable(dssdev);
394}
395
396static const struct rfbi_timings n8x0_panel_timings = {
397 .cs_on_time = 0,
398
399 .we_on_time = 9000,
400 .we_off_time = 18000,
401 .we_cycle_time = 36000,
402
403 .re_on_time = 9000,
404 .re_off_time = 27000,
405 .re_cycle_time = 36000,
406
407 .access_time = 27000,
408 .cs_off_time = 36000,
409
410 .cs_pulse_width = 0,
411};
412
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300413static int n8x0_panel_probe(struct omap_dss_device *dssdev)
414{
415 struct panel_n8x0_data *bdata = get_board_data(dssdev);
416 struct panel_drv_data *ddata;
Archit Taneja64f93892012-11-21 12:08:40 +0530417 int r;
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300418
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200419 dev_dbg(dssdev->dev, "probe\n");
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300420
421 if (!bdata)
422 return -EINVAL;
423
424 s_drv_data.dssdev = dssdev;
425
426 ddata = &s_drv_data;
427
428 mutex_init(&ddata->lock);
429
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300430 dssdev->panel.timings.x_res = 800;
431 dssdev->panel.timings.y_res = 480;
432 dssdev->ctrl.pixel_size = 16;
433 dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
Tomi Valkeinenab585252012-08-23 16:06:43 +0300434 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300435
Archit Taneja64f93892012-11-21 12:08:40 +0530436 if (gpio_is_valid(bdata->panel_reset)) {
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200437 r = devm_gpio_request_one(dssdev->dev, bdata->panel_reset,
Archit Taneja64f93892012-11-21 12:08:40 +0530438 GPIOF_OUT_INIT_LOW, "PANEL RESET");
439 if (r)
440 return r;
441 }
442
443 if (gpio_is_valid(bdata->ctrl_pwrdown)) {
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200444 r = devm_gpio_request_one(dssdev->dev, bdata->ctrl_pwrdown,
Archit Taneja64f93892012-11-21 12:08:40 +0530445 GPIOF_OUT_INIT_LOW, "PANEL PWRDOWN");
446 if (r)
447 return r;
448 }
449
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300450 return 0;
451}
452
453static void n8x0_panel_remove(struct omap_dss_device *dssdev)
454{
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200455 dev_dbg(dssdev->dev, "remove\n");
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300456
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200457 dev_set_drvdata(dssdev->dev, NULL);
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300458}
459
460static int n8x0_panel_enable(struct omap_dss_device *dssdev)
461{
462 struct panel_drv_data *ddata = get_drv_data(dssdev);
463 int r;
464
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200465 dev_dbg(dssdev->dev, "enable\n");
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300466
467 mutex_lock(&ddata->lock);
468
469 rfbi_bus_lock();
470
471 r = n8x0_panel_power_on(dssdev);
472
473 rfbi_bus_unlock();
474
475 if (r) {
476 mutex_unlock(&ddata->lock);
477 return r;
478 }
479
480 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
481
482 mutex_unlock(&ddata->lock);
483
484 return 0;
485}
486
487static void n8x0_panel_disable(struct omap_dss_device *dssdev)
488{
489 struct panel_drv_data *ddata = get_drv_data(dssdev);
490
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200491 dev_dbg(dssdev->dev, "disable\n");
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300492
493 mutex_lock(&ddata->lock);
494
495 rfbi_bus_lock();
496
497 n8x0_panel_power_off(dssdev);
498
499 rfbi_bus_unlock();
500
501 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
502
503 mutex_unlock(&ddata->lock);
504}
505
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300506static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
507 u16 *xres, u16 *yres)
508{
509 *xres = dssdev->panel.timings.x_res;
510 *yres = dssdev->panel.timings.y_res;
511}
512
513static void update_done(void *data)
514{
515 rfbi_bus_unlock();
516}
517
518static int n8x0_panel_update(struct omap_dss_device *dssdev,
519 u16 x, u16 y, u16 w, u16 h)
520{
521 struct panel_drv_data *ddata = get_drv_data(dssdev);
Archit Taneja43eab862012-08-13 12:24:53 +0530522 u16 dw, dh;
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300523
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200524 dev_dbg(dssdev->dev, "update\n");
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300525
Archit Taneja43eab862012-08-13 12:24:53 +0530526 dw = dssdev->panel.timings.x_res;
527 dh = dssdev->panel.timings.y_res;
528
529 if (x != 0 || y != 0 || w != dw || h != dh) {
Linus Torvalds5f097cd2013-07-09 15:51:32 -0700530 dev_err(dssdev->dev, "invalid update region %d, %d, %d, %d\n",
Archit Taneja43eab862012-08-13 12:24:53 +0530531 x, y, w, h);
532 return -EINVAL;
533 }
534
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300535 mutex_lock(&ddata->lock);
536 rfbi_bus_lock();
537
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300538 blizzard_ctrl_setup_update(dssdev, x, y, w, h);
539
Archit Taneja43eab862012-08-13 12:24:53 +0530540 omap_rfbi_update(dssdev, update_done, NULL);
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300541
542 mutex_unlock(&ddata->lock);
543
544 return 0;
545}
546
547static int n8x0_panel_sync(struct omap_dss_device *dssdev)
548{
549 struct panel_drv_data *ddata = get_drv_data(dssdev);
550
Tomi Valkeinenecc8b372013-02-14 14:17:28 +0200551 dev_dbg(dssdev->dev, "sync\n");
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300552
553 mutex_lock(&ddata->lock);
554 rfbi_bus_lock();
555 rfbi_bus_unlock();
556 mutex_unlock(&ddata->lock);
557
558 return 0;
559}
560
561static struct omap_dss_driver n8x0_panel_driver = {
562 .probe = n8x0_panel_probe,
563 .remove = n8x0_panel_remove,
564
565 .enable = n8x0_panel_enable,
566 .disable = n8x0_panel_disable,
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300567
568 .update = n8x0_panel_update,
569 .sync = n8x0_panel_sync,
570
571 .get_resolution = n8x0_panel_get_resolution,
572 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
573
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300574 .driver = {
575 .name = "n8x0_panel",
576 .owner = THIS_MODULE,
577 },
578};
579
580/* PANEL */
581
582static int mipid_spi_probe(struct spi_device *spi)
583{
Aaro Koskinenee6352d2012-11-21 21:48:52 +0200584 int r;
585
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300586 dev_dbg(&spi->dev, "mipid_spi_probe\n");
587
588 spi->mode = SPI_MODE_0;
589
590 s_drv_data.spidev = spi;
591
Aaro Koskinenee6352d2012-11-21 21:48:52 +0200592 r = omap_dss_register_driver(&n8x0_panel_driver);
593 if (r)
594 pr_err("n8x0_panel: dss driver registration failed\n");
595
596 return r;
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300597}
598
599static int mipid_spi_remove(struct spi_device *spi)
600{
601 dev_dbg(&spi->dev, "mipid_spi_remove\n");
Aaro Koskinenee6352d2012-11-21 21:48:52 +0200602 omap_dss_unregister_driver(&n8x0_panel_driver);
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300603 return 0;
604}
605
606static struct spi_driver mipid_spi_driver = {
607 .driver = {
608 .name = "lcd_mipid",
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300609 .owner = THIS_MODULE,
610 },
611 .probe = mipid_spi_probe,
Greg Kroah-Hartman48c68c42012-12-21 13:07:39 -0800612 .remove = mipid_spi_remove,
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300613};
Aaro Koskinenee6352d2012-11-21 21:48:52 +0200614module_spi_driver(mipid_spi_driver);
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300615
Tomi Valkeinen562a0602011-04-21 19:53:59 +0300616MODULE_LICENSE("GPL");