diff options
| author | mattis fjallstrom <mattis@acm.org> | 2015-04-13 16:13:47 -0700 |
|---|---|---|
| committer | mattis fjallstrom <mattis@acm.org> | 2015-04-13 16:13:47 -0700 |
| commit | 51f4dba7f9029e25e6b91b3a8b9c6569c21af0cc (patch) | |
| tree | 317ea024c532133ba7d259e427d9164816e1c2f6 | |
| parent | 26621f86d74d70df0afdb4fc1de819ced3a074f2 (diff) | |
| download | olio-linux-3.10-51f4dba7f9029e25e6b91b3a8b9c6569c21af0cc.tar.xz olio-linux-3.10-51f4dba7f9029e25e6b91b3a8b9c6569c21af0cc.zip | |
Adding basic power management for the backlight and the display panel driver.
Change-Id: Ibe4546e9f7b694f03b5aa6f8b6188f96806c8ad1
| -rw-r--r-- | drivers/leds/leds-lm3530.c | 46 | ||||
| -rw-r--r-- | drivers/video/omap2/displays/panel-ili9342.c | 143 |
2 files changed, 178 insertions, 11 deletions
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c index c3182fae12e..b9661ea70bb 100644 --- a/drivers/leds/leds-lm3530.c +++ b/drivers/leds/leds-lm3530.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015 Olio Devices * Copyright (C) 2011 ST-Ericsson SA. * Copyright (C) 2009 Motorola, Inc. * @@ -6,7 +7,8 @@ * * Simple driver for National Semiconductor LM3530 Backlight driver chip * - * Author: Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com> + * Author: Mattis Fjallstrom <mattis@oliodevices.com> + * based on Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com> * based on leds-lm3530.c by Dan Murphy <D.Murphy@motorola.com> */ @@ -487,7 +489,7 @@ static int lm3530_remove(struct i2c_client *client) } -/*************************************************************************** +/** * lm3530_shutdown - make sure brightness is set to 0 * * The PMIC of the Olio H1 can't provide the power needed by the lm3530, @@ -504,6 +506,45 @@ static void lm3530_shutdown(struct i2c_client *client) return; } +/** + * lm3530_suspend - suspend backlight + * + * For now, off. Should also save the previous setting. + */ + +static int lm3530_suspend(struct device *dev) { + struct led_classdev *led_cdev = dev_get_drvdata(dev); + + printk ("OLIO %s:%s Suspending\n", __FILE__, __FUNCTION__); + + lm3530_brightness_set(led_cdev, LED_OFF); + + return 0; +} + +/** + * lm3530_resume - reset backlight + * + * Turn the backlight on again (Does android take care of this for us?) + */ + +static int lm3530_resume(struct device *dev) { + struct led_classdev *led_cdev = dev_get_drvdata(dev); + + printk ("OLIO %s:%s Resuming\n", __FILE__, __FUNCTION__); + + /* lm3530_brightness_set(led_cdev, 100); */ + + return 0; +} + + +/* ---------------------------------------------------------------------- */ + +static const struct dev_pm_ops lm3530_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(lm3530_suspend, lm3530_resume) +}; + static const struct i2c_device_id lm3530_id[] = { {LM3530_NAME, 0}, {} @@ -518,6 +559,7 @@ static struct i2c_driver lm3530_i2c_driver = { .driver = { .name = LM3530_NAME, .owner = THIS_MODULE, + .pm = &lm3530_pm_ops, }, }; diff --git a/drivers/video/omap2/displays/panel-ili9342.c b/drivers/video/omap2/displays/panel-ili9342.c index 37dc5165e9c..afcf05dfa79 100644 --- a/drivers/video/omap2/displays/panel-ili9342.c +++ b/drivers/video/omap2/displays/panel-ili9342.c @@ -2,8 +2,9 @@ /* * Driver for ili9342 display driver * - * Copyright (C) 2014 Olio Devices Inc. + * Copyright (C) 2014,2015 Olio Devices Inc. * Author: Evan Wilson <evan@oliodevices.com> + * Author: Mattis Fjallstrom <mattis@oliodevices.com> * * Adapted from panel-generic-dpi.c, panel-nec-nl8048hl11-01b.c * @@ -25,8 +26,17 @@ #include <linux/slab.h> #include <linux/spi/spi.h> #include <linux/gpio.h> +#include <linux/device.h> +#include <linux/regulator/consumer.h> + #include <video/omapdss.h> +#ifdef OLIODEBUG +#define oliodebug(...) printk ( __VA_ARGS__ ) +#else +#define oliodebug(...) +#endif + struct panel_config { struct omap_video_timings timings; @@ -250,6 +260,28 @@ static int ili9342_get_recommended_bpp(struct omap_dss_device *dssdev) { return 24; } +/*************************************************************************** + * suspend & resume + * + * For now, this is all handled by the SPI driver (see below). + * Leaving this functions here should we change our minds. + */ + +static int ili9342_disp_suspend (struct device * dev) { + + return 0; +} + +static int ili9342_disp_resume (struct device * dev) { + + return 0; +} + +static struct dev_pm_ops ili9342_disp_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ili9342_disp_suspend, ili9342_disp_resume) +}; + + static struct omap_dss_driver ili9342_driver = { .probe = ili9342_panel_probe, .remove = __exit_p(ili9342_panel_remove), @@ -266,9 +298,20 @@ static struct omap_dss_driver ili9342_driver = { .driver = { .name = "ili9342_panel", .owner = THIS_MODULE, + .pm = &ili9342_disp_pm_ops, }, }; +/* ====================================================================== */ + +/* Here follows the SPI driver - it's required by the panel, but the + * coupling is rather weak. It registers another driver. + */ + +/* ====================================================================== */ + +static struct regulator *spi_regulator; + static int ili9342_spi_write(struct spi_device *spi, bool cmd, unsigned char val) { unsigned short buf; struct spi_message m; @@ -407,6 +450,20 @@ static inline void ili9342_init_seq(struct spi_device *spi) { ili9342_write_cmd(spi, 0x29); } + +static inline void init_ili9342_hw (struct spi_device *spi) { + struct omap_dss_device *panel = spi->dev.platform_data; + + gpio_set_value(panel->reset_gpio, 1); + mdelay(1); + gpio_set_value(panel->reset_gpio, 0); + mdelay(50); + gpio_set_value(panel->reset_gpio, 1); + mdelay(120); + + ili9342_init_seq(spi); +} + static inline int init_ili9342_spi(struct spi_device *spi) { struct omap_dss_device *panel = spi->dev.platform_data; int reset_gpio; @@ -433,35 +490,103 @@ static inline int init_ili9342_spi(struct spi_device *spi) { return -EINVAL; } - gpio_set_value(panel->reset_gpio, 1); - mdelay(1); - gpio_set_value(panel->reset_gpio, 0); - mdelay(50); - gpio_set_value(panel->reset_gpio, 1); - mdelay(120); - - ili9342_init_seq(spi); + init_ili9342_hw (spi); return 0; } + static int ili9342_spi_probe(struct spi_device *spi) { + int err; + int ret; + + spi_regulator = devm_regulator_get(&spi->dev, "vdd"); + + if (IS_ERR(spi_regulator)) { + dev_err(&spi->dev, "regulator get failed\n"); + err = PTR_ERR(spi_regulator); + spi_regulator = NULL; + return err; + } + + ret = regulator_enable(spi_regulator); + + if (ret) { + dev_err(&spi->dev, "Failed to enable vdd: %d\n", ret); + return ret; + } + init_ili9342_spi(spi); + return omap_dss_register_driver(&ili9342_driver); } static int ili9342_spi_remove(struct spi_device *spi) { + oliodebug ("OLIO %s:%s Removing SPI\n", __FILE__, __FUNCTION__); + omap_dss_unregister_driver(&ili9342_driver); return 0; } +static int ili9342_suspend(struct device *dev) { + int ret; + + oliodebug ("OLIO %s:%s Suspending SPI for %s\n", __FILE__, __FUNCTION__, dev_name(dev)); + + ret = regulator_disable(spi_regulator); + if (ret) { + dev_err(dev, "Failed to disable vdd:%d\n", + ret); + return ret; + } + + return 0; +} + + +static int ili9342_resume(struct device *dev) { + int ret; + + /* HACK WARNING: We need an spi_device here. If, as can be assumed, + * the device pointer passed in points to a device in an spi_device, + * it's the first device in the spi_device struct. In other words, + * it's address is the same as the spi_device and a cast should be OK. + */ + + /* IF, otoh, that's an incorrect assumption ... then this will lead + * to horrible crashes. But oh well, you can't win 'em all. + */ + + struct spi_device * spi = (struct spi_device *) dev; + + oliodebug ("OLIO %s:%s Resuming SPI for %s\n", __FILE__, __FUNCTION__, dev_name(dev)); + + ret = regulator_enable(spi_regulator); + + if (ret) { + dev_err(&spi->dev, "Failed to enable vdd: %d\n", ret); + return ret; + } + + init_ili9342_hw (spi); + + return 0; +} + + +static struct dev_pm_ops ili9342_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ili9342_suspend, ili9342_resume) +}; + + static struct spi_driver ili9342_spi_driver = { .probe = ili9342_spi_probe, .remove = ili9342_spi_remove, .driver = { .name = "ili9342-spi", .owner = THIS_MODULE, + .pm = &ili9342_pm_ops, }, }; |