aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid10
-rw-r--r--drivers/hid/Kconfig45
-rw-r--r--drivers/hid/Makefile7
-rw-r--r--drivers/hid/hid-axff.c31
-rw-r--r--drivers/hid/hid-core.c41
-rw-r--r--drivers/hid/hid-dr.c (renamed from drivers/hid/hid-drff.c)117
-rw-r--r--drivers/hid/hid-egalax.c279
-rw-r--r--drivers/hid/hid-gyration.c5
-rw-r--r--drivers/hid/hid-ids.h11
-rw-r--r--drivers/hid/hid-input.c31
-rw-r--r--drivers/hid/hid-keytouch.c66
-rw-r--r--drivers/hid/hid-lcpower.c70
-rw-r--r--drivers/hid/hid-lg.c2
-rw-r--r--drivers/hid/hid-magicmouse.c4
-rw-r--r--drivers/hid/hid-multitouch.c76
-rw-r--r--drivers/hid/hid-ntrig.c519
-rw-r--r--drivers/hid/hid-ortek.c6
-rw-r--r--drivers/hid/hid-sony.c20
-rw-r--r--drivers/hid/hidraw.c112
-rw-r--r--drivers/hid/usbhid/hid-core.c35
-rw-r--r--include/linux/hid.h5
-rw-r--r--include/linux/hidraw.h3
-rw-r--r--net/bluetooth/hidp/core.c197
-rw-r--r--net/bluetooth/hidp/hidp.h15
24 files changed, 1122 insertions, 585 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid b/Documentation/ABI/testing/sysfs-driver-hid
new file mode 100644
index 00000000000..b6490e14fe8
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid
@@ -0,0 +1,10 @@
+What: For USB devices : /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/report_descriptor
+ For BT devices : /sys/class/bluetooth/hci<addr>/<hid-bus>:<vendor-id>:<product-id>.<num>/report_descriptor
+ Symlink : /sys/class/hidraw/hidraw<num>/device/report_descriptor
+Date: Jan 2011
+KernelVersion: 2.0.39
+Contact: Alan Ott <alan@signal11.us>
+Description: When read, this file returns the device's raw binary HID
+ report descriptor.
+ This file cannot be written.
+Users: HIDAPI library (http://www.signal11.us/oss/hidapi)
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 022515fdd6f..d8123920f79 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -68,9 +68,15 @@ config HID_A4TECH
---help---
Support for A4 tech X5 and WOP-35 / Trust 450L mice.
-config HID_ACRUX_FF
- tristate "ACRUX force feedback"
+config HID_ACRUX
+ tristate "ACRUX game controller support"
depends on USB_HID
+ ---help---
+ Say Y here if you want to enable support for ACRUX game controllers.
+
+config HID_ACRUX_FF
+ tristate "ACRUX force feedback support"
+ depends on HID_ACRUX
select INPUT_FF_MEMLESS
---help---
Say Y here if you want to enable force feedback support for ACRUX
@@ -140,7 +146,12 @@ config HID_DRAGONRISE
tristate "DragonRise Inc. game controller"
depends on USB_HID
---help---
- Say Y here if you have DragonRise Inc.game controllers.
+ Say Y here if you have DragonRise Inc. game controllers.
+ These might be branded as:
+ - Tesun USB-703
+ - Media-tech MT1504 "Rogue"
+ - DVTech JS19 "Gear"
+ - Defender Game Master
config DRAGONRISE_FF
bool "DragonRise Inc. force feedback"
@@ -160,13 +171,6 @@ config HID_EMS_FF
Currently the following devices are known to be supported:
- Trio Linker Plus II
-config HID_EGALAX
- tristate "eGalax multi-touch panel"
- depends on USB_HID
- ---help---
- Support for the eGalax dual-touch panels, including the
- Joojoo and Wetab tablets.
-
config HID_ELECOM
tristate "ELECOM BM084 bluetooth mouse"
depends on BT_HIDP
@@ -180,6 +184,14 @@ config HID_EZKEY
---help---
Support for Ezkey BTC 8193 keyboard.
+config HID_KEYTOUCH
+ tristate "Keyoutch HID devices"
+ depends on USB_HID
+ ---help---
+ Support for Keytouch HID devices not fully compliant with
+ the specification. Currently supported:
+ - Keytouch IEC 60945
+
config HID_KYE
tristate "Kye/Genius Ergo Mouse" if EMBEDDED
depends on USB_HID
@@ -218,6 +230,12 @@ config HID_KENSINGTON
---help---
Support for Kensington Slimblade Trackball.
+config HID_LCPOWER
+ tristate "LC-Power"
+ depends on USB_HID
+ ---help---
+ Support for LC-Power RC1000MCE RF remote control.
+
config HID_LOGITECH
tristate "Logitech devices" if EMBEDDED
depends on USB_HID
@@ -304,8 +322,11 @@ config HID_MULTITOUCH
Say Y here if you have one of the following devices:
- Cypress TrueTouch panels
- Hanvon dual touch panels
+ - IrTouch Infrared USB panels
- Pixcir dual touch panels
- 'Sensing Win7-TwoFinger' panel by GeneralTouch
+ - eGalax dual-touch panels, including the
+ Joojoo and Wetab tablets
If unsure, say N.
@@ -319,10 +340,10 @@ config HID_NTRIG
Support for N-Trig touch screen.
config HID_ORTEK
- tristate "Ortek WKB-2000 wireless keyboard and mouse trackpad"
+ tristate "Ortek PKB-1700/WKB-2000 wireless keyboard and mouse trackpad"
depends on USB_HID
---help---
- Support for Ortek WKB-2000 wireless keyboard + mouse trackpad.
+ Support for Ortek PKB-1700/WKB-2000 wireless keyboard + mouse trackpad.
config HID_PANTHERLORD
tristate "Pantherlord/GreenAsia game controller"
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index cb80181da90..06c68ae3abe 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -27,21 +27,22 @@ endif
obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o
obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
-obj-$(CONFIG_HID_ACRUX_FF) += hid-axff.o
+obj-$(CONFIG_HID_ACRUX) += hid-axff.o
obj-$(CONFIG_HID_APPLE) += hid-apple.o
obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
obj-$(CONFIG_HID_CANDO) += hid-cando.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_DRAGONRISE) += hid-drff.o
+obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o
obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o
-obj-$(CONFIG_HID_EGALAX) += hid-egalax.o
obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
+obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
obj-$(CONFIG_HID_KYE) += hid-kye.o
+obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o
obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c
index e5b961d6ff2..b4554288de0 100644
--- a/drivers/hid/hid-axff.c
+++ b/drivers/hid/hid-axff.c
@@ -33,6 +33,8 @@
#include <linux/hid.h>
#include "hid-ids.h"
+
+#ifdef CONFIG_HID_ACRUX_FF
#include "usbhid/usbhid.h"
struct axff_device {
@@ -109,6 +111,12 @@ err_free_mem:
kfree(axff);
return error;
}
+#else
+static inline int axff_init(struct hid_device *hid)
+{
+ return 0;
+}
+#endif
static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
@@ -139,9 +147,25 @@ static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id)
error);
}
+ /*
+ * We need to start polling device right away, otherwise
+ * it will go into a coma.
+ */
+ error = hid_hw_open(hdev);
+ if (error) {
+ dev_err(&hdev->dev, "hw open failed\n");
+ return error;
+ }
+
return 0;
}
+static void ax_remove(struct hid_device *hdev)
+{
+ hid_hw_close(hdev);
+ hid_hw_stop(hdev);
+}
+
static const struct hid_device_id ax_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802), },
{ }
@@ -149,9 +173,10 @@ static const struct hid_device_id ax_devices[] = {
MODULE_DEVICE_TABLE(hid, ax_devices);
static struct hid_driver ax_driver = {
- .name = "acrux",
- .id_table = ax_devices,
- .probe = ax_probe,
+ .name = "acrux",
+ .id_table = ax_devices,
+ .probe = ax_probe,
+ .remove = ax_remove,
};
static int __init ax_init(void)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 0180f20d4fa..c3d66269ed7 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1159,6 +1159,32 @@ static bool hid_hiddev(struct hid_device *hdev)
return !!hid_match_id(hdev, hid_hiddev_list);
}
+
+static ssize_t
+read_report_descriptor(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+
+ if (off >= hdev->rsize)
+ return 0;
+
+ if (off + count > hdev->rsize)
+ count = hdev->rsize - off;
+
+ memcpy(buf, hdev->rdesc + off, count);
+
+ return count;
+}
+
+static struct bin_attribute dev_bin_attr_report_desc = {
+ .attr = { .name = "report_descriptor", .mode = 0444 },
+ .read = read_report_descriptor,
+ .size = HID_MAX_DESCRIPTOR_SIZE,
+};
+
int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
{
static const char *types[] = { "Device", "Pointer", "Mouse", "Device",
@@ -1169,6 +1195,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
char buf[64];
unsigned int i;
int len;
+ int ret;
if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
@@ -1230,6 +1257,11 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
bus = "<UNKNOWN>";
}
+ ret = device_create_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
+ if (ret)
+ hid_warn(hdev,
+ "can't create sysfs report descriptor attribute err: %d\n", ret);
+
hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n",
buf, bus, hdev->version >> 8, hdev->version & 0xff,
type, hdev->name, hdev->phys);
@@ -1240,6 +1272,7 @@ EXPORT_SYMBOL_GPL(hid_connect);
void hid_disconnect(struct hid_device *hdev)
{
+ device_remove_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
if (hdev->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(hdev);
if (hdev->claimed & HID_CLAIMED_HIDDEV)
@@ -1256,9 +1289,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
-#if defined(CONFIG_HID_ACRUX_FF) || defined(CONFIG_HID_ACRUX_FF_MODULE)
{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
-#endif
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
@@ -1328,6 +1359,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
@@ -1345,9 +1377,12 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
@@ -1368,6 +1403,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
@@ -1400,6 +1436,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
diff --git a/drivers/hid/hid-drff.c b/drivers/hid/hid-dr.c
index afcf3d67eb0..61eece47204 100644
--- a/drivers/hid/hid-drff.c
+++ b/drivers/hid/hid-dr.c
@@ -145,6 +145,110 @@ static inline int drff_init(struct hid_device *hid)
}
#endif
+/*
+ * The original descriptor of joystick with PID 0x0011, represented by DVTech PC
+ * JS19. It seems both copied from another device and a result of confusion
+ * either about the specification or about the program used to create the
+ * descriptor. In any case, it's a wonder it works on Windows.
+ *
+ * Usage Page (Desktop), ; Generic desktop controls (01h)
+ * Usage (Joystik), ; Joystik (04h, application collection)
+ * Collection (Application),
+ * Collection (Logical),
+ * Report Size (8),
+ * Report Count (5),
+ * Logical Minimum (0),
+ * Logical Maximum (255),
+ * Physical Minimum (0),
+ * Physical Maximum (255),
+ * Usage (X), ; X (30h, dynamic value)
+ * Usage (X), ; X (30h, dynamic value)
+ * Usage (X), ; X (30h, dynamic value)
+ * Usage (X), ; X (30h, dynamic value)
+ * Usage (Y), ; Y (31h, dynamic value)
+ * Input (Variable),
+ * Report Size (4),
+ * Report Count (1),
+ * Logical Maximum (7),
+ * Physical Maximum (315),
+ * Unit (Degrees),
+ * Usage (00h),
+ * Input (Variable, Null State),
+ * Unit,
+ * Report Size (1),
+ * Report Count (10),
+ * Logical Maximum (1),
+ * Physical Maximum (1),
+ * Usage Page (Button), ; Button (09h)
+ * Usage Minimum (01h),
+ * Usage Maximum (0Ah),
+ * Input (Variable),
+ * Usage Page (FF00h), ; FF00h, vendor-defined
+ * Report Size (1),
+ * Report Count (10),
+ * Logical Maximum (1),
+ * Physical Maximum (1),
+ * Usage (01h),
+ * Input (Variable),
+ * End Collection,
+ * Collection (Logical),
+ * Report Size (8),
+ * Report Count (4),
+ * Physical Maximum (255),
+ * Logical Maximum (255),
+ * Usage (02h),
+ * Output (Variable),
+ * End Collection,
+ * End Collection
+ */
+
+/* Size of the original descriptor of the PID 0x0011 joystick */
+#define PID0011_RDESC_ORIG_SIZE 101
+
+/* Fixed report descriptor for PID 0x011 joystick */
+static __u8 pid0011_rdesc_fixed[] = {
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x04, /* Usage (Joystik), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0xA1, 0x02, /* Collection (Logical), */
+ 0x14, /* Logical Minimum (0), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
+ 0x95, 0x02, /* Report Count (2), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x95, 0x04, /* Report Count (4), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x95, 0x0A, /* Report Count (10), */
+ 0x05, 0x09, /* Usage Page (Button), */
+ 0x19, 0x01, /* Usage Minimum (01h), */
+ 0x29, 0x0A, /* Usage Maximum (0Ah), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x0A, /* Report Count (10), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0xC0, /* End Collection, */
+ 0xC0 /* End Collection */
+};
+
+static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
+{
+ switch (hdev->product) {
+ case 0x0011:
+ if (*rsize == PID0011_RDESC_ORIG_SIZE) {
+ rdesc = pid0011_rdesc_fixed;
+ *rsize = sizeof(pid0011_rdesc_fixed);
+ }
+ break;
+ }
+ return rdesc;
+}
+
static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int ret;
@@ -163,7 +267,16 @@ static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err;
}
- drff_init(hdev);
+ switch (hdev->product) {
+ case 0x0006:
+ ret = drff_init(hdev);
+ if (ret) {
+ dev_err(&hdev->dev, "force feedback init failed\n");
+ hid_hw_stop(hdev);
+ goto err;
+ }
+ break;
+ }
return 0;
err:
@@ -172,6 +285,7 @@ err:
static const struct hid_device_id dr_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006), },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011), },
{ }
};
MODULE_DEVICE_TABLE(hid, dr_devices);
@@ -179,6 +293,7 @@ MODULE_DEVICE_TABLE(hid, dr_devices);
static struct hid_driver dr_driver = {
.name = "dragonrise",
.id_table = dr_devices,
+ .report_fixup = dr_report_fixup,
.probe = dr_probe,
};
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c
deleted file mode 100644
index 03bee1970d7..00000000000
--- a/drivers/hid/hid-egalax.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * HID driver for eGalax dual-touch panels
- *
- * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
- * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
- * Copyright (c) 2010 Canonical, Ltd.
- *
- */
-
-/*
- * 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 <linux/input/mt.h>
-#include <linux/slab.h>
-#include "usbhid/usbhid.h"
-
-MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
-MODULE_DESCRIPTION("eGalax dual-touch panel");
-MODULE_LICENSE("GPL");
-
-#include "hid-ids.h"
-
-#define MAX_SLOTS 2
-
-/* estimated signal-to-noise ratios */
-#define SN_MOVE 4096
-#define SN_PRESSURE 32
-
-struct egalax_data {
- int valid;
- int slot;
- int touch;
- int x, y, z;
-};
-
-static void set_abs(struct input_dev *input, unsigned int code,
- struct hid_field *field, int snratio)
-{
- int fmin = field->logical_minimum;
- int fmax = field->logical_maximum;
- int fuzz = snratio ? (fmax - fmin) / snratio : 0;
- input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
-}
-
-static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- struct input_dev *input = hi->input;
-
- switch (usage->hid & HID_USAGE_PAGE) {
-
- case HID_UP_GENDESK:
- switch (usage->hid) {
- case HID_GD_X:
- field->logical_maximum = 32760;
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_POSITION_X);
- set_abs(input, ABS_MT_POSITION_X, field, SN_MOVE);
- /* touchscreen emulation */
- set_abs(input, ABS_X, field, SN_MOVE);
- return 1;
- case HID_GD_Y:
- field->logical_maximum = 32760;
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_POSITION_Y);
- set_abs(input, ABS_MT_POSITION_Y, field, SN_MOVE);
- /* touchscreen emulation */
- set_abs(input, ABS_Y, field, SN_MOVE);
- return 1;
- }
- return 0;
-
- case HID_UP_DIGITIZER:
- switch (usage->hid) {
- case HID_DG_TIPSWITCH:
- /* touchscreen emulation */
- hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
- input_set_capability(input, EV_KEY, BTN_TOUCH);
- return 1;
- case HID_DG_INRANGE:
- case HID_DG_CONFIDENCE:
- case HID_DG_CONTACTCOUNT:
- case HID_DG_CONTACTMAX:
- return -1;
- case HID_DG_CONTACTID:
- input_mt_init_slots(input, MAX_SLOTS);
- return 1;
- case HID_DG_TIPPRESSURE:
- field->logical_minimum = 0;
- hid_map_usage(hi, usage, bit, max,
- EV_ABS, ABS_MT_PRESSURE);
- set_abs(input, ABS_MT_PRESSURE, field, SN_PRESSURE);
- /* touchscreen emulation */
- set_abs(input, ABS_PRESSURE, field, SN_PRESSURE);
- return 1;
- }
- return 0;
- }
-
- /* ignore others (from other reports we won't get anyway) */
- return -1;
-}
-
-static int egalax_input_mapped(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- /* tell hid-input to skip setup of these event types */
- if (usage->type == EV_KEY || usage->type == EV_ABS)
- set_bit(usage->type, hi->input->evbit);
- return -1;
-}
-
-/*
- * this function is called when a whole finger has been parsed,
- * so that it can decide what to send to the input layer.
- */
-static void egalax_filter_event(struct egalax_data *td, struct input_dev *input)
-{
- input_mt_slot(input, td->slot);
- input_mt_report_slot_state(input, MT_TOOL_FINGER, td->touch);
- if (td->touch) {
- input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
- input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
- input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z);
- }
- input_mt_report_pointer_emulation(input, true);
-}
-
-static int egalax_event(struct hid_device *hid, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- struct egalax_data *td = hid_get_drvdata(hid);
-
- /* Note, eGalax has two product lines: the first is resistive and
- * uses a standard parallel multitouch protocol (product ID ==
- * 48xx). The second is capacitive and uses an unusual "serial"
- * protocol with a different message for each multitouch finger
- * (product ID == 72xx).
- */
- if (hid->claimed & HID_CLAIMED_INPUT) {
- struct input_dev *input = field->hidinput->input;
-
- switch (usage->hid) {
- case HID_DG_INRANGE:
- td->valid = value;
- break;
- case HID_DG_CONFIDENCE:
- /* avoid interference from generic hidinput handling */
- break;
- case HID_DG_TIPSWITCH:
- td->touch = value;
- break;
- case HID_DG_TIPPRESSURE:
- td->z = value;
- break;
- case HID_DG_CONTACTID:
- td->slot = clamp_val(value, 0, MAX_SLOTS - 1);
- break;
- case HID_GD_X:
- td->x = value;
- break;
- case HID_GD_Y:
- td->y = value;
- /* this is the last field in a finger */
- if (td->valid)
- egalax_filter_event(td, input);
- break;
- case HID_DG_CONTACTCOUNT:
- /* touch emulation: this is the last field in a frame */
- break;
-
- default:
- /* fallback to the generic hidinput handling */
- return 0;
- }
- }
-
- /* we have handled the hidinput part, now remains hiddev */
- if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
- hid->hiddev_hid_event(hid, field, usage, value);
-
- return 1;
-}
-
-static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
- int ret;
- struct egalax_data *td;
- struct hid_report *report;
-
- td = kzalloc(sizeof(struct egalax_data), GFP_KERNEL);
- if (!td) {
- hid_err(hdev, "cannot allocate eGalax data\n");
- return -ENOMEM;
- }
- hid_set_drvdata(hdev, td);
-
- ret = hid_parse(hdev);
- if (ret)
- goto end;
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret)
- goto end;
-
- report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[5];
- if (report) {
- report->field[0]->value[0] = 2;
- usbhid_submit_report(hdev, report, USB_DIR_OUT);
- }
-
-end:
- if (ret)
- kfree(td);
-
- return ret;
-}
-
-static void egalax_remove(struct hid_device *hdev)
-{
- hid_hw_stop(hdev);
- kfree(hid_get_drvdata(hdev));
- hid_set_drvdata(hdev, NULL);
-}
-
-static const struct hid_device_id egalax_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, egalax_devices);
-
-static const struct hid_usage_id egalax_grabbed_usages[] = {
- { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
-};
-
-static struct hid_driver egalax_driver = {
- .name = "egalax-touch",
- .id_table = egalax_devices,
- .probe = egalax_probe,
- .remove = egalax_remove,
- .input_mapping = egalax_input_mapping,
- .input_mapped = egalax_input_mapped,
- .usage_table = egalax_grabbed_usages,
- .event = egalax_event,
-};
-
-static int __init egalax_init(void)
-{
- return hid_register_driver(&egalax_driver);
-}
-
-static void __exit egalax_exit(void)
-{
- hid_unregister_driver(&egalax_driver);
-}
-
-module_init(egalax_init);
-module_exit(egalax_exit);
-
diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c
index 3975e039c3d..e88b951cd10 100644
--- a/drivers/hid/hid-gyration.c
+++ b/drivers/hid/hid-gyration.c
@@ -43,6 +43,11 @@ static int gyration_input_mapping(struct hid_device *hdev, struct hid_input *hi,
case 0x048: gy_map_key_clear(KEY_MEDIA); break;
case 0x049: gy_map_key_clear(KEY_CAMERA); break;
case 0x04a: gy_map_key_clear(KEY_VIDEO); break;
+ case 0x05a: gy_map_key_clear(KEY_TEXT); break;
+ case 0x05b: gy_map_key_clear(KEY_RED); break;
+ case 0x05c: gy_map_key_clear(KEY_GREEN); break;
+ case 0x05d: gy_map_key_clear(KEY_YELLOW); break;
+ case 0x05e: gy_map_key_clear(KEY_BLUE); break;
default:
return 0;
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 75f2e1430a5..d485894ff4d 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -333,6 +333,9 @@
#define USB_VENDOR_ID_IMATION 0x0718
#define USB_DEVICE_ID_DISC_STAKKA 0xd000
+#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615
+#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070
+
#define USB_VENDOR_ID_JESS 0x0c45
#define USB_DEVICE_ID_JESS_YUREX 0x1010
@@ -345,6 +348,9 @@
#define USB_VENDOR_ID_KWORLD 0x1b80
#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700
+#define USB_VENDOR_ID_KEYTOUCH 0x0926
+#define USB_DEVICE_ID_KEYTOUCH_IEC 0x3333
+
#define USB_VENDOR_ID_KYE 0x0458
#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
@@ -352,6 +358,9 @@
#define USB_VENDOR_ID_LABTEC 0x1020
#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
+#define USB_VENDOR_ID_LCPOWER 0x1241
+#define USB_DEVICE_ID_LCPOWER_LC1000 0xf767
+
#define USB_VENDOR_ID_LD 0x0f11
#define USB_DEVICE_ID_LD_CASSY 0x1000
#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010
@@ -383,6 +392,7 @@
#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293
#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295
+#define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298
#define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299
#define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c
#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a
@@ -466,6 +476,7 @@
#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
#define USB_VENDOR_ID_ORTEK 0x05a4
+#define USB_DEVICE_ID_ORTEK_PKB1700 0x1700
#define USB_DEVICE_ID_ORTEK_WKB2000 0x2000
#define USB_VENDOR_ID_PANJIT 0x134c
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 7f552bfad32..cd74203c817 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -290,14 +290,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
goto ignore;
}
- if (field->report_type == HID_FEATURE_REPORT) {
- if (device->driver->feature_mapping) {
- device->driver->feature_mapping(device, hidinput, field,
- usage);
- }
- goto ignore;
- }
-
if (device->driver->input_mapping) {
int ret = device->driver->input_mapping(device, hidinput, field,
usage, &bit, &max);
@@ -835,6 +827,24 @@ static void hidinput_close(struct input_dev *dev)
hid_hw_close(hid);
}
+static void report_features(struct hid_device *hid)
+{
+ struct hid_driver *drv = hid->driver;
+ struct hid_report_enum *rep_enum;
+ struct hid_report *rep;
+ int i, j;
+
+ if (!drv->feature_mapping)
+ return;
+
+ rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
+ list_for_each_entry(rep, &rep_enum->report_list, list)
+ for (i = 0; i < rep->maxfield; i++)
+ for (j = 0; j < rep->field[i]->maxusage; j++)
+ drv->feature_mapping(hid, rep->field[i],
+ rep->field[i]->usage + j);
+}
+
/*
* Register the input device; print a message.
* Configure the input layer interface
@@ -863,7 +873,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
return -1;
}
- for (k = HID_INPUT_REPORT; k <= HID_FEATURE_REPORT; k++) {
+ report_features(hid);
+
+ for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
if (k == HID_OUTPUT_REPORT &&
hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)