aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/rfkill.h21
-rw-r--r--net/rfkill/Kconfig7
-rw-r--r--net/rfkill/rfkill.c42
3 files changed, 69 insertions, 1 deletions
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index d76397ca95ad..26fddea12c25 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -26,6 +26,7 @@
26#include <linux/list.h> 26#include <linux/list.h>
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/device.h> 28#include <linux/device.h>
29#include <linux/leds.h>
29 30
30/** 31/**
31 * enum rfkill_type - type of rfkill switch. 32 * enum rfkill_type - type of rfkill switch.
@@ -56,6 +57,7 @@ enum rfkill_state {
56 * @data: Pointer to the RF button drivers private data which will be 57 * @data: Pointer to the RF button drivers private data which will be
57 * passed along when toggling radio state. 58 * passed along when toggling radio state.
58 * @toggle_radio(): Mandatory handler to control state of the radio. 59 * @toggle_radio(): Mandatory handler to control state of the radio.
60 * @led_trigger: A LED trigger for this button's LED.
59 * @dev: Device structure integrating the switch into device tree. 61 * @dev: Device structure integrating the switch into device tree.
60 * @node: Used to place switch into list of all switches known to the 62 * @node: Used to place switch into list of all switches known to the
61 * the system. 63 * the system.
@@ -74,6 +76,10 @@ struct rfkill {
74 void *data; 76 void *data;
75 int (*toggle_radio)(void *data, enum rfkill_state state); 77 int (*toggle_radio)(void *data, enum rfkill_state state);
76 78
79#ifdef CONFIG_RFKILL_LEDS
80 struct led_trigger led_trigger;
81#endif
82
77 struct device dev; 83 struct device dev;
78 struct list_head node; 84 struct list_head node;
79}; 85};
@@ -84,4 +90,19 @@ void rfkill_free(struct rfkill *rfkill);
84int rfkill_register(struct rfkill *rfkill); 90int rfkill_register(struct rfkill *rfkill);
85void rfkill_unregister(struct rfkill *rfkill); 91void rfkill_unregister(struct rfkill *rfkill);
86 92
93/**
94 * rfkill_get_led_name - Get the LED trigger name for the button's LED.
95 * This function might return a NULL pointer if registering of the
96 * LED trigger failed.
97 * Use this as "default_trigger" for the LED.
98 */
99static inline char *rfkill_get_led_name(struct rfkill *rfkill)
100{
101#ifdef CONFIG_RFKILL_LEDS
102 return (char *)(rfkill->led_trigger.name);
103#else
104 return NULL;
105#endif
106}
107
87#endif /* RFKILL_H */ 108#endif /* RFKILL_H */
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig
index d28a6d9303e4..7f807b30cfbb 100644
--- a/net/rfkill/Kconfig
+++ b/net/rfkill/Kconfig
@@ -22,3 +22,10 @@ config RFKILL_INPUT
22 22
23 To compile this driver as a module, choose M here: the 23 To compile this driver as a module, choose M here: the
24 module will be called rfkill-input. 24 module will be called rfkill-input.
25
26# LED trigger support
27config RFKILL_LEDS
28 bool
29 depends on RFKILL && LEDS_TRIGGERS
30 default y
31
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 637a9f0c7655..a8c5e0b914e4 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -37,6 +37,22 @@ static DEFINE_MUTEX(rfkill_mutex);
37 37
38static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX]; 38static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX];
39 39
40
41static void rfkill_led_trigger(struct rfkill *rfkill,
42 enum rfkill_state state)
43{
44#ifdef CONFIG_RFKILL_LEDS
45 struct led_trigger *led = &rfkill->led_trigger;
46
47 if (!led->name)
48 return;
49 if (state == RFKILL_STATE_OFF)
50 led_trigger_event(led, LED_OFF);
51 else
52 led_trigger_event(led, LED_FULL);
53#endif /* CONFIG_RFKILL_LEDS */
54}
55
40static int rfkill_toggle_radio(struct rfkill *rfkill, 56static int rfkill_toggle_radio(struct rfkill *rfkill,
41 enum rfkill_state state) 57 enum rfkill_state state)
42{ 58{
@@ -48,8 +64,10 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
48 64
49 if (state != rfkill->state) { 65 if (state != rfkill->state) {
50 retval = rfkill->toggle_radio(rfkill->data, state); 66 retval = rfkill->toggle_radio(rfkill->data, state);
51 if (!retval) 67 if (!retval) {
52 rfkill->state = state; 68 rfkill->state = state;
69 rfkill_led_trigger(rfkill, state);
70 }
53 } 71 }
54 72
55 mutex_unlock(&rfkill->mutex); 73 mutex_unlock(&rfkill->mutex);
@@ -328,6 +346,26 @@ void rfkill_free(struct rfkill *rfkill)
328} 346}
329EXPORT_SYMBOL(rfkill_free); 347EXPORT_SYMBOL(rfkill_free);
330 348
349static void rfkill_led_trigger_register(struct rfkill *rfkill)
350{
351#ifdef CONFIG_RFKILL_LEDS
352 int error;
353
354 rfkill->led_trigger.name = rfkill->dev.bus_id;
355 error = led_trigger_register(&rfkill->led_trigger);
356 if (error)
357 rfkill->led_trigger.name = NULL;
358#endif /* CONFIG_RFKILL_LEDS */
359}
360
361static void rfkill_led_trigger_unregister(struct rfkill *rfkill)
362{
363#ifdef CONFIG_RFKILL_LEDS
364 if (rfkill->led_trigger.name)
365 led_trigger_unregister(&rfkill->led_trigger);
366#endif
367}
368
331/** 369/**
332 * rfkill_register - Register a rfkill structure. 370 * rfkill_register - Register a rfkill structure.
333 * @rfkill: rfkill structure to be registered 371 * @rfkill: rfkill structure to be registered
@@ -357,6 +395,7 @@ int rfkill_register(struct rfkill *rfkill)
357 rfkill_remove_switch(rfkill); 395 rfkill_remove_switch(rfkill);
358 return error; 396 return error;
359 } 397 }
398 rfkill_led_trigger_register(rfkill);
360 399
361 return 0; 400 return 0;
362} 401}
@@ -372,6 +411,7 @@ EXPORT_SYMBOL(rfkill_register);
372 */ 411 */
373void rfkill_unregister(struct rfkill *rfkill) 412void rfkill_unregister(struct rfkill *rfkill)
374{ 413{
414 rfkill_led_trigger_unregister(rfkill);
375 device_del(&rfkill->dev); 415 device_del(&rfkill->dev);
376 rfkill_remove_switch(rfkill); 416 rfkill_remove_switch(rfkill);
377 put_device(&rfkill->dev); 417 put_device(&rfkill->dev);