2016-01-08 21:28:58 +03:00
/*
* Copyright 2015 , Heiner Kallweit < hkallweit1 @ gmail . 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 <net/bluetooth/bluetooth.h>
# include <net/bluetooth/hci_core.h>
# include "leds.h"
2016-07-21 15:12:41 +03:00
DEFINE_LED_TRIGGER ( bt_power_led_trigger ) ;
2016-01-08 21:28:58 +03:00
struct hci_basic_led_trigger {
struct led_trigger led_trigger ;
struct hci_dev * hdev ;
} ;
# define to_hci_basic_led_trigger(arg) container_of(arg, \
struct hci_basic_led_trigger , led_trigger )
void hci_leds_update_powered ( struct hci_dev * hdev , bool enabled )
{
if ( hdev - > power_led )
led_trigger_event ( hdev - > power_led ,
enabled ? LED_FULL : LED_OFF ) ;
2016-07-21 15:12:41 +03:00
if ( ! enabled ) {
struct hci_dev * d ;
read_lock ( & hci_dev_list_lock ) ;
list_for_each_entry ( d , & hci_dev_list , list ) {
if ( test_bit ( HCI_UP , & d - > flags ) )
enabled = true ;
}
read_unlock ( & hci_dev_list_lock ) ;
}
led_trigger_event ( bt_power_led_trigger , enabled ? LED_FULL : LED_OFF ) ;
2016-01-08 21:28:58 +03:00
}
static void power_activate ( struct led_classdev * led_cdev )
{
struct hci_basic_led_trigger * htrig ;
bool powered ;
htrig = to_hci_basic_led_trigger ( led_cdev - > trigger ) ;
powered = test_bit ( HCI_UP , & htrig - > hdev - > flags ) ;
led_trigger_event ( led_cdev - > trigger , powered ? LED_FULL : LED_OFF ) ;
}
static struct led_trigger * led_allocate_basic ( struct hci_dev * hdev ,
void ( * activate ) ( struct led_classdev * led_cdev ) ,
const char * name )
{
struct hci_basic_led_trigger * htrig ;
htrig = devm_kzalloc ( & hdev - > dev , sizeof ( * htrig ) , GFP_KERNEL ) ;
if ( ! htrig )
return NULL ;
htrig - > hdev = hdev ;
htrig - > led_trigger . activate = activate ;
htrig - > led_trigger . name = devm_kasprintf ( & hdev - > dev , GFP_KERNEL ,
" %s-%s " , hdev - > name ,
name ) ;
if ( ! htrig - > led_trigger . name )
goto err_alloc ;
2016-01-25 22:46:21 +03:00
if ( devm_led_trigger_register ( & hdev - > dev , & htrig - > led_trigger ) )
2016-01-08 21:28:58 +03:00
goto err_register ;
return & htrig - > led_trigger ;
err_register :
devm_kfree ( & hdev - > dev , ( void * ) htrig - > led_trigger . name ) ;
err_alloc :
devm_kfree ( & hdev - > dev , htrig ) ;
return NULL ;
}
void hci_leds_init ( struct hci_dev * hdev )
{
/* initialize power_led */
hdev - > power_led = led_allocate_basic ( hdev , power_activate , " power " ) ;
}
2016-07-21 15:12:41 +03:00
void bt_leds_init ( void )
{
led_trigger_register_simple ( " bluetooth-power " , & bt_power_led_trigger ) ;
}
void bt_leds_cleanup ( void )
{
led_trigger_unregister_simple ( bt_power_led_trigger ) ;
}