diff options
| -rw-r--r-- | arch/arm/configs/omap3_h1_defconfig | 2 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/board-omap3h1.c | 4 | ||||
| -rw-r--r-- | drivers/video/omap2/displays/panel-ili9342.c | 327 | ||||
| -rw-r--r-- | kernel/power/Kconfig | 2 | 
4 files changed, 117 insertions, 218 deletions
| diff --git a/arch/arm/configs/omap3_h1_defconfig b/arch/arm/configs/omap3_h1_defconfig index 9b7c431d7b8..b107860b808 100644 --- a/arch/arm/configs/omap3_h1_defconfig +++ b/arch/arm/configs/omap3_h1_defconfig @@ -548,7 +548,7 @@ CONFIG_PM_OPP=y  CONFIG_PM_CLK=y  CONFIG_CPU_PM=y  CONFIG_SUSPEND_TIME=y -CONFIG_HAS_AMBIENTMODE=y +# CONFIG_HAS_AMBIENTMODE is not set  CONFIG_ARCH_SUSPEND_POSSIBLE=y  CONFIG_ARM_CPU_SUSPEND=y  CONFIG_NET=y diff --git a/arch/arm/mach-omap2/board-omap3h1.c b/arch/arm/mach-omap2/board-omap3h1.c index d81c63eb628..063b3851b4e 100644 --- a/arch/arm/mach-omap2/board-omap3h1.c +++ b/arch/arm/mach-omap2/board-omap3h1.c @@ -204,8 +204,8 @@ static struct lm3530_platform_data omap3h1_backlight_platform_data = {  	//.pwm_pol_hi = true,  	//.als_avrg_time = LM3530_ALS_AVRG_TIME_512ms,  	.brt_ramp_law = 0, -	.brt_ramp_fall = LM3530_RAMP_TIME_1s, /* LM3530_RAMP_TIME_1s, */ -	.brt_ramp_rise = LM3530_RAMP_TIME_1s, /* LM3530_RAMP_TIME_1s, */ +	.brt_ramp_fall = LM3530_RAMP_TIME_1ms, /* LM3530_RAMP_TIME_1s, */ +	.brt_ramp_rise = LM3530_RAMP_TIME_1ms, /* LM3530_RAMP_TIME_1s, */  	//.als1_resistor_sel = LM3530_ALS_IMPD_13_53kOhm,  	//.als2_resistor_sel = LM3530_ALS_IMPD_Z,  	//.als_vmin = 730,	    /* mV */ diff --git a/drivers/video/omap2/displays/panel-ili9342.c b/drivers/video/omap2/displays/panel-ili9342.c index 42f23fdb4ff..d79284e7326 100644 --- a/drivers/video/omap2/displays/panel-ili9342.c +++ b/drivers/video/omap2/displays/panel-ili9342.c @@ -38,6 +38,11 @@  #define oliodebug(...)   #endif  +#define CMD_SLEEP_IN		0x10 +#define CMD_SLEEP_OUT		0x11 +#define CMD_DISP_OFF		0x28 +#define CMD_DISP_ON		0x29 +  struct panel_config {  	struct omap_video_timings timings; @@ -82,14 +87,86 @@ static struct panel_config ili9342_panels[] = {  };  struct panel_drv_data { -  	struct omap_dss_device *dssdev; -  	struct panel_config *panel_config; +	unsigned long	hw_guard_end;		/* next value of jiffies +						   when we can issue the +						   next sleep in/out command */ +	unsigned long	hw_guard_wait;		/* max guard time in jiffies */ +	struct spi_device *spi; +  	struct mutex lock;  }; +static struct panel_drv_data ili9342_drv_data; + +static int ili9342_spi_write(struct spi_device *spi, bool cmd, unsigned char val) { +	unsigned short buf; +	struct spi_message m; +	struct spi_transfer t = { +		.tx_buf = &buf, +		.len = 2, +		.bits_per_word = 9, +	}; + +	buf = cmd ? 0 : (1 << 8); +	buf |= val; +	dev_dbg(&spi->dev, "SPI sync: %x", buf); + +	spi_message_init(&m); +	spi_message_add_tail(&t, &m); +	if (spi_sync(spi, &m) < 0) { +		dev_err(&spi->dev, "SPI sync failed."); +		return -EINVAL; +	} + +	return 0; +} + +static int ili9342_write_cmd(struct spi_device *spi, unsigned char val) { +	return ili9342_spi_write(spi, 1, val); +} + +static int ili9342_write_data(struct spi_device *spi, unsigned char val) { +	return ili9342_spi_write(spi, 0, val); +} + +static void hw_guard_start(struct panel_drv_data *md, int guard_msec) +{ +	md->hw_guard_wait = msecs_to_jiffies(guard_msec); +	md->hw_guard_end = jiffies + md->hw_guard_wait; +} + +static void hw_guard_wait(struct panel_drv_data *md) +{ +	unsigned long wait = md->hw_guard_end - jiffies; + +	if ((long)wait > 0 && wait <= md->hw_guard_wait) { +		set_current_state(TASK_UNINTERRUPTIBLE); +		schedule_timeout(wait); +	} +} + +static void set_sleep_mode(struct panel_drv_data *drv_data, int on) +{ +	int cmd = on ? CMD_SLEEP_IN : CMD_SLEEP_OUT; +	/* +	 * We have to keep 120msec between sleep in/out commands. +	 * (8.2.11, 8.2.12). +	 */ +	//hw_guard_wait(drv_data); +	ili9342_write_cmd(drv_data->spi, cmd); +	//hw_guard_start(drv_data, 120); +} + +static void set_display_state(struct panel_drv_data *drv_data, int enabled) +{ +	int cmd = enabled ? CMD_DISP_ON : CMD_DISP_OFF; + +	ili9342_write_cmd(drv_data->spi, cmd); +} +  static int ili9342_panel_power_on(struct omap_dss_device *dssdev)  {  	int r; @@ -104,11 +181,11 @@ static int ili9342_panel_power_on(struct omap_dss_device *dssdev)  	r = omapdss_dpi_display_enable(dssdev);  	if (r) -		goto err0; +		return r; +	printk ("OLIO %s entered\n", __FUNCTION__);  	/* wait couple of vsyncs until enabling the LCD */ -	if (panel_config->power_on_delay) -		msleep(panel_config->power_on_delay); +	msleep(panel_config->power_on_delay);  	if (dssdev->platform_enable) {  		r = dssdev->platform_enable(dssdev); @@ -116,10 +193,13 @@ static int ili9342_panel_power_on(struct omap_dss_device *dssdev)  			goto err1;  	} +	set_sleep_mode(drv_data, 0); +	usleep_range(5000, 10000); +	//set_display_state(drv_data, 1); +  	return 0;  err1:  	omapdss_dpi_display_disable(dssdev); -err0:  	return r;  } @@ -131,25 +211,27 @@ static void ili9342_panel_power_off(struct omap_dss_device *dssdev)  	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)  		return; +	//set_display_state(drv_data, 0); +	set_sleep_mode(drv_data, 1); +	printk ("OLIO %s entered\n", __FUNCTION__); +	/* wait couple of vsyncs after disabling the LCD */ +	msleep(panel_config->power_off_delay); +  	if (dssdev->platform_disable)  		dssdev->platform_disable(dssdev); -	/* wait couple of vsyncs after disabling the LCD */ -	if (panel_config->power_off_delay) -		msleep(panel_config->power_off_delay); -  	omapdss_dpi_display_disable(dssdev);  }  static int ili9342_panel_probe(struct omap_dss_device *dssdev)  {  	struct panel_config *panel_config = NULL; -	struct panel_drv_data *drv_data = NULL; +	struct panel_drv_data *drv_data = &ili9342_drv_data;  	int i;  	dev_dbg(&dssdev->dev, "probe\n"); -    printk ("OLIO %s entered\n", __FUNCTION__); +	printk ("OLIO %s entered\n", __FUNCTION__);  	if (!dssdev || !dssdev->name)  		return -EINVAL; @@ -168,10 +250,6 @@ static int ili9342_panel_probe(struct omap_dss_device *dssdev)  	dssdev->panel.timings = panel_config->timings; -	drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); -	if (!drv_data) -		return -ENOMEM; -  	drv_data->dssdev = dssdev;  	drv_data->panel_config = panel_config; @@ -198,10 +276,10 @@ static int ili9342_panel_enable(struct omap_dss_device *dssdev)  	r = ili9342_panel_power_on(dssdev);  	if (r) -		goto err; +		goto ret;  	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -err: +ret:  	mutex_unlock(&drv_data->lock);  	return r; @@ -253,9 +331,7 @@ static int ili9342_panel_check_timings(struct omap_dss_device *dssdev,  	int r;  	mutex_lock(&drv_data->lock); -  	r = dpi_check_timings(dssdev, timings); -  	mutex_unlock(&drv_data->lock);  	return r; @@ -265,40 +341,6 @@ 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) { -  printk ("OLIO: %s Suspending display.\n", __FUNCTION__); -  ili9342_panel_disable(to_dss_device(dev)); -  return 0; -} - -static int ili9342_disp_resume (struct device * dev) { -  printk ("OLIO: %s Resuming display.\n", __FUNCTION__); -  ili9342_panel_enable(to_dss_device(dev)); -  return 0; -} - -#if defined(CONFIG_HAS_AMBIENTMODE) -static int ili9342_panel_disable_wrapper (struct omap_dss_device *display) { -  printk ("OLIO: %s Suspending display.\n", __FUNCTION__); -  ili9342_panel_disable(display); -  return 0; -} -#endif  - - -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), @@ -312,66 +354,12 @@ static struct omap_dss_driver ili9342_driver = {  	.get_recommended_bpp = ili9342_get_recommended_bpp, -#if 0 -#if defined(CONFIG_HAS_AMBIENTMODE) -    .resume  = ili9342_panel_enable, -    .suspend = ili9342_panel_disable_wrapper, -#endif -#endif  -  	.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; -	struct spi_transfer t = { -			.tx_buf = &buf, -			.len = 2, -			.bits_per_word = 9, -	}; -	int r; - -	if(cmd) { -		buf = 0; -	} else { -		buf = 1 << 8; -	} -	buf |= val; - -	dev_dbg(&spi->dev, "SPI sync: %x", buf); -	spi_message_init(&m); -	spi_message_add_tail(&t, &m); -	r = spi_sync(spi, &m); -	if(r < 0) { -		dev_err(&spi->dev, "SPI sync failed."); -		return -EINVAL; -	} -	return 0; -} - -static int ili9342_write_cmd(struct spi_device *spi, unsigned char val) { -	return ili9342_spi_write(spi, 1, val); -} - -static int ili9342_write_data(struct spi_device *spi, unsigned char val) { -	return ili9342_spi_write(spi, 0, val); -} -  static inline void ili9342_init_seq(struct spi_device *spi) {  	ili9342_write_cmd(spi, 0xC8);  	ili9342_write_data(spi, 0xFF); @@ -474,75 +462,41 @@ static inline void ili9342_init_seq(struct spi_device *spi) {  	ili9342_write_cmd(spi, 0x29);  } +static inline int ili9342_init_reset_gpio(int reset_gpio) +{ +	if (gpio_request_one(reset_gpio, GPIOF_OUT_INIT_LOW, "ili9342-reset")) +		return -EINVAL; -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); +	gpio_set_value(reset_gpio, 1);  	mdelay(1); -	gpio_set_value(panel->reset_gpio, 0); +	gpio_set_value(reset_gpio, 0);  	mdelay(50); -	gpio_set_value(panel->reset_gpio, 1); +	gpio_set_value(reset_gpio, 1);  	mdelay(120); -	ili9342_init_seq(spi); +	return 0;  } -static inline int init_ili9342_spi(struct spi_device *spi) { +static int ili9342_spi_probe(struct spi_device *spi) +{ +	struct panel_drv_data *drv_data = &ili9342_drv_data;  	struct omap_dss_device *panel = spi->dev.platform_data; -	int reset_gpio; -	if(!panel->reset_gpio) { -		dev_err(&spi->dev, "platform data requires reset\n"); -		return -EINVAL; -	} - -	reset_gpio = panel->reset_gpio; +	printk ("OLIO %s entered\n", __FUNCTION__);  	if (!panel) {  		dev_err(&spi->dev, "no platform data\n");  		return -EINVAL;  	} -	if(gpio_request_one(reset_gpio, GPIOF_OUT_INIT_LOW, "ili9342-reset")) { -		dev_err(&spi->dev, "Could not request reset gpio %d", panel->reset_gpio); +	if (ili9342_init_reset_gpio(panel->reset_gpio)) { +		dev_err(&spi->dev, "Could not request reset gpio %d", +			panel->reset_gpio);  		return -EINVAL;  	} -	if(gpio_export(reset_gpio, 0)) { -		dev_err(&spi->dev, "Could not export reset gpio %d", panel->reset_gpio); -		return -EINVAL; -	} - -    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"); - -    printk ("OLIO %s entered\n", __FUNCTION__); - -	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); +	drv_data->spi = spi; +	ili9342_init_seq(spi);  	return omap_dss_register_driver(&ili9342_driver);  } @@ -555,67 +509,12 @@ static int ili9342_spi_remove(struct spi_device *spi)  	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; -	} - -	/* ili9342_init_seq(spi); */  -    init_ili9342_hw (spi); - -    return 0; -} - - -static struct dev_pm_ops ili9342_pm_ops = { -    /* SET_SYSTEM_SLEEP_PM_OPS(ili9342_suspend, ili9342_resume) */ -    .suspend_late = ili9342_suspend, -    .resume_early = 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,  	},  }; diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 361341b6069..1c7f33b6e0f 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -291,7 +291,7 @@ config SUSPEND_TIME  	  /sys/kernel/debug/suspend_time  config HAS_AMBIENTMODE -	def_bool y +	def_bool n  	depends on PM  	---help---  	  Ambient mode should not turn off/on display/back-light/etc. |