Commit 1bd465e6 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Richard Purdie

leds: allow led-drivers to use a variable range of brightness values

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: default avatarGuennadi Liakhovetski <lg@denx.de>
Signed-off-by: default avatarRichard Purdie <rpurdie@linux.intel.com>
parent a7d878af
...@@ -64,7 +64,16 @@ static ssize_t led_brightness_store(struct device *dev, ...@@ -64,7 +64,16 @@ static ssize_t led_brightness_store(struct device *dev,
return ret; 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(brightness, 0644, led_brightness_show, led_brightness_store);
static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
#ifdef CONFIG_LEDS_TRIGGERS #ifdef CONFIG_LEDS_TRIGGERS
static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
#endif #endif
...@@ -138,6 +147,13 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) ...@@ -138,6 +147,13 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
list_add_tail(&led_cdev->node, &leds_list); list_add_tail(&led_cdev->node, &leds_list);
up_write(&leds_list_lock); 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); led_update_brightness(led_cdev);
#ifdef CONFIG_LEDS_TRIGGERS #ifdef CONFIG_LEDS_TRIGGERS
...@@ -155,9 +171,11 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) ...@@ -155,9 +171,11 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
#ifdef CONFIG_LEDS_TRIGGERS #ifdef CONFIG_LEDS_TRIGGERS
err_out_led_list: 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); device_remove_file(led_cdev->dev, &dev_attr_brightness);
list_del(&led_cdev->node); list_del(&led_cdev->node);
#endif
err_out: err_out:
device_unregister(led_cdev->dev); device_unregister(led_cdev->dev);
return rc; return rc;
...@@ -172,6 +190,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register); ...@@ -172,6 +190,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
*/ */
void led_classdev_unregister(struct led_classdev *led_cdev) 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); device_remove_file(led_cdev->dev, &dev_attr_brightness);
#ifdef CONFIG_LEDS_TRIGGERS #ifdef CONFIG_LEDS_TRIGGERS
device_remove_file(led_cdev->dev, &dev_attr_trigger); device_remove_file(led_cdev->dev, &dev_attr_trigger);
......
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
static inline void led_set_brightness(struct led_classdev *led_cdev, static inline void led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness value) enum led_brightness value)
{ {
if (value > LED_FULL) if (value > led_cdev->max_brightness)
value = LED_FULL; value = led_cdev->max_brightness;
led_cdev->brightness = value; led_cdev->brightness = value;
if (!(led_cdev->flags & LED_SUSPENDED)) if (!(led_cdev->flags & LED_SUSPENDED))
led_cdev->brightness_set(led_cdev, value); led_cdev->brightness_set(led_cdev, value);
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
static void defon_trig_activate(struct led_classdev *led_cdev) 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 = { static struct led_trigger defon_led_trigger = {
......
...@@ -47,7 +47,7 @@ static void led_heartbeat_function(unsigned long data) ...@@ -47,7 +47,7 @@ static void led_heartbeat_function(unsigned long data)
msecs_to_jiffies(heartbeat_data->period); msecs_to_jiffies(heartbeat_data->period);
delay = msecs_to_jiffies(70); delay = msecs_to_jiffies(70);
heartbeat_data->phase++; heartbeat_data->phase++;
brightness = LED_FULL; brightness = led_cdev->max_brightness;
break; break;
case 1: case 1:
delay = heartbeat_data->period / 4 - msecs_to_jiffies(70); delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
...@@ -56,7 +56,7 @@ static void led_heartbeat_function(unsigned long data) ...@@ -56,7 +56,7 @@ static void led_heartbeat_function(unsigned long data)
case 2: case 2:
delay = msecs_to_jiffies(70); delay = msecs_to_jiffies(70);
heartbeat_data->phase++; heartbeat_data->phase++;
brightness = LED_FULL; brightness = led_cdev->max_brightness;
break; break;
default: default:
delay = heartbeat_data->period - heartbeat_data->period / 4 - delay = heartbeat_data->period - heartbeat_data->period / 4 -
......
...@@ -37,7 +37,8 @@ static void ledtrig_ide_timerfunc(unsigned long data) ...@@ -37,7 +37,8 @@ static void ledtrig_ide_timerfunc(unsigned long data)
{ {
if (ide_lastactivity != ide_activity) { if (ide_lastactivity != ide_activity) {
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)); mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
} else { } else {
led_trigger_event(ledtrig_ide, LED_OFF); led_trigger_event(ledtrig_ide, LED_OFF);
......
...@@ -166,7 +166,7 @@ static void timer_trig_activate(struct led_classdev *led_cdev) ...@@ -166,7 +166,7 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
timer_data->brightness_on = led_get_brightness(led_cdev); timer_data->brightness_on = led_get_brightness(led_cdev);
if (timer_data->brightness_on == LED_OFF) 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; led_cdev->trigger_data = timer_data;
init_timer(&timer_data->timer); init_timer(&timer_data->timer);
......
...@@ -30,6 +30,7 @@ enum led_brightness { ...@@ -30,6 +30,7 @@ enum led_brightness {
struct led_classdev { struct led_classdev {
const char *name; const char *name;
int brightness; int brightness;
int max_brightness;
int flags; int flags;
/* Lower 16 bits reflect status */ /* Lower 16 bits reflect status */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment