Merge branch 'for-3.4' of git://gitorious.org/linux-omap-dss2/linux into fbdev-next
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>
Tue, 20 Mar 2012 08:49:51 +0000 (08:49 +0000)
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>
Tue, 20 Mar 2012 08:49:51 +0000 (08:49 +0000)
1  2 
drivers/video/omap2/displays/panel-tpo-td043mtea1.c

index 0ca9644f9ea5b1cf6a5cb72f7330c787ac45fa4c,d63e5e5dbbfac2d505ca2be38b569594946baad2..32f3fcd7f0f0adc8361523035ce5435412578424
                        TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
  
  static const u16 tpo_td043_def_gamma[12] = {
-       106, 200, 289, 375, 460, 543, 625, 705, 785, 864, 942, 1020
+       105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
  };
  
  struct tpo_td043_device {
        struct spi_device *spi;
        struct regulator *vcc_reg;
+       int nreset_gpio;
        u16 gamma[12];
        u32 mode;
        u32 hmirror:1;
        u32 vmirror:1;
+       u32 powered_on:1;
+       u32 spi_suspended:1;
+       u32 power_on_resume:1;
  };
  
  static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
@@@ -265,28 -269,16 +269,16 @@@ static const struct omap_video_timings 
        .vbp            = 34,
  };
  
- static int tpo_td043_power_on(struct omap_dss_device *dssdev)
+ static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
  {
-       struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
-       int nreset_gpio = dssdev->reset_gpio;
-       int r;
+       int nreset_gpio = tpo_td043->nreset_gpio;
  
-       if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+       if (tpo_td043->powered_on)
                return 0;
  
-       r = omapdss_dpi_display_enable(dssdev);
-       if (r)
-               goto err0;
-       if (dssdev->platform_enable) {
-               r = dssdev->platform_enable(dssdev);
-               if (r)
-                       goto err1;
-       }
        regulator_enable(tpo_td043->vcc_reg);
  
-       /* wait for power up */
+       /* wait for regulator to stabilize */
        msleep(160);
  
        if (gpio_is_valid(nreset_gpio))
                        tpo_td043->vmirror);
        tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
  
+       tpo_td043->powered_on = 1;
        return 0;
- err1:
-       omapdss_dpi_display_disable(dssdev);
- err0:
-       return r;
  }
  
- static void tpo_td043_power_off(struct omap_dss_device *dssdev)
+ static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
  {
-       struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
-       int nreset_gpio = dssdev->reset_gpio;
+       int nreset_gpio = tpo_td043->nreset_gpio;
  
-       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+       if (!tpo_td043->powered_on)
                return;
  
        tpo_td043_write(tpo_td043->spi, 3,
  
        regulator_disable(tpo_td043->vcc_reg);
  
+       tpo_td043->powered_on = 0;
+ }
+ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
+ {
+       struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+       int r;
+       if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+               return 0;
+       r = omapdss_dpi_display_enable(dssdev);
+       if (r)
+               goto err0;
+       if (dssdev->platform_enable) {
+               r = dssdev->platform_enable(dssdev);
+               if (r)
+                       goto err1;
+       }
+       /*
+        * If we are resuming from system suspend, SPI clocks might not be
+        * enabled yet, so we'll program the LCD from SPI PM resume callback.
+        */
+       if (!tpo_td043->spi_suspended) {
+               r = tpo_td043_power_on(tpo_td043);
+               if (r)
+                       goto err1;
+       }
+       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+       return 0;
+ err1:
+       omapdss_dpi_display_disable(dssdev);
+ err0:
+       return r;
+ }
+ static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
+ {
+       struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+               return;
        if (dssdev->platform_disable)
                dssdev->platform_disable(dssdev);
  
        omapdss_dpi_display_disable(dssdev);
+       if (!tpo_td043->spi_suspended)
+               tpo_td043_power_off(tpo_td043);
  }
  
  static int tpo_td043_enable(struct omap_dss_device *dssdev)
  {
-       int ret;
        dev_dbg(&dssdev->dev, "enable\n");
  
-       ret = tpo_td043_power_on(dssdev);
-       if (ret)
-               return ret;
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-       return 0;
+       return tpo_td043_enable_dss(dssdev);
  }
  
  static void tpo_td043_disable(struct omap_dss_device *dssdev)
  {
        dev_dbg(&dssdev->dev, "disable\n");
  
-       tpo_td043_power_off(dssdev);
+       tpo_td043_disable_dss(dssdev);
  
        dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
  }
  
  static int tpo_td043_suspend(struct omap_dss_device *dssdev)
  {
-       tpo_td043_power_off(dssdev);
+       dev_dbg(&dssdev->dev, "suspend\n");
+       tpo_td043_disable_dss(dssdev);
        dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
        return 0;
  }
  
  static int tpo_td043_resume(struct omap_dss_device *dssdev)
  {
-       int r = 0;
-       r = tpo_td043_power_on(dssdev);
-       if (r)
-               return r;
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+       dev_dbg(&dssdev->dev, "resume\n");
  
-       return 0;
+       return tpo_td043_enable_dss(dssdev);
  }
  
  static int tpo_td043_probe(struct omap_dss_device *dssdev)
        }
  
        if (gpio_is_valid(nreset_gpio)) {
 -              ret = gpio_request(nreset_gpio, "lcd reset");
 +              ret = gpio_request_one(nreset_gpio, GPIOF_OUT_INIT_LOW,
 +                                      "lcd reset");
                if (ret < 0) {
                        dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
                        goto fail_gpio_req;
                }
 -
 -              ret = gpio_direction_output(nreset_gpio, 0);
 -              if (ret < 0) {
 -                      dev_err(&dssdev->dev, "couldn't set GPIO direction\n");
 -                      goto fail_gpio_direction;
 -              }
        }
  
        ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
  
        return 0;
  
 -fail_gpio_direction:
 -      gpio_free(nreset_gpio);
  fail_gpio_req:
        regulator_put(tpo_td043->vcc_reg);
  fail_regulator:
