1 /* #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>
8 #include <linux/backlight.h>
9 #include <linux/fb.h>
10 
11 #include <video/omapdss.h>
12 #include <video/omap-panel-n8x0.h>
13 
14 #define BLIZZARD_REV_CODE                      0x00
15 #define BLIZZARD_CONFIG                        0x02
16 #define BLIZZARD_PLL_DIV                       0x04
17 #define BLIZZARD_PLL_LOCK_RANGE                0x06
18 #define BLIZZARD_PLL_CLOCK_SYNTH_0             0x08
19 #define BLIZZARD_PLL_CLOCK_SYNTH_1             0x0a
20 #define BLIZZARD_PLL_MODE                      0x0c
21 #define BLIZZARD_CLK_SRC                       0x0e
22 #define BLIZZARD_MEM_BANK0_ACTIVATE            0x10
23 #define BLIZZARD_MEM_BANK0_STATUS              0x14
24 #define BLIZZARD_PANEL_CONFIGURATION           0x28
25 #define BLIZZARD_HDISP                         0x2a
26 #define BLIZZARD_HNDP                          0x2c
27 #define BLIZZARD_VDISP0                        0x2e
28 #define BLIZZARD_VDISP1                        0x30
29 #define BLIZZARD_VNDP                          0x32
30 #define BLIZZARD_HSW                           0x34
31 #define BLIZZARD_VSW                           0x38
32 #define BLIZZARD_DISPLAY_MODE                  0x68
33 #define BLIZZARD_INPUT_WIN_X_START_0           0x6c
34 #define BLIZZARD_DATA_SOURCE_SELECT            0x8e
35 #define BLIZZARD_DISP_MEM_DATA_PORT            0x90
36 #define BLIZZARD_DISP_MEM_READ_ADDR0           0x92
37 #define BLIZZARD_POWER_SAVE                    0xE6
38 #define BLIZZARD_NDISP_CTRL_STATUS             0xE8
39 
40 /* Data source select */
41 /* For S1D13745 */
42 #define BLIZZARD_SRC_WRITE_LCD_BACKGROUND	0x00
43 #define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE	0x01
44 #define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE	0x04
45 #define BLIZZARD_SRC_DISABLE_OVERLAY		0x05
46 /* For S1D13744 */
47 #define BLIZZARD_SRC_WRITE_LCD			0x00
48 #define BLIZZARD_SRC_BLT_LCD			0x06
49 
50 #define BLIZZARD_COLOR_RGB565			0x01
51 #define BLIZZARD_COLOR_YUV420			0x09
52 
53 #define BLIZZARD_VERSION_S1D13745		0x01	/* Hailstorm */
54 #define BLIZZARD_VERSION_S1D13744		0x02	/* Blizzard */
55 
56 #define MIPID_CMD_READ_DISP_ID		0x04
57 #define MIPID_CMD_READ_RED		0x06
58 #define MIPID_CMD_READ_GREEN		0x07
59 #define MIPID_CMD_READ_BLUE		0x08
60 #define MIPID_CMD_READ_DISP_STATUS	0x09
61 #define MIPID_CMD_RDDSDR		0x0F
62 #define MIPID_CMD_SLEEP_IN		0x10
63 #define MIPID_CMD_SLEEP_OUT		0x11
64 #define MIPID_CMD_DISP_OFF		0x28
65 #define MIPID_CMD_DISP_ON		0x29
66 
67 static struct panel_drv_data {
68 	struct mutex lock;
69 
70 	struct omap_dss_device *dssdev;
71 	struct spi_device *spidev;
72 	struct backlight_device *bldev;
73 
74 	int blizzard_ver;
75 } s_drv_data;
76 
77 
78 static inline
get_board_data(const struct omap_dss_device * dssdev)79 struct panel_n8x0_data *get_board_data(const struct omap_dss_device *dssdev)
80 {
81 	return dssdev->data;
82 }
83 
84 static inline
get_drv_data(const struct omap_dss_device * dssdev)85 struct panel_drv_data *get_drv_data(const struct omap_dss_device *dssdev)
86 {
87 	return &s_drv_data;
88 }
89 
90 
blizzard_cmd(u8 cmd)91 static inline void blizzard_cmd(u8 cmd)
92 {
93 	omap_rfbi_write_command(&cmd, 1);
94 }
95 
blizzard_write(u8 cmd,const u8 * buf,int len)96 static inline void blizzard_write(u8 cmd, const u8 *buf, int len)
97 {
98 	omap_rfbi_write_command(&cmd, 1);
99 	omap_rfbi_write_data(buf, len);
100 }
101 
blizzard_read(u8 cmd,u8 * buf,int len)102 static inline void blizzard_read(u8 cmd, u8 *buf, int len)
103 {
104 	omap_rfbi_write_command(&cmd, 1);
105 	omap_rfbi_read_data(buf, len);
106 }
107 
blizzard_read_reg(u8 cmd)108 static u8 blizzard_read_reg(u8 cmd)
109 {
110 	u8 data;
111 	blizzard_read(cmd, &data, 1);
112 	return data;
113 }
114 
blizzard_ctrl_setup_update(struct omap_dss_device * dssdev,int x,int y,int w,int h)115 static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
116 		int x, int y, int w, int h)
117 {
118 	struct panel_drv_data *ddata = get_drv_data(dssdev);
119 	u8 tmp[18];
120 	int x_end, y_end;
121 
122 	x_end = x + w - 1;
123 	y_end = y + h - 1;
124 
125 	tmp[0] = x;
126 	tmp[1] = x >> 8;
127 	tmp[2] = y;
128 	tmp[3] = y >> 8;
129 	tmp[4] = x_end;
130 	tmp[5] = x_end >> 8;
131 	tmp[6] = y_end;
132 	tmp[7] = y_end >> 8;
133 
134 	/* scaling? */
135 	tmp[8] = x;
136 	tmp[9] = x >> 8;
137 	tmp[10] = y;
138 	tmp[11] = y >> 8;
139 	tmp[12] = x_end;
140 	tmp[13] = x_end >> 8;
141 	tmp[14] = y_end;
142 	tmp[15] = y_end >> 8;
143 
144 	tmp[16] = BLIZZARD_COLOR_RGB565;
145 
146 	if (ddata->blizzard_ver == BLIZZARD_VERSION_S1D13745)
147 		tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
148 	else
149 		tmp[17] = ddata->blizzard_ver == BLIZZARD_VERSION_S1D13744 ?
150 			BLIZZARD_SRC_WRITE_LCD :
151 			BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
152 
153 	omap_rfbi_configure(dssdev, 16, 8);
154 
155 	blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
156 
157 	omap_rfbi_configure(dssdev, 16, 16);
158 }
159 
mipid_transfer(struct spi_device * spi,int cmd,const u8 * wbuf,int wlen,u8 * rbuf,int rlen)160 static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
161 		int wlen, u8 *rbuf, int rlen)
162 {
163 	struct spi_message	m;
164 	struct spi_transfer	*x, xfer[4];
165 	u16			w;
166 	int			r;
167 
168 	spi_message_init(&m);
169 
170 	memset(xfer, 0, sizeof(xfer));
171 	x = &xfer[0];
172 
173 	cmd &=  0xff;
174 	x->tx_buf		= &cmd;
175 	x->bits_per_word	= 9;
176 	x->len			= 2;
177 	spi_message_add_tail(x, &m);
178 
179 	if (wlen) {
180 		x++;
181 		x->tx_buf		= wbuf;
182 		x->len			= wlen;
183 		x->bits_per_word	= 9;
184 		spi_message_add_tail(x, &m);
185 	}
186 
187 	if (rlen) {
188 		x++;
189 		x->rx_buf	= &w;
190 		x->len		= 1;
191 		spi_message_add_tail(x, &m);
192 
193 		if (rlen > 1) {
194 			/* Arrange for the extra clock before the first
195 			 * data bit.
196 			 */
197 			x->bits_per_word = 9;
198 			x->len		 = 2;
199 
200 			x++;
201 			x->rx_buf	 = &rbuf[1];
202 			x->len		 = rlen - 1;
203 			spi_message_add_tail(x, &m);
204 		}
205 	}
206 
207 	r = spi_sync(spi, &m);
208 	if (r < 0)
209 		dev_dbg(&spi->dev, "spi_sync %d\n", r);
210 
211 	if (rlen)
212 		rbuf[0] = w & 0xff;
213 }
214 
mipid_cmd(struct spi_device * spi,int cmd)215 static inline void mipid_cmd(struct spi_device *spi, int cmd)
216 {
217 	mipid_transfer(spi, cmd, NULL, 0, NULL, 0);
218 }
219 
mipid_write(struct spi_device * spi,int reg,const u8 * buf,int len)220 static inline void mipid_write(struct spi_device *spi,
221 		int reg, const u8 *buf, int len)
222 {
223 	mipid_transfer(spi, reg, buf, len, NULL, 0);
224 }
225 
mipid_read(struct spi_device * spi,int reg,u8 * buf,int len)226 static inline void mipid_read(struct spi_device *spi,
227 		int reg, u8 *buf, int len)
228 {
229 	mipid_transfer(spi, reg, NULL, 0, buf, len);
230 }
231 
set_data_lines(struct spi_device * spi,int data_lines)232 static void set_data_lines(struct spi_device *spi, int data_lines)
233 {
234 	u16 par;
235 
236 	switch (data_lines) {
237 	case 16:
238 		par = 0x150;
239 		break;
240 	case 18:
241 		par = 0x160;
242 		break;
243 	case 24:
244 		par = 0x170;
245 		break;
246 	}
247 
248 	mipid_write(spi, 0x3a, (u8 *)&par, 2);
249 }
250 
send_init_string(struct spi_device * spi)251 static void send_init_string(struct spi_device *spi)
252 {
253 	u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
254 	mipid_write(spi, 0xc2, (u8 *)initpar, sizeof(initpar));
255 }
256 
send_display_on(struct spi_device * spi)257 static void send_display_on(struct spi_device *spi)
258 {
259 	mipid_cmd(spi, MIPID_CMD_DISP_ON);
260 }
261 
send_display_off(struct spi_device * spi)262 static void send_display_off(struct spi_device *spi)
263 {
264 	mipid_cmd(spi, MIPID_CMD_DISP_OFF);
265 }
266 
send_sleep_out(struct spi_device * spi)267 static void send_sleep_out(struct spi_device *spi)
268 {
269 	mipid_cmd(spi, MIPID_CMD_SLEEP_OUT);
270 	msleep(120);
271 }
272 
send_sleep_in(struct spi_device * spi)273 static void send_sleep_in(struct spi_device *spi)
274 {
275 	mipid_cmd(spi, MIPID_CMD_SLEEP_IN);
276 	msleep(50);
277 }
278 
n8x0_panel_power_on(struct omap_dss_device * dssdev)279 static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
280 {
281 	int r;
282 	struct panel_n8x0_data *bdata = get_board_data(dssdev);
283 	struct panel_drv_data *ddata = get_drv_data(dssdev);
284 	struct spi_device *spi = ddata->spidev;
285 	u8 rev, conf;
286 	u8 display_id[3];
287 	const char *panel_name;
288 
289 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
290 		return 0;
291 
292 	gpio_direction_output(bdata->ctrl_pwrdown, 1);
293 
294 	if (bdata->platform_enable) {
295 		r = bdata->platform_enable(dssdev);
296 		if (r)
297 			goto err_plat_en;
298 	}
299 
300 	r = omapdss_rfbi_display_enable(dssdev);
301 	if (r)
302 		goto err_rfbi_en;
303 
304 	rev = blizzard_read_reg(BLIZZARD_REV_CODE);
305 	conf = blizzard_read_reg(BLIZZARD_CONFIG);
306 
307 	switch (rev & 0xfc) {
308 	case 0x9c:
309 		ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744;
310 		dev_info(&dssdev->dev, "s1d13744 LCD controller rev %d "
311 			"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
312 		break;
313 	case 0xa4:
314 		ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745;
315 		dev_info(&dssdev->dev, "s1d13745 LCD controller rev %d "
316 			"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
317 		break;
318 	default:
319 		dev_err(&dssdev->dev, "invalid s1d1374x revision %02x\n", rev);
320 		r = -ENODEV;
321 		goto err_inv_chip;
322 	}
323 
324 	/* panel */
325 
326 	gpio_direction_output(bdata->panel_reset, 1);
327 
328 	mipid_read(spi, MIPID_CMD_READ_DISP_ID, display_id, 3);
329 	dev_dbg(&spi->dev, "MIPI display ID: %02x%02x%02x\n",
330 			display_id[0], display_id[1], display_id[2]);
331 
332 	switch (display_id[0]) {
333 	case 0x45:
334 		panel_name = "lph8923";
335 		break;
336 	case 0x83:
337 		panel_name = "ls041y3";
338 		break;
339 	default:
340 		dev_err(&dssdev->dev, "invalid display ID 0x%x\n",
341 				display_id[0]);
342 		r = -ENODEV;
343 		goto err_inv_panel;
344 	}
345 
346 	dev_info(&dssdev->dev, "%s rev %02x LCD detected\n",
347 			panel_name, display_id[1]);
348 
349 	send_sleep_out(spi);
350 	send_init_string(spi);
351 	set_data_lines(spi, 24);
352 	send_display_on(spi);
353 
354 	return 0;
355 
356 err_inv_panel:
357 	/*
358 	 * HACK: we should turn off the panel here, but there is some problem
359 	 * with the initialization sequence, and we fail to init the panel if we
360 	 * have turned it off
361 	 */
362 	/* gpio_direction_output(bdata->panel_reset, 0); */
363 err_inv_chip:
364 	omapdss_rfbi_display_disable(dssdev);
365 err_rfbi_en:
366 	if (bdata->platform_disable)
367 		bdata->platform_disable(dssdev);
368 err_plat_en:
369 	gpio_direction_output(bdata->ctrl_pwrdown, 0);
370 	return r;
371 }
372 
n8x0_panel_power_off(struct omap_dss_device * dssdev)373 static void n8x0_panel_power_off(struct omap_dss_device *dssdev)
374 {
375 	struct panel_n8x0_data *bdata = get_board_data(dssdev);
376 	struct panel_drv_data *ddata = get_drv_data(dssdev);
377 	struct spi_device *spi = ddata->spidev;
378 
379 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
380 		return;
381 
382 	send_display_off(spi);
383 	send_sleep_in(spi);
384 
385 	if (bdata->platform_disable)
386 		bdata->platform_disable(dssdev);
387 
388 	/*
389 	 * HACK: we should turn off the panel here, but there is some problem
390 	 * with the initialization sequence, and we fail to init the panel if we
391 	 * have turned it off
392 	 */
393 	/* gpio_direction_output(bdata->panel_reset, 0); */
394 	gpio_direction_output(bdata->ctrl_pwrdown, 0);
395 	omapdss_rfbi_display_disable(dssdev);
396 }
397 
398 static const struct rfbi_timings n8x0_panel_timings = {
399 	.cs_on_time     = 0,
400 
401 	.we_on_time     = 9000,
402 	.we_off_time    = 18000,
403 	.we_cycle_time  = 36000,
404 
405 	.re_on_time     = 9000,
406 	.re_off_time    = 27000,
407 	.re_cycle_time  = 36000,
408 
409 	.access_time    = 27000,
410 	.cs_off_time    = 36000,
411 
412 	.cs_pulse_width = 0,
413 };
414 
n8x0_bl_update_status(struct backlight_device * dev)415 static int n8x0_bl_update_status(struct backlight_device *dev)
416 {
417 	struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
418 	struct panel_n8x0_data *bdata = get_board_data(dssdev);
419 	struct panel_drv_data *ddata = get_drv_data(dssdev);
420 	int r;
421 	int level;
422 
423 	mutex_lock(&ddata->lock);
424 
425 	if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
426 			dev->props.power == FB_BLANK_UNBLANK)
427 		level = dev->props.brightness;
428 	else
429 		level = 0;
430 
431 	dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
432 
433 	if (!bdata->set_backlight)
434 		r = -EINVAL;
435 	else
436 		r = bdata->set_backlight(dssdev, level);
437 
438 	mutex_unlock(&ddata->lock);
439 
440 	return r;
441 }
442 
n8x0_bl_get_intensity(struct backlight_device * dev)443 static int n8x0_bl_get_intensity(struct backlight_device *dev)
444 {
445 	if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
446 			dev->props.power == FB_BLANK_UNBLANK)
447 		return dev->props.brightness;
448 
449 	return 0;
450 }
451 
452 static const struct backlight_ops n8x0_bl_ops = {
453 	.get_brightness = n8x0_bl_get_intensity,
454 	.update_status  = n8x0_bl_update_status,
455 };
456 
n8x0_panel_probe(struct omap_dss_device * dssdev)457 static int n8x0_panel_probe(struct omap_dss_device *dssdev)
458 {
459 	struct panel_n8x0_data *bdata = get_board_data(dssdev);
460 	struct panel_drv_data *ddata;
461 	struct backlight_device *bldev;
462 	struct backlight_properties props;
463 	int r;
464 
465 	dev_dbg(&dssdev->dev, "probe\n");
466 
467 	if (!bdata)
468 		return -EINVAL;
469 
470 	s_drv_data.dssdev = dssdev;
471 
472 	ddata = &s_drv_data;
473 
474 	mutex_init(&ddata->lock);
475 
476 	dssdev->panel.config = OMAP_DSS_LCD_TFT;
477 	dssdev->panel.timings.x_res = 800;
478 	dssdev->panel.timings.y_res = 480;
479 	dssdev->ctrl.pixel_size = 16;
480 	dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
481 
482 	memset(&props, 0, sizeof(props));
483 	props.max_brightness = 127;
484 	props.type = BACKLIGHT_PLATFORM;
485 	bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
486 			dssdev, &n8x0_bl_ops, &props);
487 	if (IS_ERR(bldev)) {
488 		r = PTR_ERR(bldev);
489 		dev_err(&dssdev->dev, "register backlight failed\n");
490 		return r;
491 	}
492 
493 	ddata->bldev = bldev;
494 
495 	bldev->props.fb_blank = FB_BLANK_UNBLANK;
496 	bldev->props.power = FB_BLANK_UNBLANK;
497 	bldev->props.brightness = 127;
498 
499 	n8x0_bl_update_status(bldev);
500 
501 	return 0;
502 }
503 
n8x0_panel_remove(struct omap_dss_device * dssdev)504 static void n8x0_panel_remove(struct omap_dss_device *dssdev)
505 {
506 	struct panel_drv_data *ddata = get_drv_data(dssdev);
507 	struct backlight_device *bldev;
508 
509 	dev_dbg(&dssdev->dev, "remove\n");
510 
511 	bldev = ddata->bldev;
512 	bldev->props.power = FB_BLANK_POWERDOWN;
513 	n8x0_bl_update_status(bldev);
514 	backlight_device_unregister(bldev);
515 
516 	dev_set_drvdata(&dssdev->dev, NULL);
517 }
518 
n8x0_panel_enable(struct omap_dss_device * dssdev)519 static int n8x0_panel_enable(struct omap_dss_device *dssdev)
520 {
521 	struct panel_drv_data *ddata = get_drv_data(dssdev);
522 	int r;
523 
524 	dev_dbg(&dssdev->dev, "enable\n");
525 
526 	mutex_lock(&ddata->lock);
527 
528 	rfbi_bus_lock();
529 
530 	r = n8x0_panel_power_on(dssdev);
531 
532 	rfbi_bus_unlock();
533 
534 	if (r) {
535 		mutex_unlock(&ddata->lock);
536 		return r;
537 	}
538 
539 	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
540 
541 	mutex_unlock(&ddata->lock);
542 
543 	return 0;
544 }
545 
n8x0_panel_disable(struct omap_dss_device * dssdev)546 static void n8x0_panel_disable(struct omap_dss_device *dssdev)
547 {
548 	struct panel_drv_data *ddata = get_drv_data(dssdev);
549 
550 	dev_dbg(&dssdev->dev, "disable\n");
551 
552 	mutex_lock(&ddata->lock);
553 
554 	rfbi_bus_lock();
555 
556 	n8x0_panel_power_off(dssdev);
557 
558 	rfbi_bus_unlock();
559 
560 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
561 
562 	mutex_unlock(&ddata->lock);
563 }
564 
n8x0_panel_suspend(struct omap_dss_device * dssdev)565 static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
566 {
567 	struct panel_drv_data *ddata = get_drv_data(dssdev);
568 
569 	dev_dbg(&dssdev->dev, "suspend\n");
570 
571 	mutex_lock(&ddata->lock);
572 
573 	rfbi_bus_lock();
574 
575 	n8x0_panel_power_off(dssdev);
576 
577 	rfbi_bus_unlock();
578 
579 	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
580 
581 	mutex_unlock(&ddata->lock);
582 
583 	return 0;
584 }
585 
n8x0_panel_resume(struct omap_dss_device * dssdev)586 static int n8x0_panel_resume(struct omap_dss_device *dssdev)
587 {
588 	struct panel_drv_data *ddata = get_drv_data(dssdev);
589 	int r;
590 
591 	dev_dbg(&dssdev->dev, "resume\n");
592 
593 	mutex_lock(&ddata->lock);
594 
595 	rfbi_bus_lock();
596 
597 	r = n8x0_panel_power_on(dssdev);
598 
599 	rfbi_bus_unlock();
600 
601 	if (r) {
602 		mutex_unlock(&ddata->lock);
603 		return r;
604 	}
605 
606 	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
607 
608 	mutex_unlock(&ddata->lock);
609 
610 	return 0;
611 }
612 
n8x0_panel_get_timings(struct omap_dss_device * dssdev,struct omap_video_timings * timings)613 static void n8x0_panel_get_timings(struct omap_dss_device *dssdev,
614 		struct omap_video_timings *timings)
615 {
616 	*timings = dssdev->panel.timings;
617 }
618 
n8x0_panel_get_resolution(struct omap_dss_device * dssdev,u16 * xres,u16 * yres)619 static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
620 		u16 *xres, u16 *yres)
621 {
622 	*xres = dssdev->panel.timings.x_res;
623 	*yres = dssdev->panel.timings.y_res;
624 }
625 
update_done(void * data)626 static void update_done(void *data)
627 {
628 	rfbi_bus_unlock();
629 }
630 
n8x0_panel_update(struct omap_dss_device * dssdev,u16 x,u16 y,u16 w,u16 h)631 static int n8x0_panel_update(struct omap_dss_device *dssdev,
632 		u16 x, u16 y, u16 w, u16 h)
633 {
634 	struct panel_drv_data *ddata = get_drv_data(dssdev);
635 
636 	dev_dbg(&dssdev->dev, "update\n");
637 
638 	mutex_lock(&ddata->lock);
639 	rfbi_bus_lock();
640 
641 	omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h);
642 
643 	blizzard_ctrl_setup_update(dssdev, x, y, w, h);
644 
645 	omap_rfbi_update(dssdev, x, y, w, h, update_done, NULL);
646 
647 	mutex_unlock(&ddata->lock);
648 
649 	return 0;
650 }
651 
n8x0_panel_sync(struct omap_dss_device * dssdev)652 static int n8x0_panel_sync(struct omap_dss_device *dssdev)
653 {
654 	struct panel_drv_data *ddata = get_drv_data(dssdev);
655 
656 	dev_dbg(&dssdev->dev, "sync\n");
657 
658 	mutex_lock(&ddata->lock);
659 	rfbi_bus_lock();
660 	rfbi_bus_unlock();
661 	mutex_unlock(&ddata->lock);
662 
663 	return 0;
664 }
665 
666 static struct omap_dss_driver n8x0_panel_driver = {
667 	.probe		= n8x0_panel_probe,
668 	.remove		= n8x0_panel_remove,
669 
670 	.enable		= n8x0_panel_enable,
671 	.disable	= n8x0_panel_disable,
672 	.suspend	= n8x0_panel_suspend,
673 	.resume		= n8x0_panel_resume,
674 
675 	.update		= n8x0_panel_update,
676 	.sync		= n8x0_panel_sync,
677 
678 	.get_resolution	= n8x0_panel_get_resolution,
679 	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
680 
681 	.get_timings	= n8x0_panel_get_timings,
682 
683 	.driver         = {
684 		.name   = "n8x0_panel",
685 		.owner  = THIS_MODULE,
686 	},
687 };
688 
689 /* PANEL */
690 
mipid_spi_probe(struct spi_device * spi)691 static int mipid_spi_probe(struct spi_device *spi)
692 {
693 	dev_dbg(&spi->dev, "mipid_spi_probe\n");
694 
695 	spi->mode = SPI_MODE_0;
696 
697 	s_drv_data.spidev = spi;
698 
699 	return 0;
700 }
701 
mipid_spi_remove(struct spi_device * spi)702 static int mipid_spi_remove(struct spi_device *spi)
703 {
704 	dev_dbg(&spi->dev, "mipid_spi_remove\n");
705 	return 0;
706 }
707 
708 static struct spi_driver mipid_spi_driver = {
709 	.driver = {
710 		.name	= "lcd_mipid",
711 		.owner	= THIS_MODULE,
712 	},
713 	.probe	= mipid_spi_probe,
714 	.remove	= __devexit_p(mipid_spi_remove),
715 };
716 
n8x0_panel_drv_init(void)717 static int __init n8x0_panel_drv_init(void)
718 {
719 	int r;
720 
721 	r = spi_register_driver(&mipid_spi_driver);
722 	if (r) {
723 		pr_err("n8x0_panel: spi driver registration failed\n");
724 		return r;
725 	}
726 
727 	r = omap_dss_register_driver(&n8x0_panel_driver);
728 	if (r) {
729 		pr_err("n8x0_panel: dss driver registration failed\n");
730 		spi_unregister_driver(&mipid_spi_driver);
731 		return r;
732 	}
733 
734 	return 0;
735 }
736 
n8x0_panel_drv_exit(void)737 static void __exit n8x0_panel_drv_exit(void)
738 {
739 	spi_unregister_driver(&mipid_spi_driver);
740 
741 	omap_dss_unregister_driver(&n8x0_panel_driver);
742 }
743 
744 module_init(n8x0_panel_drv_init);
745 module_exit(n8x0_panel_drv_exit);
746 MODULE_LICENSE("GPL");
747