aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Dunn <mikedunn@newsguy.com>2013-09-22 12:59:56 -0400
committerThierry Reding <thierry.reding@gmail.com>2013-10-16 03:20:09 -0400
commit8f43e18e2769b3b28383903d501b4da29e388aad (patch)
treedcddafc52c90afc98fa8037a0ad682e5e8b6d194
parent22ceeee16eb8f0d04de3ef43a5174fb30ec18af9 (diff)
pwm-backlight: Allow for non-increasing brightness levels
Currently the driver assumes that the values specified in the brightness-levels device tree property increase as they are parsed from left to right. But boards that invert the signal between the PWM output and the backlight will need to specify decreasing brightness-levels. This patch removes the assumption that the last element of the array is the maximum value, and instead searches the array for the maximum value and uses that in the duty cycle calculation. Signed-off-by: Mike Dunn <mikedunn@newsguy.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/video/backlight/pwm_bl.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index eec6c98527f9..32e96e3525a1 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -34,6 +34,7 @@ struct pwm_bl_data {
34 struct regulator *power_supply; 34 struct regulator *power_supply;
35 int enable_gpio; 35 int enable_gpio;
36 unsigned long enable_gpio_flags; 36 unsigned long enable_gpio_flags;
37 unsigned int scale;
37 int (*notify)(struct device *, 38 int (*notify)(struct device *,
38 int brightness); 39 int brightness);
39 void (*notify_after)(struct device *, 40 void (*notify_after)(struct device *,
@@ -42,23 +43,20 @@ struct pwm_bl_data {
42 void (*exit)(struct device *); 43 void (*exit)(struct device *);
43}; 44};
44 45
45static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness, 46static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness)
46 int max)
47{ 47{
48 unsigned int lth = pb->lth_brightness;
48 int duty_cycle, err; 49 int duty_cycle, err;
49 50
50 if (pb->enabled) 51 if (pb->enabled)
51 return; 52 return;
52 53
53 if (pb->levels) { 54 if (pb->levels)
54 duty_cycle = pb->levels[brightness]; 55 duty_cycle = pb->levels[brightness];
55 max = pb->levels[max]; 56 else
56 } else {
57 duty_cycle = brightness; 57 duty_cycle = brightness;
58 }
59 58
60 duty_cycle = (duty_cycle * (pb->period - pb->lth_brightness) / max) + 59 duty_cycle = (duty_cycle * (pb->period - lth) / pb->scale) + lth;
61 pb->lth_brightness;
62 60
63 pwm_config(pb->pwm, duty_cycle, pb->period); 61 pwm_config(pb->pwm, duty_cycle, pb->period);
64 62
@@ -100,7 +98,6 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
100{ 98{
101 struct pwm_bl_data *pb = bl_get_data(bl); 99 struct pwm_bl_data *pb = bl_get_data(bl);
102 int brightness = bl->props.brightness; 100 int brightness = bl->props.brightness;
103 int max = bl->props.max_brightness;
104 101
105 if (bl->props.power != FB_BLANK_UNBLANK || 102 if (bl->props.power != FB_BLANK_UNBLANK ||
106 bl->props.fb_blank != FB_BLANK_UNBLANK || 103 bl->props.fb_blank != FB_BLANK_UNBLANK ||
@@ -111,7 +108,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
111 brightness = pb->notify(pb->dev, brightness); 108 brightness = pb->notify(pb->dev, brightness);
112 109
113 if (brightness > 0) 110 if (brightness > 0)
114 pwm_backlight_power_on(pb, brightness, max); 111 pwm_backlight_power_on(pb, brightness);
115 else 112 else
116 pwm_backlight_power_off(pb); 113 pwm_backlight_power_off(pb);
117 114
@@ -218,7 +215,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
218 struct backlight_properties props; 215 struct backlight_properties props;
219 struct backlight_device *bl; 216 struct backlight_device *bl;
220 struct pwm_bl_data *pb; 217 struct pwm_bl_data *pb;
221 unsigned int max;
222 int ret; 218 int ret;
223 219
224 if (!data) { 220 if (!data) {
@@ -245,10 +241,15 @@ static int pwm_backlight_probe(struct platform_device *pdev)
245 } 241 }
246 242
247 if (data->levels) { 243 if (data->levels) {
248 max = data->levels[data->max_brightness]; 244 unsigned int i;
245
246 for (i = 0; i <= data->max_brightness; i++)
247 if (data->levels[i] > pb->scale)
248 pb->scale = data->levels[i];
249
249 pb->levels = data->levels; 250 pb->levels = data->levels;
250 } else 251 } else
251 max = data->max_brightness; 252 pb->scale = data->max_brightness;
252 253
253 pb->enable_gpio = data->enable_gpio; 254 pb->enable_gpio = data->enable_gpio;
254 pb->enable_gpio_flags = data->enable_gpio_flags; 255 pb->enable_gpio_flags = data->enable_gpio_flags;
@@ -304,7 +305,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
304 pwm_set_period(pb->pwm, data->pwm_period_ns); 305 pwm_set_period(pb->pwm, data->pwm_period_ns);
305 306
306 pb->period = pwm_get_period(pb->pwm); 307 pb->period = pwm_get_period(pb->pwm);
307 pb->lth_brightness = data->lth_brightness * (pb->period / max); 308 pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale);
308 309
309 memset(&props, 0, sizeof(struct backlight_properties)); 310 memset(&props, 0, sizeof(struct backlight_properties));
310 props.type = BACKLIGHT_RAW; 311 props.type = BACKLIGHT_RAW;