[UPSTREAM] Move backlight handling out of pcf50633 driver

Sean McNeil sean at mcneil.com
Sun Oct 19 07:18:55 CEST 2008


Can you make the max brightness a #define where it can be an arbitrary
value such as 100 or 255? I'm also curious about suspend/resume ordering
and turning on the lcd backlight. You need to make sure the lcds are on
before the backlight to prevent white screen flashes and should turn off
backlight before the lcds.

Balaji Rao wrote:
> Hi,
>
> This moves backlight handling code out of pcf50633 driver. It uses the
> Generic (aka Corgi) backlight driver.
>
> This works only on andy-tracking where code to establish the right
> device relationships exits.
>
> I've booted andy-tracking with this patch and found it to work
> perfectly.
>
> Please review.
>
>  arch/arm/mach-s3c2440/mach-gta02.c |   63 +++++++++++++++++--
>  drivers/i2c/chips/pcf50633.c       |  121 -------------------------------------
>  drivers/video/display/jbt6k74.c    |    5 +
>  include/linux/jbt6k74.h            |    2 
>  4 files changed, 65 insertions(+), 126 deletions(-)
>
> diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
> index acc8e3f..dd8ce08 100644
> --- a/arch/arm/mach-s3c2440/mach-gta02.c
> +++ b/arch/arm/mach-s3c2440/mach-gta02.c
> @@ -49,6 +49,8 @@
>  
>  #include <linux/regulator/machine.h>
>  
> +#include <linux/backlight.h>
> +
>  #include <linux/pcf50633.h>
>  #include <linux/lis302dl.h>
>  
> @@ -702,8 +704,6 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
>  			},
>  		},
>  	},
> -	.defer_resume_backlight = 1,
> -	.resume_backlight_ramp_speed = 5,
>  	.attach_child_devices = gta02_pcf50633_attach_child_devices
>  
>  };
> @@ -1027,6 +1027,56 @@ static struct s3c2410_ts_mach_info gta02_ts_cfg = {
>  	},
>  };
>  
> +/* Backlight control */
> +
> +static void gta02_bl_set_intensity(int intensity)
> +{
> +	struct pcf50633_data *pcf = gta02_pcf_pdata.pcf;
> +
> +	int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
> +	u_int8_t ledena = 2;
> +	int ret;
> +
> +	/* We can't do this anywhere else */
> +	pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5);
> +
> +	if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 1))
> +		old_intensity = 0;
> +
> +	/*
> +	 * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60)
> +	 */
> +	if (intensity != 0 && old_intensity == 0) {
> +		ledena = pcf50633_reg_read(pcf, PCF50633_REG_LEDENA);
> +		pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x00);
> +	}
> +
> +	if (!intensity) /* illegal to set LEDOUT to 0 */
> +		ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2);
> +	else
> +		ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f,
> +			       intensity);
> +
> +	if (intensity != 0 && old_intensity == 0)
> +		pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, ledena);
> +
> +}
> +
> +static struct generic_bl_info gta02_bl_info = {
> +	.name 			= "gta02-bl",
> +	.max_intensity 		= 0x3f,
> +	.default_intensity 	= 0x3f,
> +	.set_bl_intensity 	= gta02_bl_set_intensity,
> +};
> +
> +static struct platform_device gta02_bl_dev = {
> +	.name		  = "generic-bl",
> +	.id		  = 1,
> +	.dev = {
> +		.platform_data = &gta02_bl_info,
> +	},
> +};
> +
>  /* SPI: LCM control interface attached to Glamo3362 */
>  
>  static void gta02_jbt6k74_reset(int devidx, int level)
> @@ -1034,17 +1084,20 @@ static void gta02_jbt6k74_reset(int devidx, int level)
>  	glamo_lcm_reset(level);
>  }
>  
> -/* finally bring up deferred backlight resume now LCM is resumed itself */
> -
>  static void gta02_jbt6k74_resuming(int devidx)
>  {
> -	pcf50633_backlight_resume(gta02_pcf_pdata.pcf);
>  }
>  
> +static void gta02_jbt6k74_probe_completed(struct device *dev)
> +{
> +	gta02_bl_dev.dev.parent = dev;
> +	platform_device_register(&gta02_bl_dev);
> +}
>  
>  const struct jbt6k74_platform_data jbt6k74_pdata = {
>  	.reset		= gta02_jbt6k74_reset,
>  	.resuming	= gta02_jbt6k74_resuming,
> +	.probe_completed = gta02_jbt6k74_probe_completed,
>  };
>  
>  static struct spi_board_info gta02_spi_board_info[] = {
> diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c
> index d6e875e..5610f73 100644
> --- a/drivers/i2c/chips/pcf50633.c
> +++ b/drivers/i2c/chips/pcf50633.c
> @@ -24,7 +24,6 @@
>   * - charging control for main and backup battery
>   * - rtc / alarm
>   * - adc driver (hw_sensors like)
> - * - backlight
>   *
>   */
>  
> @@ -42,7 +41,6 @@
>  #include <linux/miscdevice.h>
>  #include <linux/input.h>
>  #include <linux/fb.h>
> -#include <linux/backlight.h>
>  #include <linux/sched.h>
>  #include <linux/platform_device.h>
>  #include <linux/pcf50633.h>
> @@ -120,7 +118,6 @@ enum pcf50633_suspend_states {
>  struct pcf50633_data {
>  	struct i2c_client *client;
>  	struct pcf50633_platform_data *pdata;
> -	struct backlight_device *backlight;
>  	struct mutex lock;
>  	unsigned int flags;
>  	unsigned int working;
> @@ -1848,69 +1845,6 @@ static struct rtc_class_ops pcf50633_rtc_ops = {
>  	.set_alarm	= pcf50633_rtc_set_alarm,
>  };
>  
> -/***********************************************************************
> - * Backlight device
> - ***********************************************************************/
> -
> -static int pcf50633bl_get_intensity(struct backlight_device *bd)
> -{
> -	struct pcf50633_data *pcf = bl_get_data(bd);
> -	int intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
> -
> -	return intensity & 0x3f;
> -}
> -
> -static int __pcf50633bl_set_intensity(struct pcf50633_data *pcf, int intensity)
> -{
> -	int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT);
> -	u_int8_t ledena = 2;
> -	int ret;
> -
> -	if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 1))
> -		old_intensity = 0;
> -
> -	if ((pcf->backlight->props.power != FB_BLANK_UNBLANK) ||
> -	    (pcf->backlight->props.fb_blank != FB_BLANK_UNBLANK))
> -		intensity = 0;
> -
> -	/*
> -	 * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60)
> -	 * if seen, you have to re-enable the LED unit
> -	 */
> -
> -	if (intensity != 0 && old_intensity == 0) {
> -		ledena = pcf50633_reg_read(pcf, PCF50633_REG_LEDENA);
> -		pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0x00);
> -	}
> -
> -	if (!intensity) /* illegal to set LEDOUT to 0 */
> -		ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2);
> -	else
> -		ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f,
> -			       intensity);
> -
> -	if (intensity != 0 && old_intensity == 0)
> -		pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, ledena);
> -
> -	return ret;
> -}
> -
> -static int pcf50633bl_set_intensity(struct backlight_device *bd)
> -{
> -	struct pcf50633_data *pcf = bl_get_data(bd);
> -	int intensity = bd->props.brightness;
> -
> -	if ((bd->props.power != FB_BLANK_UNBLANK) ||
> -	    (bd->props.fb_blank != FB_BLANK_UNBLANK))
> -		intensity = 0;
> -
> -	return __pcf50633bl_set_intensity(pcf, intensity);
> -}
> -
> -static struct backlight_ops pcf50633bl_ops = {
> -	.get_brightness	= pcf50633bl_get_intensity,
> -	.update_status	= pcf50633bl_set_intensity,
> -};
>  
>  /*
>   * Charger type
> @@ -2178,23 +2112,6 @@ static int pcf50633_probe(struct i2c_client *client, const struct i2c_device_id
>  			goto exit_irq;
>  		}
>  	}
> -
> -	if (pcf->pdata->used_features & PCF50633_FEAT_PWM_BL) {
> -		pcf->backlight = backlight_device_register("pcf50633-bl",
> -							    &client->dev,
> -							    pcf,
> -							    &pcf50633bl_ops);
> -		if (!pcf->backlight)
> -			goto exit_rtc;
> -
> -		pcf->backlight->props.max_brightness = 0x3f;
> -		pcf->backlight->props.power = FB_BLANK_UNBLANK;
> -		pcf->backlight->props.fb_blank = FB_BLANK_UNBLANK;
> -		pcf->backlight->props.brightness =
> -					pcf->backlight->props.max_brightness;
> -		backlight_update_status(pcf->backlight);
> -	}
> -
>  	if (pcf->pdata->flag_use_apm_emulation)
>  		apm_get_power_status = NULL;
>  
> @@ -2239,9 +2156,6 @@ static int pcf50633_remove(struct i2c_client *client)
>  
>  	input_unregister_device(pcf->input_dev);
>  
> -	if (pcf->pdata->used_features & PCF50633_FEAT_PWM_BL)
> -		backlight_device_unregister(pcf->backlight);
> -
>  	if (pcf->pdata->used_features & PCF50633_FEAT_RTC)
>  		rtc_device_unregister(pcf->rtc);
>  
> @@ -2392,11 +2306,6 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state)
>  		__reg_write(pcf, regulator_registers[i] + 1, tmp & 0xfe);
>  	}
>  
> -	/* turn off the backlight */
> -	__reg_write(pcf, PCF50633_REG_LEDDIM, 0);
> -	__reg_write(pcf, PCF50633_REG_LEDOUT, 2);
> -	__reg_write(pcf, PCF50633_REG_LEDENA, 0x00);
> -
>  	/* set interrupt masks so only those sources we want to wake
>  	 * us are able to
>  	 */
> @@ -2455,25 +2364,6 @@ int pcf50633_wait_for_ready(struct pcf50633_data *pcf, int timeout_ms,
>  }
>  EXPORT_SYMBOL_GPL(pcf50633_wait_for_ready);
>  
> -/*
> - * if backlight resume is selected to be deferred by platform, then it
> - * can call this to finally reset backlight status (after LCM is resumed
> - * for example
> - */
> -
> -void pcf50633_backlight_resume(struct pcf50633_data *pcf)
> -{
> -	dev_dbg(&pcf->client->dev, "pcf50633_backlight_resume\n");
> -
> -	/* platform defines resume ramp speed */
> -	pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM,
> -				       pcf->pdata->resume_backlight_ramp_speed);
> -
> -	__pcf50633bl_set_intensity(pcf, pcf->backlight->props.brightness);
> -}
> -EXPORT_SYMBOL_GPL(pcf50633_backlight_resume);
> -
> -
>  static int pcf50633_resume(struct device *dev)
>  {
>  	struct i2c_client *client = to_i2c_client(dev);
> @@ -2494,13 +2384,6 @@ static int pcf50633_resume(struct device *dev)
>  
>  	memcpy(misc, pcf->standby_regs.misc, sizeof(pcf->standby_regs.misc));
>  
> -	if (pcf->pdata->defer_resume_backlight) {
> -		misc[PCF50633_REG_LEDOUT - PCF50633_REG_AUTOOUT] = 1;
> -		misc[PCF50633_REG_LEDENA - PCF50633_REG_AUTOOUT] = 0x20;
> -		misc[PCF50633_REG_LEDCTL - PCF50633_REG_AUTOOUT] = 1;
> -		misc[PCF50633_REG_LEDDIM - PCF50633_REG_AUTOOUT] = 1;
> -	}
> -
>  	/* regulator voltages and enable states */
>  	ret = i2c_smbus_write_i2c_block_data(pcf->client,
>  					     PCF50633_REG_AUTOOUT,
> @@ -2509,10 +2392,6 @@ static int pcf50633_resume(struct device *dev)
>  	if (ret)
>  		dev_err(dev, "Failed to restore misc :-( %d\n", ret);
>  
> -	/* platform can choose to defer backlight bringup */
> -	if (!pcf->pdata->defer_resume_backlight)
> -		pcf50633_backlight_resume(pcf);
> -
>  	/* regulator voltages and enable states */
>  	ret = i2c_smbus_write_i2c_block_data(pcf->client,
>  					     PCF50633_REG_LDO1OUT,
> diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c
> index 77f9528..9fd41f2 100644
> --- a/drivers/video/display/jbt6k74.c
> +++ b/drivers/video/display/jbt6k74.c
> @@ -592,6 +592,8 @@ static int __devinit jbt_probe(struct spi_device *spi)
>  {
>  	int rc;
>  	struct jbt_info *jbt;
> +	struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data;
> +
>  
>  	/* the controller doesn't have a MISO pin; we can't do detection */
>  
> @@ -640,6 +642,9 @@ static int __devinit jbt_probe(struct spi_device *spi)
>  		goto err_sysfs;
>  	}
>  
> +	if (jbt6k74_pdata->probe_completed)
> +		jbt6k74_pdata->probe_completed(&spi->dev);
> +
>  	return 0;
>  
>  err_sysfs:
> diff --git a/include/linux/jbt6k74.h b/include/linux/jbt6k74.h
> index 50e3934..763c55b 100644
> --- a/include/linux/jbt6k74.h
> +++ b/include/linux/jbt6k74.h
> @@ -2,10 +2,12 @@
>  #define __JBT6K74_H__
>  
>  #include <linux/spi/spi.h>
> +#include <linux/device.h>
>  
>  struct jbt6k74_platform_data {
>  	void (*reset)(int devindex, int level);
>  	void (*resuming)(int devindex); /* called when LCM is resumed */
> +	void (*probe_completed)(struct device *dev);
>  };
>  
>  #endif
>
>   



More information about the openmoko-kernel mailing list