@@@ -484,6 -519,7 +512,7 @@@ static int tpo_td043_spi_probe(struct s
                return -ENOMEM;
  
        tpo_td043->spi = spi;
+       tpo_td043->nreset_gpio = dssdev->reset_gpio;
        dev_set_drvdata(&spi->dev, tpo_td043);
        dev_set_drvdata(&dssdev->dev, tpo_td043);
  
@@@ -502,16 -538,63 +531,52 @@@ static int __devexit tpo_td043_spi_remo
        return 0;
  }
  
+ #ifdef CONFIG_PM_SLEEP
+ static int tpo_td043_spi_suspend(struct device *dev)
+ {
+       struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
+       dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043);
+       tpo_td043->power_on_resume = tpo_td043->powered_on;
+       tpo_td043_power_off(tpo_td043);
+       tpo_td043->spi_suspended = 1;
+       return 0;
+ }
+ static int tpo_td043_spi_resume(struct device *dev)
+ {
+       struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
+       int ret;
+       dev_dbg(dev, "tpo_td043_spi_resume\n");
+       if (tpo_td043->power_on_resume) {
+               ret = tpo_td043_power_on(tpo_td043);
+               if (ret)
+                       return ret;
+       }
+       tpo_td043->spi_suspended = 0;
+       return 0;
+ }
+ #endif
+ static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,
+       tpo_td043_spi_suspend, tpo_td043_spi_resume);
  static struct spi_driver tpo_td043_spi_driver = {
        .driver = {
                .name   = "tpo_td043mtea1_panel_spi",
                .owner  = THIS_MODULE,
+               .pm     = &tpo_td043_spi_pm,
        },
        .probe  = tpo_td043_spi_probe,
        .remove = __devexit_p(tpo_td043_spi_remove),
  };
  
 -static int __init tpo_td043_init(void)
 -{
 -      return spi_register_driver(&tpo_td043_spi_driver);
 -}
 -
 -static void __exit tpo_td043_exit(void)
 -{
 -      spi_unregister_driver(&tpo_td043_spi_driver);
 -}
 -
 -module_init(tpo_td043_init);
 -module_exit(tpo_td043_exit);
 +module_spi_driver(tpo_td043_spi_driver);
  
  MODULE_AUTHOR("GraÅžvydas Ignotas <notasas@gmail.com>");
  MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");