aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/Kconfig20
-rw-r--r--drivers/misc/thinkpad_acpi.c144
-rw-r--r--drivers/misc/thinkpad_acpi.h1
3 files changed, 88 insertions, 77 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index a26655881e6a..73e248fb2ff1 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -202,25 +202,5 @@ config THINKPAD_ACPI_BAY
202 202
203 If you are not sure, say Y here. 203 If you are not sure, say Y here.
204 204
205config THINKPAD_ACPI_INPUT_ENABLED
206 bool "Enable input layer support by default"
207 depends on THINKPAD_ACPI
208 default n
209 ---help---
210 This option enables thinkpad-acpi hot key handling over the input
211 layer at driver load time. When it is unset, the driver does not
212 enable hot key handling by default, and also starts up with a mostly
213 empty keymap.
214
215 This option should be enabled if you have a new enough HAL or other
216 userspace support that properly handles the thinkpad-acpi event
217 device. It auto-tunes the hot key support to those reported by the
218 firmware and enables it automatically.
219
220 If unsure, say N here to retain the old behaviour of ibm-acpi, and
221 thinkpad-acpi up to kernel 2.6.21: userspace will have to enable and
222 set up the thinkpad-acpi hot key handling using the sysfs interace
223 after loading the driver.
224
225 205
226endif # MISC_DEVICES 206endif # MISC_DEVICES
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index bb8956d0c104..0222bbaf7b76 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -21,7 +21,7 @@
21 * 02110-1301, USA. 21 * 02110-1301, USA.
22 */ 22 */
23 23
24#define IBM_VERSION "0.15" 24#define IBM_VERSION "0.16"
25#define TPACPI_SYSFS_VERSION 0x010000 25#define TPACPI_SYSFS_VERSION 0x010000
26 26
27/* 27/*
@@ -906,9 +906,26 @@ static ssize_t hotkey_radio_sw_show(struct device *dev,
906static struct device_attribute dev_attr_hotkey_radio_sw = 906static struct device_attribute dev_attr_hotkey_radio_sw =
907 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); 907 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
908 908
909/* sysfs hotkey report_mode -------------------------------------------- */
910static ssize_t hotkey_report_mode_show(struct device *dev,
911 struct device_attribute *attr,
912 char *buf)
913{
914 return snprintf(buf, PAGE_SIZE, "%d\n",
915 (hotkey_report_mode != 0) ? hotkey_report_mode : 1);
916}
917
918static struct device_attribute dev_attr_hotkey_report_mode =
919 __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL);
920
909/* --------------------------------------------------------------------- */ 921/* --------------------------------------------------------------------- */
910 922
911static struct attribute *hotkey_mask_attributes[] = { 923static struct attribute *hotkey_attributes[] __initdata = {
924 &dev_attr_hotkey_enable.attr,
925 &dev_attr_hotkey_report_mode.attr,
926};
927
928static struct attribute *hotkey_mask_attributes[] __initdata = {
912 &dev_attr_hotkey_mask.attr, 929 &dev_attr_hotkey_mask.attr,
913 &dev_attr_hotkey_bios_enabled.attr, 930 &dev_attr_hotkey_bios_enabled.attr,
914 &dev_attr_hotkey_bios_mask.attr, 931 &dev_attr_hotkey_bios_mask.attr,
@@ -987,11 +1004,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
987 str_supported(tp_features.hotkey)); 1004 str_supported(tp_features.hotkey));
988 1005
989 if (tp_features.hotkey) { 1006 if (tp_features.hotkey) {
990 hotkey_dev_attributes = create_attr_set(7, NULL); 1007 hotkey_dev_attributes = create_attr_set(8, NULL);
991 if (!hotkey_dev_attributes) 1008 if (!hotkey_dev_attributes)
992 return -ENOMEM; 1009 return -ENOMEM;
993 res = add_to_attr_set(hotkey_dev_attributes, 1010 res = add_many_to_attr_set(hotkey_dev_attributes,
994 &dev_attr_hotkey_enable.attr); 1011 hotkey_attributes,
1012 ARRAY_SIZE(hotkey_attributes));
995 if (res) 1013 if (res)
996 return res; 1014 return res;
997 1015
@@ -1055,11 +1073,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
1055 TPACPI_HOTKEY_MAP_SIZE); 1073 TPACPI_HOTKEY_MAP_SIZE);
1056 } 1074 }
1057 1075
1058#ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
1059 for (i = 0; i < 12; i++)
1060 hotkey_keycode_map[i] = KEY_UNKNOWN;
1061#endif /* ! CONFIG_THINKPAD_ACPI_INPUT_ENABLED */
1062
1063 set_bit(EV_KEY, tpacpi_inputdev->evbit); 1076 set_bit(EV_KEY, tpacpi_inputdev->evbit);
1064 set_bit(EV_MSC, tpacpi_inputdev->evbit); 1077 set_bit(EV_MSC, tpacpi_inputdev->evbit);
1065 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); 1078 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
@@ -1081,14 +1094,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
1081 set_bit(SW_RADIO, tpacpi_inputdev->swbit); 1094 set_bit(SW_RADIO, tpacpi_inputdev->swbit);
1082 } 1095 }
1083 1096
1084#ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
1085 dbg_printk(TPACPI_DBG_INIT, 1097 dbg_printk(TPACPI_DBG_INIT,
1086 "enabling hot key handling\n"); 1098 "enabling hot key handling\n");
1087 res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask) 1099 res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask)
1088 | hotkey_orig_mask); 1100 | hotkey_orig_mask);
1089 if (res) 1101 if (res)
1090 return res; 1102 return res;
1091#endif /* CONFIG_THINKPAD_ACPI_INPUT_ENABLED */ 1103
1104 dbg_printk(TPACPI_DBG_INIT,
1105 "legacy hot key reporting over procfs %s\n",
1106 (hotkey_report_mode < 2) ?
1107 "enabled" : "disabled");
1092 } 1108 }
1093 1109
1094 return (tp_features.hotkey)? 0 : 1; 1110 return (tp_features.hotkey)? 0 : 1;
@@ -1142,58 +1158,65 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
1142{ 1158{
1143 u32 hkey; 1159 u32 hkey;
1144 unsigned int keycode, scancode; 1160 unsigned int keycode, scancode;
1145 int sendacpi = 1; 1161 int send_acpi_ev = 0;
1146 1162
1147 if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { 1163 if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
1148 if (tpacpi_inputdev->users > 0) { 1164 switch (hkey >> 12) {
1149 switch (hkey >> 12) { 1165 case 1:
1150 case 1: 1166 /* 0x1000-0x1FFF: key presses */
1151 /* 0x1000-0x1FFF: key presses */ 1167 scancode = hkey & 0xfff;
1152 scancode = hkey & 0xfff; 1168 if (scancode > 0 && scancode < 0x21) {
1153 if (scancode > 0 && scancode < 0x21) { 1169 scancode--;
1154 scancode--; 1170 keycode = hotkey_keycode_map[scancode];
1155 keycode = hotkey_keycode_map[scancode]; 1171 tpacpi_input_send_key(scancode, keycode);
1156 tpacpi_input_send_key(scancode, keycode); 1172 } else {
1157 sendacpi = (keycode == KEY_RESERVED 1173 printk(IBM_ERR
1158 || keycode == KEY_UNKNOWN); 1174 "hotkey 0x%04x out of range for keyboard map\n",
1159 } else { 1175 hkey);
1160 printk(IBM_ERR 1176 send_acpi_ev = 1;
1161 "hotkey 0x%04x out of range for keyboard map\n", 1177 }
1162 hkey); 1178 break;
1163 } 1179 case 5:
1164 break; 1180 /* 0x5000-0x5FFF: LID */
1165 case 5: 1181 /* we don't handle it through this path, just
1166 /* 0x5000-0x5FFF: LID */ 1182 * eat up known LID events */
1167 /* we don't handle it through this path, just 1183 if (hkey != 0x5001 && hkey != 0x5002) {
1168 * eat up known LID events */ 1184 printk(IBM_ERR
1169 if (hkey != 0x5001 && hkey != 0x5002) { 1185 "unknown LID-related hotkey event: 0x%04x\n",
1170 printk(IBM_ERR 1186 hkey);
1171 "unknown LID-related hotkey event: 0x%04x\n", 1187 send_acpi_ev = 1;
1172 hkey); 1188 }
1173 } 1189 break;
1190 case 7:
1191 /* 0x7000-0x7FFF: misc */
1192 if (tp_features.hotkey_wlsw && hkey == 0x7000) {
1193 tpacpi_input_send_radiosw();
1174 break; 1194 break;
1175 case 7:
1176 /* 0x7000-0x7FFF: misc */
1177 if (tp_features.hotkey_wlsw && hkey == 0x7000) {
1178 tpacpi_input_send_radiosw();
1179 sendacpi = 0;
1180 break;
1181 }
1182 /* fallthrough to default */
1183 default:
1184 /* case 2: dock-related */
1185 /* 0x2305 - T43 waking up due to bay lever eject while aslept */
1186 /* case 3: ultra-bay related. maybe bay in dock? */
1187 /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */
1188 printk(IBM_NOTICE "unhandled hotkey event 0x%04x\n", hkey);
1189 } 1195 }
1196 /* fallthrough to default */
1197 default:
1198 /* case 2: dock-related */
1199 /* 0x2305 - T43 waking up due to bay lever eject while aslept */
1200 /* case 3: ultra-bay related. maybe bay in dock? */
1201 /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */
1202 printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey);
1203 send_acpi_ev = 1;
1190 } 1204 }
1191
1192 if (sendacpi)
1193 acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
1194 } else { 1205 } else {
1195 printk(IBM_ERR "unknown hotkey notification event %d\n", event); 1206 printk(IBM_ERR "unknown hotkey notification event %d\n", event);
1196 acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); 1207 hkey = 0;
1208 send_acpi_ev = 1;
1209 }
1210
1211 /* Legacy events */
1212 if (send_acpi_ev || hotkey_report_mode < 2)
1213 acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
1214
1215 /* netlink events */
1216 if (send_acpi_ev) {
1217 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
1218 ibm->acpi->device->dev.bus_id,
1219 event, hkey);
1197 } 1220 }
1198} 1221}
1199 1222
@@ -4623,6 +4646,9 @@ module_param_named(fan_control, fan_control_allowed, bool, 0);
4623static int brightness_mode; 4646static int brightness_mode;
4624module_param_named(brightness_mode, brightness_mode, int, 0); 4647module_param_named(brightness_mode, brightness_mode, int, 0);
4625 4648
4649static unsigned int hotkey_report_mode;
4650module_param(hotkey_report_mode, uint, 0);
4651
4626#define IBM_PARAM(feature) \ 4652#define IBM_PARAM(feature) \
4627 module_param_call(feature, set_ibm_param, NULL, NULL, 0) 4653 module_param_call(feature, set_ibm_param, NULL, NULL, 0)
4628 4654
@@ -4648,6 +4674,10 @@ static int __init thinkpad_acpi_module_init(void)
4648{ 4674{
4649 int ret, i; 4675 int ret, i;
4650 4676
4677 /* Parameter checking */
4678 if (hotkey_report_mode > 2)
4679 return -EINVAL;
4680
4651 /* Driver-level probe */ 4681 /* Driver-level probe */
4652 4682
4653 get_thinkpad_model_data(&thinkpad_id); 4683 get_thinkpad_model_data(&thinkpad_id);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index eee8809a50d9..082a1cbc16c0 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -181,6 +181,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv);
181static int experimental; 181static int experimental;
182static u32 dbg_level; 182static u32 dbg_level;
183static int force_load; 183static int force_load;
184static unsigned int hotkey_report_mode;
184 185
185static int thinkpad_acpi_module_init(void); 186static int thinkpad_acpi_module_init(void);
186static void thinkpad_acpi_module_exit(void); 187static void thinkpad_acpi_module_exit(void);