aboutsummaryrefslogtreecommitdiff
path: root/drivers/hid
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-03-23 08:06:43 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-23 08:06:43 -0300
commit7483d45f0aee3afc0646d185cabd4af9f6cab58c (patch)
treea312f7d77c34748bec62f0431df33007b10e4e7f /drivers/hid
parent3e85fc1b9fc1c7e20b9a01f2314bb633bb10501a (diff)
parentf92c97c8bd77992ff8bd6ef29a23dc82dca799cb (diff)
Merge branch 'staging/for_v3.4' into v4l_for_linus
* staging/for_v3.4: (10117 commits) [media] update CARDLIST.em28xx [media] partially reverts changeset fa5527c [media] stb0899: fix the limits for signal strength values [media] em28xx: support for 2304:0242 PCTV QuatroStick (510e) [media] em28xx: support for 2013:0251 PCTV QuatroStick nano (520e) [media] -EINVAL -> -ENOTTY [media] gspca - sn9c20x: Cleanup source [media] gspca - sn9c20x: Simplify register write for capture start/stop [media] gspca - sn9c20x: Add automatic JPEG compression mechanism [media] gspca - sn9c20x: Greater delay in case of sensor no response [media] gspca - sn9c20x: Optimize the code of write sequences [media] gspca - sn9c20x: Add the JPEG compression quality control [media] gspca - sn9c20x: Add a delay after Omnivision sensor reset [media] gspca - sn9c20x: Propagate USB errors to higher level [media] gspca - sn9c20x: Use the new video control mechanism [media] gspca - sn9c20x: Fix loss of frame start [media] gspca - zc3xx: Lack of register 08 value for sensor cs2102k [media] gspca - ov534_9: Add brightness to OmniVision 5621 sensor [media] gspca - zc3xx: Add V4L2_CID_JPEG_COMPRESSION_QUALITY control support [media] pvrusb2: fix 7MHz & 8MHz DVB-T tuner support for HVR1900 rev D1F5 ...
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig38
-rw-r--r--drivers/hid/Makefile11
-rw-r--r--drivers/hid/hid-core.c92
-rw-r--r--drivers/hid/hid-debug.c8
-rw-r--r--drivers/hid/hid-emsff.c2
-rw-r--r--drivers/hid/hid-hyperv.c587
-rw-r--r--drivers/hid/hid-ids.h47
-rw-r--r--drivers/hid/hid-input.c233
-rw-r--r--drivers/hid/hid-lg4ff.c2
-rw-r--r--drivers/hid/hid-multitouch.c213
-rw-r--r--drivers/hid/hid-picolcd.c4
-rw-r--r--drivers/hid/hid-pl.c4
-rw-r--r--drivers/hid/hid-prodikeys.c2
-rw-r--r--drivers/hid/hid-quanta.c261
-rw-r--r--drivers/hid/hid-roccat-common.c4
-rw-r--r--drivers/hid/hid-roccat-isku.c487
-rw-r--r--drivers/hid/hid-roccat-isku.h147
-rw-r--r--drivers/hid/hid-roccat-kone.c4
-rw-r--r--drivers/hid/hid-twinhan.c2
-rw-r--r--drivers/hid/hid-wacom.c196
-rw-r--r--drivers/hid/hid-wiimote-core.c (renamed from drivers/hid/hid-wiimote.c)256
-rw-r--r--drivers/hid/hid-wiimote-debug.c227
-rw-r--r--drivers/hid/hid-wiimote-ext.c752
-rw-r--r--drivers/hid/hid-wiimote.h208
-rw-r--r--drivers/hid/usbhid/hid-core.c241
-rw-r--r--drivers/hid/usbhid/hid-quirks.c5
-rw-r--r--drivers/hid/usbhid/hiddev.c6
-rw-r--r--drivers/hid/usbhid/usbhid.h3
-rw-r--r--drivers/hid/usbhid/usbkbd.c81
-rw-r--r--drivers/hid/usbhid/usbmouse.c17
30 files changed, 3467 insertions, 673 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 22a4a051f22..a421abdd1ab 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -31,6 +31,11 @@ config HID
If unsure, say Y.
+config HID_BATTERY_STRENGTH
+ bool
+ depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY
+ default y
+
config HIDRAW
bool "/dev/hidraw raw HID device support"
depends on HID
@@ -335,6 +340,7 @@ config HID_MULTITOUCH
Say Y here if you have one of the following devices:
- 3M PCT touch screens
- ActionStar dual touch panels
+ - Atmel panels
- Cando dual touch panels
- Chunghwa panels
- CVTouch panels
@@ -349,12 +355,15 @@ config HID_MULTITOUCH
- Lumio CrystalTouch panels
- MosArt dual-touch panels
- PenMount dual touch panels
+ - PixArt optical touch screen
- Pixcir dual touch panels
+ - Quanta panels
- eGalax dual-touch panels, including the Joojoo and Wetab tablets
- Stantum multitouch panels
- Touch International Panels
- Unitec Panels
- XAT optical touch panels
+ - Xiroku optical touch panels
If unsure, say N.
@@ -466,12 +475,6 @@ config HID_PRIMAX
Support for Primax devices that are not fully compliant with the
HID standard.
-config HID_QUANTA
- tristate "Quanta Optical Touch panels"
- depends on USB_HID
- ---help---
- Support for Quanta Optical Touch dual-touch panels.
-
config HID_ROCCAT
tristate "Roccat special event support"
depends on USB_HID
@@ -492,6 +495,13 @@ config HID_ROCCAT_ARVO
---help---
Support for Roccat Arvo keyboard.
+config HID_ROCCAT_ISKU
+ tristate "Roccat Isku keyboard support"
+ depends on USB_HID
+ depends on HID_ROCCAT
+ ---help---
+ Support for Roccat Isku keyboard.
+
config HID_ROCCAT_KONE
tristate "Roccat Kone Mouse support"
depends on USB_HID
@@ -560,6 +570,12 @@ config GREENASIA_FF
(like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter
and want to enable force feedback support for it.
+config HID_HYPERV_MOUSE
+ tristate "Microsoft Hyper-V mouse driver"
+ depends on HYPERV
+ ---help---
+ Select this option to enable the Hyper-V mouse driver.
+
config HID_SMARTJOYPLUS
tristate "SmartJoy PLUS PS2/USB adapter support"
depends on USB_HID
@@ -620,9 +636,19 @@ config HID_WIIMOTE
depends on BT_HIDP
depends on LEDS_CLASS
select POWER_SUPPLY
+ select INPUT_FF_MEMLESS
---help---
Support for the Nintendo Wii Remote bluetooth device.
+config HID_WIIMOTE_EXT
+ bool "Nintendo Wii Remote Extension support"
+ depends on HID_WIIMOTE
+ default HID_WIIMOTE
+ ---help---
+ Support for extension controllers of the Nintendo Wii Remote. Say yes
+ here if you want to use the Nintendo Motion+, Nunchuck or Classic
+ extension controllers with your Wii Remote.
+
config HID_ZEROPLUS
tristate "Zeroplus based game controller support"
depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 1e0d2a638b2..8aefdc963cc 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -25,6 +25,14 @@ ifdef CONFIG_LOGIWHEELS_FF
hid-logitech-y += hid-lg4ff.o
endif
+hid-wiimote-y := hid-wiimote-core.o
+ifdef CONFIG_HID_WIIMOTE_EXT
+ hid-wiimote-y += hid-wiimote-ext.o
+endif
+ifdef CONFIG_DEBUG_FS
+ hid-wiimote-y += hid-wiimote-debug.o
+endif
+
obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
obj-$(CONFIG_HID_ACRUX) += hid-axff.o
obj-$(CONFIG_HID_APPLE) += hid-apple.o
@@ -38,6 +46,7 @@ obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o
+obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o
obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
obj-$(CONFIG_HID_KYE) += hid-kye.o
@@ -51,7 +60,6 @@ obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o
obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o
obj-$(CONFIG_HID_ORTEK) += hid-ortek.o
obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o
-obj-$(CONFIG_HID_QUANTA) += hid-quanta.o
obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
@@ -59,6 +67,7 @@ obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o
obj-$(CONFIG_HID_ROCCAT_COMMON) += hid-roccat-common.o
obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o
+obj-$(CONFIG_HID_ROCCAT_ISKU) += hid-roccat-isku.o
obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o
obj-$(CONFIG_HID_ROCCAT_KONEPLUS) += hid-roccat-koneplus.o
obj-$(CONFIG_HID_ROCCAT_KOVAPLUS) += hid-roccat-kovaplus.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index af353842f75..dd1bab48117 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -90,7 +90,7 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned
struct hid_field *field;
if (report->maxfield == HID_MAX_FIELDS) {
- dbg_hid("too many fields in report\n");
+ hid_err(report->device, "too many fields in report\n");
return NULL;
}
@@ -121,7 +121,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
usage = parser->local.usage[0];
if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
- dbg_hid("collection stack overflow\n");
+ hid_err(parser->device, "collection stack overflow\n");
return -1;
}
@@ -129,7 +129,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
collection = kmalloc(sizeof(struct hid_collection) *
parser->device->collection_size * 2, GFP_KERNEL);
if (collection == NULL) {
- dbg_hid("failed to reallocate collection array\n");
+ hid_err(parser->device, "failed to reallocate collection array\n");
return -1;
}
memcpy(collection, parser->device->collection,
@@ -165,7 +165,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
static int close_collection(struct hid_parser *parser)
{
if (!parser->collection_stack_ptr) {
- dbg_hid("collection stack underflow\n");
+ hid_err(parser->device, "collection stack underflow\n");
return -1;
}
parser->collection_stack_ptr--;
@@ -197,7 +197,7 @@ static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
static int hid_add_usage(struct hid_parser *parser, unsigned usage)
{
if (parser->local.usage_index >= HID_MAX_USAGES) {
- dbg_hid("usage index exceeded\n");
+ hid_err(parser->device, "usage index exceeded\n");
return -1;
}
parser->local.usage[parser->local.usage_index] = usage;
@@ -222,12 +222,13 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
report = hid_register_report(parser->device, report_type, parser->global.report_id);
if (!report) {
- dbg_hid("hid_register_report failed\n");
+ hid_err(parser->device, "hid_register_report failed\n");
return -1;
}
if (parser->global.logical_maximum < parser->global.logical_minimum) {
- dbg_hid("logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum);
+ hid_err(parser->device, "logical range invalid %d %d\n",
+ parser->global.logical_minimum, parser->global.logical_maximum);
return -1;
}
@@ -307,7 +308,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
case HID_GLOBAL_ITEM_TAG_PUSH:
if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
- dbg_hid("global environment stack overflow\n");
+ hid_err(parser->device, "global environment stack overflow\n");
return -1;
}
@@ -318,7 +319,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
case HID_GLOBAL_ITEM_TAG_POP:
if (!parser->global_stack_ptr) {
- dbg_hid("global environment stack underflow\n");
+ hid_err(parser->device, "global environment stack underflow\n");
return -1;
}
@@ -362,8 +363,8 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
parser->global.report_size = item_udata(item);
- if (parser->global.report_size > 32) {
- dbg_hid("invalid report_size %d\n",
+ if (parser->global.report_size > 96) {
+ hid_err(parser->device, "invalid report_size %d\n",
parser->global.report_size);
return -1;
}
@@ -372,7 +373,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
parser->global.report_count = item_udata(item);
if (parser->global.report_count > HID_MAX_USAGES) {
- dbg_hid("invalid report_count %d\n",
+ hid_err(parser->device, "invalid report_count %d\n",
parser->global.report_count);
return -1;
}
@@ -381,13 +382,13 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
case HID_GLOBAL_ITEM_TAG_REPORT_ID:
parser->global.report_id = item_udata(item);
if (parser->global.report_id == 0) {
- dbg_hid("report_id 0 is invalid\n");
+ hid_err(parser->device, "report_id 0 is invalid\n");
return -1;
}
return 0;
default:
- dbg_hid("unknown global tag 0x%x\n", item->tag);
+ hid_err(parser->device, "unknown global tag 0x%x\n", item->tag);
return -1;
}
}
@@ -414,14 +415,14 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
* items and the first delimiter set.
*/
if (parser->local.delimiter_depth != 0) {
- dbg_hid("nested delimiters\n");
+ hid_err(parser->device, "nested delimiters\n");
return -1;
}
parser->local.delimiter_depth++;
parser->local.delimiter_branch++;
} else {
if (parser->local.delimiter_depth < 1) {
- dbg_hid("bogus close delimiter\n");
+ hid_err(parser->device, "bogus close delimiter\n");
return -1;
}
parser->local.delimiter_depth--;
@@ -506,7 +507,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
break;
default:
- dbg_hid("unknown main item tag 0x%x\n", item->tag);
+ hid_err(parser->device, "unknown main item tag 0x%x\n", item->tag);
ret = 0;
}
@@ -678,12 +679,12 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
while ((start = fetch_item(start, end, &item)) != NULL) {
if (item.format != HID_ITEM_FORMAT_SHORT) {
- dbg_hid("unexpected long global item\n");
+ hid_err(device, "unexpected long global item\n");
goto err;
}
if (dispatch_type[item.type](parser, &item)) {
- dbg_hid("item %u %u %u %u parsing failed\n",
+ hid_err(device, "item %u %u %u %u parsing failed\n",
item.format, (unsigned)item.size,
(unsigned)item.type, (unsigned)item.tag);
goto err;
@@ -691,11 +692,11 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
if (start == end) {
if (parser->collection_stack_ptr) {
- dbg_hid("unbalanced collection at end of report description\n");
+ hid_err(device, "unbalanced collection at end of report description\n");
goto err;
}
if (parser->local.delimiter_depth) {
- dbg_hid("unbalanced delimiter at end of report description\n");
+ hid_err(device, "unbalanced delimiter at end of report description\n");
goto err;
}
vfree(parser);
@@ -703,7 +704,7 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
}
}
- dbg_hid("item fetching failed at offset %d\n", (int)(end - start));
+ hid_err(device, "item fetching failed at offset %d\n", (int)(end - start));
err:
vfree(parser);
return ret;
@@ -873,7 +874,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field,
ret = hdrv->event(hid, field, usage, value);
if (ret != 0) {
if (ret < 0)
- dbg_hid("%s's event failed with %d\n",
+ hid_err(hid, "%s's event failed with %d\n",
hdrv->name, ret);
return;
}
@@ -995,12 +996,13 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
hid_dump_input(field->report->device, field->usage + offset, value);
if (offset >= field->report_count) {
- dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count);
+ hid_err(field->report->device, "offset (%d) exceeds report_count (%d)\n",
+ offset, field->report_count);
return -1;
}
if (field->logical_minimum < 0) {
if (value != snto32(s32ton(value, size), size)) {
- dbg_hid("value %d is out of range\n", value);
+ hid_err(field->report->device, "value %d is out of range\n", value);
return -1;
}
}
@@ -1157,7 +1159,7 @@ static bool hid_match_one_id(struct hid_device *hdev,
(id->product == HID_ANY_ID || id->product == hdev->product);
}
-static const struct hid_device_id *hid_match_id(struct hid_device *hdev,
+const struct hid_device_id *hid_match_id(struct hid_device *hdev,
const struct hid_device_id *id)
{
for (; id->bus; id++)
@@ -1404,11 +1406,13 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ 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) },
- { 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) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2515) },
{ HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
@@ -1423,6 +1427,7 @@ 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_HANVON_ALT, USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6650) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) },
@@ -1498,11 +1503,15 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
@@ -1544,11 +1553,21 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_XAT, USB_DEVICE_ID_XAT_CSR) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX1) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX1) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR1) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
@@ -1768,6 +1787,7 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x0004) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x000a) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
@@ -1973,6 +1993,16 @@ static bool hid_ignore(struct hid_device *hdev)
if (hdev->product >= USB_DEVICE_ID_LOGITECH_HARMONY_FIRST &&
hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST)
return true;
+ /*
+ * The Keene FM transmitter USB device has the same USB ID as
+ * the Logitech AudioHub Speaker, but it should ignore the hid.
+ * Check if the name is that of the Keene device.
+ * For reference: the name of the AudioHub is
+ * "HOLTEK AudioHub Speaker".
+ */
+ if (hdev->product == USB_DEVICE_ID_LOGITECH_AUDIOHUB &&
+ !strcmp(hdev->name, "HOLTEK B-LINK USB Audio "))
+ return true;
break;
case USB_VENDOR_ID_SOUNDGRAPH:
if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST &&
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index ee80d733801..01dd9a7daf7 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -114,6 +114,14 @@ static const struct hid_usage_entry hid_usage_table[] = {
{0, 0xbd, "FlareRelease"},
{0, 0xbe, "LandingGear"},
{0, 0xbf, "ToeBrake"},
+ { 6, 0, "GenericDeviceControls" },
+ {0, 0x20, "BatteryStrength" },
+ {0, 0x21, "WirelessChannel" },
+ {0, 0x22, "WirelessID" },
+ {0, 0x23, "DiscoverWirelessControl" },
+ {0, 0x24, "SecurityCodeCharacterEntered" },
+ {0, 0x25, "SecurityCodeCharactedErased" },
+ {0, 0x26, "SecurityCodeCleared" },
{ 7, 0, "Keyboard" },
{ 8, 0, "LED" },
{0, 0x01, "NumLock"},
diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c
index 9bdde867a02..2630d483d26 100644
--- a/drivers/hid/hid-emsff.c
+++ b/drivers/hid/hid-emsff.c
@@ -140,7 +140,7 @@ err:
}
static const struct hid_device_id ems_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_EMS, 0x118) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
{ }
};
MODULE_DEVICE_TABLE(hid, ems_devices);
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
new file mode 100644
index 00000000000..406632472c1
--- /dev/null
+++ b/drivers/hid/hid-hyperv.c
@@ -0,0 +1,587 @@
+/*
+ * Copyright (c) 2009, Citrix Systems, Inc.
+ * Copyright (c) 2010, Microsoft Corporation.
+ * Copyright (c) 2011, Novell Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/completion.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/hiddev.h>
+#include <linux/hyperv.h>
+
+
+struct hv_input_dev_info {
+ unsigned int size;
+ unsigned short vendor;
+ unsigned short product;
+ unsigned short version;
+ unsigned short reserved[11];
+};
+
+/* The maximum size of a synthetic input message. */
+#define SYNTHHID_MAX_INPUT_REPORT_SIZE 16
+
+/*
+ * Current version
+ *
+ * History:
+ * Beta, RC < 2008/1/22 1,0
+ * RC > 2008/1/22 2,0
+ */
+#define SYNTHHID_INPUT_VERSION_MAJOR 2
+#define SYNTHHID_INPUT_VERSION_MINOR 0
+#define SYNTHHID_INPUT_VERSION (SYNTHHID_INPUT_VERSION_MINOR | \
+ (SYNTHHID_INPUT_VERSION_MAJOR << 16))
+
+
+#pragma pack(push, 1)
+/*
+ * Message types in the synthetic input protocol
+ */
+enum synthhid_msg_type {
+ SYNTH_HID_PROTOCOL_REQUEST,
+ SYNTH_HID_PROTOCOL_RESPONSE,
+ SYNTH_HID_INITIAL_DEVICE_INFO,
+ SYNTH_HID_INITIAL_DEVICE_INFO_ACK,
+ SYNTH_HID_INPUT_REPORT,
+ SYNTH_HID_MAX
+};
+
+/*
+ * Basic message structures.
+ */
+struct synthhid_msg_hdr {
+ enum synthhid_msg_type type;
+ u32 size;
+};
+
+struct synthhid_msg {
+ struct synthhid_msg_hdr header;
+ char data[1]; /* Enclosed message */
+};
+
+union synthhid_version {
+ struct {
+ u16 minor_version;
+ u16 major_version;
+ };
+ u32 version;
+};
+
+/*
+ * Protocol messages
+ */
+struct synthhid_protocol_request {
+ struct synthhid_msg_hdr header;
+ union synthhid_version version_requested;
+};
+
+struct synthhid_protocol_response {
+ struct synthhid_msg_hdr header;
+ union synthhid_version version_requested;
+ unsigned char approved;
+};
+
+struct synthhid_device_info {
+ struct synthhid_msg_hdr header;
+ struct hv_input_dev_info hid_dev_info;
+ struct hid_descriptor hid_descriptor;
+};
+
+struct synthhid_device_info_ack {
+ struct synthhid_msg_hdr header;
+ unsigned char reserved;
+};
+
+struct synthhid_input_report {
+ struct synthhid_msg_hdr header;
+ char buffer[1];
+};
+
+#pragma pack(pop)
+
+#define INPUTVSC_SEND_RING_BUFFER_SIZE (10*PAGE_SIZE)
+#define INPUTVSC_RECV_RING_BUFFER_SIZE (10*PAGE_SIZE)
+
+
+enum pipe_prot_msg_type {
+ PIPE_MESSAGE_INVALID,
+ PIPE_MESSAGE_DATA,
+ PIPE_MESSAGE_MAXIMUM
+};
+
+
+struct pipe_prt_msg {
+ enum pipe_prot_msg_type type;
+ u32 size;
+ char data[1];
+};
+
+struct mousevsc_prt_msg {
+ enum pipe_prot_msg_type type;
+ u32 size;
+ union {
+ struct synthhid_protocol_request request;
+ struct synthhid_protocol_response response;
+ struct synthhid_device_info_ack ack;
+ };
+};
+
+/*
+ * Represents an mousevsc device
+ */
+struct mousevsc_dev {
+ struct hv_device *device;
+ bool init_complete;
+ bool connected;
+ struct mousevsc_prt_msg protocol_req;
+ struct mousevsc_prt_msg protocol_resp;
+ /* Synchronize the request/response if needed */
+ struct completion wait_event;
+ int dev_info_status;
+
+ struct hid_descriptor *hid_desc;
+ unsigned char *report_desc;
+ u32 report_desc_size;
+ struct hv_input_dev_info hid_dev_info;
+ struct hid_device *hid_device;
+};
+
+
+static struct mousevsc_dev *mousevsc_alloc_device(struct hv_device *device)
+{
+ struct mousevsc_dev *input_dev;
+
+ input_dev = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL);
+
+ if (!input_dev)
+ return NULL;
+
+ input_dev->device = device;
+ hv_set_drvdata(device, input_dev);
+ init_completion(&input_dev->wait_event);
+ input_dev->init_complete = false;
+
+ return input_dev;
+}
+
+static void mousevsc_free_device(struct mousevsc_dev *device)
+{
+ kfree(device->hid_desc);
+ kfree(device->report_desc);
+ hv_set_drvdata(device->device, NULL);
+ kfree(device);
+}
+
+static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
+ struct synthhid_device_info *device_info)
+{
+ int ret = 0;
+ struct hid_descriptor *desc;
+ struct mousevsc_prt_msg ack;
+
+ input_device->dev_info_status = -ENOMEM;
+
+ input_device->hid_dev_info = device_info->hid_dev_info;
+ desc = &device_info->hid_descriptor;
+ if (desc->bLength == 0)
+ goto cleanup;
+
+ input_device->hid_desc = kzalloc(desc->bLength, GFP_ATOMIC);
+
+ if (!input_device->hid_desc)
+ goto cleanup;
+
+ memcpy(input_device->hid_desc, desc, desc->bLength);
+
+ input_device->report_desc_size = desc->desc[0].wDescriptorLength;
+ if (input_device->report_desc_size == 0) {
+ input_device->dev_info_status = -EINVAL;
+ goto cleanup;
+ }
+
+ input_device->report_desc = kzalloc(input_device->report_desc_size,
+ GFP_ATOMIC);
+
+ if (!input_device->report_desc) {
+ input_device->dev_info_status = -ENOMEM;
+ goto cleanup;
+ }
+
+ memcpy(input_device->report_desc,
+ ((unsigned char *)desc) + desc->bLength,
+ desc->desc[0].wDescriptorLength);
+
+ /* Send the ack */
+ memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
+
+ ack.type = PIPE_MESSAGE_DATA;
+ ack.size = sizeof(struct synthhid_device_info_ack);
+
+ ack.ack.header.type = SYNTH_HID_INITIAL_DEVICE_INFO_ACK;
+ ack.ack.header.size = 1;
+ ack.ack.reserved = 0;
+
+ ret = vmbus_sendpacket(input_device->device->channel,
+ &ack,
+ sizeof(struct pipe_prt_msg) - sizeof(unsigned char) +
+ sizeof(struct synthhid_device_info_ack),
+ (unsigned long)&ack,
+ VM_PKT_DATA_INBAND,
+ VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+ if (!ret)
+ input_device->dev_info_status = 0;
+
+cleanup:
+ complete(&input_device->wait_event);
+
+ return;
+}
+
+static void mousevsc_on_receive(struct hv_device *device,
+ struct vmpacket_descriptor *packet)
+{
+ struct pipe_prt_msg *pipe_msg;
+ struct synthhid_msg *hid_msg;
+ struct mousevsc_dev *input_dev = hv_get_drvdata(device);
+ struct synthhid_input_report *input_report;
+
+ pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet +
+ (packet->offset8 << 3));
+
+ if (pipe_msg->type != PIPE_MESSAGE_DATA)
+ return;
+
+ hid_msg = (struct synthhid_msg *)pipe_msg->data;
+