diff options
author | Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | 2012-03-20 04:49:51 -0400 |
---|---|---|
committer | Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | 2012-03-20 04:49:51 -0400 |
commit | e9fe8a714e450b26f76eaf8832f5b9fe24d00e79 (patch) | |
tree | 78d0045cfdede7ad7e42181bde96978fdc792e06 /drivers/video/omap2/displays | |
parent | f413070e3f0bccb40ca939b90699347daf815607 (diff) | |
parent | df01d53068bdf31609aafd9a857901a1f16dfa52 (diff) |
Merge branch 'for-3.4' of git://gitorious.org/linux-omap-dss2/linux into fbdev-next
Diffstat (limited to 'drivers/video/omap2/displays')
-rw-r--r-- | drivers/video/omap2/displays/panel-generic-dpi.c | 23 | ||||
-rw-r--r-- | drivers/video/omap2/displays/panel-tpo-td043mtea1.c | 153 |
2 files changed, 132 insertions, 44 deletions
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c index 28b9a6d61b0f..30fe4dfeb227 100644 --- a/drivers/video/omap2/displays/panel-generic-dpi.c +++ b/drivers/video/omap2/displays/panel-generic-dpi.c | |||
@@ -363,6 +363,29 @@ static struct panel_config generic_dpi_panels[] = { | |||
363 | 363 | ||
364 | .name = "ortustech_com43h4m10xtc", | 364 | .name = "ortustech_com43h4m10xtc", |
365 | }, | 365 | }, |
366 | |||
367 | /* Innolux AT080TN52 */ | ||
368 | { | ||
369 | { | ||
370 | .x_res = 800, | ||
371 | .y_res = 600, | ||
372 | |||
373 | .pixel_clock = 41142, | ||
374 | |||
375 | .hsw = 20, | ||
376 | .hfp = 210, | ||
377 | .hbp = 46, | ||
378 | |||
379 | .vsw = 10, | ||
380 | .vfp = 12, | ||
381 | .vbp = 23, | ||
382 | }, | ||
383 | .acb = 0x0, | ||
384 | .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | | ||
385 | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO, | ||
386 | |||
387 | .name = "innolux_at080tn52", | ||
388 | }, | ||
366 | }; | 389 | }; |
367 | 390 | ||
368 | struct panel_drv_data { | 391 | struct panel_drv_data { |
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c index 0ca9644f9ea5..32f3fcd7f0f0 100644 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c | |||
@@ -47,16 +47,20 @@ | |||
47 | TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL) | 47 | TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL) |
48 | 48 | ||
49 | static const u16 tpo_td043_def_gamma[12] = { | 49 | static const u16 tpo_td043_def_gamma[12] = { |
50 | 106, 200, 289, 375, 460, 543, 625, 705, 785, 864, 942, 1020 | 50 | 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023 |
51 | }; | 51 | }; |
52 | 52 | ||
53 | struct tpo_td043_device { | 53 | struct tpo_td043_device { |
54 | struct spi_device *spi; | 54 | struct spi_device *spi; |
55 | struct regulator *vcc_reg; | 55 | struct regulator *vcc_reg; |
56 | int nreset_gpio; | ||
56 | u16 gamma[12]; | 57 | u16 gamma[12]; |
57 | u32 mode; | 58 | u32 mode; |
58 | u32 hmirror:1; | 59 | u32 hmirror:1; |
59 | u32 vmirror:1; | 60 | u32 vmirror:1; |
61 | u32 powered_on:1; | ||
62 | u32 spi_suspended:1; | ||
63 | u32 power_on_resume:1; | ||
60 | }; | 64 | }; |
61 | 65 | ||
62 | static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) | 66 | static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) |
@@ -265,28 +269,16 @@ static const struct omap_video_timings tpo_td043_timings = { | |||
265 | .vbp = 34, | 269 | .vbp = 34, |
266 | }; | 270 | }; |
267 | 271 | ||
268 | static int tpo_td043_power_on(struct omap_dss_device *dssdev) | 272 | static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) |
269 | { | 273 | { |
270 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); | 274 | int nreset_gpio = tpo_td043->nreset_gpio; |
271 | int nreset_gpio = dssdev->reset_gpio; | ||
272 | int r; | ||
273 | 275 | ||
274 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | 276 | if (tpo_td043->powered_on) |
275 | return 0; | 277 | return 0; |
276 | 278 | ||
277 | r = omapdss_dpi_display_enable(dssdev); | ||
278 | if (r) | ||
279 | goto err0; | ||
280 | |||
281 | if (dssdev->platform_enable) { | ||
282 | r = dssdev->platform_enable(dssdev); | ||
283 | if (r) | ||
284 | goto err1; | ||
285 | } | ||
286 | |||
287 | regulator_enable(tpo_td043->vcc_reg); | 279 | regulator_enable(tpo_td043->vcc_reg); |
288 | 280 | ||
289 | /* wait for power up */ | 281 | /* wait for regulator to stabilize */ |
290 | msleep(160); | 282 | msleep(160); |
291 | 283 | ||
292 | if (gpio_is_valid(nreset_gpio)) | 284 | if (gpio_is_valid(nreset_gpio)) |
@@ -301,19 +293,15 @@ static int tpo_td043_power_on(struct omap_dss_device *dssdev) | |||
301 | tpo_td043->vmirror); | 293 | tpo_td043->vmirror); |
302 | tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); | 294 | tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); |
303 | 295 | ||
296 | tpo_td043->powered_on = 1; | ||
304 | return 0; | 297 | return 0; |
305 | err1: | ||
306 | omapdss_dpi_display_disable(dssdev); | ||
307 | err0: | ||
308 | return r; | ||
309 | } | 298 | } |
310 | 299 | ||
311 | static void tpo_td043_power_off(struct omap_dss_device *dssdev) | 300 | static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043) |
312 | { | 301 | { |
313 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); | 302 | int nreset_gpio = tpo_td043->nreset_gpio; |
314 | int nreset_gpio = dssdev->reset_gpio; | ||
315 | 303 | ||
316 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | 304 | if (!tpo_td043->powered_on) |
317 | return; | 305 | return; |
318 | 306 | ||
319 | tpo_td043_write(tpo_td043->spi, 3, | 307 | tpo_td043_write(tpo_td043->spi, 3, |
@@ -329,54 +317,94 @@ static void tpo_td043_power_off(struct omap_dss_device *dssdev) | |||
329 | 317 | ||
330 | regulator_disable(tpo_td043->vcc_reg); | 318 | regulator_disable(tpo_td043->vcc_reg); |
331 | 319 | ||
320 | tpo_td043->powered_on = 0; | ||
321 | } | ||
322 | |||
323 | static int tpo_td043_enable_dss(struct omap_dss_device *dssdev) | ||
324 | { | ||
325 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); | ||
326 | int r; | ||
327 | |||
328 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | ||
329 | return 0; | ||
330 | |||
331 | r = omapdss_dpi_display_enable(dssdev); | ||
332 | if (r) | ||
333 | goto err0; | ||
334 | |||
335 | if (dssdev->platform_enable) { | ||
336 | r = dssdev->platform_enable(dssdev); | ||
337 | if (r) | ||
338 | goto err1; | ||
339 | } | ||
340 | |||
341 | /* | ||
342 | * If we are resuming from system suspend, SPI clocks might not be | ||
343 | * enabled yet, so we'll program the LCD from SPI PM resume callback. | ||
344 | */ | ||
345 | if (!tpo_td043->spi_suspended) { | ||
346 | r = tpo_td043_power_on(tpo_td043); | ||
347 | if (r) | ||
348 | goto err1; | ||
349 | } | ||
350 | |||
351 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
352 | |||
353 | return 0; | ||
354 | err1: | ||
355 | omapdss_dpi_display_disable(dssdev); | ||
356 | err0: | ||
357 | return r; | ||
358 | } | ||
359 | |||
360 | static void tpo_td043_disable_dss(struct omap_dss_device *dssdev) | ||
361 | { | ||
362 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); | ||
363 | |||
364 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | ||
365 | return; | ||
366 | |||
332 | if (dssdev->platform_disable) | 367 | if (dssdev->platform_disable) |
333 | dssdev->platform_disable(dssdev); | 368 | dssdev->platform_disable(dssdev); |
334 | 369 | ||
335 | omapdss_dpi_display_disable(dssdev); | 370 | omapdss_dpi_display_disable(dssdev); |
371 | |||
372 | if (!tpo_td043->spi_suspended) | ||
373 | tpo_td043_power_off(tpo_td043); | ||
336 | } | 374 | } |
337 | 375 | ||
338 | static int tpo_td043_enable(struct omap_dss_device *dssdev) | 376 | static int tpo_td043_enable(struct omap_dss_device *dssdev) |
339 | { | 377 | { |
340 | int ret; | ||
341 | |||
342 | dev_dbg(&dssdev->dev, "enable\n"); | 378 | dev_dbg(&dssdev->dev, "enable\n"); |
343 | 379 | ||
344 | ret = tpo_td043_power_on(dssdev); | 380 | return tpo_td043_enable_dss(dssdev); |
345 | if (ret) | ||
346 | return ret; | ||
347 | |||
348 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
349 | |||
350 | return 0; | ||
351 | } | 381 | } |
352 | 382 | ||
353 | static void tpo_td043_disable(struct omap_dss_device *dssdev) | 383 | static void tpo_td043_disable(struct omap_dss_device *dssdev) |
354 | { | 384 | { |
355 | dev_dbg(&dssdev->dev, "disable\n"); | 385 | dev_dbg(&dssdev->dev, "disable\n"); |
356 | 386 | ||
357 | tpo_td043_power_off(dssdev); | 387 | tpo_td043_disable_dss(dssdev); |
358 | 388 | ||
359 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | 389 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; |
360 | } | 390 | } |
361 | 391 | ||
362 | static int tpo_td043_suspend(struct omap_dss_device *dssdev) | 392 | static int tpo_td043_suspend(struct omap_dss_device *dssdev) |
363 | { | 393 | { |
364 | tpo_td043_power_off(dssdev); | 394 | dev_dbg(&dssdev->dev, "suspend\n"); |
395 | |||
396 | tpo_td043_disable_dss(dssdev); | ||
397 | |||
365 | dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; | 398 | dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; |
399 | |||
366 | return 0; | 400 | return 0; |
367 | } | 401 | } |
368 | 402 | ||
369 | static int tpo_td043_resume(struct omap_dss_device *dssdev) | 403 | static int tpo_td043_resume(struct omap_dss_device *dssdev) |
370 | { | 404 | { |
371 | int r = 0; | 405 | dev_dbg(&dssdev->dev, "resume\n"); |
372 | |||
373 | r = tpo_td043_power_on(dssdev); | ||
374 | if (r) | ||
375 | return r; | ||
376 | |||
377 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
378 | 406 | ||
379 | return 0; | 407 | return tpo_td043_enable_dss(dssdev); |
380 | } | 408 | } |
381 | 409 | ||
382 | static int tpo_td043_probe(struct omap_dss_device *dssdev) | 410 | static int tpo_td043_probe(struct omap_dss_device *dssdev) |
@@ -484,6 +512,7 @@ static int tpo_td043_spi_probe(struct spi_device *spi) | |||
484 | return -ENOMEM; | 512 | return -ENOMEM; |
485 | 513 | ||
486 | tpo_td043->spi = spi; | 514 | tpo_td043->spi = spi; |
515 | tpo_td043->nreset_gpio = dssdev->reset_gpio; | ||
487 | dev_set_drvdata(&spi->dev, tpo_td043); | 516 | dev_set_drvdata(&spi->dev, tpo_td043); |
488 | dev_set_drvdata(&dssdev->dev, tpo_td043); | 517 | dev_set_drvdata(&dssdev->dev, tpo_td043); |
489 | 518 | ||
@@ -502,10 +531,46 @@ static int __devexit tpo_td043_spi_remove(struct spi_device *spi) | |||
502 | return 0; | 531 | return 0; |
503 | } | 532 | } |
504 | 533 | ||
534 | #ifdef CONFIG_PM_SLEEP | ||
535 | static int tpo_td043_spi_suspend(struct device *dev) | ||
536 | { | ||
537 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); | ||
538 | |||
539 | dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043); | ||
540 | |||
541 | tpo_td043->power_on_resume = tpo_td043->powered_on; | ||
542 | tpo_td043_power_off(tpo_td043); | ||
543 | tpo_td043->spi_suspended = 1; | ||
544 | |||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | static int tpo_td043_spi_resume(struct device *dev) | ||
549 | { | ||
550 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); | ||
551 | int ret; | ||
552 | |||
553 | dev_dbg(dev, "tpo_td043_spi_resume\n"); | ||
554 | |||
555 | if (tpo_td043->power_on_resume) { | ||
556 | ret = tpo_td043_power_on(tpo_td043); | ||
557 | if (ret) | ||
558 | return ret; | ||
559 | } | ||
560 | tpo_td043->spi_suspended = 0; | ||
561 | |||
562 | return 0; | ||
563 | } | ||
564 | #endif | ||
565 | |||
566 | static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm, | ||
567 | tpo_td043_spi_suspend, tpo_td043_spi_resume); | ||
568 | |||
505 | static struct spi_driver tpo_td043_spi_driver = { | 569 | static struct spi_driver tpo_td043_spi_driver = { |
506 | .driver = { | 570 | .driver = { |
507 | .name = "tpo_td043mtea1_panel_spi", | 571 | .name = "tpo_td043mtea1_panel_spi", |
508 | .owner = THIS_MODULE, | 572 | .owner = THIS_MODULE, |
573 | .pm = &tpo_td043_spi_pm, | ||
509 | }, | 574 | }, |
510 | .probe = tpo_td043_spi_probe, | 575 | .probe = tpo_td043_spi_probe, |
511 | .remove = __devexit_p(tpo_td043_spi_remove), | 576 | .remove = __devexit_p(tpo_td043_spi_remove), |