mirror of
https://github.com/suyu-emu/horinux.git
synced 2026-09-21 14:15:21 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (55 commits) HID: build drivers for all quirky devices by default HID: add missing blacklist entry for Apple ATV ircontrol HID: add support for Bright ABNT2 brazilian device HID: Don't let Avermedia Radio FM800 be handled by usb hid drivers HID: fix numlock led on Dell device 0x413c/0x2105 HID: remove warn() macro from usb hid drivers HID: remove info() macro from usb HID drivers HID: add appletv IR receiver quirk HID: fix a lockup regression when using force feedback on a PID device HID: hiddev.h: Fix example code. HID: hiddev.h: Fix mixed space and tabs in example code. HID: convert to dev_* prints HID: remove hid-ff HID: move zeroplus FF processing HID: move thrustmaster FF processing HID: move pantherlord FF processing HID: fix incorrent length condition in hidraw_write() HID: fix tty<->hid deadlock HID: ignore iBuddy devices HID: report descriptor fix for remaining MacBook JIS keyboards ...
This commit is contained in:
@@ -287,6 +287,13 @@ Who: Glauber Costa <gcosta@redhat.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: remove HID compat support
|
||||
When: 2.6.29
|
||||
Why: needed only as a temporary solution until distros fix themselves up
|
||||
Who: Jiri Slaby <jirislaby@gmail.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: /sys/o2cb symlink
|
||||
When: January 2010
|
||||
Why: /sys/fs/o2cb is the proper location for this information - /sys/o2cb
|
||||
|
||||
@@ -17,6 +17,25 @@ config HID
|
||||
tristate "Generic HID support"
|
||||
depends on INPUT
|
||||
default y
|
||||
select HID_A4TECH if !EMBEDDED
|
||||
select HID_APPLE if !EMBEDDED
|
||||
select HID_BELKIN if !EMBEDDED
|
||||
select HID_BRIGHT if !EMBEDDED
|
||||
select HID_CHERRY if !EMBEDDED
|
||||
select HID_CHICONY if !EMBEDDED
|
||||
select HID_CYPRESS if !EMBEDDED
|
||||
select HID_DELL if !EMBEDDED
|
||||
select HID_EZKEY if !EMBEDDED
|
||||
select HID_GYRATION if !EMBEDDED
|
||||
select HID_LOGITECH if !EMBEDDED
|
||||
select HID_MICROSOFT if !EMBEDDED
|
||||
select HID_MONTEREY if !EMBEDDED
|
||||
select HID_PANTHERLORD if !EMBEDDED
|
||||
select HID_PETALYNX if !EMBEDDED
|
||||
select HID_SAMSUNG if !EMBEDDED
|
||||
select HID_SONY if !EMBEDDED
|
||||
select HID_SUNPLUS if !EMBEDDED
|
||||
|
||||
---help---
|
||||
A human interface device (HID) is a type of computer device that
|
||||
interacts directly with and takes input from humans. The term "HID"
|
||||
@@ -67,4 +86,206 @@ config HIDRAW
|
||||
|
||||
source "drivers/hid/usbhid/Kconfig"
|
||||
|
||||
menu "Special HID drivers"
|
||||
depends on HID
|
||||
|
||||
config HID_COMPAT
|
||||
bool "Load all HID drivers on hid core load"
|
||||
default y
|
||||
---help---
|
||||
Compatible option for older userspace. If you have system without udev
|
||||
support of module loading through aliases and also old
|
||||
module-init-tools which can't handle hid bus, choose Y here. Otherwise
|
||||
say N. If you say N and your userspace is old enough, the only
|
||||
functionality you lose is modules autoloading.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config HID_A4TECH
|
||||
tristate "A4 tech"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for A4 tech X5 and WOP-35 / Trust 450L mice.
|
||||
|
||||
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_BELKIN
|
||||
tristate "Belkin"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Belkin Flip KVM and Wireless keyboard.
|
||||
|
||||
config HID_BRIGHT
|
||||
tristate "Bright"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Bright ABNT-2 keyboard.
|
||||
|
||||
config HID_CHERRY
|
||||
tristate "Cherry"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Cherry Cymotion.
|
||||
|
||||
config HID_CHICONY
|
||||
tristate "Chicony"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Chicony Tactical pad.
|
||||
|
||||
config HID_CYPRESS
|
||||
tristate "Cypress"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Cypress mouse and barcodes.
|
||||
|
||||
config HID_DELL
|
||||
tristate "Dell"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Dell W7658.
|
||||
|
||||
config HID_EZKEY
|
||||
tristate "Ezkey"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Ezkey mouse and barcodes.
|
||||
|
||||
config HID_GYRATION
|
||||
tristate "Gyration"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Gyration remote.
|
||||
|
||||
config HID_LOGITECH
|
||||
tristate "Logitech"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for some Logitech devices which breaks less or more
|
||||
HID specification.
|
||||
|
||||
config LOGITECH_FF
|
||||
bool "Logitech force feedback"
|
||||
depends on HID_LOGITECH
|
||||
select INPUT_FF_MEMLESS
|
||||
help
|
||||
Say Y here if you have one of these devices:
|
||||
- Logitech WingMan Cordless RumblePad
|
||||
- Logitech WingMan Cordless RumblePad 2
|
||||
- Logitech WingMan Force 3D
|
||||
- Logitech Formula Force EX
|
||||
- Logitech MOMO Force wheel
|
||||
|
||||
and if you want to enable force feedback for them.
|
||||
Note: if you say N here, this device will still be supported, but without
|
||||
force feedback.
|
||||
|
||||
config LOGIRUMBLEPAD2_FF
|
||||
bool "Logitech Rumblepad 2 force feedback"
|
||||
depends on HID_LOGITECH
|
||||
select INPUT_FF_MEMLESS
|
||||
help
|
||||
Say Y here if you want to enable force feedback support for Logitech
|
||||
Rumblepad 2 devices.
|
||||
|
||||
config HID_MICROSOFT
|
||||
tristate "Microsoft"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for some Microsoft devices which breaks less or more
|
||||
HID specification.
|
||||
|
||||
config HID_MONTEREY
|
||||
tristate "Monterey"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Monterey Genius KB29E.
|
||||
|
||||
config HID_PANTHERLORD
|
||||
tristate "Pantherlord devices support"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for PantherLord/GreenAsia based device support.
|
||||
|
||||
|
||||
config PANTHERLORD_FF
|
||||
bool "Pantherlord force feedback support"
|
||||
depends on HID_PANTHERLORD
|
||||
select INPUT_FF_MEMLESS
|
||||
help
|
||||
Say Y here if you have a PantherLord/GreenAsia based game controller
|
||||
or adapter and want to enable force feedback support for it.
|
||||
|
||||
config HID_PETALYNX
|
||||
tristate "Petalynx"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Petalynx Maxter remote.
|
||||
|
||||
config HID_SAMSUNG
|
||||
tristate "Samsung"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Samsung IR remote.
|
||||
|
||||
config HID_SONY
|
||||
tristate "Sony"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Sony PS3 controller.
|
||||
|
||||
config HID_SUNPLUS
|
||||
tristate "Sunplus"
|
||||
default m
|
||||
depends on USB_HID
|
||||
---help---
|
||||
Support for Sunplus WDesktop input device.
|
||||
|
||||
config THRUSTMASTER_FF
|
||||
tristate "ThrustMaster devices support"
|
||||
default m
|
||||
depends on USB_HID
|
||||
select INPUT_FF_MEMLESS
|
||||
help
|
||||
Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
|
||||
a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel.
|
||||
|
||||
config ZEROPLUS_FF
|
||||
tristate "Zeroplus based game controller support"
|
||||
default m
|
||||
depends on USB_HID
|
||||
select INPUT_FF_MEMLESS
|
||||
help
|
||||
Say Y here if you have a Zeroplus based game controller.
|
||||
|
||||
endmenu
|
||||
|
||||
endif # HID_SUPPORT
|
||||
|
||||
+34
-1
@@ -1,13 +1,46 @@
|
||||
#
|
||||
# Makefile for the HID driver
|
||||
#
|
||||
hid-objs := hid-core.o hid-input.o hid-input-quirks.o
|
||||
hid-objs := hid-core.o hid-input.o
|
||||
|
||||
obj-$(CONFIG_HID) += hid.o
|
||||
|
||||
hid-$(CONFIG_HID_DEBUG) += hid-debug.o
|
||||
hid-$(CONFIG_HIDRAW) += hidraw.o
|
||||
|
||||
ifdef CONFIG_HID_COMPAT
|
||||
obj-m += hid-dummy.o
|
||||
endif
|
||||
|
||||
hid-logitech-objs := hid-lg.o
|
||||
ifdef CONFIG_LOGITECH_FF
|
||||
hid-logitech-objs += hid-lgff.o
|
||||
endif
|
||||
ifdef CONFIG_LOGIRUMBLEPAD2_FF
|
||||
hid-logitech-objs += hid-lg2ff.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
|
||||
obj-$(CONFIG_HID_APPLE) += hid-apple.o
|
||||
obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
|
||||
obj-$(CONFIG_HID_BRIGHT) += hid-bright.o
|
||||
obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
|
||||
obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
|
||||
obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
|
||||
obj-$(CONFIG_HID_DELL) += hid-dell.o
|
||||
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
|
||||
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
|
||||
obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
|
||||
obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
|
||||
obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
|
||||
obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
|
||||
obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
|
||||
obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
|
||||
obj-$(CONFIG_HID_SONY) += hid-sony.o
|
||||
obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
|
||||
obj-$(CONFIG_THRUSTMASTER_FF) += hid-tmff.o
|
||||
obj-$(CONFIG_ZEROPLUS_FF) += hid-zpff.o
|
||||
|
||||
obj-$(CONFIG_USB_HID) += usbhid/
|
||||
obj-$(CONFIG_USB_MOUSE) += usbhid/
|
||||
obj-$(CONFIG_USB_KBD) += usbhid/
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* HID driver for some a4tech "special" devices
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/input.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "hid-ids.h"
|
||||
|
||||
#define A4_2WHEEL_MOUSE_HACK_7 0x01
|
||||
#define A4_2WHEEL_MOUSE_HACK_B8 0x02
|
||||
|
||||
struct a4tech_sc {
|
||||
unsigned long quirks;
|
||||
unsigned int hw_wheel;
|
||||
__s32 delayed_value;
|
||||
};
|
||||
|
||||
static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi,
|
||||
struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
struct a4tech_sc *a4 = hid_get_drvdata(hdev);
|
||||
|
||||
if (usage->type == EV_REL && usage->code == REL_WHEEL)
|
||||
set_bit(REL_HWHEEL, *bit);
|
||||
|
||||
if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int a4_event(struct hid_device *hdev, struct hid_field *field,
|
||||
struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
struct a4tech_sc *a4 = hid_get_drvdata(hdev);
|
||||
struct input_dev *input;
|
||||
|
||||
if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
|
||||
!usage->type)
|
||||
return 0;
|
||||
|
||||
input = field->hidinput->input;
|
||||
|
||||
if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) {
|
||||
if (usage->type == EV_REL && usage->code == REL_WHEEL) {
|
||||
a4->delayed_value = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usage->hid == 0x000100b8) {
|
||||
input_event(input, EV_REL, value ? REL_HWHEEL :
|
||||
REL_WHEEL, a4->delayed_value);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) {
|
||||
a4->hw_wheel = !!value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usage->code == REL_WHEEL && a4->hw_wheel) {
|
||||
input_event(input, usage->type, REL_HWHEEL, value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
struct a4tech_sc *a4;
|
||||
int ret;
|
||||
|
||||
a4 = kzalloc(sizeof(*a4), GFP_KERNEL);
|
||||
if (a4 == NULL) {
|
||||
dev_err(&hdev->dev, "can't alloc device descriptor\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
a4->quirks = id->driver_data;
|
||||
|
||||
hid_set_drvdata(hdev, a4);
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "parse failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_free:
|
||||
kfree(a4);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void a4_remove(struct hid_device *hdev)
|
||||
{
|
||||
struct a4tech_sc *a4 = hid_get_drvdata(hdev);
|
||||
|
||||
hid_hw_stop(hdev);
|
||||
kfree(a4);
|
||||
}
|
||||
|
||||
static const struct hid_device_id a4_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU),
|
||||
.driver_data = A4_2WHEEL_MOUSE_HACK_7 },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D),
|
||||
.driver_data = A4_2WHEEL_MOUSE_HACK_B8 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, a4_devices);
|
||||
|
||||
static struct hid_driver a4_driver = {
|
||||
.name = "a4tech",
|
||||
.id_table = a4_devices,
|
||||
.input_mapped = a4_input_mapped,
|
||||
.event = a4_event,
|
||||
.probe = a4_probe,
|
||||
.remove = a4_remove,
|
||||
};
|
||||
|
||||
static int a4_init(void)
|
||||
{
|
||||
return hid_register_driver(&a4_driver);
|
||||
}
|
||||
|
||||
static void a4_exit(void)
|
||||
{
|
||||
hid_unregister_driver(&a4_driver);
|
||||
}
|
||||
|
||||
module_init(a4_init);
|
||||
module_exit(a4_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
HID_COMPAT_LOAD_DRIVER(a4tech);
|
||||
@@ -0,0 +1,484 @@
|
||||
/*
|
||||
* 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;
|
||||
unsigned int connect_mask = HID_CONNECT_DEFAULT;
|
||||
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);
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "parse failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
if (quirks & APPLE_HIDDEV)
|
||||
connect_mask |= HID_CONNECT_HIDDEV_FORCE;
|
||||
if (quirks & APPLE_IGNORE_HIDINPUT)
|
||||
connect_mask &= ~HID_CONNECT_HIDINPUT;
|
||||
|
||||
ret = hid_hw_start(hdev, connect_mask);
|
||||
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_ATV_IRCONTROL),
|
||||
.driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT },
|
||||
{ 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 | APPLE_RDESC_JIS },
|
||||
{ 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 | APPLE_RDESC_JIS },
|
||||
{ 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 | APPLE_RDESC_JIS },
|
||||
{ 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 | APPLE_RDESC_JIS },
|
||||
{ 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");
|
||||
|
||||
HID_COMPAT_LOAD_DRIVER(apple);
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* HID driver for some belkin "special" devices
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 "hid-ids.h"
|
||||
|
||||
#define BELKIN_HIDDEV 0x01
|
||||
#define BELKIN_WKBD 0x02
|
||||
|
||||
#define belkin_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
|
||||
EV_KEY, (c))
|
||||
static int belkin_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER ||
|
||||
!(quirks & BELKIN_WKBD))
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x03a: belkin_map_key_clear(KEY_SOUND); break;
|
||||
case 0x03b: belkin_map_key_clear(KEY_CAMERA); break;
|
||||
case 0x03c: belkin_map_key_clear(KEY_DOCUMENTS); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
unsigned long quirks = id->driver_data;
|
||||
int ret;
|
||||
|
||||
hid_set_drvdata(hdev, (void *)quirks);
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "parse failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
|
||||
((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0));
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct hid_device_id belkin_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM),
|
||||
.driver_data = BELKIN_HIDDEV },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD),
|
||||
.driver_data = BELKIN_WKBD },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, belkin_devices);
|
||||
|
||||
static struct hid_driver belkin_driver = {
|
||||
.name = "belkin",
|
||||
.id_table = belkin_devices,
|
||||
.input_mapping = belkin_input_mapping,
|
||||
.probe = belkin_probe,
|
||||
};
|
||||
|
||||
static int belkin_init(void)
|
||||
{
|
||||
return hid_register_driver(&belkin_driver);
|
||||
}
|
||||
|
||||
static void belkin_exit(void)
|
||||
{
|
||||
hid_unregister_driver(&belkin_driver);
|
||||
}
|
||||
|
||||
module_init(belkin_init);
|
||||
module_exit(belkin_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
HID_COMPAT_LOAD_DRIVER(belkin);
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* HID driver for some bright "special" devices
|
||||
*
|
||||
* Copyright (c) 2008 Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
*
|
||||
* Based on hid-dell driver
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 "hid-ids.h"
|
||||
|
||||
static int bright_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "parse failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
usbhid_set_leds(hdev);
|
||||
|
||||
return 0;
|
||||
err_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct hid_device_id bright_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, bright_devices);
|
||||
|
||||
static struct hid_driver bright_driver = {
|
||||
.name = "bright",
|
||||
.id_table = bright_devices,
|
||||
.probe = bright_probe,
|
||||
};
|
||||
|
||||
static int bright_init(void)
|
||||
{
|
||||
return hid_register_driver(&bright_driver);
|
||||
}
|
||||
|
||||
static void bright_exit(void)
|
||||
{
|
||||
hid_unregister_driver(&bright_driver);
|
||||
}
|
||||
|
||||
module_init(bright_init);
|
||||
module_exit(bright_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
HID_COMPAT_LOAD_DRIVER(bright);
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* HID driver for some cherry "special" devices
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 "hid-ids.h"
|
||||
|
||||
/*
|
||||
* Cherry Cymotion keyboard have an invalid HID report descriptor,
|
||||
* that needs fixing before we can parse it.
|
||||
*/
|
||||
static void ch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int rsize)
|
||||
{
|
||||
if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
|
||||
dev_info(&hdev->dev, "fixing up Cherry Cymotion report "
|
||||
"descriptor\n");
|
||||
rdesc[11] = rdesc[16] = 0xff;
|
||||
rdesc[12] = rdesc[17] = 0x03;
|
||||
}
|
||||
}
|
||||
|
||||
#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
|
||||
EV_KEY, (c))
|
||||
static int ch_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_USAGE_PAGE) != HID_UP_CONSUMER)
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x301: ch_map_key_clear(KEY_PROG1); break;
|
||||
case 0x302: ch_map_key_clear(KEY_PROG2); break;
|
||||
case 0x303: ch_map_key_clear(KEY_PROG3); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct hid_device_id ch_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, ch_devices);
|
||||
|
||||
static struct hid_driver ch_driver = {
|
||||
.name = "cherry",
|
||||
.id_table = ch_devices,
|
||||
.report_fixup = ch_report_fixup,
|
||||
.input_mapping = ch_input_mapping,
|
||||
};
|
||||
|
||||
static int ch_init(void)
|
||||
{
|
||||
return hid_register_driver(&ch_driver);
|
||||
}
|
||||
|
||||
static void ch_exit(void)
|
||||
{
|
||||
hid_unregister_driver(&ch_driver);
|
||||
}
|
||||
|
||||
module_init(ch_init);
|
||||
module_exit(ch_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
HID_COMPAT_LOAD_DRIVER(cherry);
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* HID driver for some chicony "special" devices
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/input.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "hid-ids.h"
|
||||
|
||||
#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
|
||||
EV_KEY, (c))
|
||||
static int ch_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_USAGE_PAGE) != HID_UP_MSVENDOR)
|
||||
return 0;
|
||||
|
||||
set_bit(EV_REP, hi->input->evbit);
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0xff01: ch_map_key_clear(BTN_1); break;
|
||||
case 0xff02: ch_map_key_clear(BTN_2); break;
|
||||
case 0xff03: ch_map_key_clear(BTN_3); break;
|
||||
case 0xff04: ch_map_key_clear(BTN_4); break;
|
||||
case 0xff05: ch_map_key_clear(BTN_5); break;
|
||||
case 0xff06: ch_map_key_clear(BTN_6); break;
|
||||
case 0xff07: ch_map_key_clear(BTN_7); break;
|
||||
case 0xff08: ch_map_key_clear(BTN_8); break;
|
||||
case 0xff09: ch_map_key_clear(BTN_9); break;
|
||||
case 0xff0a: ch_map_key_clear(BTN_A); break;
|
||||
case 0xff0b: ch_map_key_clear(BTN_B); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct hid_device_id ch_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, ch_devices);
|
||||
|
||||
static struct hid_driver ch_driver = {
|
||||
.name = "chicony",
|
||||
.id_table = ch_devices,
|
||||
.input_mapping = ch_input_mapping,
|
||||
};
|
||||
|
||||
static int ch_init(void)
|
||||
{
|
||||
return hid_register_driver(&ch_driver);
|
||||
}
|
||||
|
||||
static void ch_exit(void)
|
||||
{
|
||||
hid_unregister_driver(&ch_driver);
|
||||
}
|
||||
|
||||
module_init(ch_init);
|
||||
module_exit(ch_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
HID_COMPAT_LOAD_DRIVER(chicony);
|
||||
+960
-265
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* HID driver for some cypress "special" devices
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/input.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "hid-ids.h"
|
||||
|
||||
#define CP_RDESC_SWAPPED_MIN_MAX 0x01
|
||||
#define CP_2WHEEL_MOUSE_HACK 0x02
|
||||
#define CP_2WHEEL_MOUSE_HACK_ON 0x04
|
||||
|
||||
/*
|
||||
* Some USB barcode readers from cypress have usage min and usage max in
|
||||
* the wrong order
|
||||
*/
|
||||
static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int rsize)
|
||||
{
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
unsigned int i;
|
||||
|
||||
if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX))
|
||||
return;
|
||||
|
||||
for (i = 0; i < rsize - 4; i++)
|
||||
if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) {
|
||||
__u8 tmp;
|
||||
|
||||
rdesc[i] = 0x19;
|
||||
rdesc[i + 2] = 0x29;
|
||||
tmp = rdesc[i + 3];
|
||||
rdesc[i + 3] = rdesc[i + 1];
|
||||
rdesc[i + 1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
|
||||
struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
|
||||
if (!(quirks & CP_2WHEEL_MOUSE_HACK))
|
||||
return 0;
|
||||
|
||||
if (usage->type == EV_REL && usage->code == REL_WHEEL)
|
||||
set_bit(REL_HWHEEL, *bit);
|
||||
if (usage->hid == 0x00090005)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cp_event(struct hid_device *hdev, struct hid_field *field,
|
||||
struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
|
||||
if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
|
||||
!usage->type || !(quirks & CP_2WHEEL_MOUSE_HACK))
|
||||
return 0;
|
||||
|
||||
if (usage->hid == 0x00090005) {
|
||||
if (value)
|
||||
quirks |= CP_2WHEEL_MOUSE_HACK_ON;
|
||||
else
|
||||
quirks &= ~CP_2WHEEL_MOUSE_HACK_ON;
|
||||
hid_set_drvdata(hdev, (void *)quirks);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (usage->code == REL_WHEEL && (quirks & CP_2WHEEL_MOUSE_HACK_ON)) {
|
||||
struct input_dev *input = field->hidinput->input;
|
||||
|
||||
input_event(input, usage->type, REL_HWHEEL, value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
unsigned long quirks = id->driver_data;
|
||||
int ret;
|
||||
|
||||
hid_set_drvdata(hdev, (void *)quirks);
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "parse failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct hid_device_id cp_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1),
|
||||
.driver_data = CP_RDESC_SWAPPED_MIN_MAX },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2),
|
||||
.driver_data = CP_RDESC_SWAPPED_MIN_MAX },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE),
|
||||
.driver_data = CP_2WHEEL_MOUSE_HACK },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, cp_devices);
|
||||
|
||||
static struct hid_driver cp_driver = {
|
||||
.name = "cypress",
|
||||
.id_table = cp_devices,
|
||||
.report_fixup = cp_report_fixup,
|
||||
.input_mapped = cp_input_mapped,
|
||||
.event = cp_event,
|
||||
.probe = cp_probe,
|
||||
};
|
||||
|
||||
static int cp_init(void)
|
||||
{
|
||||
return hid_register_driver(&cp_driver);
|
||||
}
|
||||
|
||||
static void cp_exit(void)
|
||||
{
|
||||
hid_unregister_driver(&cp_driver);
|
||||
}
|
||||
|
||||
module_init(cp_init);
|
||||
module_exit(cp_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
HID_COMPAT_LOAD_DRIVER(cypress);
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* HID driver for some dell "special" devices
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 "hid-ids.h"
|
||||
|
||||
static int dell_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "parse failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
usbhid_set_leds(hdev);
|
||||
|
||||
return 0;
|
||||
err_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct hid_device_id dell_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_SK8115) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, dell_devices);
|
||||
|
||||
static struct hid_driver dell_driver = {
|
||||
.name = "dell",
|
||||
.id_table = dell_devices,
|
||||
.probe = dell_probe,
|
||||
};
|
||||
|
||||
static int dell_init(void)
|
||||
{
|
||||
return hid_register_driver(&dell_driver);
|
||||
}
|
||||
|
||||
static void dell_exit(void)
|
||||
{
|
||||
hid_unregister_driver(&dell_driver);
|
||||
}
|
||||
|
||||
module_init(dell_init);
|
||||
module_exit(dell_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
HID_COMPAT_LOAD_DRIVER(dell);
|
||||
@@ -0,0 +1,72 @@
|
||||
#include <linux/autoconf.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/hid.h>
|
||||
|
||||
static int __init hid_dummy_init(void)
|
||||
{
|
||||
#ifdef CONFIG_HID_A4TECH_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(a4tech);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_APPLE_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(apple);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_BELKIN_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(belkin);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_BRIGHT_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(bright);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_CHERRY_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(cherry);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_CHICONY_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(chicony);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_CYPRESS_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(cypress);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_DELL_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(dell);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_EZKEY_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(ezkey);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_GYRATION_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(gyration);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_LOGITECH_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(logitech);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_MICROSOFT_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(microsoft);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_MONTEREY_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(monterey);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_PANTHERLORD_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(pantherlord);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_PETALYNX_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(petalynx);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_SAMSUNG_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(samsung);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_SONY_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(sony);
|
||||
#endif
|
||||
#ifdef CONFIG_HID_SUNPLUS_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(sunplus);
|
||||
#endif
|
||||
#ifdef CONFIG_THRUSTMASTER_FF_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(thrustmaster);
|
||||
#endif
|
||||
#ifdef CONFIG_ZEROPLUS_FF_MODULE
|
||||
HID_COMPAT_CALL_DRIVER(zeroplus);
|
||||
#endif
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
module_init(hid_dummy_init);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* HID driver for some ezkey "special" devices
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/input.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "hid-ids.h"
|
||||
|
||||
#define ez_map_rel(c) hid_map_usage(hi, usage, bit, max, EV_REL, (c))
|
||||
#define ez_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c))
|
||||
|
||||
static int ez_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_USAGE_PAGE) != HID_UP_CONSUMER)
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x230: ez_map_key(BTN_MOUSE); break;
|
||||
case 0x231: ez_map_rel(REL_WHEEL); break;
|
||||
/*
|
||||
* this keyboard has a scrollwheel implemented in
|
||||
* totally broken way. We map this usage temporarily
|
||||
* to HWHEEL and handle it in the event quirk handler
|
||||
*/
|
||||
case 0x232: ez_map_rel(REL_HWHEEL); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ez_event(struct hid_device *hdev, struct hid_field *field,
|
||||
struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
|
||||
!usage->type)
|
||||
return 0;
|
||||
|
||||
/* handle the temporary quirky mapping to HWHEEL */
|
||||
if (usage->type == EV_REL && usage->code == REL_HWHEEL) {
|
||||
struct input_dev *input = field->hidinput->input;
|
||||
input_event(input, usage->type, REL_WHEEL, -value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hid_device_id ez_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, ez_devices);
|
||||
|
||||
static struct hid_driver ez_driver = {
|
||||
.name = "ezkey",
|
||||
.id_table = ez_devices,
|
||||
.input_mapping = ez_input_mapping,
|
||||
.event = ez_event,
|
||||
};
|
||||
|
||||
static int ez_init(void)
|
||||
{
|
||||
return hid_register_driver(&ez_driver);
|
||||
}
|
||||
|
||||
static void ez_exit(void)
|
||||
{
|
||||
hid_unregister_driver(&ez_driver);
|
||||
}
|
||||
|
||||
module_init(ez_init);
|
||||
module_exit(ez_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
HID_COMPAT_LOAD_DRIVER(ezkey);
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* HID driver for some gyration "special" devices
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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/input.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "hid-ids.h"
|
||||
|
||||
#define gy_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
|
||||
EV_KEY, (c))
|
||||
static int gyration_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_USAGE_PAGE) != HID_UP_LOGIVENDOR)
|
||||
return 0;
|
||||
|
||||
set_bit(EV_REP, hi->input->evbit);
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
/* Reported on Gyration MCE Remote */
|
||||
case 0x00d: gy_map_key_clear(KEY_HOME); break;
|
||||
case 0x024: gy_map_key_clear(KEY_DVD); break;
|
||||
case 0x025: gy_map_key_clear(KEY_PVR); break;
|
||||
case 0x046: gy_map_key_clear(KEY_MEDIA); break;
|
||||
case 0x047: gy_map_key_clear(KEY_MP3); break;
|
||||
case 0x049: gy_map_key_clear(KEY_CAMERA); break;
|
||||
case 0x04a: gy_map_key_clear(KEY_VIDEO); break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gyration_event(struct hid_device *hdev, struct hid_field *field,
|
||||
struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
struct input_dev *input = field->hidinput->input;
|
||||
|
||||
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK &&
|
||||
(usage->hid & 0xff) == 0x82) {
|
||||
input_event(input, usage->type, usage->code, 1);
|
||||
input_sync(input);
|
||||
input_event(input, usage->type, usage->code, 0);
|
||||
input_sync(input);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hid_device_id gyration_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, gyration_devices);
|
||||
|
||||
static struct hid_driver gyration_driver = {
|
||||
.name = "gyration",
|
||||
.id_table = gyration_devices,
|
||||
.input_mapping = gyration_input_mapping,
|
||||
.event = gyration_event,
|
||||
};
|
||||
|
||||
static int gyration_init(void)
|
||||
{
|
||||
return hid_register_driver(&gyration_driver);
|
||||
}
|
||||
|
||||
static void gyration_exit(void)
|
||||
{
|
||||
hid_unregister_driver(&gyration_driver);
|
||||
}
|
||||
|
||||
module_init(gyration_init);
|
||||
module_exit(gyration_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
HID_COMPAT_LOAD_DRIVER(gyration);
|
||||
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef HID_IDS_H_FILE
|
||||
#define HID_IDS_H_FILE
|
||||
|
||||
#define USB_VENDOR_ID_A4TECH 0x09da
|
||||
#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006
|
||||
#define USB_DEVICE_ID_A4TECH_X5_005D 0x000a
|
||||
|
||||
#define USB_VENDOR_ID_AASHIMA 0x06d6
|
||||
#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025
|
||||
#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026
|
||||
|
||||
#define USB_VENDOR_ID_ACECAD 0x0460
|
||||
#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004
|
||||
#define USB_DEVICE_ID_ACECAD_302 0x0008
|
||||
|
||||
#define USB_VENDOR_ID_ADS_TECH 0x06e1
|
||||
#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155
|
||||
|
||||
#define USB_VENDOR_ID_AFATECH 0x15a4
|
||||
#define USB_DEVICE_ID_AFATECH_AF9016 0x9016
|
||||
|
||||
#define USB_VENDOR_ID_AIPTEK 0x08ca
|
||||
#define USB_DEVICE_ID_AIPTEK_01 0x0001
|
||||
#define USB_DEVICE_ID_AIPTEK_10 0x0010
|
||||
#define USB_DEVICE_ID_AIPTEK_20 0x0020
|
||||
#define USB_DEVICE_ID_AIPTEK_21 0x0021
|
||||
#define USB_DEVICE_ID_AIPTEK_22 0x0022
|
||||
#define USB_DEVICE_ID_AIPTEK_23 0x0023
|
||||
#define USB_DEVICE_ID_AIPTEK_24 0x0024
|
||||
|
||||
#define USB_VENDOR_ID_AIRCABLE 0x16CA
|
||||
#define USB_DEVICE_ID_AIRCABLE1 0x1502
|
||||
|
||||
#define USB_VENDOR_ID_ALCOR 0x058f
|
||||
#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720
|
||||
|
||||
#define USB_VENDOR_ID_ALPS 0x0433
|
||||
#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101
|
||||
|
||||
#define USB_VENDOR_ID_APPLE 0x05ac
|
||||
#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
|
||||
#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
|
||||
#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
|
||||
#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220
|
||||
#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221
|
||||
#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
|
||||
#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
|
||||
#define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241
|
||||
#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242
|
||||
|
||||
#define USB_VENDOR_ID_ASUS 0x0b05
|
||||
#define USB_DEVICE_ID_ASUS_LCM 0x1726
|
||||
|
||||
#define USB_VENDOR_ID_ATEN 0x0557
|
||||
#define USB_DEVICE_ID_ATEN_UC100KM 0x2004
|
||||
#define USB_DEVICE_ID_ATEN_CS124U 0x2202
|
||||
#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204
|
||||
#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205
|
||||
#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208
|
||||
|
||||
#define USB_VENDOR_ID_AVERMEDIA 0x07ca
|
||||
#define USB_DEVICE_ID_AVER_FM_MR800 0xb800
|
||||
|
||||
#define USB_VENDOR_ID_BELKIN 0x050d
|
||||
#define USB_DEVICE_ID_FLIP_KVM 0x3201
|
||||
|
||||
#define USB_VENDOR_ID_BRIGHT 0x1241
|
||||
#define USB_DEVICE_ID_BRIGHT_ABNT2 0x1503
|
||||
|
||||
#define USB_VENDOR_ID_BERKSHIRE 0x0c98
|
||||
#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
|
||||
|
||||
#define USB_VENDOR_ID_CHERRY 0x046a
|
||||
#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
|
||||
|
||||
#define USB_VENDOR_ID_CHIC 0x05fe
|
||||
#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014
|
||||
|
||||
#define USB_VENDOR_ID_CHICONY 0x04f2
|
||||
#define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418
|
||||
|
||||
#define USB_VENDOR_ID_CIDC 0x1677
|
||||
|
||||
#define USB_VENDOR_ID_CMEDIA 0x0d8c
|
||||
#define USB_DEVICE_ID_CM109 0x000e
|
||||
|
||||
#define USB_VENDOR_ID_CODEMERCS 0x07c0
|
||||
#define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500
|
||||
#define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff
|
||||
|
||||
#define USB_VENDOR_ID_CYGNAL 0x10c4
|
||||
#define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a
|
||||
|
||||
#define USB_VENDOR_ID_CYPRESS 0x04b4
|
||||
#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
|
||||
#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
|
||||
#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417
|
||||
#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61
|
||||
#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64
|
||||
|
||||
#define USB_VENDOR_ID_DELL 0x413c
|
||||
#define USB_DEVICE_ID_DELL_W7658 0x2005
|
||||
#define USB_DEVICE_ID_DELL_SK8115 0x2105
|
||||
|
||||
#define USB_VENDOR_ID_DELORME 0x1163
|
||||
#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
|
||||
#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200
|
||||
|
||||
#define USB_VENDOR_ID_DMI 0x0c0b
|
||||
#define USB_DEVICE_ID_DMI_ENC 0x5fab
|
||||
|
||||
#define USB_VENDOR_ID_ELO 0x04E7
|
||||
#define USB_DEVICE_ID_ELO_TS2700 0x0020
|
||||
|
||||
#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
|
||||
#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
|
||||
|
||||
#define USB_VENDOR_ID_EZKEY 0x0518
|
||||
#define USB_DEVICE_ID_BTC_8193 0x0002
|
||||
|
||||
#define USB_VENDOR_ID_GAMERON 0x0810
|
||||
#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001
|
||||
|
||||
#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc
|
||||
|
||||
#define USB_VENDOR_ID_GLAB 0x06c2
|
||||
#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038
|
||||
#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039
|
||||
#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040
|
||||
#define USB_DEVICE_ID_0_16_16_IF_KIT 0x0044
|
||||
#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045
|
||||
#define USB_DEVICE_ID_0_8_7_IF_KIT 0x0051
|
||||
#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053
|
||||
#define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058
|
||||
|
||||
#define USB_VENDOR_ID_GOTOP 0x08f2
|
||||
#define USB_DEVICE_ID_SUPER_Q2 0x007f
|
||||
#define USB_DEVICE_ID_GOGOPEN 0x00ce
|
||||
#define USB_DEVICE_ID_PENPOWER 0x00f4
|
||||
|
||||
#define USB_VENDOR_ID_GREENASIA 0x0e8f
|
||||
|
||||
#define USB_VENDOR_ID_GRETAGMACBETH 0x0971
|
||||
#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005
|
||||
|
||||
#define USB_VENDOR_ID_GRIFFIN 0x077d
|
||||
#define USB_DEVICE_ID_POWERMATE 0x0410
|
||||
#define USB_DEVICE_ID_SOUNDKNOB 0x04AA
|
||||
|
||||
#define USB_VENDOR_ID_GTCO 0x078c
|
||||
#define USB_DEVICE_ID_GTCO_90 0x0090
|
||||
#define USB_DEVICE_ID_GTCO_100 0x0100
|
||||
#define USB_DEVICE_ID_GTCO_101 0x0101
|
||||
#define USB_DEVICE_ID_GTCO_103 0x0103
|
||||
#define USB_DEVICE_ID_GTCO_104 0x0104
|
||||
#define USB_DEVICE_ID_GTCO_105 0x0105
|
||||
#define USB_DEVICE_ID_GTCO_106 0x0106
|
||||
#define USB_DEVICE_ID_GTCO_107 0x0107
|
||||
#define USB_DEVICE_ID_GTCO_108 0x0108
|
||||
#define USB_DEVICE_ID_GTCO_200 0x0200
|
||||
#define USB_DEVICE_ID_GTCO_201 0x0201
|
||||
#define USB_DEVICE_ID_GTCO_202 0x0202
|
||||
#define USB_DEVICE_ID_GTCO_203 0x0203
|
||||
#define USB_DEVICE_ID_GTCO_204 0x0204
|
||||
#define USB_DEVICE_ID_GTCO_205 0x0205
|
||||
#define USB_DEVICE_ID_GTCO_206 0x0206
|
||||
#define USB_DEVICE_ID_GTCO_207 0x0207
|
||||
#define USB_DEVICE_ID_GTCO_300 0x0300
|
||||
#define USB_DEVICE_ID_GTCO_301 0x0301
|
||||
#define USB_DEVICE_ID_GTCO_302 0x0302
|
||||
#define USB_DEVICE_ID_GTCO_303 0x0303
|
||||
#define USB_DEVICE_ID_GTCO_304 0x0304
|
||||
#define USB_DEVICE_ID_GTCO_305 0x0305
|
||||
#define USB_DEVICE_ID_GTCO_306 0x0306
|
||||
#define USB_DEVICE_ID_GTCO_307 0x0307
|
||||
#define USB_DEVICE_ID_GTCO_308 0x0308
|
||||
#define USB_DEVICE_ID_GTCO_309 0x0309
|
||||
#define USB_DEVICE_ID_GTCO_400 0x0400
|
||||
#define USB_DEVICE_ID_GTCO_401 0x0401
|
||||
#define USB_DEVICE_ID_GTCO_402 0x0402
|
||||
#define USB_DEVICE_ID_GTCO_403 0x0403
|
||||
#define USB_DEVICE_ID_GTCO_404 0x0404
|
||||
#define USB_DEVICE_ID_GTCO_405 0x0405
|
||||
#define USB_DEVICE_ID_GTCO_500 0x0500
|
||||
#define USB_DEVICE_ID_GTCO_501 0x0501
|
||||
#define USB_DEVICE_ID_GTCO_502 0x0502
|
||||
#define USB_DEVICE_ID_GTCO_503 0x0503
|
||||
#define USB_DEVICE_ID_GTCO_504 0x0504
|
||||
#define USB_DEVICE_ID_GTCO_1000 0x1000
|
||||
#define USB_DEVICE_ID_GTCO_1001 0x1001
|
||||
#define USB_DEVICE_ID_GTCO_1002 0x1002
|
||||
#define USB_DEVICE_ID_GTCO_1003 0x1003
|
||||
#define USB_DEVICE_ID_GTCO_1004 0x1004
|
||||
#define USB_DEVICE_ID_GTCO_1005 0x1005
|
||||
#define USB_DEVICE_ID_GTCO_1006 0x1006
|
||||
#define USB_DEVICE_ID_GTCO_1007 0x1007
|
||||
|
||||
#define USB_VENDOR_ID_GYRATION 0x0c16
|
||||
#define USB_DEVICE_ID_GYRATION_REMOTE 0x0002
|
||||
|
||||
#define USB_VENDOR_ID_HAPP 0x078b
|
||||
#define USB_DEVICE_ID_UGCI_DRIVING 0x0010
|
||||
#define USB_DEVICE_ID_UGCI_FLYING 0x0020
|
||||
#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030
|
||||
|
||||
#define USB_VENDOR_ID_IMATION 0x0718
|
||||
#define USB_DEVICE_ID_DISC_STAKKA 0xd000
|
||||
|
||||
#define USB_VENDOR_ID_KBGEAR 0x084e
|
||||
#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
|
||||
|
||||
#define USB_VENDOR_ID_LABTEC 0x1020
|
||||
#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
|
||||
|
||||
#define USB_VENDOR_ID_LD 0x0f11
|
||||
#define USB_DEVICE_ID_LD_CASSY 0x1000
|
||||
#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010
|
||||
#define USB_DEVICE_ID_LD_MOBILECASSY 0x1020
|
||||
#define USB_DEVICE_ID_LD_JWM 0x1080
|
||||
#define USB_DEVICE_ID_LD_DMMP 0x1081
|
||||
#define USB_DEVICE_ID_LD_UMIP 0x1090
|
||||
#define USB_DEVICE_ID_LD_XRAY1 0x1100
|
||||
#define USB_DEVICE_ID_LD_XRAY2 0x1101
|
||||
#define USB_DEVICE_ID_LD_VIDEOCOM 0x1200
|
||||
#define USB_DEVICE_ID_LD_COM3LAB 0x2000
|
||||
#define USB_DEVICE_ID_LD_TELEPORT 0x2010
|
||||
#define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020
|
||||
#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
|
||||
#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
|
||||
|
||||
#define USB_VENDOR_ID_LOGITECH 0x046d
|
||||
#define USB_DEVICE_ID_LOGITECH_LX3 0xc044
|
||||
#define USB_DEVICE_ID_LOGITECH_V150 0xc047
|
||||
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
|
||||
#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
|
||||
#define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
|
||||
#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211
|
||||
#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215
|
||||
#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218
|
||||
#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219
|
||||
#define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283
|
||||
#define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286
|
||||
#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
|
||||
#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295
|
||||
#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a
|
||||
#define USB_DEVICE_ID_LOGITECH_KBD 0xc311
|
||||
#define USB_DEVICE_ID_S510_RECEIVER 0xc50c
|
||||
#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
|
||||
#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
|
||||
#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
|
||||
#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704
|
||||
#define USB_DEVICE_ID_DINOVO_EDGE 0xc714
|
||||
#define USB_DEVICE_ID_DINOVO_MINI 0xc71f
|
||||
#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03
|
||||
|
||||
#define USB_VENDOR_ID_MCC 0x09db
|
||||
#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
|
||||
#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a
|
||||
|
||||
#define USB_VENDOR_ID_MGE 0x0463
|
||||
#define USB_DEVICE_ID_MGE_UPS 0xffff
|
||||
#define USB_DEVICE_ID_MGE_UPS1 0x0001
|
||||
|
||||
#define USB_VENDOR_ID_MICROCHIP 0x04d8
|
||||
#define USB_DEVICE_ID_PICKIT1 0x0032
|
||||
#define USB_DEVICE_ID_PICKIT2 0x0033
|
||||
|
||||
#define USB_VENDOR_ID_MICROSOFT 0x045e
|
||||
#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
|
||||
#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d
|
||||
#define USB_DEVICE_ID_MS_NE4K 0x00db
|
||||
#define USB_DEVICE_ID_MS_LK6K 0x00f9
|
||||
#define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701
|
||||
#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
|
||||
|
||||
|
||||
#define USB_VENDOR_ID_MONTEREY 0x0566
|
||||
#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
|
||||
|
||||
#define USB_VENDOR_ID_NCR 0x0404
|
||||
#define USB_DEVICE_ID_NCR_FIRST 0x0300
|
||||
#define USB_DEVICE_ID_NCR_LAST 0x03ff
|
||||
|
||||
#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
|
||||
#define USB_DEVICE_ID_N_S_HARMONY 0xc359
|
||||
|
||||
#define USB_VENDOR_ID_NATSU 0x08b7
|
||||
#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
|
||||
|
||||
#define USB_VENDOR_ID_NEC 0x073e
|
||||
#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
|
||||
|
||||
#define USB_VENDOR_ID_ONTRAK 0x0a07
|
||||
#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
|
||||
|
||||
#define USB_VENDOR_ID_PANJIT 0x134c
|
||||
|
||||
#define USB_VENDOR_ID_PANTHERLORD 0x0810
|
||||
#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001
|
||||
|
||||
#define USB_VENDOR_ID_PETALYNX 0x18b1
|
||||
#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
|
||||
|
||||
#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
|
||||
#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
|
||||
|
||||
#define USB_VENDOR_ID_SAITEK 0x06a3
|
||||
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
|
||||
|
||||
#define USB_VENDOR_ID_SAMSUNG 0x0419
|
||||
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
|
||||
|
||||
#define USB_VENDOR_ID_SONY 0x054c
|
||||
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
|
||||
|
||||
#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
|
||||
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038
|
||||
|
||||
#define USB_VENDOR_ID_SUN 0x0430
|
||||
#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
|
||||
|
||||
#define USB_VENDOR_ID_SUNPLUS 0x04fc
|
||||
#define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8
|
||||
|
||||
#define USB_VENDOR_ID_TENX 0x1130
|
||||
#define USB_DEVICE_ID_TENX_IBUDDY1 0x0001
|
||||
#define USB_DEVICE_ID_TENX_IBUDDY2 0x0002
|
||||
|
||||
#define USB_VENDOR_ID_THRUSTMASTER 0x044f
|
||||
|
||||
#define USB_VENDOR_ID_TOPMAX 0x0663
|
||||
#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
|
||||
|
||||
#define USB_VENDOR_ID_TURBOX 0x062a
|
||||
#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
|
||||
|
||||
#define USB_VENDOR_ID_VERNIER 0x08f7
|
||||
#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
|
||||
#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
|
||||
#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
|
||||
#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
|
||||
#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006
|
||||
|
||||
#define USB_VENDOR_ID_WACOM 0x056a
|
||||
|
||||
#define USB_VENDOR_ID_WISEGROUP 0x0925
|
||||
#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101
|
||||
#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104
|
||||
#define USB_DEVICE_ID_8_8_4_IF_KIT 0x8201
|
||||
#define USB_DEVICE_ID_QUAD_USB_JOYPAD 0x8800
|
||||
#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866
|
||||
|
||||
#define USB_VENDOR_ID_WISEGROUP_LTD 0x6666
|
||||
#define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677
|
||||
#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
|
||||
|
||||
#define USB_VENDOR_ID_YEALINK 0x6993
|
||||
#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001
|
||||
|
||||
#define USB_VENDOR_ID_ZEROPLUS 0x0c12
|
||||
|
||||
#define USB_VENDOR_ID_KYE 0x0458
|
||||
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
|
||||
|
||||
#endif
|
||||
@@ -1,484 +0,0 @@
|
||||
/*
|
||||
* HID-input usage mapping quirks
|
||||
*
|
||||
* This is used to handle HID-input mappings for devices violating
|
||||
* HUT 1.12 specification.
|
||||
*
|
||||
* Copyright (c) 2007-2008 Jiri Kosina
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <linux/hid.h>
|
||||
|
||||
#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; *bit = input->absbit; *max = ABS_MAX; } while (0)
|
||||
#define map_rel(c) do { usage->code = c; usage->type = EV_REL; *bit = input->relbit; *max = REL_MAX; } while (0)
|
||||
#define map_key(c) do { usage->code = c; usage->type = EV_KEY; *bit = input->keybit; *max = KEY_MAX; } while (0)
|
||||
#define map_led(c) do { usage->code = c; usage->type = EV_LED; *bit = input->ledbit; *max = LED_MAX; } 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)
|
||||
|
||||
static int quirk_belkin_wkbd(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x03a: map_key_clear(KEY_SOUND); break;
|
||||
case 0x03b: map_key_clear(KEY_CAMERA); break;
|
||||
case 0x03c: map_key_clear(KEY_DOCUMENTS); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quirk_cherry_cymotion(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x301: map_key_clear(KEY_PROG1); break;
|
||||
case 0x302: map_key_clear(KEY_PROG2); break;
|
||||
case 0x303: map_key_clear(KEY_PROG3); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
|
||||
return 0;
|
||||
|
||||
set_bit(EV_REP, input->evbit);
|
||||
switch(usage->hid & HID_USAGE) {
|
||||
/* Reported on Logitech Ultra X Media Remote */
|
||||
case 0x004: map_key_clear(KEY_AGAIN); break;
|
||||
case 0x00d: map_key_clear(KEY_HOME); break;
|
||||
case 0x024: map_key_clear(KEY_SHUFFLE); break;
|
||||
case 0x025: map_key_clear(KEY_TV); break;
|
||||
case 0x026: map_key_clear(KEY_MENU); break;
|
||||
case 0x031: map_key_clear(KEY_AUDIO); break;
|
||||
case 0x032: map_key_clear(KEY_TEXT); break;
|
||||
case 0x033: map_key_clear(KEY_LAST); break;
|
||||
case 0x047: map_key_clear(KEY_MP3); break;
|
||||
case 0x048: map_key_clear(KEY_DVD); break;
|
||||
case 0x049: map_key_clear(KEY_MEDIA); break;
|
||||
case 0x04a: map_key_clear(KEY_VIDEO); break;
|
||||
case 0x04b: map_key_clear(KEY_ANGLE); break;
|
||||
case 0x04c: map_key_clear(KEY_LANGUAGE); break;
|
||||
case 0x04d: map_key_clear(KEY_SUBTITLE); break;
|
||||
case 0x051: map_key_clear(KEY_RED); break;
|
||||
case 0x052: map_key_clear(KEY_CLOSE); break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quirk_gyration_remote(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
|
||||
return 0;
|
||||
|
||||
set_bit(EV_REP, input->evbit);
|
||||
switch(usage->hid & HID_USAGE) {
|
||||
/* Reported on Gyration MCE Remote */
|
||||
case 0x00d: map_key_clear(KEY_HOME); break;
|
||||
case 0x024: map_key_clear(KEY_DVD); break;
|
||||
case 0x025: map_key_clear(KEY_PVR); break;
|
||||
case 0x046: map_key_clear(KEY_MEDIA); break;
|
||||
case 0x047: map_key_clear(KEY_MP3); break;
|
||||
case 0x049: map_key_clear(KEY_CAMERA); break;
|
||||
case 0x04a: map_key_clear(KEY_VIDEO); break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
|
||||
return 0;
|
||||
|
||||
set_bit(EV_REP, input->evbit);
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0xff01: map_key_clear(BTN_1); break;
|
||||
case 0xff02: map_key_clear(BTN_2); break;
|
||||
case 0xff03: map_key_clear(BTN_3); break;
|
||||
case 0xff04: map_key_clear(BTN_4); break;
|
||||
case 0xff05: map_key_clear(BTN_5); break;
|
||||
case 0xff06: map_key_clear(BTN_6); break;
|
||||
case 0xff07: map_key_clear(BTN_7); break;
|
||||
case 0xff08: map_key_clear(BTN_8); break;
|
||||
case 0xff09: map_key_clear(BTN_9); break;
|
||||
case 0xff0a: map_key_clear(BTN_A); break;
|
||||
case 0xff0b: map_key_clear(BTN_B); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quirk_microsoft_ergonomy_kb(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
|
||||
return 0;
|
||||
|
||||
switch(usage->hid & HID_USAGE) {
|
||||
case 0xfd06: map_key_clear(KEY_CHAT); break;
|
||||
case 0xfd07: map_key_clear(KEY_PHONE); break;
|
||||
case 0xff05:
|
||||
set_bit(EV_REP, input->evbit);
|
||||
map_key_clear(KEY_F13);
|
||||
set_bit(KEY_F14, input->keybit);
|
||||
set_bit(KEY_F15, input->keybit);
|
||||
set_bit(KEY_F16, input->keybit);
|
||||
set_bit(KEY_F17, input->keybit);
|
||||
set_bit(KEY_F18, input->keybit);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quirk_microsoft_presenter_8k(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
|
||||
return 0;
|
||||
|
||||
set_bit(EV_REP, input->evbit);
|
||||
switch(usage->hid & HID_USAGE) {
|
||||
case 0xfd08: map_key_clear(KEY_FORWARD); break;
|
||||
case 0xfd09: map_key_clear(KEY_BACK); break;
|
||||
case 0xfd0b: map_key_clear(KEY_PLAYPAUSE); break;
|
||||
case 0xfd0e: map_key_clear(KEY_CLOSE); break;
|
||||
case 0xfd0f: map_key_clear(KEY_PLAY); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quirk_petalynx_remote(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if (((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) &&
|
||||
((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER))
|
||||
return 0;
|
||||
|
||||
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR)
|
||||
switch(usage->hid & HID_USAGE) {
|
||||
case 0x05a: map_key_clear(KEY_TEXT); break;
|
||||
case 0x05b: map_key_clear(KEY_RED); break;
|
||||
case 0x05c: map_key_clear(KEY_GREEN); break;
|
||||
case 0x05d: map_key_clear(KEY_YELLOW); break;
|
||||
case 0x05e: map_key_clear(KEY_BLUE); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
|
||||
switch(usage->hid & HID_USAGE) {
|
||||
case 0x0f6: map_key_clear(KEY_NEXT); break;
|
||||
case 0x0fa: map_key_clear(KEY_BACK); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quirk_logitech_wireless(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x1001: map_key_clear(KEY_MESSENGER); break;
|
||||
case 0x1003: map_key_clear(KEY_SOUND); break;
|
||||
case 0x1004: map_key_clear(KEY_VIDEO); break;
|
||||
case 0x1005: map_key_clear(KEY_AUDIO); break;
|
||||
case 0x100a: map_key_clear(KEY_DOCUMENTS); break;
|
||||
case 0x1011: map_key_clear(KEY_PREVIOUSSONG); break;
|
||||
case 0x1012: map_key_clear(KEY_NEXTSONG); break;
|
||||
case 0x1013: map_key_clear(KEY_CAMERA); break;
|
||||
case 0x1014: map_key_clear(KEY_MESSENGER); break;
|
||||
case 0x1015: map_key_clear(KEY_RECORD); break;
|
||||
case 0x1016: map_key_clear(KEY_PLAYER); break;
|
||||
case 0x1017: map_key_clear(KEY_EJECTCD); break;
|
||||
case 0x1018: map_key_clear(KEY_MEDIA); break;
|
||||
case 0x1019: map_key_clear(KEY_PROG1); break;
|
||||
case 0x101a: map_key_clear(KEY_PROG2); break;
|
||||
case 0x101b: map_key_clear(KEY_PROG3); break;
|
||||
case 0x101f: map_key_clear(KEY_ZOOMIN); break;
|
||||
case 0x1020: map_key_clear(KEY_ZOOMOUT); break;
|
||||
case 0x1021: map_key_clear(KEY_ZOOMRESET); break;
|
||||
case 0x1023: map_key_clear(KEY_CLOSE); break;
|
||||
case 0x1027: map_key_clear(KEY_MENU); break;
|
||||
/* this one is marked as 'Rotate' */
|
||||
case 0x1028: map_key_clear(KEY_ANGLE); break;
|
||||
case 0x1029: map_key_clear(KEY_SHUFFLE); break;
|
||||
case 0x102a: map_key_clear(KEY_BACK); break;
|
||||
case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break;
|
||||
case 0x1041: map_key_clear(KEY_BATTERY); break;
|
||||
case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break;
|
||||
case 0x1043: map_key_clear(KEY_SPREADSHEET); break;
|
||||
case 0x1044: map_key_clear(KEY_PRESENTATION); break;
|
||||
case 0x1045: map_key_clear(KEY_UNDO); break;
|
||||
case 0x1046: map_key_clear(KEY_REDO); break;
|
||||
case 0x1047: map_key_clear(KEY_PRINT); break;
|
||||
case 0x1048: map_key_clear(KEY_SAVE); break;
|
||||
case 0x1049: map_key_clear(KEY_PROG1); break;
|
||||
case 0x104a: map_key_clear(KEY_PROG2); break;
|
||||
case 0x104b: map_key_clear(KEY_PROG3); break;
|
||||
case 0x104c: map_key_clear(KEY_PROG4); break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quirk_cherry_genius_29e(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x156: map_key_clear(KEY_WORDPROCESSOR); break;
|
||||
case 0x157: map_key_clear(KEY_SPREADSHEET); break;
|
||||
case 0x158: map_key_clear(KEY_PRESENTATION); break;
|
||||
case 0x15c: map_key_clear(KEY_STOP); break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x230: map_key(BTN_MOUSE); break;
|
||||
case 0x231: map_rel(REL_WHEEL); break;
|
||||
/*
|
||||
* this keyboard has a scrollwheel implemented in
|
||||
* totally broken way. We map this usage temporarily
|
||||
* to HWHEEL and handle it in the event quirk handler
|
||||
*/
|
||||
case 0x232: map_rel(REL_HWHEEL); break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quirk_sunplus_wdesktop(struct hid_usage *usage, struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x2003: map_key_clear(KEY_ZOOMIN); break;
|
||||
case 0x2103: map_key_clear(KEY_ZOOMOUT); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define VENDOR_ID_BELKIN 0x1020
|
||||
#define DEVICE_ID_BELKIN_WIRELESS_KEYBOARD 0x0006
|
||||
|
||||
#define VENDOR_ID_CHERRY 0x046a
|
||||
#define DEVICE_ID_CHERRY_CYMOTION 0x0023
|
||||
|
||||
#define VENDOR_ID_CHICONY 0x04f2
|
||||
#define DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418
|
||||
|
||||
#define VENDOR_ID_EZKEY 0x0518
|
||||
#define DEVICE_ID_BTC_8193 0x0002
|
||||
|
||||
#define VENDOR_ID_GYRATION 0x0c16
|
||||
#define DEVICE_ID_GYRATION_REMOTE 0x0002
|
||||
|
||||
#define VENDOR_ID_LOGITECH 0x046d
|
||||
#define DEVICE_ID_LOGITECH_RECEIVER 0xc101
|
||||
#define DEVICE_ID_S510_RECEIVER 0xc50c
|
||||
#define DEVICE_ID_S510_RECEIVER_2 0xc517
|
||||
#define DEVICE_ID_MX3000_RECEIVER 0xc513
|
||||
|
||||
#define VENDOR_ID_MICROSOFT 0x045e
|
||||
#define DEVICE_ID_MS4K 0x00db
|
||||
#define DEVICE_ID_MS6K 0x00f9
|
||||
#define DEVICE_IS_MS_PRESENTER_8K_BT 0x0701
|
||||
#define DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
|
||||
|
||||
#define VENDOR_ID_MONTEREY 0x0566
|
||||
#define DEVICE_ID_GENIUS_KB29E 0x3004
|
||||
|
||||
#define VENDOR_ID_PETALYNX 0x18b1
|
||||
#define DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
|
||||
|
||||
#define VENDOR_ID_SUNPLUS 0x04fc
|
||||
#define DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8
|
||||
|
||||
static const struct hid_input_blacklist {
|
||||
__u16 idVendor;
|
||||
__u16 idProduct;
|
||||
int (*quirk)(struct hid_usage *, struct input_dev *, unsigned long **, int *);
|
||||
} hid_input_blacklist[] = {
|
||||
{ VENDOR_ID_BELKIN, DEVICE_ID_BELKIN_WIRELESS_KEYBOARD, quirk_belkin_wkbd },
|
||||
|
||||
{ VENDOR_ID_CHERRY, DEVICE_ID_CHERRY_CYMOTION, quirk_cherry_cymotion },
|
||||
|
||||
{ VENDOR_ID_CHICONY, DEVICE_ID_CHICONY_TACTICAL_PAD, quirk_chicony_tactical_pad },
|
||||
|
||||
{ VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 },
|
||||
|
||||
{ VENDOR_ID_GYRATION, DEVICE_ID_GYRATION_REMOTE, quirk_gyration_remote },
|
||||
|
||||
{ VENDOR_ID_LOGITECH, DEVICE_ID_LOGITECH_RECEIVER, quirk_logitech_ultrax_remote },
|
||||
{ VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER, quirk_logitech_wireless },
|
||||
{ VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER_2, quirk_logitech_wireless },
|
||||
{ VENDOR_ID_LOGITECH, DEVICE_ID_MX3000_RECEIVER, quirk_logitech_wireless },
|
||||
|
||||
{ VENDOR_ID_MICROSOFT, DEVICE_ID_MS4K, quirk_microsoft_ergonomy_kb },
|
||||
{ VENDOR_ID_MICROSOFT, DEVICE_ID_MS6K, quirk_microsoft_ergonomy_kb },
|
||||
{ VENDOR_ID_MICROSOFT, DEVICE_IS_MS_PRESENTER_8K_BT, quirk_microsoft_presenter_8k },
|
||||
{ VENDOR_ID_MICROSOFT, DEVICE_ID_MS_PRESENTER_8K_USB, quirk_microsoft_presenter_8k },
|
||||
|
||||
{ VENDOR_ID_MONTEREY, DEVICE_ID_GENIUS_KB29E, quirk_cherry_genius_29e },
|
||||
|
||||
{ VENDOR_ID_PETALYNX, DEVICE_ID_PETALYNX_MAXTER_REMOTE, quirk_petalynx_remote },
|
||||
|
||||
{ VENDOR_ID_SUNPLUS, DEVICE_ID_SUNPLUS_WDESKTOP, quirk_sunplus_wdesktop },
|
||||
|
||||
{ 0, 0, NULL }
|
||||
};
|
||||
|
||||
int hidinput_mapping_quirks(struct hid_usage *usage,
|
||||
struct input_dev *input,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
struct hid_device *device = input_get_drvdata(input);
|
||||
int i = 0;
|
||||
|
||||
while (hid_input_blacklist[i].quirk) {
|
||||
if (hid_input_blacklist[i].idVendor == device->vendor &&
|
||||
hid_input_blacklist[i].idProduct == device->product)
|
||||
return hid_input_blacklist[i].quirk(usage, input, bit, max);
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
struct input_dev *input;
|
||||
|
||||
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 1;
|
||||
}
|
||||
|
||||
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) &&
|
||||
(usage->type == EV_REL) &&
|
||||
(usage->code == REL_WHEEL)) {
|
||||
hid->delayed_value = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
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 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)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* handle the temporary quirky mapping to HWHEEL */
|
||||
if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT &&
|
||||
usage->type == EV_REL && usage->code == REL_HWHEEL) {
|
||||
input_event(input, usage->type, REL_WHEEL, -value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Gyration MCE remote "Sleep" key */
|
||||
if (hid->vendor == VENDOR_ID_GYRATION &&
|
||||
hid->product == DEVICE_ID_GYRATION_REMOTE &&
|
||||
(usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK &&
|
||||
(usage->hid & 0xff) == 0x82) {
|
||||
input_event(input, usage->type, usage->code, 1);
|
||||
input_sync(input);
|
||||
input_event(input, usage->type, usage->code, 0);
|
||||
input_sync(input);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+347
-622
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* HID driver for some logitech "special" devices
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 "hid-ids.h"
|
||||
#include "hid-lg.h"
|
||||
|
||||
#define LG_RDESC 0x001
|
||||
#define LG_BAD_RELATIVE_KEYS 0x002
|
||||
#define LG_DUPLICATE_USAGES 0x004
|
||||
#define LG_RESET_LEDS 0x008
|
||||
#define LG_EXPANDED_KEYMAP 0x010
|
||||
#define LG_IGNORE_DOUBLED_WHEEL 0x020
|
||||
#define LG_WIRELESS 0x040
|
||||
#define LG_INVERT_HWHEEL 0x080
|
||||
#define LG_NOGET 0x100
|
||||
#define LG_FF 0x200
|
||||
#define LG_FF2 0x400
|
||||
|
||||
/*
|
||||
* Certain Logitech keyboards send in report #3 keys which are far
|
||||
* above the logical maximum described in descriptor. This extends
|
||||
* the original value of 0x28c of logical maximum to 0x104d
|
||||
*/
|
||||
static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||
unsigned int rsize)
|
||||
{
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
|
||||
if ((quirks & LG_RDESC) && rsize >= 90 && rdesc[83] == 0x26 &&
|
||||
rdesc[84] == 0x8c && rdesc[85] == 0x02) {
|
||||
dev_info(&hdev->dev, "fixing up Logitech keyboard report "
|
||||
"descriptor\n");
|
||||
rdesc[84] = rdesc[89] = 0x4d;
|
||||
rdesc[85] = rdesc[90] = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
|
||||
EV_KEY, (c))
|
||||
|
||||
static int lg_ultrax_remote_mapping(struct hid_input *hi,
|
||||
struct hid_usage *usage, unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
|
||||
return 0;
|
||||
|
||||
set_bit(EV_REP, hi->input->evbit);
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
/* Reported on Logitech Ultra X Media Remote */
|
||||
case 0x004: lg_map_key_clear(KEY_AGAIN); break;
|
||||
case 0x00d: lg_map_key_clear(KEY_HOME); break;
|
||||
case 0x024: lg_map_key_clear(KEY_SHUFFLE); break;
|
||||
case 0x025: lg_map_key_clear(KEY_TV); break;
|
||||
case 0x026: lg_map_key_clear(KEY_MENU); break;
|
||||
case 0x031: lg_map_key_clear(KEY_AUDIO); break;
|
||||
case 0x032: lg_map_key_clear(KEY_TEXT); break;
|
||||
case 0x033: lg_map_key_clear(KEY_LAST); break;
|
||||
case 0x047: lg_map_key_clear(KEY_MP3); break;
|
||||
case 0x048: lg_map_key_clear(KEY_DVD); break;
|
||||
case 0x049: lg_map_key_clear(KEY_MEDIA); break;
|
||||
case 0x04a: lg_map_key_clear(KEY_VIDEO); break;
|
||||
case 0x04b: lg_map_key_clear(KEY_ANGLE); break;
|
||||
case 0x04c: lg_map_key_clear(KEY_LANGUAGE); break;
|
||||
case 0x04d: lg_map_key_clear(KEY_SUBTITLE); break;
|
||||
case 0x051: lg_map_key_clear(KEY_RED); break;
|
||||
case 0x052: lg_map_key_clear(KEY_CLOSE); break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
|
||||
return 0;
|
||||
|
||||
switch (usage->hid & HID_USAGE) {
|
||||
case 0x1001: lg_map_key_clear(KEY_MESSENGER); break;
|
||||
case 0x1003: lg_map_key_clear(KEY_SOUND); break;
|
||||
case 0x1004: lg_map_key_clear(KEY_VIDEO); break;
|
||||
case 0x1005: lg_map_key_clear(KEY_AUDIO); break;
|
||||
case 0x100a: lg_map_key_clear(KEY_DOCUMENTS); break;
|
||||
case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG); break;
|
||||
case 0x1012: lg_map_key_clear(KEY_NEXTSONG); break;
|
||||
case 0x1013: lg_map_key_clear(KEY_CAMERA); break;
|
||||
case 0x1014: lg_map_key_clear(KEY_MESSENGER); break;
|
||||
case 0x1015: lg_map_key_clear(KEY_RECORD); break;
|
||||
case 0x1016: lg_map_key_clear(KEY_PLAYER); break;
|
||||
case 0x1017: lg_map_key_clear(KEY_EJECTCD); break;
|
||||
case 0x1018: lg_map_key_clear(KEY_MEDIA); break;
|
||||
case 0x1019: lg_map_key_clear(KEY_PROG1); break;
|
||||
case 0x101a: lg_map_key_clear(KEY_PROG2); break;
|
||||
case 0x101b: lg_map_key_clear(KEY_PROG3); break;
|
||||
case 0x101f: lg_map_key_clear(KEY_ZOOMIN); break;
|
||||
case 0x1020: lg_map_key_clear(KEY_ZOOMOUT); break;
|
||||
case 0x1021: lg_map_key_clear(KEY_ZOOMRESET); break;
|
||||
case 0x1023: lg_map_key_clear(KEY_CLOSE); break;
|
||||
case 0x1027: lg_map_key_clear(KEY_MENU); break;
|
||||
/* this one is marked as 'Rotate' */
|
||||
case 0x1028: lg_map_key_clear(KEY_ANGLE); break;
|
||||
case 0x1029: lg_map_key_clear(KEY_SHUFFLE); break;
|
||||
case 0x102a: lg_map_key_clear(KEY_BACK); break;
|
||||
case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS); break;
|
||||
case 0x1041: lg_map_key_clear(KEY_BATTERY); break;
|
||||
case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR); break;
|
||||
case 0x1043: lg_map_key_clear(KEY_SPREADSHEET); break;
|
||||
case 0x1044: lg_map_key_clear(KEY_PRESENTATION); break;
|
||||
case 0x1045: lg_map_key_clear(KEY_UNDO); break;
|
||||
case 0x1046: lg_map_key_clear(KEY_REDO); break;
|
||||
case 0x1047: lg_map_key_clear(KEY_PRINT); break;
|
||||
case 0x1048: lg_map_key_clear(KEY_SAVE); break;
|
||||
case 0x1049: lg_map_key_clear(KEY_PROG1); break;
|
||||
case 0x104a: lg_map_key_clear(KEY_PROG2); break;
|
||||
case 0x104b: lg_map_key_clear(KEY_PROG3); break;
|
||||
case 0x104c: lg_map_key_clear(KEY_PROG4); break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||
struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
/* extended mapping for certain Logitech hardware (Logitech cordless
|
||||
desktop LX500) */
|
||||
static const u8 e_keymap[] = {
|
||||
0,216, 0,213,175,156, 0, 0, 0, 0,
|
||||
144, 0, 0, 0, 0, 0, 0, 0, 0,212,
|
||||
174,167,152,161,112, 0, 0, 0,154, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,183,184,185,186,187,
|
||||
188,189,190,191,192,193,194, 0, 0, 0
|
||||
};
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
unsigned int hid = usage->hid;
|
||||
|
||||
if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER &&
|
||||
lg_ultrax_remote_mapping(hi, usage, bit, max))
|
||||
return 1;
|
||||
|
||||
if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max))
|
||||
return 1;
|
||||
|
||||
if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
|
||||
return 0;
|
||||
|
||||
hid &= HID_USAGE;
|
||||
|
||||
/* Special handling for Logitech Cordless Desktop */
|
||||
if (field->application == HID_GD_MOUSE) {
|
||||
if ((quirks & LG_IGNORE_DOUBLED_WHEEL) &&
|
||||
(hid == 7 || hid == 8))
|
||||
return -1;
|
||||
} else {
|
||||
if ((quirks & LG_EXPANDED_KEYMAP) &&
|
||||
hid < ARRAY_SIZE(e_keymap) &&
|
||||
e_keymap[hid] != 0) {
|
||||
hid_map_usage(hi, usage, bit, max, EV_KEY,
|
||||
e_keymap[hid]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi,
|
||||
struct hid_field *field, struct hid_usage *usage,
|
||||
unsigned long **bit, int *max)
|
||||
{
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
|
||||
if ((quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY &&
|
||||
(field->flags & HID_MAIN_ITEM_RELATIVE))
|
||||
field->flags &= ~HID_MAIN_ITEM_RELATIVE;
|
||||
|
||||
if ((quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY ||
|
||||
usage->type == EV_REL || usage->type == EV_ABS))
|
||||
clear_bit(usage->code, *bit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lg_event(struct hid_device *hdev, struct hid_field *field,
|
||||
struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
|
||||
|
||||
if ((quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) {
|
||||
input_event(field->hidinput->input, usage->type, usage->code,
|
||||
-value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
{
|
||||
unsigned long quirks = id->driver_data;
|
||||
unsigned int connect_mask = HID_CONNECT_DEFAULT;
|
||||
int ret;
|
||||
|
||||
hid_set_drvdata(hdev, (void *)quirks);
|
||||
|
||||
if (quirks & LG_NOGET)
|
||||
hdev->quirks |= HID_QUIRK_NOGET;
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "parse failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
if (quirks & (LG_FF | LG_FF2))
|
||||
connect_mask &= ~HID_CONNECT_FF;
|
||||
|
||||
ret = hid_hw_start(hdev, connect_mask);
|
||||
if (ret) {
|
||||
dev_err(&hdev->dev, "hw start failed\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
if (quirks & LG_RESET_LEDS)
|
||||
usbhid_set_leds(hdev);
|
||||
|
||||
if (quirks & LG_FF)
|
||||
lgff_init(hdev);
|
||||
if (quirks & LG_FF2)
|
||||
lg2ff_init(hdev);
|
||||
|
||||
return 0;
|
||||
err_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct hid_device_id lg_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
|
||||
.driver_data = LG_RDESC | LG_WIRELESS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER),
|
||||
.driver_data = LG_RDESC | LG_WIRELESS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2),
|
||||
.driver_data = LG_RDESC | LG_WIRELESS },
|
||||
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER),
|
||||
.driver_data = LG_BAD_RELATIVE_KEYS },
|
||||
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP),
|
||||
.driver_data = LG_DUPLICATE_USAGES },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE),
|
||||
.driver_data = LG_DUPLICATE_USAGES },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI),
|
||||
.driver_data = LG_DUPLICATE_USAGES },
|
||||
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD),
|
||||
.driver_data = LG_RESET_LEDS },
|
||||
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD),
|
||||
.driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500),
|
||||
.driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },
|
||||
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_LX3),
|
||||
.driver_data = LG_INVERT_HWHEEL },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150),
|
||||
.driver_data = LG_INVERT_HWHEEL },
|
||||
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D),
|
||||
.driver_data = LG_NOGET },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL),
|
||||
.driver_data = LG_NOGET | LG_FF },
|
||||
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD),
|
||||
.driver_data = LG_FF },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2),
|
||||
.driver_data = LG_FF },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D),
|
||||
.driver_data = LG_FF },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO),
|
||||
.driver_data = LG_FF },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL),
|
||||
.driver_data = LG_FF },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2),
|
||||
.driver_data = LG_FF },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
|
||||
.driver_data = LG_FF2 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, lg_devices);
|
||||
|
||||
static struct hid_driver lg_driver = {
|
||||
.name = "logitech",
|
||||
.id_table = lg_devices,
|
||||
.report_fixup = lg_report_fixup,
|
||||
.input_mapping = lg_input_mapping,
|
||||
.input_mapped = lg_input_mapped,
|
||||
.event = lg_event,
|
||||
.probe = lg_probe,
|
||||
};
|
||||
|
||||
static int lg_init(void)
|
||||
{
|
||||
return hid_register_driver(&lg_driver);
|
||||
}
|
||||
|
||||
static void lg_exit(void)
|
||||
{
|
||||
hid_unregister_driver(&lg_driver);
|
||||
}
|
||||
|
||||
module_init(lg_init);
|
||||
module_exit(lg_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
HID_COMPAT_LOAD_DRIVER(logitech);
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef __HID_LG_H
|
||||
#define __HID_LG_H
|
||||
|
||||
#include <linux/autoconf.h>
|
||||
|
||||
#ifdef CONFIG_LOGITECH_FF
|
||||
int lgff_init(struct hid_device *hdev);
|
||||
#else
|
||||
static inline int lgff_init(struct hid_device *hdev) { return -1; }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LOGIRUMBLEPAD2_FF
|
||||
int lg2ff_init(struct hid_device *hdev);
|
||||
#else
|
||||
static inline int lg2ff_init(struct hid_device *hdev) { return -1; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user