aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2013-08-30 06:32:18 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:58:17 -0400
commit958f652dd6f28d558205d449fd44d90ce4ee0621 (patch)
tree0d23dd27695b2af348942b6bf9d577b5d7cd6b7c
parent165c2731bab54e2827beaed9d7d3c7c3c451db63 (diff)
pwm-backlight: Use new enable_gpio field
Make use of the new enable_gpio field and allow it to be set from DT as well. Now that all legacy users of platform data have been converted to initialize this field to an invalid value, it is safe to use the field from the driver. Signed-off-by: Thierry Reding <treding@nvidia.com> (cherry picked from commit 8265b2e4e62632b01f998095d1bbda4d281629fe)
-rw-r--r--Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt5
-rw-r--r--drivers/video/backlight/pwm_bl.c57
2 files changed, 55 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
index 1e4fc727f3b1..72810cc2dbc1 100644
--- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
+++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
@@ -14,8 +14,11 @@ Required properties:
14Optional properties: 14Optional properties:
15 - pwm-names: a list of names for the PWM devices specified in the 15 - pwm-names: a list of names for the PWM devices specified in the
16 "pwms" property (see PWM binding[0]) 16 "pwms" property (see PWM binding[0])
17 - enable-gpios: contains a single GPIO specifier for the GPIO which enables
18 and disables the backlight (see GPIO binding[1])
17 19
18[0]: Documentation/devicetree/bindings/pwm/pwm.txt 20[0]: Documentation/devicetree/bindings/pwm/pwm.txt
21[1]: Documentation/devicetree/bindings/gpio/gpio.txt
19 22
20Example: 23Example:
21 24
@@ -25,4 +28,6 @@ Example:
25 28
26 brightness-levels = <0 4 8 16 32 64 128 255>; 29 brightness-levels = <0 4 8 16 32 64 128 255>;
27 default-brightness-level = <6>; 30 default-brightness-level = <6>;
31
32 enable-gpios = <&gpio 58 0>;
28 }; 33 };
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 51a802fff50d..18b885497289 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -10,6 +10,8 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/gpio.h>
14#include <linux/of_gpio.h>
13#include <linux/module.h> 15#include <linux/module.h>
14#include <linux/kernel.h> 16#include <linux/kernel.h>
15#include <linux/init.h> 17#include <linux/init.h>
@@ -28,6 +30,8 @@ struct pwm_bl_data {
28 unsigned int lth_brightness; 30 unsigned int lth_brightness;
29 unsigned int *levels; 31 unsigned int *levels;
30 bool enabled; 32 bool enabled;
33 int enable_gpio;
34 unsigned long enable_gpio_flags;
31 int (*notify)(struct device *, 35 int (*notify)(struct device *,
32 int brightness); 36 int brightness);
33 void (*notify_after)(struct device *, 37 void (*notify_after)(struct device *,
@@ -56,6 +60,14 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness,
56 pb->lth_brightness; 60 pb->lth_brightness;
57 61
58 pwm_config(pb->pwm, duty_cycle, pb->period); 62 pwm_config(pb->pwm, duty_cycle, pb->period);
63
64 if (gpio_is_valid(pb->enable_gpio)) {
65 if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
66 gpio_set_value(pb->enable_gpio, 0);
67 else
68 gpio_set_value(pb->enable_gpio, 1);
69 }
70
59 pwm_enable(pb->pwm); 71 pwm_enable(pb->pwm);
60 pb->enabled = true; 72 pb->enabled = true;
61} 73}
@@ -68,6 +80,13 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb)
68 pwm_config(pb->pwm, 0, pb->period); 80 pwm_config(pb->pwm, 0, pb->period);
69 pwm_disable(pb->pwm); 81 pwm_disable(pb->pwm);
70 82
83 if (gpio_is_valid(pb->enable_gpio)) {
84 if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
85 gpio_set_value(pb->enable_gpio, 1);
86 else
87 gpio_set_value(pb->enable_gpio, 0);
88 }
89
71 pb->enabled = false; 90 pb->enabled = false;
72} 91}
73 92
@@ -120,6 +139,7 @@ static int pwm_backlight_parse_dt(struct device *dev,
120 struct platform_pwm_backlight_data *data) 139 struct platform_pwm_backlight_data *data)
121{ 140{
122 struct device_node *node = dev->of_node; 141 struct device_node *node = dev->of_node;
142 enum of_gpio_flags flags;
123 struct property *prop; 143 struct property *prop;
124 int length; 144 int length;
125 u32 value; 145 u32 value;
@@ -160,11 +180,13 @@ static int pwm_backlight_parse_dt(struct device *dev,
160 data->max_brightness--; 180 data->max_brightness--;
161 } 181 }
162 182
163 /* 183 data->enable_gpio = of_get_named_gpio_flags(node, "enable-gpios", 0,
164 * TODO: Most users of this driver use a number of GPIOs to control 184 &flags);
165 * backlight power. Support for specifying these needs to be 185 if (data->enable_gpio == -EPROBE_DEFER)
166 * added. 186 return -EPROBE_DEFER;
167 */ 187
188 if (gpio_is_valid(data->enable_gpio) && (flags & OF_GPIO_ACTIVE_LOW))
189 data->enable_gpio_flags |= PWM_BACKLIGHT_GPIO_ACTIVE_LOW;
168 190
169 return 0; 191 return 0;
170} 192}
@@ -252,6 +274,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
252 } else 274 } else
253 max = data->max_brightness; 275 max = data->max_brightness;
254 276
277 pb->enable_gpio = data->enable_gpio;
278 pb->enable_gpio_flags = data->enable_gpio_flags;
255 pb->notify = data->notify; 279 pb->notify = data->notify;
256 pb->notify_after = data->notify_after; 280 pb->notify_after = data->notify_after;
257 pb->check_fb = np ? pwm_backlight_check_fb_dt : data->check_fb; 281 pb->check_fb = np ? pwm_backlight_check_fb_dt : data->check_fb;
@@ -259,6 +283,22 @@ static int pwm_backlight_probe(struct platform_device *pdev)
259 pb->dev = &pdev->dev; 283 pb->dev = &pdev->dev;
260 pb->enabled = false; 284 pb->enabled = false;
261 285
286 if (gpio_is_valid(pb->enable_gpio)) {
287 unsigned long flags;
288
289 if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
290 flags = GPIOF_OUT_INIT_HIGH;
291 else
292 flags = GPIOF_OUT_INIT_LOW;
293
294 ret = gpio_request_one(pb->enable_gpio, flags, "enable");
295 if (ret < 0) {
296 dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n",
297 pb->enable_gpio, ret);
298 goto err_alloc;
299 }
300 }
301
262 pb->pwm = devm_pwm_get(&pdev->dev, NULL); 302 pb->pwm = devm_pwm_get(&pdev->dev, NULL);
263 if (IS_ERR(pb->pwm)) { 303 if (IS_ERR(pb->pwm)) {
264 dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n"); 304 dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");
@@ -267,7 +307,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
267 if (IS_ERR(pb->pwm)) { 307 if (IS_ERR(pb->pwm)) {
268 dev_err(&pdev->dev, "unable to request legacy PWM\n"); 308 dev_err(&pdev->dev, "unable to request legacy PWM\n");
269 ret = PTR_ERR(pb->pwm); 309 ret = PTR_ERR(pb->pwm);
270 goto err_alloc; 310 goto err_gpio;
271 } 311 }
272 } 312 }
273 313
@@ -292,7 +332,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
292 if (IS_ERR(bl)) { 332 if (IS_ERR(bl)) {
293 dev_err(&pdev->dev, "failed to register backlight\n"); 333 dev_err(&pdev->dev, "failed to register backlight\n");
294 ret = PTR_ERR(bl); 334 ret = PTR_ERR(bl);
295 goto err_alloc; 335 goto err_gpio;
296 } 336 }
297 337
298 if (data->dft_brightness > data->max_brightness) { 338 if (data->dft_brightness > data->max_brightness) {
@@ -308,6 +348,9 @@ static int pwm_backlight_probe(struct platform_device *pdev)
308 platform_set_drvdata(pdev, bl); 348 platform_set_drvdata(pdev, bl);
309 return 0; 349 return 0;
310 350
351err_gpio:
352 if (gpio_is_valid(pb->enable_gpio))
353 gpio_free(pb->enable_gpio);
311err_alloc: 354err_alloc:
312 if (data->exit) 355 if (data->exit)
313 data->exit(&pdev->dev); 356 data->exit(&pdev->dev);