X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Frfkill%2Frfkill-input.c;h=29c13d308b3104a18bf5bcf28dc556c62b99fe62;hb=526324b61a9667ed9a71f0a8a8899cf675346c76;hp=9f746be588543813b8e9e686ffef3979b6ddb046;hpb=f79e3185dd0f8650022518d7624c876d8929061b;p=linux-2.6 diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c index 9f746be588..29c13d308b 100644 --- a/net/rfkill/rfkill-input.c +++ b/net/rfkill/rfkill-input.c @@ -17,6 +17,8 @@ #include #include +#include "rfkill-input.h" + MODULE_AUTHOR("Dmitry Torokhov "); MODULE_DESCRIPTION("Input layer to RF switch connector"); MODULE_LICENSE("GPL"); @@ -53,6 +55,22 @@ static void rfkill_task_handler(struct work_struct *work) mutex_unlock(&task->mutex); } +static void rfkill_schedule_set(struct rfkill_task *task, + enum rfkill_state desired_state) +{ + unsigned long flags; + + spin_lock_irqsave(&task->lock, flags); + + if (time_after(jiffies, task->last + msecs_to_jiffies(200))) { + task->desired_state = desired_state; + task->last = jiffies; + schedule_work(&task->work); + } + + spin_unlock_irqrestore(&task->lock, flags); +} + static void rfkill_schedule_toggle(struct rfkill_task *task) { unsigned long flags; @@ -81,11 +99,14 @@ static void rfkill_schedule_toggle(struct rfkill_task *task) static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN); static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH); +static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB); +static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX); +static DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN); static void rfkill_event(struct input_handle *handle, unsigned int type, - unsigned int code, int down) + unsigned int code, int data) { - if (type == EV_KEY && down == 1) { + if (type == EV_KEY && data == 1) { switch (code) { case KEY_WLAN: rfkill_schedule_toggle(&rfkill_wlan); @@ -93,6 +114,35 @@ static void rfkill_event(struct input_handle *handle, unsigned int type, case KEY_BLUETOOTH: rfkill_schedule_toggle(&rfkill_bt); break; + case KEY_UWB: + rfkill_schedule_toggle(&rfkill_uwb); + break; + case KEY_WIMAX: + rfkill_schedule_toggle(&rfkill_wimax); + break; + default: + break; + } + } else if (type == EV_SW) { + switch (code) { + case SW_RFKILL_ALL: + /* EVERY radio type. data != 0 means radios ON */ + rfkill_schedule_set(&rfkill_wwan, + (data)? RFKILL_STATE_ON: + RFKILL_STATE_OFF); + rfkill_schedule_set(&rfkill_wimax, + (data)? RFKILL_STATE_ON: + RFKILL_STATE_OFF); + rfkill_schedule_set(&rfkill_uwb, + (data)? RFKILL_STATE_ON: + RFKILL_STATE_OFF); + rfkill_schedule_set(&rfkill_bt, + (data)? RFKILL_STATE_ON: + RFKILL_STATE_OFF); + rfkill_schedule_set(&rfkill_wlan, + (data)? RFKILL_STATE_ON: + RFKILL_STATE_OFF); + break; default: break; } @@ -140,13 +190,28 @@ static void rfkill_disconnect(struct input_handle *handle) static const struct input_device_id rfkill_ids[] = { { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT(EV_KEY) }, - .keybit = { [LONG(KEY_WLAN)] = BIT(KEY_WLAN) }, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) }, + }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) }, }, { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT(EV_KEY) }, - .keybit = { [LONG(KEY_BLUETOOTH)] = BIT(KEY_BLUETOOTH) }, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) }, + }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) }, + }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT, + .evbit = { BIT(EV_SW) }, + .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) }, }, { } };