diff options
Diffstat (limited to 'drivers/hid/hid-apple.c')
-rw-r--r-- | drivers/hid/hid-apple.c | 63 |
1 files changed, 52 insertions, 11 deletions
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index eaeca564a8d3..61aa71233392 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c | |||
@@ -16,6 +16,8 @@ | |||
16 | * any later version. | 16 | * any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
19 | #include <linux/device.h> | 21 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 22 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 23 | #include <linux/module.h> |
@@ -59,6 +61,27 @@ struct apple_key_translation { | |||
59 | u8 flags; | 61 | u8 flags; |
60 | }; | 62 | }; |
61 | 63 | ||
64 | static const struct apple_key_translation macbookair_fn_keys[] = { | ||
65 | { KEY_BACKSPACE, KEY_DELETE }, | ||
66 | { KEY_ENTER, KEY_INSERT }, | ||
67 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, | ||
68 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, | ||
69 | { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, | ||
70 | { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, | ||
71 | { KEY_F6, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, | ||
72 | { KEY_F7, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, | ||
73 | { KEY_F8, KEY_NEXTSONG, APPLE_FLAG_FKEY }, | ||
74 | { KEY_F9, KEY_MUTE, APPLE_FLAG_FKEY }, | ||
75 | { KEY_F10, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, | ||
76 | { KEY_F11, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, | ||
77 | { KEY_F12, KEY_EJECTCD, APPLE_FLAG_FKEY }, | ||
78 | { KEY_UP, KEY_PAGEUP }, | ||
79 | { KEY_DOWN, KEY_PAGEDOWN }, | ||
80 | { KEY_LEFT, KEY_HOME }, | ||
81 | { KEY_RIGHT, KEY_END }, | ||
82 | { } | ||
83 | }; | ||
84 | |||
62 | static const struct apple_key_translation apple_fn_keys[] = { | 85 | static const struct apple_key_translation apple_fn_keys[] = { |
63 | { KEY_BACKSPACE, KEY_DELETE }, | 86 | { KEY_BACKSPACE, KEY_DELETE }, |
64 | { KEY_ENTER, KEY_INSERT }, | 87 | { KEY_ENTER, KEY_INSERT }, |
@@ -146,7 +169,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, | |||
146 | struct hid_usage *usage, __s32 value) | 169 | struct hid_usage *usage, __s32 value) |
147 | { | 170 | { |
148 | struct apple_sc *asc = hid_get_drvdata(hid); | 171 | struct apple_sc *asc = hid_get_drvdata(hid); |
149 | const struct apple_key_translation *trans; | 172 | const struct apple_key_translation *trans, *table; |
150 | 173 | ||
151 | if (usage->code == KEY_FN) { | 174 | if (usage->code == KEY_FN) { |
152 | asc->fn_on = !!value; | 175 | asc->fn_on = !!value; |
@@ -157,10 +180,16 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, | |||
157 | if (fnmode) { | 180 | if (fnmode) { |
158 | int do_translate; | 181 | int do_translate; |
159 | 182 | ||
160 | trans = apple_find_translation((hid->product < 0x21d || | 183 | if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && |
161 | hid->product >= 0x300) ? | 184 | hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) |
162 | powerbook_fn_keys : apple_fn_keys, | 185 | table = macbookair_fn_keys; |
163 | usage->code); | 186 | else if (hid->product < 0x21d || hid->product >= 0x300) |
187 | table = powerbook_fn_keys; | ||
188 | else | ||
189 | table = apple_fn_keys; | ||
190 | |||
191 | trans = apple_find_translation (table, usage->code); | ||
192 | |||
164 | if (trans) { | 193 | if (trans) { |
165 | if (test_bit(usage->code, asc->pressed_fn)) | 194 | if (test_bit(usage->code, asc->pressed_fn)) |
166 | do_translate = 1; | 195 | do_translate = 1; |
@@ -253,8 +282,8 @@ static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
253 | 282 | ||
254 | if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 && | 283 | if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 && |
255 | rdesc[53] == 0x65 && rdesc[59] == 0x65) { | 284 | rdesc[53] == 0x65 && rdesc[59] == 0x65) { |
256 | dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report " | 285 | hid_info(hdev, |
257 | "descriptor\n"); | 286 | "fixing up MacBook JIS keyboard report descriptor\n"); |
258 | rdesc[53] = rdesc[59] = 0xe7; | 287 | rdesc[53] = rdesc[59] = 0xe7; |
259 | } | 288 | } |
260 | return rdesc; | 289 | return rdesc; |
@@ -324,7 +353,7 @@ static int apple_probe(struct hid_device *hdev, | |||
324 | 353 | ||
325 | asc = kzalloc(sizeof(*asc), GFP_KERNEL); | 354 | asc = kzalloc(sizeof(*asc), GFP_KERNEL); |
326 | if (asc == NULL) { | 355 | if (asc == NULL) { |
327 | dev_err(&hdev->dev, "can't alloc apple descriptor\n"); | 356 | hid_err(hdev, "can't alloc apple descriptor\n"); |
328 | return -ENOMEM; | 357 | return -ENOMEM; |
329 | } | 358 | } |
330 | 359 | ||
@@ -334,7 +363,7 @@ static int apple_probe(struct hid_device *hdev, | |||
334 | 363 | ||
335 | ret = hid_parse(hdev); | 364 | ret = hid_parse(hdev); |
336 | if (ret) { | 365 | if (ret) { |
337 | dev_err(&hdev->dev, "parse failed\n"); | 366 | hid_err(hdev, "parse failed\n"); |
338 | goto err_free; | 367 | goto err_free; |
339 | } | 368 | } |
340 | 369 | ||
@@ -345,7 +374,7 @@ static int apple_probe(struct hid_device *hdev, | |||
345 | 374 | ||
346 | ret = hid_hw_start(hdev, connect_mask); | 375 | ret = hid_hw_start(hdev, connect_mask); |
347 | if (ret) { | 376 | if (ret) { |
348 | dev_err(&hdev->dev, "hw start failed\n"); | 377 | hid_err(hdev, "hw start failed\n"); |
349 | goto err_free; | 378 | goto err_free; |
350 | } | 379 | } |
351 | 380 | ||
@@ -440,6 +469,18 @@ static const struct hid_device_id apple_devices[] = { | |||
440 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | 469 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
441 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), | 470 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), |
442 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | 471 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
472 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI), | ||
473 | .driver_data = APPLE_HAS_FN }, | ||
474 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO), | ||
475 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | ||
476 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS), | ||
477 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | ||
478 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI), | ||
479 | .driver_data = APPLE_HAS_FN }, | ||
480 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO), | ||
481 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | ||
482 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS), | ||
483 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | ||
443 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), | 484 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), |
444 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 485 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
445 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), | 486 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), |
@@ -473,7 +514,7 @@ static int __init apple_init(void) | |||
473 | 514 | ||
474 | ret = hid_register_driver(&apple_driver); | 515 | ret = hid_register_driver(&apple_driver); |
475 | if (ret) | 516 | if (ret) |
476 | printk(KERN_ERR "can't register apple driver\n"); | 517 | pr_err("can't register apple driver\n"); |
477 | 518 | ||
478 | return ret; | 519 | return ret; |
479 | } | 520 | } |