Commit 8c19a515 authored by Jiri Slaby's avatar Jiri Slaby Committed by Jiri Kosina

HID: move apple quirks

Move them from the core code to a separate driver.
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent d458a9df
......@@ -70,6 +70,20 @@ source "drivers/hid/usbhid/Kconfig"
menu "Special HID drivers"
depends on HID
config HID_APPLE
tristate "Apple"
default m
depends on (USB_HID || BT_HIDP)
---help---
Support for some Apple devices which less or more break
HID specification.
Say Y here if you want support for the special keys (Fn, Numlock) on
Apple iBooks, PowerBooks, MacBooks, MacBook Pros and aluminum USB
keyboards.
If unsure, say M.
config HID_LOGITECH
tristate "Logitech"
default m
......
......@@ -8,6 +8,7 @@ obj-$(CONFIG_HID) += hid.o
hid-$(CONFIG_HID_DEBUG) += hid-debug.o
hid-$(CONFIG_HIDRAW) += hidraw.o
obj-$(CONFIG_HID_APPLE) += hid-apple.o
obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
obj-$(CONFIG_USB_HID) += usbhid/
......
/*
* USB HID quirks support for Linux
*
* Copyright (c) 1999 Andreas Gal
* Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
* Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
* Copyright (c) 2006-2007 Jiri Kosina
* Copyright (c) 2007 Paul Walmsley
* Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com>
*/
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*/
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/usb.h>
#include "hid-ids.h"
#define APPLE_RDESC_JIS 0x0001
#define APPLE_IGNORE_MOUSE 0x0002
#define APPLE_HAS_FN 0x0004
#define APPLE_HIDDEV 0x0008
#define APPLE_ISO_KEYBOARD 0x0010
#define APPLE_MIGHTYMOUSE 0x0020
#define APPLE_INVERT_HWHEEL 0x0040
#define APPLE_IGNORE_HIDINPUT 0x0080
#define APPLE_NUMLOCK_EMULATION 0x0100
#define APPLE_FLAG_FKEY 0x01
static unsigned int fnmode = 1;
module_param(fnmode, uint, 0644);
MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, "
"[1] = fkeyslast, 2 = fkeysfirst)");
struct apple_sc {
unsigned long quirks;
unsigned int fn_on;
DECLARE_BITMAP(pressed_fn, KEY_CNT);
DECLARE_BITMAP(pressed_numlock, KEY_CNT);
};
struct apple_key_translation {
u16 from;
u16 to;
u8 flags;
};
static struct apple_key_translation apple_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
{ KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
{ KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Exposé */
{ KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */
{ KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
{ KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
{ KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
{ KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
{ KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
{ KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
{ KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
{ KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
{ KEY_UP, KEY_PAGEUP },
{ KEY_DOWN, KEY_PAGEDOWN },
{ KEY_LEFT, KEY_HOME },
{ KEY_RIGHT, KEY_END },
{ }
};
static struct apple_key_translation powerbook_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
{ KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
{ KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY },
{ KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
{ KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
{ KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY },
{ KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY },
{ KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY },
{ KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
{ KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
{ KEY_UP, KEY_PAGEUP },
{ KEY_DOWN, KEY_PAGEDOWN },
{ KEY_LEFT, KEY_HOME },
{ KEY_RIGHT, KEY_END },
{ }
};
static struct apple_key_translation powerbook_numlock_keys[] = {
{ KEY_J, KEY_KP1 },
{ KEY_K, KEY_KP2 },
{ KEY_L, KEY_KP3 },
{ KEY_U, KEY_KP4 },
{ KEY_I, KEY_KP5 },
{ KEY_O, KEY_KP6 },
{ KEY_7, KEY_KP7 },
{ KEY_8, KEY_KP8 },
{ KEY_9, KEY_KP9 },
{ KEY_M, KEY_KP0 },
{ KEY_DOT, KEY_KPDOT },
{ KEY_SLASH, KEY_KPPLUS },
{ KEY_SEMICOLON, KEY_KPMINUS },
{ KEY_P, KEY_KPASTERISK },
{ KEY_MINUS, KEY_KPEQUAL },
{ KEY_0, KEY_KPSLASH },
{ KEY_F6, KEY_NUMLOCK },
{ KEY_KPENTER, KEY_KPENTER },
{ KEY_BACKSPACE, KEY_BACKSPACE },
{ }
};
static struct apple_key_translation apple_iso_keyboard[] = {
{ KEY_GRAVE, KEY_102ND },
{ KEY_102ND, KEY_GRAVE },
{ }
};
static struct apple_key_translation *apple_find_translation(
struct apple_key_translation *table, u16 from)
{
struct apple_key_translation *trans;
/* Look for the translation */
for (trans = table; trans->from; trans++)
if (trans->from == from)
return trans;
return NULL;
}
static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
struct hid_usage *usage, __s32 value)
{
struct apple_sc *asc = hid_get_drvdata(hid);
struct apple_key_translation *trans;
if (usage->code == KEY_FN) {
asc->fn_on = !!value;
input_event(input, usage->type, usage->code, value);
return 1;
}
if (fnmode) {
int do_translate;
trans = apple_find_translation((hid->product < 0x220 ||
hid->product >= 0x300) ?
powerbook_fn_keys : apple_fn_keys,
usage->code);
if (trans) {
if (test_bit(usage->code, asc->pressed_fn))
do_translate = 1;
else if (trans->flags & APPLE_FLAG_FKEY)
do_translate = (fnmode == 2 && asc->fn_on) ||
(fnmode == 1 && !asc->fn_on);
else
do_translate = asc->fn_on;
if (do_translate) {
if (value)
set_bit(usage->code, asc->pressed_fn);
else
clear_bit(usage->code, asc->pressed_fn);
input_event(input, usage->type, trans->to,
value);
return 1;
}
}
if (asc->quirks & APPLE_NUMLOCK_EMULATION &&
(test_bit(usage->code, asc->pressed_numlock) ||
test_bit(LED_NUML, input->led))) {
trans = apple_find_translation(powerbook_numlock_keys,
usage->code);
if (trans) {
if (value)
set_bit(usage->code,
asc->pressed_numlock);
else
clear_bit(usage->code,
asc->pressed_numlock);
input_event(input, usage->type, trans->to,
value);
}
return 1;
}
}
if (asc->quirks & APPLE_ISO_KEYBOARD) {
trans = apple_find_translation(apple_iso_keyboard, usage->code);
if (trans) {
input_event(input, usage->type, trans->to, value);
return 1;
}
}
return 0;
}
static int apple_event(struct hid_device *hdev, struct hid_field *field,
struct hid_usage *usage, __s32 value)
{
struct apple_sc *asc = hid_get_drvdata(hdev);
if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
!usage->type)
return 0;
if ((asc->quirks & APPLE_INVERT_HWHEEL) &&
usage->code == REL_HWHEEL) {
input_event(field->hidinput->input, usage->type, usage->code,
-value);
return 1;
}
if ((asc->quirks & APPLE_HAS_FN) &&
hidinput_apple_event(hdev, field->hidinput->input,
usage, value))
return 1;
return 0;
}
/*
* MacBook JIS keyboard has wrong logical maximum
*/
static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int rsize)
{
struct apple_sc *asc = hid_get_drvdata(hdev);
if ((asc->quirks & APPLE_RDESC_JIS) && rsize >= 60 &&
rdesc[53] == 0x65 && rdesc[59] == 0x65) {
dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report "
"descriptor\n");
rdesc[53] = rdesc[59] = 0xe7;
}
}
static void apple_setup_input(struct input_dev *input)
{
struct apple_key_translation *trans;
set_bit(KEY_NUMLOCK, input->keybit);
/* Enable all needed keys */
for (trans = apple_fn_keys; trans->from; trans++)
set_bit(trans->to, input->keybit);
for (trans = powerbook_fn_keys; trans->from; trans++)
set_bit(trans->to, input->keybit);
for (trans = powerbook_numlock_keys; trans->from; trans++)
set_bit(trans->to, input->keybit);
for (trans = apple_iso_keyboard; trans->from; trans++)
set_bit(trans->to, input->keybit);
}
static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max)
{
if (usage->hid == (HID_UP_CUSTOM | 0x0003)) {
/* The fn key on Apple USB keyboards */
set_bit(EV_REP, hi->input->evbit);
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
apple_setup_input(hi->input);
return 1;
}
/* we want the hid layer to go through standard path (set and ignore) */
return 0;
}
static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max)
{
struct apple_sc *asc = hid_get_drvdata(hdev);
if (asc->quirks & APPLE_MIGHTYMOUSE) {
if (usage->hid == HID_GD_Z)
hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL);
else if (usage->code == BTN_1)
hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_2);
else if (usage->code == BTN_2)
hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_1);
}
return 0;
}
static int apple_probe(struct hid_device *hdev,
const struct hid_device_id *id)
{
unsigned long quirks = id->driver_data;
struct apple_sc *asc;
int ret;
/* return something else or move to hid layer? device will reside
allocated */
if (id->bus == BUS_USB && (quirks & APPLE_IGNORE_MOUSE) &&
to_usb_interface(hdev->dev.parent)->cur_altsetting->
desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE)
return -ENODEV;
asc = kzalloc(sizeof(*asc), GFP_KERNEL);
if (asc == NULL) {
dev_err(&hdev->dev, "can't alloc apple descriptor\n");
return -ENOMEM;
}
asc->quirks = quirks;
hid_set_drvdata(hdev, asc);
if (quirks & APPLE_HIDDEV)
hdev->quirks |= HID_QUIRK_HIDDEV;
if (quirks & APPLE_IGNORE_HIDINPUT)
hdev->quirks |= HID_QUIRK_IGNORE_HIDINPUT;
ret = hid_parse(hdev);
if (ret) {
dev_err(&hdev->dev, "parse failed\n");
goto err_free;
}
ret = hid_hw_start(hdev);
if (ret) {
dev_err(&hdev->dev, "hw start failed\n");
goto err_free;
}
return 0;
err_free:
kfree(asc);
return ret;
}
static void apple_remove(struct hid_device *hdev)
{
hid_hw_stop(hdev);
kfree(hid_get_drvdata(hdev));
}
static const struct hid_device_id apple_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4),
.driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE),
.driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE | APPLE_ISO_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE | APPLE_ISO_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE | APPLE_ISO_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE | APPLE_RDESC_JIS},
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI),
.driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO),
.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS),
.driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_ISO_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
.driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
.driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
.driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
.driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_IGNORE_MOUSE },
/* Apple wireless Mighty Mouse */
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c),
.driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
{ }
};
MODULE_DEVICE_TABLE(hid, apple_devices);
static struct hid_driver apple_driver = {
.name = "apple",
.id_table = apple_devices,
.report_fixup = apple_report_fixup,
.probe = apple_probe,
.remove = apple_remove,
.event = apple_event,
.input_mapping = apple_input_mapping,
.input_mapped = apple_input_mapped,
};
static int apple_init(void)
{
int ret;
ret = hid_register_driver(&apple_driver);
if (ret)
printk(KERN_ERR "can't register apple driver\n");
return ret;
}
static void apple_exit(void)
{
hid_unregister_driver(&apple_driver);
}
module_init(apple_init);
module_exit(apple_exit);
MODULE_LICENSE("GPL");
......@@ -1130,6 +1130,36 @@ static const struct hid_device_id *hid_match_id(struct hid_device *hdev,
}
static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
......@@ -1144,6 +1174,8 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
{ }
};
......
......@@ -331,19 +331,11 @@ int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struc
return 1;
}
if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) {
input_event(input, usage->type, usage->code, -value);
return 1;
}
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
input_event(input, usage->type, REL_HWHEEL, value);
return 1;
}
if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value))
return 1;
/* Handling MS keyboards special buttons */
if (hid->quirks & HID_QUIRK_MICROSOFT_KEYS &&
usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
......
......@@ -32,11 +32,6 @@
#include <linux/hid.h>
#include <linux/hid-debug.h>
static int hid_apple_fnmode = 1;
module_param_named(pb_fnmode, hid_apple_fnmode, int, 0644);
MODULE_PARM_DESC(pb_fnmode,
"Mode of fn key on Apple keyboards (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)");
#define unk KEY_UNKNOWN
static const unsigned char hid_keyboard[256] = {
......@@ -73,202 +68,6 @@ static const struct {
#define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \
&max, EV_KEY, (c))
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
struct hidinput_key_translation {
u16 from;
u16 to;
u8 flags;
};
#define APPLE_FLAG_FKEY 0x01
static struct hidinput_key_translation apple_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
{ KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
{ KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Expos */
{ KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */
{ KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
{ KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
{ KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
{ KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
{ KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
{ KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
{ KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
{ KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
{ KEY_UP, KEY_PAGEUP },
{ KEY_DOWN, KEY_PAGEDOWN },
{ KEY_LEFT, KEY_HOME },
{ KEY_RIGHT, KEY_END },
{ }
};
static struct hidinput_key_translation powerbook_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
{ KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
{ KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY },
{ KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
{ KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
{ KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY },
{ KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY },
{ KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY },
{ KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
{ KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
{ KEY_UP, KEY_PAGEUP },
{ KEY_DOWN, KEY_PAGEDOWN },
{ KEY_LEFT, KEY_HOME },