2010-01-10 17:15:32 +00:00
/*
* LED support code , ripped out of arch / arm / kernel / time . c
*
* Copyright ( C ) 1994 - 2001 Russell King
*
* 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 .
*/
2011-07-22 10:58:34 -04:00
# include <linux/export.h>
2010-01-10 17:15:32 +00:00
# include <linux/init.h>
2011-12-21 15:52:57 -08:00
# include <linux/device.h>
2011-04-22 22:02:33 +02:00
# include <linux/syscore_ops.h>
2011-07-31 10:52:44 -04:00
# include <linux/string.h>
2010-01-10 17:15:32 +00:00
# include <asm/leds.h>
static void dummy_leds_event ( led_event_t evt )
{
}
void ( * leds_event ) ( led_event_t ) = dummy_leds_event ;
struct leds_evt_name {
const char name [ 8 ] ;
int on ;
int off ;
} ;
static const struct leds_evt_name evt_names [ ] = {
{ " amber " , led_amber_on , led_amber_off } ,
{ " blue " , led_blue_on , led_blue_off } ,
{ " green " , led_green_on , led_green_off } ,
{ " red " , led_red_on , led_red_off } ,
} ;
2011-12-21 15:52:57 -08:00
static ssize_t leds_store ( struct device * dev ,
struct device_attribute * attr ,
2010-01-10 17:15:32 +00:00
const char * buf , size_t size )
{
int ret = - EINVAL , len = strcspn ( buf , " " ) ;
if ( len > 0 & & buf [ len ] = = ' \0 ' )
len - - ;
if ( strncmp ( buf , " claim " , len ) = = 0 ) {
leds_event ( led_claim ) ;
ret = size ;
} else if ( strncmp ( buf , " release " , len ) = = 0 ) {
leds_event ( led_release ) ;
ret = size ;
} else {
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( evt_names ) ; i + + ) {
if ( strlen ( evt_names [ i ] . name ) ! = len | |
strncmp ( buf , evt_names [ i ] . name , len ) ! = 0 )
continue ;
if ( strncmp ( buf + len , " on " , 3 ) = = 0 ) {
leds_event ( evt_names [ i ] . on ) ;
ret = size ;
} else if ( strncmp ( buf + len , " off " , 4 ) = = 0 ) {
leds_event ( evt_names [ i ] . off ) ;
ret = size ;
}
break ;
}
}
return ret ;
}
2011-12-21 15:52:57 -08:00
static DEVICE_ATTR ( event , 0200 , NULL , leds_store ) ;
2010-01-10 17:15:32 +00:00
2011-12-21 15:52:57 -08:00
static struct bus_type leds_subsys = {
2011-04-22 22:02:33 +02:00
. name = " leds " ,
2011-12-21 15:52:57 -08:00
. dev_name = " leds " ,
2011-04-22 22:02:33 +02:00
} ;
2011-12-21 15:52:57 -08:00
static struct device leds_device = {
2011-04-22 22:02:33 +02:00
. id = 0 ,
2011-12-21 15:52:57 -08:00
. bus = & leds_subsys ,
2011-04-22 22:02:33 +02:00
} ;
static int leds_suspend ( void )
2010-01-10 17:15:32 +00:00
{
leds_event ( led_stop ) ;
return 0 ;
}
2011-04-22 22:02:33 +02:00
static void leds_resume ( void )
2010-01-10 17:15:32 +00:00
{
leds_event ( led_start ) ;
}
2011-04-22 22:02:33 +02:00
static void leds_shutdown ( void )
2010-01-10 17:15:32 +00:00
{
leds_event ( led_halted ) ;
}
2011-04-22 22:02:33 +02:00
static struct syscore_ops leds_syscore_ops = {
2010-01-10 17:15:32 +00:00
. shutdown = leds_shutdown ,
. suspend = leds_suspend ,
. resume = leds_resume ,
} ;
static int __init leds_init ( void )
{
int ret ;
2011-12-21 15:52:57 -08:00
ret = subsys_system_register ( & leds_subsys , NULL ) ;
2010-01-10 17:15:32 +00:00
if ( ret = = 0 )
2011-12-21 15:52:57 -08:00
ret = device_register ( & leds_device ) ;
2010-01-10 17:15:32 +00:00
if ( ret = = 0 )
2011-12-21 15:52:57 -08:00
ret = device_create_file ( & leds_device , & dev_attr_event ) ;
2011-04-22 22:02:33 +02:00
if ( ret = = 0 )
register_syscore_ops ( & leds_syscore_ops ) ;
2010-01-10 17:15:32 +00:00
return ret ;
}
device_initcall ( leds_init ) ;
EXPORT_SYMBOL ( leds_event ) ;