Message ID | 1363719573-20926-10-git-send-email-achew@nvidia.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 03/19/2013 12:59 PM, Andrew Chew wrote: > Many backlights need to be explicitly enabled. Typically, this is done > with a GPIO. For flexibility, we generalize the enable mechanism to a > regulator. > > If an enable regulator is not needed, then a dummy regulator can be given > to the backlight driver. If a GPIO is used to enable the backlight, > then a fixed regulator can be instantiated to control the GPIO. > > The backlight enable regulator can be specified in the device tree node > for the backlight, or can be done with legacy board setup code in the > usual way. > diff --git a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt > index 1e4fc72..7e2e089 100644 > --- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt > +++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt > @@ -10,6 +10,11 @@ Required properties: > last value in the array represents a 100% duty cycle (brightest). > - default-brightness-level: the default brightness level (index into the > array defined by the "brightness-levels" property) > + - enable-supply: A phandle to the regulator device tree node. This > + regulator will be turned on and off as the pwm is enabled and disabled. > + Many backlights are enabled via a GPIO. In this case, we instantiate > + a fixed regulator and give that to enable-supply. If a regulator > + is not needed, then provide a dummy fixed regulator. "enable" doesn't seem like the right name here; if this really is an "enable" input, then it's not a regulator. If you're calling it "enable" because the regulator is usually controlled by a GPIO that enables it, then what you really have is a regulator that provides power to the backlight, and the method that you enable that regulator is irrelevant. Put another way, wouldn't "power" be a better name, thus making the property "power-supply"? Although that property name migth be considered to have some negative correlation with other concepts, so if people object to that, perhaps e.g. "vdd-supply"?
On Wed, Mar 20, 2013 at 12:00:10PM -0600, Stephen Warren wrote: > On 03/19/2013 12:59 PM, Andrew Chew wrote: > > Many backlights need to be explicitly enabled. Typically, this is done > > with a GPIO. For flexibility, we generalize the enable mechanism to a > > regulator. > > > > If an enable regulator is not needed, then a dummy regulator can be given > > to the backlight driver. If a GPIO is used to enable the backlight, > > then a fixed regulator can be instantiated to control the GPIO. > > > > The backlight enable regulator can be specified in the device tree node > > for the backlight, or can be done with legacy board setup code in the > > usual way. > > > diff --git a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt > > index 1e4fc72..7e2e089 100644 > > --- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt > > +++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt > > @@ -10,6 +10,11 @@ Required properties: > > last value in the array represents a 100% duty cycle (brightest). > > - default-brightness-level: the default brightness level (index into the > > array defined by the "brightness-levels" property) > > + - enable-supply: A phandle to the regulator device tree node. This > > + regulator will be turned on and off as the pwm is enabled and disabled. > > + Many backlights are enabled via a GPIO. In this case, we instantiate > > + a fixed regulator and give that to enable-supply. If a regulator > > + is not needed, then provide a dummy fixed regulator. > > "enable" doesn't seem like the right name here; if this really is an > "enable" input, then it's not a regulator. If you're calling it "enable" > because the regulator is usually controlled by a GPIO that enables it, > then what you really have is a regulator that provides power to the > backlight, and the method that you enable that regulator is irrelevant. > > Put another way, wouldn't "power" be a better name, thus making the > property "power-supply"? Although that property name migth be considered > to have some negative correlation with other concepts, so if people > object to that, perhaps e.g. "vdd-supply"? "power" sounds like a reasonable name to me. Thierry
diff --git a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt index 1e4fc72..7e2e089 100644 --- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt +++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt @@ -10,6 +10,11 @@ Required properties: last value in the array represents a 100% duty cycle (brightest). - default-brightness-level: the default brightness level (index into the array defined by the "brightness-levels" property) + - enable-supply: A phandle to the regulator device tree node. This + regulator will be turned on and off as the pwm is enabled and disabled. + Many backlights are enabled via a GPIO. In this case, we instantiate + a fixed regulator and give that to enable-supply. If a regulator + is not needed, then provide a dummy fixed regulator. Optional properties: - pwm-names: a list of names for the PWM devices specified in the @@ -19,10 +24,19 @@ Optional properties: Example: + bl_en: fixed-regulator { + compatible = "regulator-fixed"; + regulator-name = "bl-en-supply"; + regulator-boot-on; + gpio = <&some_gpio>; + enable-active-high; + }; + backlight { compatible = "pwm-backlight"; pwms = <&pwm 0 5000000>; brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <6>; + enable-supply = <&bl_en>; }; diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 1fea627..e4922f5 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -20,10 +20,13 @@ #include <linux/pwm.h> #include <linux/pwm_backlight.h> #include <linux/slab.h> +#include <linux/regulator/consumer.h> struct pwm_bl_data { struct pwm_device *pwm; struct device *dev; + bool enabled; + struct regulator *enable_supply; unsigned int period; unsigned int lth_brightness; unsigned int *levels; @@ -35,6 +38,42 @@ struct pwm_bl_data { void (*exit)(struct device *); }; +static void pwm_backlight_enable(struct backlight_device *bl) +{ + struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); + int ret; + + /* Bail if we are already enabled. */ + if (pb->enabled) + return; + + pwm_enable(pb->pwm); + + ret = regulator_enable(pb->enable_supply); + if (ret) + dev_warn(&bl->dev, "Failed to enable regulator: %d", ret); + + pb->enabled = true; +} + +static void pwm_backlight_disable(struct backlight_device *bl) +{ + struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); + int ret; + + /* Bail if we are already disabled. */ + if (!pb->enabled) + return; + + ret = regulator_disable(pb->enable_supply); + if (ret) + dev_warn(&bl->dev, "Failed to disable regulator: %d", ret); + + pwm_disable(pb->pwm); + + pb->enabled = false; +} + static int pwm_backlight_update_status(struct backlight_device *bl) { struct pwm_bl_data *pb = bl_get_data(bl); @@ -51,7 +90,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl) if (brightness == 0) { pwm_config(pb->pwm, 0, pb->period); - pwm_disable(pb->pwm); + pwm_backlight_disable(bl); } else { int duty_cycle; @@ -65,7 +104,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl) duty_cycle = pb->lth_brightness + (duty_cycle * (pb->period - pb->lth_brightness) / max); pwm_config(pb->pwm, duty_cycle, pb->period); - pwm_enable(pb->pwm); + pwm_backlight_enable(bl); } if (pb->notify_after) @@ -138,12 +177,6 @@ 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. - */ - return 0; } @@ -206,6 +239,12 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->exit = data->exit; pb->dev = &pdev->dev; + pb->enable_supply = devm_regulator_get(&pdev->dev, "enable"); + if (IS_ERR(pb->enable_supply)) { + ret = PTR_ERR(pb->enable_supply); + 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"); @@ -268,7 +307,7 @@ static int pwm_backlight_remove(struct platform_device *pdev) backlight_device_unregister(bl); pwm_config(pb->pwm, 0, pb->period); - pwm_disable(pb->pwm); + pwm_backlight_disable(bl); if (pb->exit) pb->exit(&pdev->dev); return 0; @@ -283,7 +322,7 @@ static int pwm_backlight_suspend(struct device *dev) if (pb->notify) pb->notify(pb->dev, 0); pwm_config(pb->pwm, 0, pb->period); - pwm_disable(pb->pwm); + pwm_backlight_disable(bl); if (pb->notify_after) pb->notify_after(pb->dev, 0); return 0;