@ -186,6 +186,9 @@ MODULE_PARM_DESC(als_status, "Set the ALS status on boot "
# define METHOD_PEGA_ENABLE "ENPR"
# define METHOD_PEGA_DISABLE "DAPR"
# define PEGA_WLAN 0x00
# define PEGA_BLUETOOTH 0x01
# define PEGA_WWAN 0x02
# define PEGA_ALS 0x04
# define PEGA_ALS_POWER 0x05
@ -212,6 +215,15 @@ struct asus_led {
const char * method ;
} ;
/*
* Same thing for rfkill
*/
struct asus_pega_rfkill {
int control_id ; /* type of control. Maps to PEGA_* values */
struct rfkill * rfkill ;
struct asus_laptop * asus ;
} ;
/*
* This is the main structure , we can use it to store anything interesting
* about the hotk device
@ -246,6 +258,10 @@ struct asus_laptop {
struct rfkill * gps_rfkill ;
struct asus_pega_rfkill wlanrfk ;
struct asus_pega_rfkill btrfk ;
struct asus_pega_rfkill wwanrfk ;
acpi_handle handle ; /* the handle of the hotk device */
u32 ledd_status ; /* status of the LED display */
u8 light_level ; /* light sensor level */
@ -1263,6 +1279,86 @@ static int asus_rfkill_init(struct asus_laptop *asus)
return result ;
}
static int pega_rfkill_set ( void * data , bool blocked )
{
struct asus_pega_rfkill * pega_rfk = data ;
int ret = asus_pega_lucid_set ( pega_rfk - > asus , pega_rfk - > control_id , ! blocked ) ;
pr_warn ( " Setting rfkill %d, to %d; returned %d \n " , pega_rfk - > control_id , ! blocked , ret ) ;
return ret ;
}
static const struct rfkill_ops pega_rfkill_ops = {
. set_block = pega_rfkill_set ,
} ;
static void pega_rfkill_terminate ( struct asus_pega_rfkill * pega_rfk )
{
pr_warn ( " Terminating %d \n " , pega_rfk - > control_id ) ;
if ( pega_rfk - > rfkill ) {
rfkill_unregister ( pega_rfk - > rfkill ) ;
rfkill_destroy ( pega_rfk - > rfkill ) ;
pega_rfk - > rfkill = NULL ;
}
}
static void pega_rfkill_exit ( struct asus_laptop * asus )
{
pega_rfkill_terminate ( & asus - > wwanrfk ) ;
pega_rfkill_terminate ( & asus - > btrfk ) ;
pega_rfkill_terminate ( & asus - > wlanrfk ) ;
}
static int pega_rfkill_setup ( struct asus_laptop * asus , struct asus_pega_rfkill * pega_rfk ,
const char * name , int controlid , int rfkill_type )
{
int result ;
pr_warn ( " Setting up rfk %s, control %d, type %d \n " , name , controlid , rfkill_type ) ;
pega_rfk - > control_id = controlid ;
pega_rfk - > asus = asus ;
pega_rfk - > rfkill = rfkill_alloc ( name , & asus - > platform_device - > dev ,
rfkill_type , & pega_rfkill_ops , pega_rfk ) ;
if ( ! pega_rfk - > rfkill )
return - EINVAL ;
result = rfkill_register ( pega_rfk - > rfkill ) ;
if ( result ) {
rfkill_destroy ( pega_rfk - > rfkill ) ;
pega_rfk - > rfkill = NULL ;
}
return result ;
}
static int pega_rfkill_init ( struct asus_laptop * asus )
{
int ret = 0 ;
if ( ! asus - > is_pega_lucid )
return - ENODEV ;
ret = pega_rfkill_setup ( asus , & asus - > wlanrfk , " pega-wlan " , PEGA_WLAN , RFKILL_TYPE_WLAN ) ;
if ( ret )
return ret ;
ret = pega_rfkill_setup ( asus , & asus - > btrfk , " pega-bt " , PEGA_BLUETOOTH , RFKILL_TYPE_BLUETOOTH ) ;
if ( ret )
goto err_btrfk ;
ret = pega_rfkill_setup ( asus , & asus - > wwanrfk , " pega-wwan " , PEGA_WWAN , RFKILL_TYPE_WWAN ) ;
if ( ret )
goto err_wwanrfk ;
pr_warn ( " Pega rfkill init succeeded \n " ) ;
return 0 ;
err_wwanrfk :
pega_rfkill_terminate ( & asus - > btrfk ) ;
err_btrfk :
pega_rfkill_terminate ( & asus - > wlanrfk ) ;
return ret ;
}
/*
* Input device ( i . e . hotkeys )
*/
@ -1697,9 +1793,15 @@ static int __devinit asus_acpi_add(struct acpi_device *device)
if ( result & & result ! = - ENODEV )
goto fail_pega_accel ;
result = pega_rfkill_init ( asus ) ;
if ( result & & result ! = - ENODEV )
goto fail_pega_rfkill ;
asus_device_present = true ;
return 0 ;
fail_pega_rfkill :
pega_accel_exit ( asus ) ;
fail_pega_accel :
asus_rfkill_exit ( asus ) ;
fail_rfkill :
@ -1726,6 +1828,7 @@ static int asus_acpi_remove(struct acpi_device *device, int type)
asus_led_exit ( asus ) ;
asus_input_exit ( asus ) ;
pega_accel_exit ( asus ) ;
pega_rfkill_exit ( asus ) ;
asus_platform_exit ( asus ) ;
kfree ( asus - > name ) ;