1 From a73f30916ee524437253739eacc682f6fb0f3ea8 Mon Sep 17 00:00:00 2001
2 From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
3 Date: Sun, 11 Jan 2009 03:01:00 -0200
4 Subject: ACPI: thinkpad-acpi: debug facility to emulate the rf switches
6 This code is required to keep the thinkpad-acpi maintainer sane, and
7 it is disabled by default.
9 Add a debug facility to simulate an rfkill hardware rocker switch, a
10 bluetooth rfkill soft-switch, a WWAN rfkill soft-switch on thinkpads.
12 The simulated switches obviously do not kill any radios in hardware or
13 firmware (unlike the real one). They also don't issue deprecated proc
16 Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
17 Signed-off-by: Len Brown <len.brown@intel.com>
19 drivers/platform/x86/Kconfig | 11 ++
20 drivers/platform/x86/thinkpad_acpi.c | 190 ++++++++++++++++++++++++++++++++++
21 2 files changed, 201 insertions(+), 0 deletions(-)
23 diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
24 index e65448e..431772b 100644
25 --- a/drivers/platform/x86/Kconfig
26 +++ b/drivers/platform/x86/Kconfig
27 @@ -192,6 +192,17 @@ config THINKPAD_ACPI
29 If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
31 +config THINKPAD_ACPI_DEBUGFACILITIES
32 + bool "Maintainer debug facilities"
33 + depends on THINKPAD_ACPI
36 + Enables extra stuff in the thinkpad-acpi which is completely useless
37 + for normal use. Read the driver source to find out what it does.
39 + Say N here, unless you were told by a kernel maintainer to do
42 config THINKPAD_ACPI_DEBUG
43 bool "Verbose debug mode"
44 depends on THINKPAD_ACPI
45 diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
46 index ee3fa00..a086ce8 100644
47 --- a/drivers/platform/x86/thinkpad_acpi.c
48 +++ b/drivers/platform/x86/thinkpad_acpi.c
49 @@ -288,6 +288,16 @@ struct tpacpi_led_classdev {
53 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
54 +static int dbg_wlswemul;
55 +static int tpacpi_wlsw_emulstate;
56 +static int dbg_bluetoothemul;
57 +static int tpacpi_bluetooth_emulstate;
58 +static int dbg_wwanemul;
59 +static int tpacpi_wwan_emulstate;
63 /****************************************************************************
64 ****************************************************************************
66 @@ -1006,6 +1016,94 @@ static DRIVER_ATTR(version, S_IRUGO,
68 /* --------------------------------------------------------------------- */
70 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
72 +static void tpacpi_send_radiosw_update(void);
74 +/* wlsw_emulstate ------------------------------------------------------ */
75 +static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv,
78 + return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wlsw_emulstate);
81 +static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv,
82 + const char *buf, size_t count)
86 + if (parse_strtoul(buf, 1, &t))
89 + if (tpacpi_wlsw_emulstate != t) {
90 + tpacpi_wlsw_emulstate = !!t;
91 + tpacpi_send_radiosw_update();
93 + tpacpi_wlsw_emulstate = !!t;
98 +static DRIVER_ATTR(wlsw_emulstate, S_IWUSR | S_IRUGO,
99 + tpacpi_driver_wlsw_emulstate_show,
100 + tpacpi_driver_wlsw_emulstate_store);
102 +/* bluetooth_emulstate ------------------------------------------------- */
103 +static ssize_t tpacpi_driver_bluetooth_emulstate_show(
104 + struct device_driver *drv,
107 + return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_bluetooth_emulstate);
110 +static ssize_t tpacpi_driver_bluetooth_emulstate_store(
111 + struct device_driver *drv,
112 + const char *buf, size_t count)
116 + if (parse_strtoul(buf, 1, &t))
119 + tpacpi_bluetooth_emulstate = !!t;
124 +static DRIVER_ATTR(bluetooth_emulstate, S_IWUSR | S_IRUGO,
125 + tpacpi_driver_bluetooth_emulstate_show,
126 + tpacpi_driver_bluetooth_emulstate_store);
128 +/* wwan_emulstate ------------------------------------------------- */
129 +static ssize_t tpacpi_driver_wwan_emulstate_show(
130 + struct device_driver *drv,
133 + return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wwan_emulstate);
136 +static ssize_t tpacpi_driver_wwan_emulstate_store(
137 + struct device_driver *drv,
138 + const char *buf, size_t count)
142 + if (parse_strtoul(buf, 1, &t))
145 + tpacpi_wwan_emulstate = !!t;
150 +static DRIVER_ATTR(wwan_emulstate, S_IWUSR | S_IRUGO,
151 + tpacpi_driver_wwan_emulstate_show,
152 + tpacpi_driver_wwan_emulstate_store);
156 +/* --------------------------------------------------------------------- */
158 static struct driver_attribute *tpacpi_driver_attributes[] = {
159 &driver_attr_debug_level, &driver_attr_version,
160 &driver_attr_interface_version,
161 @@ -1022,6 +1120,15 @@ static int __init tpacpi_create_driver_attributes(struct device_driver *drv)
165 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
166 + if (!res && dbg_wlswemul)
167 + res = driver_create_file(drv, &driver_attr_wlsw_emulstate);
168 + if (!res && dbg_bluetoothemul)
169 + res = driver_create_file(drv, &driver_attr_bluetooth_emulstate);
170 + if (!res && dbg_wwanemul)
171 + res = driver_create_file(drv, &driver_attr_wwan_emulstate);
177 @@ -1031,6 +1138,12 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
179 for (i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++)
180 driver_remove_file(drv, tpacpi_driver_attributes[i]);
182 +#ifdef THINKPAD_ACPI_DEBUGFACILITIES
183 + driver_remove_file(drv, &driver_attr_wlsw_emulstate);
184 + driver_remove_file(drv, &driver_attr_bluetooth_emulstate);
185 + driver_remove_file(drv, &driver_attr_wwan_emulstate);
189 /****************************************************************************
190 @@ -1216,6 +1329,12 @@ static struct attribute_set *hotkey_dev_attributes;
192 static int hotkey_get_wlsw(int *status)
194 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
195 + if (dbg_wlswemul) {
196 + *status = !!tpacpi_wlsw_emulstate;
200 if (!acpi_evalf(hkey_handle, status, "WLSW", "d"))
203 @@ -2222,6 +2341,13 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
204 hotkey_source_mask, hotkey_poll_freq);
207 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
208 + if (dbg_wlswemul) {
209 + tp_features.hotkey_wlsw = 1;
211 + "radio switch emulation enabled\n");
214 /* Not all thinkpads have a hardware radio switch */
215 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
216 tp_features.hotkey_wlsw = 1;
217 @@ -2656,6 +2782,12 @@ static int bluetooth_get_radiosw(void)
218 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
219 return RFKILL_STATE_HARD_BLOCKED;
221 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
222 + if (dbg_bluetoothemul)
223 + return (tpacpi_bluetooth_emulstate) ?
224 + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
227 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
230 @@ -2689,6 +2821,15 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk)
234 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
235 + if (dbg_bluetoothemul) {
236 + tpacpi_bluetooth_emulstate = !!radio_on;
238 + bluetooth_update_rfk();
243 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
246 @@ -2792,6 +2933,13 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
247 str_supported(tp_features.bluetooth),
250 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
251 + if (dbg_bluetoothemul) {
252 + tp_features.bluetooth = 1;
254 + "bluetooth switch emulation enabled\n");
257 if (tp_features.bluetooth &&
258 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
259 /* no bluetooth hardware present in system */
260 @@ -2890,6 +3038,12 @@ static int wan_get_radiosw(void)
261 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
262 return RFKILL_STATE_HARD_BLOCKED;
264 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
266 + return (tpacpi_wwan_emulstate) ?
267 + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
270 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
273 @@ -2923,6 +3077,15 @@ static int wan_set_radiosw(int radio_on, int update_rfk)
277 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
278 + if (dbg_wwanemul) {
279 + tpacpi_wwan_emulstate = !!radio_on;
286 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
289 @@ -3024,6 +3187,13 @@ static int __init wan_init(struct ibm_init_struct *iibm)
290 str_supported(tp_features.wan),
293 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
294 + if (dbg_wwanemul) {
295 + tp_features.wan = 1;
297 + "wwan switch emulation enabled\n");
300 if (tp_features.wan &&
301 !(status & TP_ACPI_WANCARD_HWPRESENT)) {
302 /* no wan hardware present in system */
303 @@ -6701,6 +6871,26 @@ TPACPI_PARAM(brightness);
304 TPACPI_PARAM(volume);
307 +#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
308 +module_param(dbg_wlswemul, uint, 0);
309 +MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation");
310 +module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0);
311 +MODULE_PARM_DESC(wlsw_state,
312 + "Initial state of the emulated WLSW switch");
314 +module_param(dbg_bluetoothemul, uint, 0);
315 +MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation");
316 +module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0);
317 +MODULE_PARM_DESC(bluetooth_state,
318 + "Initial state of the emulated bluetooth switch");
320 +module_param(dbg_wwanemul, uint, 0);
321 +MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation");
322 +module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0);
323 +MODULE_PARM_DESC(wwan_state,
324 + "Initial state of the emulated WWAN switch");
327 static void thinkpad_acpi_module_exit(void)
329 struct ibm_struct *ibm, *itmp;