Skip to content

Commit

Permalink
pwm-backlight: Use new enable_gpio field
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Thierry Reding authored and Thierry Reding committed Oct 16, 2013
1 parent 611c86c commit 8265b2e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ Required properties:
Optional properties:
- pwm-names: a list of names for the PWM devices specified in the
"pwms" property (see PWM binding[0])
- enable-gpios: contains a single GPIO specifier for the GPIO which enables
and disables the backlight (see GPIO binding[1])

[0]: Documentation/devicetree/bindings/pwm/pwm.txt
[1]: Documentation/devicetree/bindings/gpio/gpio.txt

Example:

Expand All @@ -25,4 +28,6 @@ Example:

brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;

enable-gpios = <&gpio 58 0>;
};
57 changes: 50 additions & 7 deletions drivers/video/backlight/pwm_bl.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
* published by the Free Software Foundation.
*/

#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
Expand All @@ -28,6 +30,8 @@ struct pwm_bl_data {
unsigned int lth_brightness;
unsigned int *levels;
bool enabled;
int enable_gpio;
unsigned long enable_gpio_flags;
int (*notify)(struct device *,
int brightness);
void (*notify_after)(struct device *,
Expand Down Expand Up @@ -55,6 +59,14 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness,
pb->lth_brightness;

pwm_config(pb->pwm, duty_cycle, pb->period);

if (gpio_is_valid(pb->enable_gpio)) {
if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
gpio_set_value(pb->enable_gpio, 0);
else
gpio_set_value(pb->enable_gpio, 1);
}

pwm_enable(pb->pwm);
pb->enabled = true;
}
Expand All @@ -67,6 +79,13 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb)
pwm_config(pb->pwm, 0, pb->period);
pwm_disable(pb->pwm);

if (gpio_is_valid(pb->enable_gpio)) {
if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
gpio_set_value(pb->enable_gpio, 1);
else
gpio_set_value(pb->enable_gpio, 0);
}

pb->enabled = false;
}

Expand Down Expand Up @@ -119,6 +138,7 @@ static int pwm_backlight_parse_dt(struct device *dev,
struct platform_pwm_backlight_data *data)
{
struct device_node *node = dev->of_node;
enum of_gpio_flags flags;
struct property *prop;
int length;
u32 value;
Expand Down Expand Up @@ -159,11 +179,13 @@ static int pwm_backlight_parse_dt(struct device *dev,
data->max_brightness--;
}

/*
* TODO: Most users of this driver use a number of GPIOs to control
* backlight power. Support for specifying these needs to be
* added.
*/
data->enable_gpio = of_get_named_gpio_flags(node, "enable-gpios", 0,
&flags);
if (data->enable_gpio == -EPROBE_DEFER)
return -EPROBE_DEFER;

if (gpio_is_valid(data->enable_gpio) && (flags & OF_GPIO_ACTIVE_LOW))
data->enable_gpio_flags |= PWM_BACKLIGHT_GPIO_ACTIVE_LOW;

return 0;
}
Expand Down Expand Up @@ -221,13 +243,31 @@ static int pwm_backlight_probe(struct platform_device *pdev)
} else
max = data->max_brightness;

pb->enable_gpio = data->enable_gpio;
pb->enable_gpio_flags = data->enable_gpio_flags;
pb->notify = data->notify;
pb->notify_after = data->notify_after;
pb->check_fb = data->check_fb;
pb->exit = data->exit;
pb->dev = &pdev->dev;
pb->enabled = false;

if (gpio_is_valid(pb->enable_gpio)) {
unsigned long flags;

if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
flags = GPIOF_OUT_INIT_HIGH;
else
flags = GPIOF_OUT_INIT_LOW;

ret = gpio_request_one(pb->enable_gpio, flags, "enable");
if (ret < 0) {
dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n",
pb->enable_gpio, ret);
goto err_alloc;
}
}

pb->pwm = devm_pwm_get(&pdev->dev, NULL);
if (IS_ERR(pb->pwm)) {
dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");
Expand All @@ -236,7 +276,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
if (IS_ERR(pb->pwm)) {
dev_err(&pdev->dev, "unable to request legacy PWM\n");
ret = PTR_ERR(pb->pwm);
goto err_alloc;
goto err_gpio;
}
}

Expand All @@ -261,7 +301,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
ret = PTR_ERR(bl);
goto err_alloc;
goto err_gpio;
}

if (data->dft_brightness > data->max_brightness) {
Expand All @@ -277,6 +317,9 @@ static int pwm_backlight_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, bl);
return 0;

err_gpio:
if (gpio_is_valid(pb->enable_gpio))
gpio_free(pb->enable_gpio);
err_alloc:
if (data->exit)
data->exit(&pdev->dev);
Expand Down

0 comments on commit 8265b2e

Please sign in to comment.