mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 19:26:25 +00:00
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: Guennadi Liakhovetski <lg@denx.de> Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
This commit is contained in:
parent
a7d878af94
commit
1bd465e6b0
7 changed files with 29 additions and 8 deletions
|
@ -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)
|
||||||
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)
|
||||||
|
|
||||||
#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);
|
||||||
*/
|
*/
|
||||||
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 @@
|
||||||
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 @@
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
|
||||||
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 {
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in a new issue