mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
leds: add oneshot blink functions
Add two new functions, led_blink_set_oneshot and led_trigger_blink_oneshot, to be used by triggers for one-shot blink of led devices. This is implemented extending the existing software-blink code, and uses the same timer and handler function. The behavior of the code is to do a blink-on, blink-off sequence when the function is called, ignoring other calls until the sequence is completed so that the leds keep blinking at constant rate if the functions are called repeatedly. This is meant to be used by drivers which needs to trigger on sporadic event, but doesn't have clear busy/idle trigger points. After the blink sequence the led remains off. This behavior can be inverted setting the "invert" argument, which blink the led off, than on and leave the led on after the sequence. ([email protected]: rebase to commit 'leds: don't disable blinking when writing the same value to delay_on or delay_off') Signed-off-by: Fabio Baltieri <[email protected]> Acked-by: Shuah Khan <[email protected]> Signed-off-by: Bryan Wu <[email protected]>
This commit is contained in:
parent
eb202621f8
commit
5bb629c504
4 changed files with 108 additions and 11 deletions
|
|
@ -86,6 +86,11 @@ static void led_timer_function(unsigned long data)
|
|||
return;
|
||||
}
|
||||
|
||||
if (led_cdev->flags & LED_BLINK_ONESHOT_STOP) {
|
||||
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
|
||||
return;
|
||||
}
|
||||
|
||||
brightness = led_get_brightness(led_cdev);
|
||||
if (!brightness) {
|
||||
/* Time to switch the LED on. */
|
||||
|
|
@ -102,6 +107,20 @@ static void led_timer_function(unsigned long data)
|
|||
|
||||
led_set_brightness(led_cdev, brightness);
|
||||
|
||||
/* Return in next iteration if led is in one-shot mode and we are in
|
||||
* the final blink state so that the led is toggled each delay_on +
|
||||
* delay_off milliseconds in worst case.
|
||||
*/
|
||||
if (led_cdev->flags & LED_BLINK_ONESHOT) {
|
||||
if (led_cdev->flags & LED_BLINK_INVERT) {
|
||||
if (brightness)
|
||||
led_cdev->flags |= LED_BLINK_ONESHOT_STOP;
|
||||
} else {
|
||||
if (!brightness)
|
||||
led_cdev->flags |= LED_BLINK_ONESHOT_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ EXPORT_SYMBOL_GPL(leds_list);
|
|||
static void led_stop_software_blink(struct led_classdev *led_cdev)
|
||||
{
|
||||
/* deactivate previous settings */
|
||||
del_timer_sync(&led_cdev->blink_timer);
|
||||
led_cdev->blink_delay_on = 0;
|
||||
led_cdev->blink_delay_off = 0;
|
||||
}
|
||||
|
|
@ -61,13 +60,12 @@ static void led_set_software_blink(struct led_classdev *led_cdev,
|
|||
}
|
||||
|
||||
|
||||
void led_blink_set(struct led_classdev *led_cdev,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off)
|
||||
void led_blink_setup(struct led_classdev *led_cdev,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off)
|
||||
{
|
||||
del_timer_sync(&led_cdev->blink_timer);
|
||||
|
||||
if (led_cdev->blink_set &&
|
||||
if (!(led_cdev->flags & LED_BLINK_ONESHOT) &&
|
||||
led_cdev->blink_set &&
|
||||
!led_cdev->blink_set(led_cdev, delay_on, delay_off))
|
||||
return;
|
||||
|
||||
|
|
@ -77,8 +75,41 @@ void led_blink_set(struct led_classdev *led_cdev,
|
|||
|
||||
led_set_software_blink(led_cdev, *delay_on, *delay_off);
|
||||
}
|
||||
|
||||
void led_blink_set(struct led_classdev *led_cdev,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off)
|
||||
{
|
||||
del_timer_sync(&led_cdev->blink_timer);
|
||||
|
||||
led_cdev->flags &= ~LED_BLINK_ONESHOT;
|
||||
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
|
||||
|
||||
led_blink_setup(led_cdev, delay_on, delay_off);
|
||||
}
|
||||
EXPORT_SYMBOL(led_blink_set);
|
||||
|
||||
void led_blink_set_oneshot(struct led_classdev *led_cdev,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off,
|
||||
int invert)
|
||||
{
|
||||
if ((led_cdev->flags & LED_BLINK_ONESHOT) &&
|
||||
timer_pending(&led_cdev->blink_timer))
|
||||
return;
|
||||
|
||||
led_cdev->flags |= LED_BLINK_ONESHOT;
|
||||
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
|
||||
|
||||
if (invert)
|
||||
led_cdev->flags |= LED_BLINK_INVERT;
|
||||
else
|
||||
led_cdev->flags &= ~LED_BLINK_INVERT;
|
||||
|
||||
led_blink_setup(led_cdev, delay_on, delay_off);
|
||||
}
|
||||
EXPORT_SYMBOL(led_blink_set_oneshot);
|
||||
|
||||
void led_brightness_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -230,9 +230,11 @@ void led_trigger_event(struct led_trigger *trig,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_event);
|
||||
|
||||
void led_trigger_blink(struct led_trigger *trig,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off)
|
||||
void led_trigger_blink_setup(struct led_trigger *trig,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off,
|
||||
int oneshot,
|
||||
int invert)
|
||||
{
|
||||
struct list_head *entry;
|
||||
|
||||
|
|
@ -244,12 +246,32 @@ void led_trigger_blink(struct led_trigger *trig,
|
|||
struct led_classdev *led_cdev;
|
||||
|
||||
led_cdev = list_entry(entry, struct led_classdev, trig_list);
|
||||
led_blink_set(led_cdev, delay_on, delay_off);
|
||||
if (oneshot)
|
||||
led_blink_set_oneshot(led_cdev, delay_on, delay_off,
|
||||
invert);
|
||||
else
|
||||
led_blink_set(led_cdev, delay_on, delay_off);
|
||||
}
|
||||
read_unlock(&trig->leddev_list_lock);
|
||||
}
|
||||
|
||||
void led_trigger_blink(struct led_trigger *trig,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off)
|
||||
{
|
||||
led_trigger_blink_setup(trig, delay_on, delay_off, 0, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_blink);
|
||||
|
||||
void led_trigger_blink_oneshot(struct led_trigger *trig,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off,
|
||||
int invert)
|
||||
{
|
||||
led_trigger_blink_setup(trig, delay_on, delay_off, 1, invert);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(led_trigger_blink_oneshot);
|
||||
|
||||
void led_trigger_register_simple(const char *name, struct led_trigger **tp)
|
||||
{
|
||||
struct led_trigger *trig;
|
||||
|
|
|
|||
Loading…
Reference in a new issue