2006-03-31 14:31:04 +04:00
/*
* LED Class Core
*
* Copyright 2005 - 2006 Openedhand Ltd .
*
* Author : Richard Purdie < rpurdie @ openedhand . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
*/
# include <linux/kernel.h>
# include <linux/list.h>
# include <linux/module.h>
2008-01-01 02:09:44 +03:00
# include <linux/rwsem.h>
2006-03-31 14:31:04 +04:00
# include <linux/leds.h>
# include "leds.h"
2008-01-01 02:09:44 +03:00
DECLARE_RWSEM ( leds_list_lock ) ;
2008-03-09 23:59:57 +03:00
EXPORT_SYMBOL_GPL ( leds_list_lock ) ;
2006-03-31 14:31:04 +04:00
2008-03-09 23:59:57 +03:00
LIST_HEAD ( leds_list ) ;
2006-03-31 14:31:04 +04:00
EXPORT_SYMBOL_GPL ( leds_list ) ;
2012-03-24 02:02:14 +04:00
static void led_set_software_blink ( struct led_classdev * led_cdev ,
unsigned long delay_on ,
unsigned long delay_off )
{
int current_brightness ;
current_brightness = led_get_brightness ( led_cdev ) ;
if ( current_brightness )
led_cdev - > blink_brightness = current_brightness ;
if ( ! led_cdev - > blink_brightness )
led_cdev - > blink_brightness = led_cdev - > max_brightness ;
led_cdev - > blink_delay_on = delay_on ;
led_cdev - > blink_delay_off = delay_off ;
/* never on - don't blink */
if ( ! delay_on )
return ;
/* never off - just set to brightness */
if ( ! delay_off ) {
2012-06-13 06:01:37 +04:00
__led_set_brightness ( led_cdev , led_cdev - > blink_brightness ) ;
2012-03-24 02:02:14 +04:00
return ;
}
mod_timer ( & led_cdev - > blink_timer , jiffies + 1 ) ;
}
2012-05-27 03:19:22 +04:00
void led_blink_setup ( struct led_classdev * led_cdev ,
unsigned long * delay_on ,
unsigned long * delay_off )
2012-03-24 02:02:14 +04:00
{
2012-05-27 03:19:22 +04:00
if ( ! ( led_cdev - > flags & LED_BLINK_ONESHOT ) & &
led_cdev - > blink_set & &
2012-03-24 02:02:14 +04:00
! led_cdev - > blink_set ( led_cdev , delay_on , delay_off ) )
return ;
/* blink with 1 Hz as default if nothing specified */
if ( ! * delay_on & & ! * delay_off )
* delay_on = * delay_off = 500 ;
led_set_software_blink ( led_cdev , * delay_on , * delay_off ) ;
}
2012-05-27 03:19:22 +04:00
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 ) ;
}
2012-03-24 02:02:14 +04:00
EXPORT_SYMBOL ( led_blink_set ) ;
2012-05-27 03:19:22 +04:00
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 ) ;
2012-03-24 02:02:14 +04:00
void led_brightness_set ( struct led_classdev * led_cdev ,
enum led_brightness brightness )
{
2012-06-06 23:12:34 +04:00
/* stop and clear soft-blink timer */
del_timer_sync ( & led_cdev - > blink_timer ) ;
led_cdev - > blink_delay_on = 0 ;
led_cdev - > blink_delay_off = 0 ;
2012-06-13 06:01:37 +04:00
__led_set_brightness ( led_cdev , brightness ) ;
2012-03-24 02:02:14 +04:00
}
EXPORT_SYMBOL ( led_brightness_set ) ;