mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 15:18:19 +00:00
HID: separate hid-input event quirks from generic code
This patch separates also the hid-input quirks that have to be applied at the time the event occurs, so that the generic code handling HUT-compliant devices is not messed up by them too much. Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
parent
10bd065fac
commit
87bc2aa993
3 changed files with 71 additions and 59 deletions
|
@ -322,5 +322,68 @@ int hidinput_mapping_quirks(struct hid_usage *usage,
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(hidinput_mapping_quirks);
|
|
||||||
|
#define IS_MS_KB(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9))
|
||||||
|
|
||||||
|
void hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
|
||||||
|
{
|
||||||
|
struct input_dev *input;
|
||||||
|
unsigned *quirks = &hid->quirks;
|
||||||
|
|
||||||
|
input = field->hidinput->input;
|
||||||
|
|
||||||
|
if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
|
||||||
|
|| ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) {
|
||||||
|
if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
|
||||||
|
else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) &&
|
||||||
|
(usage->type == EV_REL) &&
|
||||||
|
(usage->code == REL_WHEEL)) {
|
||||||
|
hid->delayed_value = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) &&
|
||||||
|
(usage->hid == 0x000100b8)) {
|
||||||
|
input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) {
|
||||||
|
input_event(input, usage->type, usage->code, -value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
|
||||||
|
input_event(input, usage->type, REL_HWHEEL, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Handling MS keyboards special buttons */
|
||||||
|
if (IS_MS_KB(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
|
||||||
|
int key = 0;
|
||||||
|
static int last_key = 0;
|
||||||
|
switch (value) {
|
||||||
|
case 0x01: key = KEY_F14; break;
|
||||||
|
case 0x02: key = KEY_F15; break;
|
||||||
|
case 0x04: key = KEY_F16; break;
|
||||||
|
case 0x08: key = KEY_F17; break;
|
||||||
|
case 0x10: key = KEY_F18; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
if (key) {
|
||||||
|
input_event(input, usage->type, key, 1);
|
||||||
|
last_key = key;
|
||||||
|
} else {
|
||||||
|
input_event(input, usage->type, last_key, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -86,11 +86,6 @@ static const struct {
|
||||||
#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0)
|
#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0)
|
||||||
#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
|
#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
|
||||||
|
|
||||||
/* hardware needing special handling due to colliding MSVENDOR page usages */
|
|
||||||
#define IS_CHICONY_TACTICAL_PAD(x) (x->vendor == 0x04f2 && device->product == 0x0418)
|
|
||||||
#define IS_MS_KB(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9))
|
|
||||||
#define IS_MS_PRESENTER_8000(x) (x->vendor == 0x045e && x->product == 0x0713)
|
|
||||||
|
|
||||||
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
|
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
|
||||||
|
|
||||||
struct hidinput_key_translation {
|
struct hidinput_key_translation {
|
||||||
|
@ -177,7 +172,7 @@ static struct hidinput_key_translation *find_translation(struct hidinput_key_tra
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
|
int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
|
||||||
struct hid_usage *usage, __s32 value)
|
struct hid_usage *usage, __s32 value)
|
||||||
{
|
{
|
||||||
struct hidinput_key_translation *trans;
|
struct hidinput_key_translation *trans;
|
||||||
|
@ -269,7 +264,7 @@ static void hidinput_apple_setup(struct input_dev *input)
|
||||||
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline int hidinput_apple_event(struct hid_device *hid,
|
inline int hidinput_apple_event(struct hid_device *hid,
|
||||||
struct input_dev *input,
|
struct input_dev *input,
|
||||||
struct hid_usage *usage, __s32 value)
|
struct hid_usage *usage, __s32 value)
|
||||||
{
|
{
|
||||||
|
@ -386,6 +381,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
||||||
goto ignore;
|
goto ignore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* handle input mappings for quirky devices */
|
||||||
ret = hidinput_mapping_quirks(usage, input, bit, &max);
|
ret = hidinput_mapping_quirks(usage, input, bit, &max);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto mapped;
|
goto mapped;
|
||||||
|
@ -857,38 +853,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
|
||||||
if (!usage->type)
|
if (!usage->type)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
|
/* handle input events for quirky devices */
|
||||||
|| ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) {
|
hidinput_event_quirks(hid, field, usage, value);
|
||||||
if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
|
|
||||||
else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) &&
|
|
||||||
(usage->type == EV_REL) &&
|
|
||||||
(usage->code == REL_WHEEL)) {
|
|
||||||
hid->delayed_value = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) &&
|
|
||||||
(usage->hid == 0x000100b8)) {
|
|
||||||
input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) {
|
|
||||||
input_event(input, usage->type, usage->code, -value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
|
|
||||||
input_event(input, usage->type, REL_HWHEEL, value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (usage->hat_min < usage->hat_max || usage->hat_dir) {
|
if (usage->hat_min < usage->hat_max || usage->hat_dir) {
|
||||||
int hat_dir = usage->hat_dir;
|
int hat_dir = usage->hat_dir;
|
||||||
|
@ -949,25 +915,6 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handling MS keyboards special buttons */
|
|
||||||
if (IS_MS_KB(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
|
|
||||||
int key = 0;
|
|
||||||
static int last_key = 0;
|
|
||||||
switch (value) {
|
|
||||||
case 0x01: key = KEY_F14; break;
|
|
||||||
case 0x02: key = KEY_F15; break;
|
|
||||||
case 0x04: key = KEY_F16; break;
|
|
||||||
case 0x08: key = KEY_F17; break;
|
|
||||||
case 0x10: key = KEY_F18; break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
if (key) {
|
|
||||||
input_event(input, usage->type, key, 1);
|
|
||||||
last_key = key;
|
|
||||||
} else {
|
|
||||||
input_event(input, usage->type, last_key, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* report the usage code as scancode if the key status has changed */
|
/* report the usage code as scancode if the key status has changed */
|
||||||
if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
|
if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
|
||||||
input_event(input, EV_MSC, MSC_SCAN, usage->hid);
|
input_event(input, EV_MSC, MSC_SCAN, usage->hid);
|
||||||
|
|
|
@ -525,6 +525,8 @@ int hid_set_field(struct hid_field *, unsigned, __s32);
|
||||||
int hid_input_report(struct hid_device *, int type, u8 *, int, int);
|
int hid_input_report(struct hid_device *, int type, u8 *, int, int);
|
||||||
int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
|
int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
|
||||||
int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long *, int *);
|
int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long *, int *);
|
||||||
|
void hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
|
||||||
|
int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32);
|
||||||
void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt);
|
void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt);
|
||||||
void hid_output_report(struct hid_report *report, __u8 *data);
|
void hid_output_report(struct hid_report *report, __u8 *data);
|
||||||
void hid_free_device(struct hid_device *device);
|
void hid_free_device(struct hid_device *device);
|
||||||
|
|
Loading…
Reference in a new issue