aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2010-05-13 23:20:53 +0200
committerLars-Peter Clausen <lars@metafoo.de>2010-05-17 19:30:27 +0200
commit3a821bff143548dd67dbc7292fa9dce24f5b864e (patch)
treee41b3339c895c41453e79c1b1392a4fda2aca833
parente40152ee1e1c7a63f4777791863215e3faa37a86 (diff)
LEDS: leds-pwm: Add init, notfiy and exit callbacks
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>
-rw-r--r--drivers/leds/leds-pwm.c29
-rw-r--r--include/linux/leds_pwm.h20
2 files changed, 44 insertions, 5 deletions
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index da3fa8dcdf5..ee9c7085664 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -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);
}
diff --git a/include/linux/leds_pwm.h b/include/linux/leds_pwm.h
index 33a07116748..42d49694cbd 100644
--- a/include/linux/leds_pwm.h
+++ b/include/linux/leds_pwm.h
@@ -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