diff options
author | Thierry Reding <treding@nvidia.com> | 2013-08-30 06:32:18 -0400 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2013-10-16 03:20:09 -0400 |
commit | 8265b2e4e62632b01f998095d1bbda4d281629fe (patch) | |
tree | 31f3f3d6714f58553feff2b670adf1bd5d393455 | |
parent | 611c86c6de7a58c59b231804ffa19d1b70f6fd90 (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>
-rw-r--r-- | Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt | 5 | ||||
-rw-r--r-- | drivers/video/backlight/pwm_bl.c | 57 |
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: | |||
14 | Optional properties: | 14 | Optional 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 | ||
20 | Example: | 23 | Example: |
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 4053efbe5edb..cdef4a346555 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 *, |
@@ -55,6 +59,14 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness, | |||
55 | pb->lth_brightness; | 59 | pb->lth_brightness; |
56 | 60 | ||
57 | pwm_config(pb->pwm, duty_cycle, pb->period); | 61 | pwm_config(pb->pwm, duty_cycle, pb->period); |
62 | |||
63 | if (gpio_is_valid(pb->enable_gpio)) { | ||
64 | if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) | ||
65 | gpio_set_value(pb->enable_gpio, 0); | ||
66 | else | ||
67 | gpio_set_value(pb->enable_gpio, 1); | ||
68 | } | ||
69 | |||
58 | pwm_enable(pb->pwm); | 70 | pwm_enable(pb->pwm); |
59 | pb->enabled = true; | 71 | pb->enabled = true; |
60 | } | 72 | } |
@@ -67,6 +79,13 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb) | |||
67 | pwm_config(pb->pwm, 0, pb->period); | 79 | pwm_config(pb->pwm, 0, pb->period); |
68 | pwm_disable(pb->pwm); | 80 | pwm_disable(pb->pwm); |
69 | 81 | ||
82 | if (gpio_is_valid(pb->enable_gpio)) { | ||
83 | if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) | ||
84 | gpio_set_value(pb->enable_gpio, 1); | ||
85 | else | ||
86 | gpio_set_value(pb->enable_gpio, 0); | ||
87 | } | ||
88 | |||
70 | pb->enabled = false; | 89 | pb->enabled = false; |
71 | } | 90 | } |
72 | 91 | ||
@@ -119,6 +138,7 @@ static int pwm_backlight_parse_dt(struct device *dev, | |||
119 | struct platform_pwm_backlight_data *data) | 138 | struct platform_pwm_backlight_data *data) |
120 | { | 139 | { |
121 | struct device_node *node = dev->of_node; | 140 | struct device_node *node = dev->of_node; |
141 | enum of_gpio_flags flags; | ||
122 | struct property *prop; | 142 | struct property *prop; |
123 | int length; | 143 | int length; |
124 | u32 value; | 144 | u32 value; |
@@ -159,11 +179,13 @@ static int pwm_backlight_parse_dt(struct device *dev, | |||
159 | data->max_brightness--; | 179 | data->max_brightness--; |
160 | } | 180 | } |
161 | 181 | ||
162 | /* | 182 | data->enable_gpio = of_get_named_gpio_flags(node, "enable-gpios", 0, |
163 | * TODO: Most users of this driver use a number of GPIOs to control | 183 | &flags); |
164 | * backlight power. Support for specifying these needs to be | 184 | if (data->enable_gpio == -EPROBE_DEFER) |
165 | * added. | 185 | return -EPROBE_DEFER; |
166 | */ | 186 | |
187 | if (gpio_is_valid(data->enable_gpio) && (flags & OF_GPIO_ACTIVE_LOW)) | ||
188 | data->enable_gpio_flags |= PWM_BACKLIGHT_GPIO_ACTIVE_LOW; | ||
167 | 189 | ||
168 | return 0; | 190 | return 0; |
169 | } | 191 | } |
@@ -221,6 +243,8 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
221 | } else | 243 | } else |
222 | max = data->max_brightness; | 244 | max = data->max_brightness; |
223 | 245 | ||
246 | pb->enable_gpio = data->enable_gpio; | ||
247 | pb->enable_gpio_flags = data->enable_gpio_flags; | ||
224 | pb->notify = data->notify; | 248 | pb->notify = data->notify; |
225 | pb->notify_after = data->notify_after; | 249 | pb->notify_after = data->notify_after; |
226 | pb->check_fb = data->check_fb; | 250 | pb->check_fb = data->check_fb; |
@@ -228,6 +252,22 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
228 | pb->dev = &pdev->dev; | 252 | pb->dev = &pdev->dev; |
229 | pb->enabled = false; | 253 | pb->enabled = false; |
230 | 254 | ||
255 | if (gpio_is_valid(pb->enable_gpio)) { | ||
256 | unsigned long flags; | ||
257 | |||
258 | if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) | ||
259 | flags = GPIOF_OUT_INIT_HIGH; | ||
260 | else | ||
261 | flags = GPIOF_OUT_INIT_LOW; | ||
262 | |||
263 | ret = gpio_request_one(pb->enable_gpio, flags, "enable"); | ||
264 | if (ret < 0) { | ||
265 | dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n", | ||
266 | pb->enable_gpio, ret); | ||
267 | goto err_alloc; | ||
268 | } | ||
269 | } | ||
270 | |||
231 | pb->pwm = devm_pwm_get(&pdev->dev, NULL); | 271 | pb->pwm = devm_pwm_get(&pdev->dev, NULL); |
232 | if (IS_ERR(pb->pwm)) { | 272 | if (IS_ERR(pb->pwm)) { |
233 | dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n"); | 273 | dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n"); |
@@ -236,7 +276,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
236 | if (IS_ERR(pb->pwm)) { | 276 | if (IS_ERR(pb->pwm)) { |
237 | dev_err(&pdev->dev, "unable to request legacy PWM\n"); | 277 | dev_err(&pdev->dev, "unable to request legacy PWM\n"); |
238 | ret = PTR_ERR(pb->pwm); | 278 | ret = PTR_ERR(pb->pwm); |
239 | goto err_alloc; | 279 | goto err_gpio; |
240 | } | 280 | } |
241 | } | 281 | } |
242 | 282 | ||
@@ -261,7 +301,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
261 | if (IS_ERR(bl)) { | 301 | if (IS_ERR(bl)) { |
262 | dev_err(&pdev->dev, "failed to register backlight\n"); | 302 | dev_err(&pdev->dev, "failed to register backlight\n"); |
263 | ret = PTR_ERR(bl); | 303 | ret = PTR_ERR(bl); |
264 | goto err_alloc; | 304 | goto err_gpio; |
265 | } | 305 | } |
266 | 306 | ||
267 | if (data->dft_brightness > data->max_brightness) { | 307 | if (data->dft_brightness > data->max_brightness) { |
@@ -277,6 +317,9 @@ static int pwm_backlight_probe(struct platform_device *pdev) | |||
277 | platform_set_drvdata(pdev, bl); | 317 | platform_set_drvdata(pdev, bl); |
278 | return 0; | 318 | return 0; |
279 | 319 | ||
320 | err_gpio: | ||
321 | if (gpio_is_valid(pb->enable_gpio)) | ||
322 | gpio_free(pb->enable_gpio); | ||
280 | err_alloc: | 323 | err_alloc: |
281 | if (data->exit) | 324 | if (data->exit) |
282 | data->exit(&pdev->dev); | 325 | data->exit(&pdev->dev); |