diff options
Diffstat (limited to 'drivers')
| -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,  	},  };  |