aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/thinkpad_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/thinkpad_acpi.c')
-rw-r--r--drivers/misc/thinkpad_acpi.c144
1 files changed, 87 insertions, 57 deletions
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);