Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 318961
b: refs/heads/master
c: 5bb629c
h: refs/heads/master
i:
  318959: e7d441b
v: v3
  • Loading branch information
Fabio Baltieri authored and Bryan Wu committed Jul 23, 2012
1 parent 616a7e3 commit 752a32f
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: eb202621f8c0fb264a35e1b35fc00bdb3114a897
refs/heads/master: 5bb629c504394f4d42c53a25d75ccb02a393f92f
19 changes: 19 additions & 0 deletions trunk/drivers/leds/led-class.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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));
}

Expand Down
45 changes: 38 additions & 7 deletions trunk/drivers/leds/led-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;

Expand All @@ -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)
{
Expand Down
30 changes: 26 additions & 4 deletions trunk/drivers/leds/led-triggers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down
25 changes: 25 additions & 0 deletions trunk/include/linux/leds.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ struct led_classdev {
#define LED_SUSPENDED (1 << 0)
/* Upper 16 bits reflect control information */
#define LED_CORE_SUSPENDRESUME (1 << 16)
#define LED_BLINK_ONESHOT (1 << 17)
#define LED_BLINK_ONESHOT_STOP (1 << 18)
#define LED_BLINK_INVERT (1 << 19)

/* Set LED brightness level */
/* Must not sleep, use a workqueue if needed */
Expand Down Expand Up @@ -102,6 +105,24 @@ extern void led_classdev_resume(struct led_classdev *led_cdev);
extern void led_blink_set(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off);
/**
* led_blink_set_oneshot - do a oneshot software blink
* @led_cdev: the LED to start blinking
* @delay_on: the time it should be on (in ms)
* @delay_off: the time it should ble off (in ms)
* @invert: blink off, then on, leaving the led on
*
* This function makes the LED blink one time for delay_on +
* delay_off time, ignoring the request if another one-shot
* blink is already in progress.
*
* If invert is set, led blinks for delay_off first, then for
* delay_on and leave the led on after the on-off cycle.
*/
extern void led_blink_set_oneshot(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off,
int invert);
/**
* led_brightness_set - set LED brightness
* @led_cdev: the LED to set
Expand Down Expand Up @@ -150,6 +171,10 @@ extern void led_trigger_event(struct led_trigger *trigger,
extern void led_trigger_blink(struct led_trigger *trigger,
unsigned long *delay_on,
unsigned long *delay_off);
extern void led_trigger_blink_oneshot(struct led_trigger *trigger,
unsigned long *delay_on,
unsigned long *delay_off,
int invert);

#else

Expand Down

0 comments on commit 752a32f

Please sign in to comment.