aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/displays/panel-tpo-td043mtea1.c')
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c211
1 files changed, 79 insertions, 132 deletions
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index 6b6643911d2..2462b9ec666 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -47,20 +47,16 @@
47 TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL) 47 TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
48 48
49static const u16 tpo_td043_def_gamma[12] = { 49static const u16 tpo_td043_def_gamma[12] = {
50 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023 50 106, 200, 289, 375, 460, 543, 625, 705, 785, 864, 942, 1020
51}; 51};
52 52
53struct tpo_td043_device { 53struct 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;
57 u16 gamma[12]; 56 u16 gamma[12];
58 u32 mode; 57 u32 mode;
59 u32 hmirror:1; 58 u32 hmirror:1;
60 u32 vmirror:1; 59 u32 vmirror:1;
61 u32 powered_on:1;
62 u32 spi_suspended:1;
63 u32 power_on_resume:1;
64}; 60};
65 61
66static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) 62static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
@@ -267,27 +263,30 @@ static const struct omap_video_timings tpo_td043_timings = {
267 .vsw = 1, 263 .vsw = 1,
268 .vfp = 39, 264 .vfp = 39,
269 .vbp = 34, 265 .vbp = 34,
270
271 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
272 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
273 .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE,
274 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
275 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
276}; 266};
277 267
278static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) 268static int tpo_td043_power_on(struct omap_dss_device *dssdev)
279{ 269{
280 int nreset_gpio = tpo_td043->nreset_gpio; 270 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
271 int nreset_gpio = dssdev->reset_gpio;
281 int r; 272 int r;
282 273
283 if (tpo_td043->powered_on) 274 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
284 return 0; 275 return 0;
285 276
286 r = regulator_enable(tpo_td043->vcc_reg); 277 r = omapdss_dpi_display_enable(dssdev);
287 if (r != 0) 278 if (r)
288 return 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);
289 288
290 /* wait for panel to stabilize */ 289 /* wait for power up */
291 msleep(160); 290 msleep(160);
292 291
293 if (gpio_is_valid(nreset_gpio)) 292 if (gpio_is_valid(nreset_gpio))
@@ -302,15 +301,19 @@ static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
302 tpo_td043->vmirror); 301 tpo_td043->vmirror);
303 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); 302 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
304 303
305 tpo_td043->powered_on = 1;
306 return 0; 304 return 0;
305err1:
306 omapdss_dpi_display_disable(dssdev);
307err0:
308 return r;
307} 309}
308 310
309static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043) 311static void tpo_td043_power_off(struct omap_dss_device *dssdev)
310{ 312{
311 int nreset_gpio = tpo_td043->nreset_gpio; 313 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
314 int nreset_gpio = dssdev->reset_gpio;
312 315
313 if (!tpo_td043->powered_on) 316 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
314 return; 317 return;
315 318
316 tpo_td043_write(tpo_td043->spi, 3, 319 tpo_td043_write(tpo_td043->spi, 3,
@@ -326,79 +329,54 @@ static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
326 329
327 regulator_disable(tpo_td043->vcc_reg); 330 regulator_disable(tpo_td043->vcc_reg);
328 331
329 tpo_td043->powered_on = 0; 332 if (dssdev->platform_disable)
333 dssdev->platform_disable(dssdev);
334
335 omapdss_dpi_display_disable(dssdev);
330} 336}
331 337
332static int tpo_td043_enable_dss(struct omap_dss_device *dssdev) 338static int tpo_td043_enable(struct omap_dss_device *dssdev)
333{ 339{
334 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 340 int ret;
335 int r;
336
337 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
338 return 0;
339
340 omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
341 omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
342
343 r = omapdss_dpi_display_enable(dssdev);
344 if (r)
345 goto err0;
346 341
347 if (dssdev->platform_enable) { 342 dev_dbg(&dssdev->dev, "enable\n");
348 r = dssdev->platform_enable(dssdev);
349 if (r)
350 goto err1;
351 }
352 343
353 /* 344 ret = tpo_td043_power_on(dssdev);
354 * If we are resuming from system suspend, SPI clocks might not be 345 if (ret)
355 * enabled yet, so we'll program the LCD from SPI PM resume callback. 346 return ret;
356 */
357 if (!tpo_td043->spi_suspended) {
358 r = tpo_td043_power_on(tpo_td043);
359 if (r)
360 goto err1;
361 }
362 347
363 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 348 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
364 349
365 return 0; 350 return 0;
366err1:
367 omapdss_dpi_display_disable(dssdev);
368err0:
369 return r;
370} 351}
371 352
372static void tpo_td043_disable_dss(struct omap_dss_device *dssdev) 353static void tpo_td043_disable(struct omap_dss_device *dssdev)
373{ 354{
374 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 355 dev_dbg(&dssdev->dev, "disable\n");
375
376 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
377 return;
378
379 if (dssdev->platform_disable)
380 dssdev->platform_disable(dssdev);
381 356
382 omapdss_dpi_display_disable(dssdev); 357 tpo_td043_power_off(dssdev);
383 358
384 if (!tpo_td043->spi_suspended) 359 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
385 tpo_td043_power_off(tpo_td043);
386} 360}
387 361
388static int tpo_td043_enable(struct omap_dss_device *dssdev) 362static int tpo_td043_suspend(struct omap_dss_device *dssdev)
389{ 363{
390 dev_dbg(&dssdev->dev, "enable\n"); 364 tpo_td043_power_off(dssdev);
391 365 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
392 return tpo_td043_enable_dss(dssdev); 366 return 0;
393} 367}
394 368
395static void tpo_td043_disable(struct omap_dss_device *dssdev) 369static int tpo_td043_resume(struct omap_dss_device *dssdev)
396{ 370{
397 dev_dbg(&dssdev->dev, "disable\n"); 371 int r = 0;
372
373 r = tpo_td043_power_on(dssdev);
374 if (r)
375 return r;
398 376
399 tpo_td043_disable_dss(dssdev); 377 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
400 378
401 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 379 return 0;
402} 380}
403 381
404static int tpo_td043_probe(struct omap_dss_device *dssdev) 382static int tpo_td043_probe(struct omap_dss_device *dssdev)
@@ -414,6 +392,8 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
414 return -ENODEV; 392 return -ENODEV;
415 } 393 }
416 394
395 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS |
396 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IPC;
417 dssdev->panel.timings = tpo_td043_timings; 397 dssdev->panel.timings = tpo_td043_timings;
418 dssdev->ctrl.pixel_size = 24; 398 dssdev->ctrl.pixel_size = 24;
419 399
@@ -428,12 +408,17 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
428 } 408 }
429 409
430 if (gpio_is_valid(nreset_gpio)) { 410 if (gpio_is_valid(nreset_gpio)) {
431 ret = gpio_request_one(nreset_gpio, GPIOF_OUT_INIT_LOW, 411 ret = gpio_request(nreset_gpio, "lcd reset");
432 "lcd reset");
433 if (ret < 0) { 412 if (ret < 0) {
434 dev_err(&dssdev->dev, "couldn't request reset GPIO\n"); 413 dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
435 goto fail_gpio_req; 414 goto fail_gpio_req;
436 } 415 }
416
417 ret = gpio_direction_output(nreset_gpio, 0);
418 if (ret < 0) {
419 dev_err(&dssdev->dev, "couldn't set GPIO direction\n");
420 goto fail_gpio_direction;
421 }
437 } 422 }
438 423
439 ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group); 424 ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
@@ -442,6 +427,8 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
442 427
443 return 0; 428 return 0;
444 429
430fail_gpio_direction:
431 gpio_free(nreset_gpio);
445fail_gpio_req: 432fail_gpio_req:
446 regulator_put(tpo_td043->vcc_reg); 433 regulator_put(tpo_td043->vcc_reg);
447fail_regulator: 434fail_regulator:
@@ -462,32 +449,17 @@ static void tpo_td043_remove(struct omap_dss_device *dssdev)
462 gpio_free(nreset_gpio); 449 gpio_free(nreset_gpio);
463} 450}
464 451
465static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
466 struct omap_video_timings *timings)
467{
468 omapdss_dpi_set_timings(dssdev, timings);
469
470 dssdev->panel.timings = *timings;
471}
472
473static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
474 struct omap_video_timings *timings)
475{
476 return dpi_check_timings(dssdev, timings);
477}
478
479static struct omap_dss_driver tpo_td043_driver = { 452static struct omap_dss_driver tpo_td043_driver = {
480 .probe = tpo_td043_probe, 453 .probe = tpo_td043_probe,
481 .remove = tpo_td043_remove, 454 .remove = tpo_td043_remove,
482 455
483 .enable = tpo_td043_enable, 456 .enable = tpo_td043_enable,
484 .disable = tpo_td043_disable, 457 .disable = tpo_td043_disable,
458 .suspend = tpo_td043_suspend,
459 .resume = tpo_td043_resume,
485 .set_mirror = tpo_td043_set_hmirror, 460 .set_mirror = tpo_td043_set_hmirror,
486 .get_mirror = tpo_td043_get_hmirror, 461 .get_mirror = tpo_td043_get_hmirror,
487 462
488 .set_timings = tpo_td043_set_timings,
489 .check_timings = tpo_td043_check_timings,
490
491 .driver = { 463 .driver = {
492 .name = "tpo_td043mtea1_panel", 464 .name = "tpo_td043mtea1_panel",
493 .owner = THIS_MODULE, 465 .owner = THIS_MODULE,
@@ -519,7 +491,6 @@ static int tpo_td043_spi_probe(struct spi_device *spi)
519 return -ENOMEM; 491 return -ENOMEM;
520 492
521 tpo_td043->spi = spi; 493 tpo_td043->spi = spi;
522 tpo_td043->nreset_gpio = dssdev->reset_gpio;
523 dev_set_drvdata(&spi->dev, tpo_td043); 494 dev_set_drvdata(&spi->dev, tpo_td043);
524 dev_set_drvdata(&dssdev->dev, tpo_td043); 495 dev_set_drvdata(&dssdev->dev, tpo_td043);
525 496
@@ -528,7 +499,7 @@ static int tpo_td043_spi_probe(struct spi_device *spi)
528 return 0; 499 return 0;
529} 500}
530 501
531static int tpo_td043_spi_remove(struct spi_device *spi) 502static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
532{ 503{
533 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev); 504 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev);
534 505
@@ -538,52 +509,28 @@ static int tpo_td043_spi_remove(struct spi_device *spi)
538 return 0; 509 return 0;
539} 510}
540 511
541#ifdef CONFIG_PM_SLEEP
542static int tpo_td043_spi_suspend(struct device *dev)
543{
544 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
545
546 dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043);
547
548 tpo_td043->power_on_resume = tpo_td043->powered_on;
549 tpo_td043_power_off(tpo_td043);
550 tpo_td043->spi_suspended = 1;
551
552 return 0;
553}
554
555static int tpo_td043_spi_resume(struct device *dev)
556{
557 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
558 int ret;
559
560 dev_dbg(dev, "tpo_td043_spi_resume\n");
561
562 if (tpo_td043->power_on_resume) {
563 ret = tpo_td043_power_on(tpo_td043);
564 if (ret)
565 return ret;
566 }
567 tpo_td043->spi_suspended = 0;
568
569 return 0;
570}
571#endif
572
573static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,
574 tpo_td043_spi_suspend, tpo_td043_spi_resume);
575
576static struct spi_driver tpo_td043_spi_driver = { 512static struct spi_driver tpo_td043_spi_driver = {
577 .driver = { 513 .driver = {
578 .name = "tpo_td043mtea1_panel_spi", 514 .name = "tpo_td043mtea1_panel_spi",
515 .bus = &spi_bus_type,
579 .owner = THIS_MODULE, 516 .owner = THIS_MODULE,
580 .pm = &tpo_td043_spi_pm,
581 }, 517 },
582 .probe = tpo_td043_spi_probe, 518 .probe = tpo_td043_spi_probe,
583 .remove = tpo_td043_spi_remove, 519 .remove = __devexit_p(tpo_td043_spi_remove),
584}; 520};
585 521
586module_spi_driver(tpo_td043_spi_driver); 522static int __init tpo_td043_init(void)
523{
524 return spi_register_driver(&tpo_td043_spi_driver);
525}
526
527static void __exit tpo_td043_exit(void)
528{
529 spi_unregister_driver(&tpo_td043_spi_driver);
530}
531
532module_init(tpo_td043_init);
533module_exit(tpo_td043_exit);
587 534
588MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>"); 535MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
589MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver"); 536MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");