leds-clevo-mail: hw accelerated LED blink extension
Subsystems (2)
PATCH 2/3 leds-clevo-mail: hw accelerated LED blink extension
From: Márton Németh <[email protected]>
Extends the leds subsystem with a blink_set() callback function which can be optionally implemented by a LED driver. If implemented, the driver can use the hardware acceleration for blinking a LED.
---
Documentation/leds-class.txt +12 -4
@@ -47,6 +47,18 @@ overhead, I suggest these become part of above leaves scope for further attributes should they be needed. +Hardware accelerated blink of LEDs +================================== + +Some LEDs can be programmed to blink without any CPU interaction. To +support this feature, a LED driver can optionally implement the +blink_set() function (see <linux/leds.h>). If implemeted, the +ledtrig-timer tries to use it. The blink_set() function should return +0 if the blink setting is supported, or -EINVAL otherwise, which means +that the LED will be turned on and off from software by the leds +subsystem. + + Known Issues ============
@@ -55,10 +67,6 @@ would cause nightmare dependency issues. compared to the benefits the simple trigger functionality brings. The rest of the LED subsystem can be modular. -Some leds can be programmed to flash in hardware. As this isn't a generic -LED device property, this should be exported as a device specific sysfs -attribute rather than part of the class if this functionality is required. - Future Development ==================
drivers/leds/ledtrig-timer.c +30 -4
@@ -77,8 +77,21 @@ static ssize_t led_delay_on_store(struct count++;if (count == size) { - timer_data->delay_on = state; -mod_timer (&timer_data->timer, jiffies +1 ); +if (timer_data->delay_on != state) { +/* the new value differs from the previous */ + timer_data->delay_on = state; + +/* deactivate previous settings */ +del_timer_sync (&timer_data->timer); + +/* try to activate hardware acceleration, if any */ +if (!led_cdev->blink_set || + led_cdev->blink_set (led_cdev, + timer_data->delay_on, timer_data->delay_off)) { +/* no hardware acceleration, blink via timer */ +mod_timer (&timer_data->timer, jiffies +1 ); + } + } ret = count; }
@@ -110,8 +123,21 @@ static ssize_t led_delay_off_store(struc count++;if (count == size) { - timer_data->delay_off = state; -mod_timer (&timer_data->timer, jiffies +1 ); +if (timer_data->delay_off != state) { +/* the new value differs from the previous */ + timer_data->delay_off = state; + +/* deactivate previous settings */ +del_timer_sync (&timer_data->timer); + +/* try to activate hardware acceleration, if any */ +if (!led_cdev->blink_set || + led_cdev->blink_set (led_cdev, + timer_data->delay_on, timer_data->delay_off)) { +/* no hardware acceleration, blink via timer */ +mod_timer (&timer_data->timer, jiffies +1 ); + } + } ret = count; }
include/linux/leds.h +4 -0
@@ -37,6 +37,10 @@ struct led_classdev {void (*brightness_set)(struct led_classdev *led_cdev,enum led_brightness brightness); +/* Activate hardware accelerated blink */ +int (*blink_set)(struct led_classdev *led_cdev, +int delay_on,int delay_off); +struct device *dev;struct list_head node;/* LED Device list */ char *default_trigger;/* Trigger to use */
From: Márton Németh <[email protected]>
Extends the leds subsystem with a blink_set() callback function which can be optionally implemented by a LED driver. If implemented, the driver can use the hardware acceleration for blinking a LED.
---
Documentation/leds-class.txt +13 -4
@@ -47,6 +49,19 @@ overhead, I suggest these become part of above leaves scope for further attributes should they be needed. + +Hardware accelerated blink of LEDs +================================== + +Some LEDs can be programmed to blink without any CPU interaction. To +support this feature, a LED driver can optionally implement the +blink_set() function (see <linux/leds.h>). If implemeted, the +ledtrig-timer tries to use it. The blink_set() function should return +0 if the blink setting is supported, or -EINVAL otherwise, which means +that the LED will be turned on and off from software by the leds +subsystem. + + Known Issues ============
@@ -55,10 +70,6 @@ would cause nightmare dependency issues. compared to the benefits the simple trigger functionality brings. The rest of the LED subsystem can be modular. -Some leds can be programmed to flash in hardware. As this isn't a generic -LED device property, this should be exported as a device specific sysfs -attribute rather than part of the class if this functionality is required. - Future Development ==================
drivers/leds/Kconfig +5 -1
@@ -115,7 +148,11 @@ config LEDS_TRIGGER_TIMER depends on LEDS_TRIGGERS help This allows LEDs to be controlled by a programmable timer - via sysfs. If unsure, say Y. + via sysfs. Some LED hardware can be programmed to start + blinking the LED without any further software interaction. + For more details read Documentation/leds-class.txt. + + If unsure, say Y. config LEDS_TRIGGER_IDE_DISK bool "LED IDE Disk Trigger"
drivers/leds/ledtrig-timer.c +30 -4
@@ -77,8 +77,21 @@ static ssize_t led_delay_on_store(struct count++;if (count == size) { - timer_data->delay_on = state; -mod_timer (&timer_data->timer, jiffies +1 ); +if (timer_data->delay_on != state) { +/* the new value differs from the previous */ + timer_data->delay_on = state; + +/* deactivate previous settings */ +del_timer_sync (&timer_data->timer); + +/* try to activate hardware acceleration, if any */ +if (!led_cdev->blink_set || + led_cdev->blink_set (led_cdev, + timer_data->delay_on, timer_data->delay_off)) { +/* no hardware acceleration, blink via timer */ +mod_timer (&timer_data->timer, jiffies +1 ); + } + } ret = count; }
@@ -110,8 +123,21 @@ static ssize_t led_delay_off_store(struc count++;if (count == size) { - timer_data->delay_off = state; -mod_timer (&timer_data->timer, jiffies +1 ); +if (timer_data->delay_off != state) { +/* the new value differs from the previous */ + timer_data->delay_off = state; + +/* deactivate previous settings */ +del_timer_sync (&timer_data->timer); + +/* try to activate hardware acceleration, if any */ +if (!led_cdev->blink_set || + led_cdev->blink_set (led_cdev, + timer_data->delay_on, timer_data->delay_off)) { +/* no hardware acceleration, blink via timer */ +mod_timer (&timer_data->timer, jiffies +1 ); + } + } ret = count; }
include/linux/leds.h +4 -0
@@ -37,6 +37,10 @@ struct led_classdev {void (*brightness_set)(struct led_classdev *led_cdev,enum led_brightness brightness); +/* Activate hardware accelerated blink */ +int (*blink_set)(struct led_classdev *led_cdev, +int delay_on,int delay_off); +struct device *dev;struct list_head node;/* LED Device list */ char *default_trigger;/* Trigger to use */
Quoted 16 lines · Németh Márton
From: Márton Németh <[email protected]>
Extends the leds subsystem with a
blink_set()callback function which can be optionally implemented by a LED driver. If implemented, the driver can use the hardware acceleration for blinking a LED.Signed-off-by Márton Németh <[email protected]>---
diff -uprNlinux-2.6.23.orig/Documentation/leds-class.txtlinux-2.6.23/Documentation/leds-class.txtDocumentation/leds-class.txt +1
-0@@ -47,6 +49,19 @@ overhead, I suggest these become part of above leaves scope for further attributes should they be needed. +
Documentation/leds-class.txt overhead, I suggest these become part of · line 62
Quoted 10 lines
Documentation/leds-class.txt +10
-0+Hardware accelerated blink of LEDs +================================== + +Some LEDs can be programmed to blink without any CPU interaction. To +support this feature, a LED driver can optionally implement the +blink_set() function (see <linux/leds.h>). If implemeted, the +ledtrig-timer tries to use it. The blink_set() function should return +0 if the blink setting is supported, or -EINVAL otherwise, which means +that the LED will be turned on and off from software by the leds +subsystem.
Hardware acceleration of the timer triggers is great to see and worst case I'll happily apply this patch to the LED tree, thanks.
Before I do, I did wonder if we should enhance the meaning of the set_blink function a bit. If set_blink is called with delay_on = 0, delay_off = 0 it could mean "blink with some user friendly value, hardware assisted". The use for this would be a more generic blink trigger where you wouldn't need to know about magically hardware assisted values for blinking, it would simply make an LED blink in a hardware assisted way.
We also need to document that the brightness_set overrides any blinking which may or may not be active (which is implied in your driver).
Cheers,
Richard