diff options
author | Dmitry Torokhov <dtor@mail.ru> | 2010-01-06 16:07:39 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-01-16 01:49:41 -0500 |
commit | 642e0447cb910ceabae0b4ea6c0cd3449d5c5abb (patch) | |
tree | 9f0b33620830c3c90e0a94d02a79a1d9ee5c7b2b /drivers/platform | |
parent | 10ae4b5663ff3092553bfbd867e7bd474ce6c553 (diff) |
eeepc-laptop: switch to using sparse keymap library
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Tested-by: Alan Jenkins <alan-jenkins@tuffmail.co.uk>
Acked-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/Kconfig | 1 | ||||
-rw-r--r-- | drivers/platform/x86/eeepc-laptop.c | 186 |
2 files changed, 52 insertions, 135 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index db32c25e3605..f526e735c5ab 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -364,6 +364,7 @@ config EEEPC_LAPTOP | |||
364 | select HWMON | 364 | select HWMON |
365 | select LEDS_CLASS | 365 | select LEDS_CLASS |
366 | select NEW_LEDS | 366 | select NEW_LEDS |
367 | select INPUT_SPARSEKMAP | ||
367 | ---help--- | 368 | ---help--- |
368 | This driver supports the Fn-Fx keys on Eee PC laptops. | 369 | This driver supports the Fn-Fx keys on Eee PC laptops. |
369 | 370 | ||
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 7fc944ac2070..07d7978c558f 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <acpi/acpi_bus.h> | 31 | #include <acpi/acpi_bus.h> |
32 | #include <linux/uaccess.h> | 32 | #include <linux/uaccess.h> |
33 | #include <linux/input.h> | 33 | #include <linux/input.h> |
34 | #include <linux/input/sparse-keymap.h> | ||
34 | #include <linux/rfkill.h> | 35 | #include <linux/rfkill.h> |
35 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
36 | #include <linux/pci_hotplug.h> | 37 | #include <linux/pci_hotplug.h> |
@@ -121,38 +122,28 @@ static const char *cm_setv[] = { | |||
121 | NULL, NULL, "PBPS", "TPDS" | 122 | NULL, NULL, "PBPS", "TPDS" |
122 | }; | 123 | }; |
123 | 124 | ||
124 | struct key_entry { | ||
125 | char type; | ||
126 | u8 code; | ||
127 | u16 keycode; | ||
128 | }; | ||
129 | |||
130 | enum { KE_KEY, KE_END }; | ||
131 | |||
132 | static const struct key_entry eeepc_keymap[] = { | 125 | static const struct key_entry eeepc_keymap[] = { |
133 | /* Sleep already handled via generic ACPI code */ | 126 | { KE_KEY, 0x10, { KEY_WLAN } }, |
134 | {KE_KEY, 0x10, KEY_WLAN }, | 127 | { KE_KEY, 0x11, { KEY_WLAN } }, |
135 | {KE_KEY, 0x11, KEY_WLAN }, | 128 | { KE_KEY, 0x12, { KEY_PROG1 } }, |
136 | {KE_KEY, 0x12, KEY_PROG1 }, | 129 | { KE_KEY, 0x13, { KEY_MUTE } }, |
137 | {KE_KEY, 0x13, KEY_MUTE }, | 130 | { KE_KEY, 0x14, { KEY_VOLUMEDOWN } }, |
138 | {KE_KEY, 0x14, KEY_VOLUMEDOWN }, | 131 | { KE_KEY, 0x15, { KEY_VOLUMEUP } }, |
139 | {KE_KEY, 0x15, KEY_VOLUMEUP }, | 132 | { KE_KEY, 0x16, { KEY_DISPLAY_OFF } }, |
140 | {KE_KEY, 0x16, KEY_DISPLAY_OFF }, | 133 | { KE_KEY, 0x1a, { KEY_COFFEE } }, |
141 | {KE_KEY, 0x1a, KEY_COFFEE }, | 134 | { KE_KEY, 0x1b, { KEY_ZOOM } }, |
142 | {KE_KEY, 0x1b, KEY_ZOOM }, | 135 | { KE_KEY, 0x1c, { KEY_PROG2 } }, |
143 | {KE_KEY, 0x1c, KEY_PROG2 }, | 136 | { KE_KEY, 0x1d, { KEY_PROG3 } }, |
144 | {KE_KEY, 0x1d, KEY_PROG3 }, | 137 | { KE_KEY, NOTIFY_BRN_MIN, { KEY_BRIGHTNESSDOWN } }, |
145 | {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN }, | 138 | { KE_KEY, NOTIFY_BRN_MAX, { KEY_BRIGHTNESSUP } }, |
146 | {KE_KEY, NOTIFY_BRN_MAX, KEY_BRIGHTNESSUP }, | 139 | { KE_KEY, 0x30, { KEY_SWITCHVIDEOMODE } }, |
147 | {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, | 140 | { KE_KEY, 0x31, { KEY_SWITCHVIDEOMODE } }, |
148 | {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, | 141 | { KE_KEY, 0x32, { KEY_SWITCHVIDEOMODE } }, |
149 | {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, | 142 | { KE_KEY, 0x37, { KEY_F13 } }, /* Disable Touchpad */ |
150 | {KE_KEY, 0x37, KEY_F13 }, /* Disable Touchpad */ | 143 | { KE_KEY, 0x38, { KEY_F14 } }, |
151 | {KE_KEY, 0x38, KEY_F14 }, | 144 | { KE_END, 0 }, |
152 | {KE_END, 0}, | ||
153 | }; | 145 | }; |
154 | 146 | ||
155 | |||
156 | /* | 147 | /* |
157 | * This is the main structure, we can use it to store useful information | 148 | * This is the main structure, we can use it to store useful information |
158 | */ | 149 | */ |
@@ -1143,120 +1134,42 @@ static void eeepc_backlight_exit(struct eeepc_laptop *eeepc) | |||
1143 | /* | 1134 | /* |
1144 | * Input device (i.e. hotkeys) | 1135 | * Input device (i.e. hotkeys) |
1145 | */ | 1136 | */ |
1146 | static struct key_entry *eeepc_get_entry_by_scancode( | 1137 | static int eeepc_input_init(struct eeepc_laptop *eeepc) |
1147 | struct eeepc_laptop *eeepc, | ||
1148 | int code) | ||
1149 | { | 1138 | { |
1150 | struct key_entry *key; | 1139 | struct input_dev *input; |
1151 | 1140 | int error; | |
1152 | for (key = eeepc->keymap; key->type != KE_END; key++) | ||
1153 | if (code == key->code) | ||
1154 | return key; | ||
1155 | 1141 | ||
1156 | return NULL; | 1142 | input = input_allocate_device(); |
1157 | } | 1143 | if (!input) { |
1158 | 1144 | pr_info("Unable to allocate input device\n"); | |
1159 | static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event) | 1145 | return -ENOMEM; |
1160 | { | ||
1161 | static struct key_entry *key; | ||
1162 | |||
1163 | key = eeepc_get_entry_by_scancode(eeepc, event); | ||
1164 | if (key) { | ||
1165 | switch (key->type) { | ||
1166 | case KE_KEY: | ||
1167 | input_report_key(eeepc->inputdev, key->keycode, | ||
1168 | 1); | ||
1169 | input_sync(eeepc->inputdev); | ||
1170 | input_report_key(eeepc->inputdev, key->keycode, | ||
1171 | 0); | ||
1172 | input_sync(eeepc->inputdev); | ||
1173 | break; | ||
1174 | } | ||
1175 | } | 1146 | } |
1176 | } | ||
1177 | |||
1178 | static struct key_entry *eeepc_get_entry_by_keycode( | ||
1179 | struct eeepc_laptop *eeepc, int code) | ||
1180 | { | ||
1181 | struct key_entry *key; | ||
1182 | |||
1183 | for (key = eeepc->keymap; key->type != KE_END; key++) | ||
1184 | if (code == key->keycode && key->type == KE_KEY) | ||
1185 | return key; | ||
1186 | 1147 | ||
1187 | return NULL; | 1148 | input->name = "Asus EeePC extra buttons"; |
1188 | } | 1149 | input->phys = EEEPC_LAPTOP_FILE "/input0"; |
1150 | input->id.bustype = BUS_HOST; | ||
1151 | input->dev.parent = &eeepc->platform_device->dev; | ||
1189 | 1152 | ||
1190 | static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode) | 1153 | error = sparse_keymap_setup(input, eeepc_keymap, NULL); |
1191 | { | 1154 | if (error) { |
1192 | struct eeepc_laptop *eeepc = input_get_drvdata(dev); | 1155 | pr_err("Unable to setup input device keymap\n"); |
1193 | struct key_entry *key = eeepc_get_entry_by_scancode(eeepc, scancode); | 1156 | goto err_free_dev; |
1194 | |||
1195 | if (key && key->type == KE_KEY) { | ||
1196 | *keycode = key->keycode; | ||
1197 | return 0; | ||
1198 | } | 1157 | } |
1199 | 1158 | ||
1200 | return -EINVAL; | 1159 | error = input_register_device(input); |
1201 | } | 1160 | if (error) { |
1202 | 1161 | pr_err("Unable to register input device\n"); | |
1203 | static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) | 1162 | goto err_free_keymap; |
1204 | { | ||
1205 | struct eeepc_laptop *eeepc = input_get_drvdata(dev); | ||
1206 | struct key_entry *key; | ||
1207 | int old_keycode; | ||
1208 | |||
1209 | if (keycode < 0 || keycode > KEY_MAX) | ||
1210 | return -EINVAL; | ||
1211 | |||
1212 | key = eeepc_get_entry_by_scancode(eeepc, scancode); | ||
1213 | if (key && key->type == KE_KEY) { | ||
1214 | old_keycode = key->keycode; | ||
1215 | key->keycode = keycode; | ||
1216 | set_bit(keycode, dev->keybit); | ||
1217 | if (!eeepc_get_entry_by_keycode(eeepc, old_keycode)) | ||
1218 | clear_bit(old_keycode, dev->keybit); | ||
1219 | return 0; | ||
1220 | } | 1163 | } |
1221 | 1164 | ||
1222 | return -EINVAL; | 1165 | eeepc->inputdev = input; |
1223 | } | ||
1224 | |||
1225 | static int eeepc_input_init(struct eeepc_laptop *eeepc) | ||
1226 | { | ||
1227 | const struct key_entry *key; | ||
1228 | int result; | ||
1229 | |||
1230 | eeepc->inputdev = input_allocate_device(); | ||
1231 | if (!eeepc->inputdev) { | ||
1232 | pr_info("Unable to allocate input device\n"); | ||
1233 | return -ENOMEM; | ||
1234 | } | ||
1235 | eeepc->inputdev->name = "Asus EeePC extra buttons"; | ||
1236 | eeepc->inputdev->dev.parent = &eeepc->platform_device->dev; | ||
1237 | eeepc->inputdev->phys = EEEPC_LAPTOP_FILE "/input0"; | ||
1238 | eeepc->inputdev->id.bustype = BUS_HOST; | ||
1239 | eeepc->inputdev->getkeycode = eeepc_getkeycode; | ||
1240 | eeepc->inputdev->setkeycode = eeepc_setkeycode; | ||
1241 | input_set_drvdata(eeepc->inputdev, eeepc); | ||
1242 | |||
1243 | eeepc->keymap = kmemdup(eeepc_keymap, sizeof(eeepc_keymap), | ||
1244 | GFP_KERNEL); | ||
1245 | for (key = eeepc_keymap; key->type != KE_END; key++) { | ||
1246 | switch (key->type) { | ||
1247 | case KE_KEY: | ||
1248 | set_bit(EV_KEY, eeepc->inputdev->evbit); | ||
1249 | set_bit(key->keycode, eeepc->inputdev->keybit); | ||
1250 | break; | ||
1251 | } | ||
1252 | } | ||
1253 | result = input_register_device(eeepc->inputdev); | ||
1254 | if (result) { | ||
1255 | pr_info("Unable to register input device\n"); | ||
1256 | input_free_device(eeepc->inputdev); | ||
1257 | return result; | ||
1258 | } | ||
1259 | return 0; | 1166 | return 0; |
1167 | |||
1168 | err_free_keymap: | ||
1169 | sparse_keymap_free(input); | ||
1170 | err_free_dev: | ||
1171 | input_free_device(input); | ||
1172 | return error; | ||
1260 | } | 1173 | } |
1261 | 1174 | ||
1262 | static void eeepc_input_exit(struct eeepc_laptop *eeepc) | 1175 | static void eeepc_input_exit(struct eeepc_laptop *eeepc) |
@@ -1306,11 +1219,12 @@ static void eeepc_acpi_notify(struct acpi_device *device, u32 event) | |||
1306 | * event will be desired value (or else ignored) | 1219 | * event will be desired value (or else ignored) |
1307 | */ | 1220 | */ |
1308 | } | 1221 | } |
1309 | eeepc_input_notify(eeepc, event); | 1222 | sparse_keymap_report_event(eeepc->inputdev, event, |
1223 | 1, true); | ||
1310 | } | 1224 | } |
1311 | } else { | 1225 | } else { |
1312 | /* Everything else is a bona-fide keypress event */ | 1226 | /* Everything else is a bona-fide keypress event */ |
1313 | eeepc_input_notify(eeepc, event); | 1227 | sparse_keymap_report_event(eeepc->inputdev, event, 1, true); |
1314 | } | 1228 | } |
1315 | } | 1229 | } |
1316 | 1230 | ||
@@ -1554,10 +1468,12 @@ static int __init eeepc_laptop_init(void) | |||
1554 | result = acpi_bus_register_driver(&eeepc_acpi_driver); | 1468 | result = acpi_bus_register_driver(&eeepc_acpi_driver); |
1555 | if (result < 0) | 1469 | if (result < 0) |
1556 | goto fail_acpi_driver; | 1470 | goto fail_acpi_driver; |
1471 | |||
1557 | if (!eeepc_device_present) { | 1472 | if (!eeepc_device_present) { |
1558 | result = -ENODEV; | 1473 | result = -ENODEV; |
1559 | goto fail_no_device; | 1474 | goto fail_no_device; |
1560 | } | 1475 | } |
1476 | |||
1561 | return 0; | 1477 | return 0; |
1562 | 1478 | ||
1563 | fail_no_device: | 1479 | fail_no_device: |