Skip to content

Commit

Permalink
leds: allow led-drivers to use a variable range of brightness values
Browse files Browse the repository at this point in the history
This patch allows drivers to override the default maximum brightness value
of 255.  We take care to preserve backwards-compatibility as much as
possible, so that user-space ABI doesn't change for existing drivers.
LED trigger code has also been updated to use the per-LED maximum.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
  • Loading branch information
Guennadi Liakhovetski authored and Richard Purdie committed Apr 6, 2009
1 parent a7d878a commit 1bd465e
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 8 deletions.
21 changes: 20 additions & 1 deletion drivers/leds/led-class.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,16 @@ static ssize_t led_brightness_store(struct device *dev,
return ret;
}

static ssize_t led_max_brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);

return sprintf(buf, "%u\n", led_cdev->max_brightness);
}

static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
#ifdef CONFIG_LEDS_TRIGGERS
static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
#endif
Expand Down Expand Up @@ -138,6 +147,13 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
list_add_tail(&led_cdev->node, &leds_list);
up_write(&leds_list_lock);

if (!led_cdev->max_brightness)
led_cdev->max_brightness = LED_FULL;

rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness);
if (rc)
goto err_out_attr_max;

led_update_brightness(led_cdev);

#ifdef CONFIG_LEDS_TRIGGERS
Expand All @@ -155,9 +171,11 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)

#ifdef CONFIG_LEDS_TRIGGERS
err_out_led_list:
device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
#endif
err_out_attr_max:
device_remove_file(led_cdev->dev, &dev_attr_brightness);
list_del(&led_cdev->node);
#endif
err_out:
device_unregister(led_cdev->dev);
return rc;
Expand All @@ -172,6 +190,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
*/
void led_classdev_unregister(struct led_classdev *led_cdev)
{
device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
device_remove_file(led_cdev->dev, &dev_attr_brightness);
#ifdef CONFIG_LEDS_TRIGGERS
device_remove_file(led_cdev->dev, &dev_attr_trigger);
Expand Down
4 changes: 2 additions & 2 deletions drivers/leds/leds.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
static inline void led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness value)
{
if (value > LED_FULL)
value = LED_FULL;
if (value > led_cdev->max_brightness)
value = led_cdev->max_brightness;
led_cdev->brightness = value;
if (!(led_cdev->flags & LED_SUSPENDED))
led_cdev->brightness_set(led_cdev, value);
Expand Down
2 changes: 1 addition & 1 deletion drivers/leds/ledtrig-default-on.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

static void defon_trig_activate(struct led_classdev *led_cdev)
{
led_set_brightness(led_cdev, LED_FULL);
led_set_brightness(led_cdev, led_cdev->max_brightness);
}

static struct led_trigger defon_led_trigger = {
Expand Down
4 changes: 2 additions & 2 deletions drivers/leds/ledtrig-heartbeat.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static void led_heartbeat_function(unsigned long data)
msecs_to_jiffies(heartbeat_data->period);
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
brightness = LED_FULL;
brightness = led_cdev->max_brightness;
break;
case 1:
delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
Expand All @@ -56,7 +56,7 @@ static void led_heartbeat_function(unsigned long data)
case 2:
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
brightness = LED_FULL;
brightness = led_cdev->max_brightness;
break;
default:
delay = heartbeat_data->period - heartbeat_data->period / 4 -
Expand Down
3 changes: 2 additions & 1 deletion drivers/leds/ledtrig-ide-disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ static void ledtrig_ide_timerfunc(unsigned long data)
{
if (ide_lastactivity != ide_activity) {
ide_lastactivity = ide_activity;
led_trigger_event(ledtrig_ide, LED_FULL);
/* INT_MAX will set each LED to its maximum brightness */
led_trigger_event(ledtrig_ide, INT_MAX);
mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
} else {
led_trigger_event(ledtrig_ide, LED_OFF);
Expand Down
2 changes: 1 addition & 1 deletion drivers/leds/ledtrig-timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ static void timer_trig_activate(struct led_classdev *led_cdev)

timer_data->brightness_on = led_get_brightness(led_cdev);
if (timer_data->brightness_on == LED_OFF)
timer_data->brightness_on = LED_FULL;
timer_data->brightness_on = led_cdev->max_brightness;
led_cdev->trigger_data = timer_data;

init_timer(&timer_data->timer);
Expand Down
1 change: 1 addition & 0 deletions include/linux/leds.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum led_brightness {
struct led_classdev {
const char *name;
int brightness;
int max_brightness;
int flags;

/* Lower 16 bits reflect status */
Expand Down

0 comments on commit 1bd465e

Please sign in to comment.