aboutsummaryrefslogtreecommitdiff
path: root/drivers
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 /drivers
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/leds/leds-pwm.c29
1 files changed, 24 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);
}