Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Thierry Reding and committed by
Thierry Reding
8265b2e4 611c86c6

+55 -7
+5
Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
··· 14 14 Optional properties: 15 15 - pwm-names: a list of names for the PWM devices specified in the 16 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 20 [0]: Documentation/devicetree/bindings/pwm/pwm.txt 21 + [1]: Documentation/devicetree/bindings/gpio/gpio.txt 19 22 20 23 Example: 21 24 ··· 28 25 29 26 brightness-levels = <0 4 8 16 32 64 128 255>; 30 27 default-brightness-level = <6>; 28 + 29 + enable-gpios = <&gpio 58 0>; 31 30 };
+50 -7
drivers/video/backlight/pwm_bl.c
··· 10 10 * published by the Free Software Foundation. 11 11 */ 12 12 13 + #include <linux/gpio.h> 14 + #include <linux/of_gpio.h> 13 15 #include <linux/module.h> 14 16 #include <linux/kernel.h> 15 17 #include <linux/init.h> ··· 30 28 unsigned int lth_brightness; 31 29 unsigned int *levels; 32 30 bool enabled; 31 + int enable_gpio; 32 + unsigned long enable_gpio_flags; 33 33 int (*notify)(struct device *, 34 34 int brightness); 35 35 void (*notify_after)(struct device *, ··· 59 55 pb->lth_brightness; 60 56 61 57 pwm_config(pb->pwm, duty_cycle, pb->period); 58 + 59 + if (gpio_is_valid(pb->enable_gpio)) { 60 + if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) 61 + gpio_set_value(pb->enable_gpio, 0); 62 + else 63 + gpio_set_value(pb->enable_gpio, 1); 64 + } 65 + 62 66 pwm_enable(pb->pwm); 63 67 pb->enabled = true; 64 68 } ··· 78 66 79 67 pwm_config(pb->pwm, 0, pb->period); 80 68 pwm_disable(pb->pwm); 69 + 70 + if (gpio_is_valid(pb->enable_gpio)) { 71 + if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) 72 + gpio_set_value(pb->enable_gpio, 1); 73 + else 74 + gpio_set_value(pb->enable_gpio, 0); 75 + } 81 76 82 77 pb->enabled = false; 83 78 } ··· 138 119 struct platform_pwm_backlight_data *data) 139 120 { 140 121 struct device_node *node = dev->of_node; 122 + enum of_gpio_flags flags; 141 123 struct property *prop; 142 124 int length; 143 125 u32 value; ··· 179 159 data->max_brightness--; 180 160 } 181 161 182 - /* 183 - * TODO: Most users of this driver use a number of GPIOs to control 184 - * backlight power. Support for specifying these needs to be 185 - * added. 186 - */ 162 + data->enable_gpio = of_get_named_gpio_flags(node, "enable-gpios", 0, 163 + &flags); 164 + if (data->enable_gpio == -EPROBE_DEFER) 165 + return -EPROBE_DEFER; 166 + 167 + if (gpio_is_valid(data->enable_gpio) && (flags & OF_GPIO_ACTIVE_LOW)) 168 + data->enable_gpio_flags |= PWM_BACKLIGHT_GPIO_ACTIVE_LOW; 187 169 188 170 return 0; 189 171 } ··· 243 221 } else 244 222 max = data->max_brightness; 245 223 224 + pb->enable_gpio = data->enable_gpio; 225 + pb->enable_gpio_flags = data->enable_gpio_flags; 246 226 pb->notify = data->notify; 247 227 pb->notify_after = data->notify_after; 248 228 pb->check_fb = data->check_fb; 249 229 pb->exit = data->exit; 250 230 pb->dev = &pdev->dev; 251 231 pb->enabled = false; 232 + 233 + if (gpio_is_valid(pb->enable_gpio)) { 234 + unsigned long flags; 235 + 236 + if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) 237 + flags = GPIOF_OUT_INIT_HIGH; 238 + else 239 + flags = GPIOF_OUT_INIT_LOW; 240 + 241 + ret = gpio_request_one(pb->enable_gpio, flags, "enable"); 242 + if (ret < 0) { 243 + dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n", 244 + pb->enable_gpio, ret); 245 + goto err_alloc; 246 + } 247 + } 252 248 253 249 pb->pwm = devm_pwm_get(&pdev->dev, NULL); 254 250 if (IS_ERR(pb->pwm)) { ··· 276 236 if (IS_ERR(pb->pwm)) { 277 237 dev_err(&pdev->dev, "unable to request legacy PWM\n"); 278 238 ret = PTR_ERR(pb->pwm); 279 - goto err_alloc; 239 + goto err_gpio; 280 240 } 281 241 } 282 242 ··· 301 261 if (IS_ERR(bl)) { 302 262 dev_err(&pdev->dev, "failed to register backlight\n"); 303 263 ret = PTR_ERR(bl); 304 - goto err_alloc; 264 + goto err_gpio; 305 265 } 306 266 307 267 if (data->dft_brightness > data->max_brightness) { ··· 317 277 platform_set_drvdata(pdev, bl); 318 278 return 0; 319 279 280 + err_gpio: 281 + if (gpio_is_valid(pb->enable_gpio)) 282 + gpio_free(pb->enable_gpio); 320 283 err_alloc: 321 284 if (data->exit) 322 285 data->exit(&pdev->dev);