Signed-off-by: Alban Bedel <alban.be...@avionic-design.de>
---
 .../bindings/video/backlight/pwm-backlight.txt     |    1 +
 drivers/video/backlight/pwm_bl.c                   |   22 ++++++++++++++-----
 include/linux/pwm_backlight.h                      |    1 +
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt 
b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
index 1e4fc72..3a40539 100644
--- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
+++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
@@ -14,6 +14,7 @@ Required properties:
 Optional properties:
   - pwm-names: a list of names for the PWM devices specified in the
                "pwms" property (see PWM binding[0])
+  - active-low: boolean indicating that the backlight use active low logic
 
 [0]: Documentation/devicetree/bindings/pwm/pwm.txt
 
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 995f016..109c703 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -25,6 +25,7 @@ struct pwm_bl_data {
        struct pwm_device       *pwm;
        struct device           *dev;
        unsigned int            period;
+       unsigned int            active_low;
        unsigned int            lth_brightness;
        unsigned int            *levels;
        int                     (*notify)(struct device *,
@@ -40,6 +41,7 @@ static int pwm_backlight_update_status(struct 
backlight_device *bl)
        struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
        int brightness = bl->props.brightness;
        int max = bl->props.max_brightness;
+       int duty_cycle;
 
        if (bl->props.power != FB_BLANK_UNBLANK)
                brightness = 0;
@@ -51,11 +53,8 @@ static int pwm_backlight_update_status(struct 
backlight_device *bl)
                brightness = pb->notify(pb->dev, brightness);
 
        if (brightness == 0) {
-               pwm_config(pb->pwm, 0, pb->period);
-               pwm_disable(pb->pwm);
+               duty_cycle = 0;
        } else {
-               int duty_cycle;
-
                if (pb->levels) {
                        duty_cycle = pb->levels[brightness];
                        max = pb->levels[max];
@@ -65,10 +64,17 @@ 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);
        }
 
+       if (pb->active_low)
+               duty_cycle = pb->period - duty_cycle;
+
+       pwm_config(pb->pwm, duty_cycle, pb->period);
+       if (duty_cycle == 0)
+               pwm_disable(pb->pwm);
+       else
+               pwm_enable(pb->pwm);
+
        if (pb->notify_after)
                pb->notify_after(pb->dev, brightness);
 
@@ -145,6 +151,9 @@ static int pwm_backlight_parse_dt(struct device *dev,
                data->max_brightness--;
        }
 
+       /* Is the backlight low active? */
+       data->active_low = of_property_read_bool(node, "active-low");
+
        /*
         * TODO: Most users of this driver use a number of GPIOs to control
         *       backlight power. Support for specifying these needs to be
@@ -237,6 +246,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 
        pb->period = pwm_get_period(pb->pwm);
        pb->lth_brightness = data->lth_brightness * (pb->period / max);
+       pb->active_low = data->active_low;
 
        memset(&props, 0, sizeof(struct backlight_properties));
        props.type = BACKLIGHT_RAW;
diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h
index 56f4a86..52b19d9 100644
--- a/include/linux/pwm_backlight.h
+++ b/include/linux/pwm_backlight.h
@@ -12,6 +12,7 @@ struct platform_pwm_backlight_data {
        unsigned int dft_brightness;
        unsigned int lth_brightness;
        unsigned int pwm_period_ns;
+       unsigned int active_low;
        unsigned int *levels;
        int (*init)(struct device *dev);
        int (*notify)(struct device *dev, int brightness);
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to