LEDS: leds-pwm: Add init, notfiy and exit callbacks
authorLars-Peter Clausen <lars@metafoo.de>
Thu, 13 May 2010 21:20:53 +0000 (23:20 +0200)
committerLars-Peter Clausen <lars@metafoo.de>
Mon, 17 May 2010 17:30:27 +0000 (19:30 +0200)
This patch adds init, notify and exit callbacks to the leds-pwm driver.

One usecase for these callbacks is that on certain platforms it is neccessary
to configure a gpio pin as pwm pin. On these platforms it is usefull to have
the added callbacks, so that the gpio pin can be configured at the same time
as the pwm device.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
drivers/leds/leds-pwm.c
include/linux/leds_pwm.h

index da3fa8d..ee9c708 100644 (file)
@@ -26,8 +26,8 @@
 struct led_pwm_data {
        struct led_classdev     cdev;
        struct pwm_device       *pwm;
-       unsigned int            active_low;
-       unsigned int            period;
+       struct led_pwm          *led;
+       struct device           *parent;
 };
 
 static void led_pwm_set(struct led_classdev *led_cdev,
@@ -35,8 +35,13 @@ static void led_pwm_set(struct led_classdev *led_cdev,
 {
        struct led_pwm_data *led_dat =
                container_of(led_cdev, struct led_pwm_data, cdev);
+       struct device *parent = led_dat->parent;
+       struct led_pwm_platform_data *pdata = parent->platform_data;
        unsigned int max = led_dat->cdev.max_brightness;
-       unsigned int period =  led_dat->period;
+       unsigned int period =  led_dat->led->pwm_period_ns;
+
+       if (pdata->notify)
+           brightness = pdata->notify(parent, led_dat->led, brightness);
 
        if (brightness == 0) {
                pwm_config(led_dat->pwm, 0, period);
@@ -76,18 +81,28 @@ static int led_pwm_probe(struct platform_device *pdev)
 
                led_dat->cdev.name = cur_led->name;
                led_dat->cdev.default_trigger = cur_led->default_trigger;
-               led_dat->active_low = cur_led->active_low;
-               led_dat->period = cur_led->pwm_period_ns;
                led_dat->cdev.brightness_set = led_pwm_set;
                led_dat->cdev.brightness = LED_OFF;
                led_dat->cdev.max_brightness = cur_led->max_brightness;
                led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
 
+               led_dat->led = cur_led;
+               led_dat->parent = &pdev->dev;
+
                ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
                if (ret < 0) {
                        pwm_free(led_dat->pwm);
                        goto err;
                }
+
+               if (pdata->init) {
+                       ret = pdata->init(&pdev->dev, cur_led);
+                       if (ret < 0) {
+                               led_classdev_unregister(&led_dat->cdev);
+                               pwm_free(led_dat->pwm);
+                               goto err;
+                       }
+               }
        }
 
        platform_set_drvdata(pdev, leds_data);
@@ -97,6 +112,8 @@ static int led_pwm_probe(struct platform_device *pdev)
 err:
        if (i > 0) {
                for (i = i - 1; i >= 0; i--) {
+                       if (pdata->exit)
+                               pdata->exit(&pdev->dev, &pdata->leds[i]);
                        led_classdev_unregister(&leds_data[i].cdev);
                        pwm_free(leds_data[i].pwm);
                }
@@ -116,6 +133,8 @@ static int __devexit led_pwm_remove(struct platform_device *pdev)
        leds_data = platform_get_drvdata(pdev);
 
        for (i = 0; i < pdata->num_leds; i++) {
+               if (pdata->exit)
+                       pdata->exit(&pdev->dev, &pdata->leds[i]);
                led_classdev_unregister(&leds_data[i].cdev);
                pwm_free(leds_data[i].pwm);
        }
index 33a0711..42d4969 100644 (file)
@@ -16,6 +16,26 @@ struct led_pwm {
 struct led_pwm_platform_data {
        int                     num_leds;
        struct led_pwm  *leds;
+
+       /* @init: The init callback is called after the pwm device for a led has
+        * been successfully configured. If the return value is negative it will be
+        * seen as an error and initzalisation of the leds-pwm device will fail.
+        */
+       int (*init)(struct device *dev, struct led_pwm *led);
+
+       /* @notify: The notify callback is called whenever the brightness of a led
+        * is changed.
+        * The return value of the callback will be the brightness which is used to
+        * configure the pwm device.
+        */
+       enum led_brightness (*notify)(struct device *dev, struct led_pwm *led,
+           enum led_brightness brightness);
+
+       /* @exit: The exit callback is called, whenever a led device registered by
+        * the leds-pwm device is unregistered. It will be called prior to freeing
+        * the pwm device.
+        */
+       void (*exit)(struct device *dev, struct led_pwm *led);
 };
 
 #endif