2 * Input layer to RF Kill interface connector
4 * Copyright (c) 2007 Dmitry Torokhov
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
13 #include <linux/module.h>
14 #include <linux/input.h>
15 #include <linux/slab.h>
16 #include <linux/workqueue.h>
17 #include <linux/init.h>
18 #include <linux/rfkill.h>
20 #include "rfkill-input.h"
22 MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
23 MODULE_DESCRIPTION("Input layer to RF switch connector");
24 MODULE_LICENSE("GPL");
26 enum rfkill_input_master_mode
{
27 RFKILL_INPUT_MASTER_DONOTHING
= 0,
28 RFKILL_INPUT_MASTER_RESTORE
= 1,
29 RFKILL_INPUT_MASTER_UNBLOCKALL
= 2,
30 RFKILL_INPUT_MASTER_MAX
, /* marker */
33 static enum rfkill_input_master_mode rfkill_master_switch_mode
=
34 RFKILL_INPUT_MASTER_UNBLOCKALL
;
35 module_param_named(master_switch_mode
, rfkill_master_switch_mode
, uint
, 0);
36 MODULE_PARM_DESC(master_switch_mode
,
37 "SW_RFKILL_ALL ON should: 0=do nothing; 1=restore; 2=unblock all");
39 enum rfkill_global_sched_op
{
40 RFKILL_GLOBAL_OP_EPO
= 0,
41 RFKILL_GLOBAL_OP_RESTORE
,
42 RFKILL_GLOBAL_OP_UNLOCK
,
43 RFKILL_GLOBAL_OP_UNBLOCK
,
47 * Currently, the code marked with RFKILL_NEED_SWSET is inactive.
48 * If handling of EV_SW SW_WLAN/WWAN/BLUETOOTH/etc is needed in the
49 * future, when such events are added, that code will be necessary.
53 struct work_struct work
;
55 /* ensures that task is serialized */
58 /* protects everything below */
61 /* pending regular switch operations (1=pending) */
62 unsigned long sw_pending
[BITS_TO_LONGS(RFKILL_TYPE_MAX
)];
64 #ifdef RFKILL_NEED_SWSET
65 /* set operation pending (1=pending) */
66 unsigned long sw_setpending
[BITS_TO_LONGS(RFKILL_TYPE_MAX
)];
68 /* desired state for pending set operation (1=unblock) */
69 unsigned long sw_newstate
[BITS_TO_LONGS(RFKILL_TYPE_MAX
)];
72 /* should the state be complemented (1=yes) */
73 unsigned long sw_togglestate
[BITS_TO_LONGS(RFKILL_TYPE_MAX
)];
75 bool global_op_pending
;
76 enum rfkill_global_sched_op op
;
79 static void __rfkill_handle_global_op(enum rfkill_global_sched_op op
)
84 case RFKILL_GLOBAL_OP_EPO
:
87 case RFKILL_GLOBAL_OP_RESTORE
:
88 rfkill_restore_states();
90 case RFKILL_GLOBAL_OP_UNLOCK
:
91 rfkill_remove_epo_lock();
93 case RFKILL_GLOBAL_OP_UNBLOCK
:
94 rfkill_remove_epo_lock();
95 for (i
= 0; i
< RFKILL_TYPE_MAX
; i
++)
96 rfkill_switch_all(i
, RFKILL_STATE_UNBLOCKED
);
99 /* memory corruption or bug, fail safely */
101 WARN(1, "Unknown requested operation %d! "
102 "rfkill Emergency Power Off activated\n",
107 #ifdef RFKILL_NEED_SWSET
108 static void __rfkill_handle_normal_op(const enum rfkill_type type
,
109 const bool sp
, const bool s
, const bool c
)
111 enum rfkill_state state
;
114 state
= (s
) ? RFKILL_STATE_UNBLOCKED
:
115 RFKILL_STATE_SOFT_BLOCKED
;
117 state
= rfkill_get_global_state(type
);
120 state
= rfkill_state_complement(state
);
122 rfkill_switch_all(type
, state
);
125 static void __rfkill_handle_normal_op(const enum rfkill_type type
,
128 enum rfkill_state state
;
130 state
= rfkill_get_global_state(type
);
132 state
= rfkill_state_complement(state
);
134 rfkill_switch_all(type
, state
);
138 static void rfkill_task_handler(struct work_struct
*work
)
140 struct rfkill_task
*task
=
141 container_of(work
, struct rfkill_task
, work
);
144 mutex_lock(&task
->mutex
);
146 spin_lock_irq(&task
->lock
);
148 if (task
->global_op_pending
) {
149 enum rfkill_global_sched_op op
= task
->op
;
150 task
->global_op_pending
= false;
151 memset(task
->sw_pending
, 0, sizeof(task
->sw_pending
));
152 spin_unlock_irq(&task
->lock
);
154 __rfkill_handle_global_op(op
);
156 /* make sure we do at least one pass with
157 * !task->global_op_pending */
158 spin_lock_irq(&task
->lock
);
160 } else if (!rfkill_is_epo_lock_active()) {
163 while (!task
->global_op_pending
&&
164 i
< RFKILL_TYPE_MAX
) {
165 if (test_and_clear_bit(i
, task
->sw_pending
)) {
167 #ifdef RFKILL_NEED_SWSET
169 sp
= test_and_clear_bit(i
,
170 task
->sw_setpending
);
171 s
= test_bit(i
, task
->sw_newstate
);
173 c
= test_and_clear_bit(i
,
174 task
->sw_togglestate
);
175 spin_unlock_irq(&task
->lock
);
177 #ifdef RFKILL_NEED_SWSET
178 __rfkill_handle_normal_op(i
, sp
, s
, c
);
180 __rfkill_handle_normal_op(i
, c
);
183 spin_lock_irq(&task
->lock
);
188 doit
= task
->global_op_pending
;
190 spin_unlock_irq(&task
->lock
);
192 mutex_unlock(&task
->mutex
);
195 static struct rfkill_task rfkill_task
= {
196 .work
= __WORK_INITIALIZER(rfkill_task
.work
,
197 rfkill_task_handler
),
198 .mutex
= __MUTEX_INITIALIZER(rfkill_task
.mutex
),
199 .lock
= __SPIN_LOCK_UNLOCKED(rfkill_task
.lock
),
202 static void rfkill_schedule_global_op(enum rfkill_global_sched_op op
)
206 spin_lock_irqsave(&rfkill_task
.lock
, flags
);
208 rfkill_task
.global_op_pending
= true;
209 schedule_work(&rfkill_task
.work
);
210 spin_unlock_irqrestore(&rfkill_task
.lock
, flags
);
213 #ifdef RFKILL_NEED_SWSET
214 /* Use this if you need to add EV_SW SW_WLAN/WWAN/BLUETOOTH/etc handling */
216 static void rfkill_schedule_set(enum rfkill_type type
,
217 enum rfkill_state desired_state
)
221 if (rfkill_is_epo_lock_active())
224 spin_lock_irqsave(&rfkill_task
.lock
, flags
);
225 if (!rfkill_task
.global_op_pending
) {
226 set_bit(type
, rfkill_task
.sw_pending
);
227 set_bit(type
, rfkill_task
.sw_setpending
);
228 clear_bit(type
, rfkill_task
.sw_togglestate
);
230 set_bit(type
, rfkill_task
.sw_newstate
);
232 clear_bit(type
, rfkill_task
.sw_newstate
);
233 schedule_work(&rfkill_task
.work
);
235 spin_unlock_irqrestore(&rfkill_task
.lock
, flags
);
239 static void rfkill_schedule_toggle(enum rfkill_type type
)
243 if (rfkill_is_epo_lock_active())
246 spin_lock_irqsave(&rfkill_task
.lock
, flags
);
247 if (!rfkill_task
.global_op_pending
) {
248 set_bit(type
, rfkill_task
.sw_pending
);
249 change_bit(type
, rfkill_task
.sw_togglestate
);
250 schedule_work(&rfkill_task
.work
);
252 spin_unlock_irqrestore(&rfkill_task
.lock
, flags
);
255 static void rfkill_schedule_evsw_rfkillall(int state
)
258 switch (rfkill_master_switch_mode
) {
259 case RFKILL_INPUT_MASTER_UNBLOCKALL
:
260 rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNBLOCK
);
262 case RFKILL_INPUT_MASTER_RESTORE
:
263 rfkill_schedule_global_op(RFKILL_GLOBAL_OP_RESTORE
);
265 case RFKILL_INPUT_MASTER_DONOTHING
:
266 rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNLOCK
);
269 /* memory corruption or driver bug! fail safely */
270 rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO
);
271 WARN(1, "Unknown rfkill_master_switch_mode (%d), "
272 "driver bug or memory corruption detected!\n",
273 rfkill_master_switch_mode
);
277 rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO
);
280 static void rfkill_event(struct input_handle
*handle
, unsigned int type
,
281 unsigned int code
, int data
)
283 if (type
== EV_KEY
&& data
== 1) {
288 t
= RFKILL_TYPE_WLAN
;
291 t
= RFKILL_TYPE_BLUETOOTH
;
297 t
= RFKILL_TYPE_WIMAX
;
302 rfkill_schedule_toggle(t
);
304 } else if (type
== EV_SW
) {
307 rfkill_schedule_evsw_rfkillall(data
);
315 static int rfkill_connect(struct input_handler
*handler
, struct input_dev
*dev
,
316 const struct input_device_id
*id
)
318 struct input_handle
*handle
;
321 handle
= kzalloc(sizeof(struct input_handle
), GFP_KERNEL
);
326 handle
->handler
= handler
;
327 handle
->name
= "rfkill";
329 /* causes rfkill_start() to be called */
330 error
= input_register_handle(handle
);
332 goto err_free_handle
;
334 error
= input_open_device(handle
);
336 goto err_unregister_handle
;
340 err_unregister_handle
:
341 input_unregister_handle(handle
);
347 static void rfkill_start(struct input_handle
*handle
)
349 /* Take event_lock to guard against configuration changes, we
350 * should be able to deal with concurrency with rfkill_event()
351 * just fine (which event_lock will also avoid). */
352 spin_lock_irq(&handle
->dev
->event_lock
);
354 if (test_bit(EV_SW
, handle
->dev
->evbit
)) {
355 if (test_bit(SW_RFKILL_ALL
, handle
->dev
->swbit
))
356 rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL
,
358 /* add resync for further EV_SW events here */
361 spin_unlock_irq(&handle
->dev
->event_lock
);
364 static void rfkill_disconnect(struct input_handle
*handle
)
366 input_close_device(handle
);
367 input_unregister_handle(handle
);
371 static const struct input_device_id rfkill_ids
[] = {
373 .flags
= INPUT_DEVICE_ID_MATCH_EVBIT
| INPUT_DEVICE_ID_MATCH_KEYBIT
,
374 .evbit
= { BIT_MASK(EV_KEY
) },
375 .keybit
= { [BIT_WORD(KEY_WLAN
)] = BIT_MASK(KEY_WLAN
) },
378 .flags
= INPUT_DEVICE_ID_MATCH_EVBIT
| INPUT_DEVICE_ID_MATCH_KEYBIT
,
379 .evbit
= { BIT_MASK(EV_KEY
) },
380 .keybit
= { [BIT_WORD(KEY_BLUETOOTH
)] = BIT_MASK(KEY_BLUETOOTH
) },
383 .flags
= INPUT_DEVICE_ID_MATCH_EVBIT
| INPUT_DEVICE_ID_MATCH_KEYBIT
,
384 .evbit
= { BIT_MASK(EV_KEY
) },
385 .keybit
= { [BIT_WORD(KEY_UWB
)] = BIT_MASK(KEY_UWB
) },
388 .flags
= INPUT_DEVICE_ID_MATCH_EVBIT
| INPUT_DEVICE_ID_MATCH_KEYBIT
,
389 .evbit
= { BIT_MASK(EV_KEY
) },
390 .keybit
= { [BIT_WORD(KEY_WIMAX
)] = BIT_MASK(KEY_WIMAX
) },
393 .flags
= INPUT_DEVICE_ID_MATCH_EVBIT
| INPUT_DEVICE_ID_MATCH_SWBIT
,
394 .evbit
= { BIT(EV_SW
) },
395 .swbit
= { [BIT_WORD(SW_RFKILL_ALL
)] = BIT_MASK(SW_RFKILL_ALL
) },
400 static struct input_handler rfkill_handler
= {
401 .event
= rfkill_event
,
402 .connect
= rfkill_connect
,
403 .disconnect
= rfkill_disconnect
,
404 .start
= rfkill_start
,
406 .id_table
= rfkill_ids
,
409 static int __init
rfkill_handler_init(void)
411 if (rfkill_master_switch_mode
>= RFKILL_INPUT_MASTER_MAX
)
414 return input_register_handler(&rfkill_handler
);
417 static void __exit
rfkill_handler_exit(void)
419 input_unregister_handler(&rfkill_handler
);
420 flush_scheduled_work();
421 rfkill_remove_epo_lock();
424 module_init(rfkill_handler_init
);
425 module_exit(rfkill_handler_exit
);