aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2009-01-11 00:01:00 -0500
committerLen Brown <len.brown@intel.com>2009-01-15 13:29:21 -0500
commita73f30916ee524437253739eacc682f6fb0f3ea8 (patch)
tree82005ee460486436207106f0c5b906ac5137f271
parente0b36fc5efd610a208b6b80e821a49302ca424ab (diff)
ACPI: thinkpad-acpi: debug facility to emulate the rf switches
This code is required to keep the thinkpad-acpi maintainer sane, and it is disabled by default. Add a debug facility to simulate an rfkill hardware rocker switch, a bluetooth rfkill soft-switch, a WWAN rfkill soft-switch on thinkpads. The simulated switches obviously do not kill any radios in hardware or firmware (unlike the real one). They also don't issue deprecated proc events. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/platform/x86/Kconfig11
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c190
2 files changed, 201 insertions, 0 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index e65448e99b48..431772b8a1d0 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -192,6 +192,17 @@ config THINKPAD_ACPI
192 192
193 If you have an IBM or Lenovo ThinkPad laptop, say Y or M here. 193 If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
194 194
195config THINKPAD_ACPI_DEBUGFACILITIES
196 bool "Maintainer debug facilities"
197 depends on THINKPAD_ACPI
198 default n
199 ---help---
200 Enables extra stuff in the thinkpad-acpi which is completely useless
201 for normal use. Read the driver source to find out what it does.
202
203 Say N here, unless you were told by a kernel maintainer to do
204 otherwise.
205
195config THINKPAD_ACPI_DEBUG 206config THINKPAD_ACPI_DEBUG
196 bool "Verbose debug mode" 207 bool "Verbose debug mode"
197 depends on THINKPAD_ACPI 208 depends on THINKPAD_ACPI
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index ee3fa007f312..a086ce8ed4eb 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -288,6 +288,16 @@ struct tpacpi_led_classdev {
288 unsigned int led; 288 unsigned int led;
289}; 289};
290 290
291#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
292static int dbg_wlswemul;
293static int tpacpi_wlsw_emulstate;
294static int dbg_bluetoothemul;
295static int tpacpi_bluetooth_emulstate;
296static int dbg_wwanemul;
297static int tpacpi_wwan_emulstate;
298#endif
299
300
291/**************************************************************************** 301/****************************************************************************
292 **************************************************************************** 302 ****************************************************************************
293 * 303 *
@@ -1006,6 +1016,94 @@ static DRIVER_ATTR(version, S_IRUGO,
1006 1016
1007/* --------------------------------------------------------------------- */ 1017/* --------------------------------------------------------------------- */
1008 1018
1019#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1020
1021static void tpacpi_send_radiosw_update(void);
1022
1023/* wlsw_emulstate ------------------------------------------------------ */
1024static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv,
1025 char *buf)
1026{
1027 return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wlsw_emulstate);
1028}
1029
1030static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv,
1031 const char *buf, size_t count)
1032{
1033 unsigned long t;
1034
1035 if (parse_strtoul(buf, 1, &t))
1036 return -EINVAL;
1037
1038 if (tpacpi_wlsw_emulstate != t) {
1039 tpacpi_wlsw_emulstate = !!t;
1040 tpacpi_send_radiosw_update();
1041 } else
1042 tpacpi_wlsw_emulstate = !!t;
1043
1044 return count;
1045}
1046
1047static DRIVER_ATTR(wlsw_emulstate, S_IWUSR | S_IRUGO,
1048 tpacpi_driver_wlsw_emulstate_show,
1049 tpacpi_driver_wlsw_emulstate_store);
1050
1051/* bluetooth_emulstate ------------------------------------------------- */
1052static ssize_t tpacpi_driver_bluetooth_emulstate_show(
1053 struct device_driver *drv,
1054 char *buf)
1055{
1056 return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_bluetooth_emulstate);
1057}
1058
1059static ssize_t tpacpi_driver_bluetooth_emulstate_store(
1060 struct device_driver *drv,
1061 const char *buf, size_t count)
1062{
1063 unsigned long t;
1064
1065 if (parse_strtoul(buf, 1, &t))
1066 return -EINVAL;
1067
1068 tpacpi_bluetooth_emulstate = !!t;
1069
1070 return count;
1071}
1072
1073static DRIVER_ATTR(bluetooth_emulstate, S_IWUSR | S_IRUGO,
1074 tpacpi_driver_bluetooth_emulstate_show,
1075 tpacpi_driver_bluetooth_emulstate_store);
1076
1077/* wwan_emulstate ------------------------------------------------- */
1078static ssize_t tpacpi_driver_wwan_emulstate_show(
1079 struct device_driver *drv,
1080 char *buf)
1081{
1082 return snprintf(buf, PAGE_SIZE, "%d\n", !!tpacpi_wwan_emulstate);
1083}
1084
1085static ssize_t tpacpi_driver_wwan_emulstate_store(
1086 struct device_driver *drv,
1087 const char *buf, size_t count)
1088{
1089 unsigned long t;
1090
1091 if (parse_strtoul(buf, 1, &t))
1092 return -EINVAL;
1093
1094 tpacpi_wwan_emulstate = !!t;
1095
1096 return count;
1097}
1098
1099static DRIVER_ATTR(wwan_emulstate, S_IWUSR | S_IRUGO,
1100 tpacpi_driver_wwan_emulstate_show,
1101 tpacpi_driver_wwan_emulstate_store);
1102
1103#endif
1104
1105/* --------------------------------------------------------------------- */
1106
1009static struct driver_attribute *tpacpi_driver_attributes[] = { 1107static struct driver_attribute *tpacpi_driver_attributes[] = {
1010 &driver_attr_debug_level, &driver_attr_version, 1108 &driver_attr_debug_level, &driver_attr_version,
1011 &driver_attr_interface_version, 1109 &driver_attr_interface_version,
@@ -1022,6 +1120,15 @@ static int __init tpacpi_create_driver_attributes(struct device_driver *drv)
1022 i++; 1120 i++;
1023 } 1121 }
1024 1122
1123#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1124 if (!res && dbg_wlswemul)
1125 res = driver_create_file(drv, &driver_attr_wlsw_emulstate);
1126 if (!res && dbg_bluetoothemul)
1127 res = driver_create_file(drv, &driver_attr_bluetooth_emulstate);
1128 if (!res && dbg_wwanemul)
1129 res = driver_create_file(drv, &driver_attr_wwan_emulstate);
1130#endif
1131
1025 return res; 1132 return res;
1026} 1133}
1027 1134
@@ -1031,6 +1138,12 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
1031 1138
1032 for (i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++) 1139 for (i = 0; i < ARRAY_SIZE(tpacpi_driver_attributes); i++)
1033 driver_remove_file(drv, tpacpi_driver_attributes[i]); 1140 driver_remove_file(drv, tpacpi_driver_attributes[i]);
1141
1142#ifdef THINKPAD_ACPI_DEBUGFACILITIES
1143 driver_remove_file(drv, &driver_attr_wlsw_emulstate);
1144 driver_remove_file(drv, &driver_attr_bluetooth_emulstate);
1145 driver_remove_file(drv, &driver_attr_wwan_emulstate);
1146#endif
1034} 1147}
1035 1148
1036/**************************************************************************** 1149/****************************************************************************
@@ -1216,6 +1329,12 @@ static struct attribute_set *hotkey_dev_attributes;
1216 1329
1217static int hotkey_get_wlsw(int *status) 1330static int hotkey_get_wlsw(int *status)
1218{ 1331{
1332#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1333 if (dbg_wlswemul) {
1334 *status = !!tpacpi_wlsw_emulstate;
1335 return 0;
1336 }
1337#endif
1219 if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) 1338 if (!acpi_evalf(hkey_handle, status, "WLSW", "d"))
1220 return -EIO; 1339 return -EIO;
1221 return 0; 1340 return 0;
@@ -2222,6 +2341,13 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2222 hotkey_source_mask, hotkey_poll_freq); 2341 hotkey_source_mask, hotkey_poll_freq);
2223#endif 2342#endif
2224 2343
2344#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
2345 if (dbg_wlswemul) {
2346 tp_features.hotkey_wlsw = 1;
2347 printk(TPACPI_INFO
2348 "radio switch emulation enabled\n");
2349 } else
2350#endif
2225 /* Not all thinkpads have a hardware radio switch */ 2351 /* Not all thinkpads have a hardware radio switch */
2226 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { 2352 if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
2227 tp_features.hotkey_wlsw = 1; 2353 tp_features.hotkey_wlsw = 1;
@@ -2656,6 +2782,12 @@ static int bluetooth_get_radiosw(void)
2656 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) 2782 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
2657 return RFKILL_STATE_HARD_BLOCKED; 2783 return RFKILL_STATE_HARD_BLOCKED;
2658 2784
2785#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
2786 if (dbg_bluetoothemul)
2787 return (tpacpi_bluetooth_emulstate) ?
2788 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
2789#endif
2790
2659 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 2791 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
2660 return -EIO; 2792 return -EIO;
2661 2793
@@ -2689,6 +2821,15 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk)
2689 && radio_on) 2821 && radio_on)
2690 return -EPERM; 2822 return -EPERM;
2691 2823
2824#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
2825 if (dbg_bluetoothemul) {
2826 tpacpi_bluetooth_emulstate = !!radio_on;
2827 if (update_rfk)
2828 bluetooth_update_rfk();
2829 return 0;
2830 }
2831#endif
2832
2692 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 2833 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
2693 return -EIO; 2834 return -EIO;
2694 if (radio_on) 2835 if (radio_on)
@@ -2792,6 +2933,13 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
2792 str_supported(tp_features.bluetooth), 2933 str_supported(tp_features.bluetooth),
2793 status); 2934 status);
2794 2935
2936#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
2937 if (dbg_bluetoothemul) {
2938 tp_features.bluetooth = 1;
2939 printk(TPACPI_INFO
2940 "bluetooth switch emulation enabled\n");
2941 } else
2942#endif
2795 if (tp_features.bluetooth && 2943 if (tp_features.bluetooth &&
2796 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) { 2944 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
2797 /* no bluetooth hardware present in system */ 2945 /* no bluetooth hardware present in system */
@@ -2890,6 +3038,12 @@ static int wan_get_radiosw(void)
2890 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) 3038 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
2891 return RFKILL_STATE_HARD_BLOCKED; 3039 return RFKILL_STATE_HARD_BLOCKED;
2892 3040
3041#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3042 if (dbg_wwanemul)
3043 return (tpacpi_wwan_emulstate) ?
3044 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
3045#endif
3046
2893 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 3047 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
2894 return -EIO; 3048 return -EIO;
2895 3049
@@ -2923,6 +3077,15 @@ static int wan_set_radiosw(int radio_on, int update_rfk)
2923 && radio_on) 3077 && radio_on)
2924 return -EPERM; 3078 return -EPERM;
2925 3079
3080#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3081 if (dbg_wwanemul) {
3082 tpacpi_wwan_emulstate = !!radio_on;
3083 if (update_rfk)
3084 wan_update_rfk();
3085 return 0;
3086 }
3087#endif
3088
2926 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 3089 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
2927 return -EIO; 3090 return -EIO;
2928 if (radio_on) 3091 if (radio_on)
@@ -3024,6 +3187,13 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3024 str_supported(tp_features.wan), 3187 str_supported(tp_features.wan),
3025 status); 3188 status);
3026 3189
3190#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3191 if (dbg_wwanemul) {
3192 tp_features.wan = 1;
3193 printk(TPACPI_INFO
3194 "wwan switch emulation enabled\n");
3195 } else
3196#endif
3027 if (tp_features.wan && 3197 if (tp_features.wan &&
3028 !(status & TP_ACPI_WANCARD_HWPRESENT)) { 3198 !(status & TP_ACPI_WANCARD_HWPRESENT)) {
3029 /* no wan hardware present in system */ 3199 /* no wan hardware present in system */
@@ -6701,6 +6871,26 @@ TPACPI_PARAM(brightness);
6701TPACPI_PARAM(volume); 6871TPACPI_PARAM(volume);
6702TPACPI_PARAM(fan); 6872TPACPI_PARAM(fan);
6703 6873
6874#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
6875module_param(dbg_wlswemul, uint, 0);
6876MODULE_PARM_DESC(dbg_wlswemul, "Enables WLSW emulation");
6877module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0);
6878MODULE_PARM_DESC(wlsw_state,
6879 "Initial state of the emulated WLSW switch");
6880
6881module_param(dbg_bluetoothemul, uint, 0);
6882MODULE_PARM_DESC(dbg_bluetoothemul, "Enables bluetooth switch emulation");
6883module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0);
6884MODULE_PARM_DESC(bluetooth_state,
6885 "Initial state of the emulated bluetooth switch");
6886
6887module_param(dbg_wwanemul, uint, 0);
6888MODULE_PARM_DESC(dbg_wwanemul, "Enables WWAN switch emulation");
6889module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0);
6890MODULE_PARM_DESC(wwan_state,
6891 "Initial state of the emulated WWAN switch");
6892#endif
6893
6704static void thinkpad_acpi_module_exit(void) 6894static void thinkpad_acpi_module_exit(void)
6705{ 6895{
6706 struct ibm_struct *ibm, *itmp; 6896 struct ibm_struct *ibm, *itmp;