[ARM] 5044/1: pwm_bl: add init/notify/exit callbacks
authorPhilipp Zabel <philipp.zabel@gmail.com>
Thu, 22 May 2008 13:18:40 +0000 (14:18 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 3 Jul 2008 12:25:05 +0000 (13:25 +0100)
This allows platform code to manipulate GPIOs and brightness level as
needed.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/video/backlight/pwm_bl.c
include/linux/pwm_backlight.h

index 9637f5e08cb6242f17f2d27bc1d41c8c37bb4ccf..8346dfc01cf695266a39872c7999f7ec7bd387c7 100644 (file)
@@ -23,6 +23,7 @@
 struct pwm_bl_data {
        struct pwm_device       *pwm;
        unsigned int            period;
+       int                     (*notify)(int brightness);
 };
 
 static int pwm_backlight_update_status(struct backlight_device *bl)
@@ -37,6 +38,9 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
        if (bl->props.fb_blank != FB_BLANK_UNBLANK)
                brightness = 0;
 
+       if (pb->notify)
+               brightness = pb->notify(brightness);
+
        if (brightness == 0) {
                pwm_config(pb->pwm, 0, pb->period);
                pwm_disable(pb->pwm);
@@ -62,30 +66,39 @@ static int pwm_backlight_probe(struct platform_device *pdev)
        struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
        struct backlight_device *bl;
        struct pwm_bl_data *pb;
+       int ret;
 
        if (!data)
                return -EINVAL;
 
+       if (data->init) {
+               ret = data->init(&pdev->dev);
+               if (ret < 0)
+                       return ret;
+       }
+
        pb = kzalloc(sizeof(*pb), GFP_KERNEL);
-       if (!pb)
-               return -ENOMEM;
+       if (!pb) {
+               ret = -ENOMEM;
+               goto err_alloc;
+       }
 
        pb->period = data->pwm_period_ns;
+       pb->notify = data->notify;
 
        pb->pwm = pwm_request(data->pwm_id, "backlight");
        if (pb->pwm == NULL) {
                dev_err(&pdev->dev, "unable to request PWM for backlight\n");
-               kfree(pb);
-               return -EBUSY;
+               ret = -EBUSY;
+               goto err_pwm;
        }
 
        bl = backlight_device_register(pdev->name, &pdev->dev,
                        pb, &pwm_backlight_ops);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
-               pwm_free(pb->pwm);
-               kfree(pb);
-               return PTR_ERR(bl);
+               ret = PTR_ERR(bl);
+               goto err_bl;
        }
 
        bl->props.max_brightness = data->max_brightness;
@@ -94,10 +107,20 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, bl);
        return 0;
+
+err_bl:
+       pwm_free(pb->pwm);
+err_pwm:
+       kfree(pb);
+err_alloc:
+       if (data->exit)
+               data->exit(&pdev->dev);
+       return ret;
 }
 
 static int pwm_backlight_remove(struct platform_device *pdev)
 {
+       struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
        struct backlight_device *bl = platform_get_drvdata(pdev);
        struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
 
@@ -106,6 +129,8 @@ static int pwm_backlight_remove(struct platform_device *pdev)
        pwm_disable(pb->pwm);
        pwm_free(pb->pwm);
        kfree(pb);
+       if (data->exit)
+               data->exit(&pdev->dev);
        return 0;
 }
 
index aeeffedbe8224d8afbaffd792d11e7e31a23d215..7a9754c96775091d1ac9ef9c002682e29c38ca88 100644 (file)
@@ -9,6 +9,9 @@ struct platform_pwm_backlight_data {
        unsigned int max_brightness;
        unsigned int dft_brightness;
        unsigned int pwm_period_ns;
+       int (*init)(struct device *dev);
+       int (*notify)(int brightness);
+       void (*exit)(struct device *dev);
 };
 
 #endif