Skip to content

Commit

Permalink
Merge branches 'for-3.11/multitouch', 'for-3.11/sony' and 'for-3.11/u…
Browse files Browse the repository at this point in the history
…pstream' into for-linus

Conflicts:
	drivers/hid/hid-core.c
  • Loading branch information
Jiri Kosina committed Jul 4, 2013
4 parents db58316 + adb91ae + 078328d + 3685c18 commit 08ec2dc
Show file tree
Hide file tree
Showing 12 changed files with 736 additions and 256 deletions.
26 changes: 14 additions & 12 deletions drivers/hid/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,12 @@ config HOLTEK_FF
Say Y here if you have a Holtek On Line Grip based game controller
and want to have force feedback support for it.

config HID_HUION
tristate "Huion tablets"
depends on USB_HID
---help---
Support for Huion 580 tablet.

config HID_KEYTOUCH
tristate "Keytouch HID devices"
depends on HID
Expand Down Expand Up @@ -571,15 +577,6 @@ config HID_PRIMAX
Support for Primax devices that are not fully compliant with the
HID standard.

config HID_PS3REMOTE
tristate "Sony PS3 BD Remote Control"
depends on HID
---help---
Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech
Harmony Adapter for PS3, which connect over Bluetooth.

Support for the 6-axis controllers is provided by HID_SONY.

config HID_ROCCAT
tristate "Roccat device support"
depends on USB_HID
Expand All @@ -604,12 +601,17 @@ config HID_SAMSUNG
Support for Samsung InfraRed remote control or keyboards.

config HID_SONY
tristate "Sony PS3 controller"
tristate "Sony PS2/3 accessories"
depends on USB_HID
depends on NEW_LEDS
depends on LEDS_CLASS
---help---
Support for Sony PS3 6-axis controllers.
Support for

Support for the Sony PS3 BD Remote is provided by HID_PS3REMOTE.
* Sony PS3 6-axis controllers
* Buzz controllers
* Sony PS3 Blue-ray Disk Remote Control (Bluetooth)
* Logitech Harmony adapter for Sony Playstation 3 (Bluetooth)

config HID_SPEEDLINK
tristate "Speedlink VAD Cezanne mouse support"
Expand Down
2 changes: 1 addition & 1 deletion drivers/hid/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o
obj-$(CONFIG_HID_HOLTEK) += hid-holtek-mouse.o
obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o
obj-$(CONFIG_HID_HUION) += hid-huion.o
obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o
obj-$(CONFIG_HID_ICADE) += hid-icade.o
obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
Expand Down Expand Up @@ -94,7 +95,6 @@ hid-picolcd-y += hid-picolcd_debugfs.o
endif

obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o
obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \
Expand Down
8 changes: 7 additions & 1 deletion drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1293,7 +1293,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i

if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
ret = hdrv->raw_event(hid, report, data, size);
if (ret != 0) {
if (ret < 0) {
ret = ret < 0 ? ret : 0;
goto unlock;
}
Expand Down Expand Up @@ -1588,10 +1588,12 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
{ 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_GENIUS_GILA_GAMING_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
Expand Down Expand Up @@ -1684,6 +1686,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
Expand Down Expand Up @@ -2046,6 +2050,8 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) },
{ HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_410) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_510) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
Expand Down
177 changes: 177 additions & 0 deletions drivers/hid/hid-huion.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* HID driver for Huion devices not fully compliant with HID standard
*
* Copyright (c) 2013 Martin Rusko
*/

/*
* 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 "usbhid/usbhid.h"

#include "hid-ids.h"

/* Original Huion 580 report descriptor size */
#define HUION_580_RDESC_ORIG_SIZE 177

/* Fixed Huion 580 report descriptor */
static __u8 huion_580_rdesc_fixed[] = {
0x05, 0x0D, /* Usage Page (Digitizer), */
0x09, 0x02, /* Usage (Pen), */
0xA1, 0x01, /* Collection (Application), */
0x85, 0x07, /* Report ID (7), */
0x09, 0x20, /* Usage (Stylus), */
0xA0, /* Collection (Physical), */
0x14, /* Logical Minimum (0), */
0x25, 0x01, /* Logical Maximum (1), */
0x75, 0x01, /* Report Size (1), */
0x09, 0x42, /* Usage (Tip Switch), */
0x09, 0x44, /* Usage (Barrel Switch), */
0x09, 0x46, /* Usage (Tablet Pick), */
0x95, 0x03, /* Report Count (3), */
0x81, 0x02, /* Input (Variable), */
0x95, 0x03, /* Report Count (3), */
0x81, 0x03, /* Input (Constant, Variable), */
0x09, 0x32, /* Usage (In Range), */
0x95, 0x01, /* Report Count (1), */
0x81, 0x02, /* Input (Variable), */
0x95, 0x01, /* Report Count (1), */
0x81, 0x03, /* Input (Constant, Variable), */
0x75, 0x10, /* Report Size (16), */
0x95, 0x01, /* Report Count (1), */
0xA4, /* Push, */
0x05, 0x01, /* Usage Page (Desktop), */
0x65, 0x13, /* Unit (Inch), */
0x55, 0xFD, /* Unit Exponent (-3), */
0x34, /* Physical Minimum (0), */
0x09, 0x30, /* Usage (X), */
0x46, 0x40, 0x1F, /* Physical Maximum (8000), */
0x26, 0x00, 0x7D, /* Logical Maximum (32000), */
0x81, 0x02, /* Input (Variable), */
0x09, 0x31, /* Usage (Y), */
0x46, 0x88, 0x13, /* Physical Maximum (5000), */
0x26, 0x20, 0x4E, /* Logical Maximum (20000), */
0x81, 0x02, /* Input (Variable), */
0xB4, /* Pop, */
0x09, 0x30, /* Usage (Tip Pressure), */
0x26, 0xFF, 0x07, /* Logical Maximum (2047), */
0x81, 0x02, /* Input (Variable), */
0xC0, /* End Collection, */
0xC0 /* End Collection */
};

static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
switch (hdev->product) {
case USB_DEVICE_ID_HUION_580:
if (*rsize == HUION_580_RDESC_ORIG_SIZE) {
rdesc = huion_580_rdesc_fixed;
*rsize = sizeof(huion_580_rdesc_fixed);
}
break;
}
return rdesc;
}

/**
* Enable fully-functional tablet mode by reading special string
* descriptor.
*
* @hdev: HID device
*
* The specific string descriptor and data were discovered by sniffing
* the Windows driver traffic.
*/
static int huion_tablet_enable(struct hid_device *hdev)
{
int rc;
char buf[22];

rc = usb_string(hid_to_usb_dev(hdev), 0x64, buf, sizeof(buf));
if (rc < 0)
return rc;

return 0;
}

static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int ret;
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);

/* Ignore interfaces 1 (mouse) and 2 (keyboard) for Huion 580 tablet,
* as they are not used
*/
switch (id->product) {
case USB_DEVICE_ID_HUION_580:
if (intf->cur_altsetting->desc.bInterfaceNumber != 0x00)
return -ENODEV;
break;
}

ret = hid_parse(hdev);
if (ret) {
hid_err(hdev, "parse failed\n");
goto err;
}

ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret) {
hid_err(hdev, "hw start failed\n");
goto err;
}

switch (id->product) {
case USB_DEVICE_ID_HUION_580:
ret = huion_tablet_enable(hdev);
if (ret) {
hid_err(hdev, "tablet enabling failed\n");
goto enabling_err;
}
break;
}

return 0;
enabling_err:
hid_hw_stop(hdev);
err:
return ret;
}

static int huion_raw_event(struct hid_device *hdev, struct hid_report *report,
u8 *data, int size)
{
/* If this is a pen input report then invert the in-range bit */
if (report->type == HID_INPUT_REPORT && report->id == 0x07 && size >= 2)
data[1] ^= 0x40;

return 0;
}

static const struct hid_device_id huion_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
{ }
};
MODULE_DEVICE_TABLE(hid, huion_devices);

static struct hid_driver huion_driver = {
.name = "huion",
.id_table = huion_devices,
.probe = huion_probe,
.report_fixup = huion_report_fixup,
.raw_event = huion_raw_event,
};
module_hid_driver(huion_driver);

MODULE_AUTHOR("Martin Rusko");
MODULE_DESCRIPTION("Huion HID driver");
MODULE_LICENSE("GPL");
4 changes: 1 addition & 3 deletions drivers/hid/hid-hyperv.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,11 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
if (desc->bLength == 0)
goto cleanup;

input_device->hid_desc = kzalloc(desc->bLength, GFP_ATOMIC);
input_device->hid_desc = kmemdup(desc, 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;
Expand Down
20 changes: 16 additions & 4 deletions drivers/hid/hid-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@
#define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81
#define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001

#define USB_VENDOR_ID_DATA_MODUL 0x7374
#define USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH 0x1201

#define USB_VENDOR_ID_DEALEXTREAME 0x10c5
#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a

Expand All @@ -272,16 +275,15 @@
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E 0x725e
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262 0x7262
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA 0x72aa
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1 0x72a1
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA 0x72aa
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4 0x72c4
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0 0x72d0
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA 0x72fa
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302 0x7302
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349 0x7349
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224 0x7224
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0 0x72d0
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4 0x72c4

#define USB_VENDOR_ID_ELECOM 0x056e
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
Expand Down Expand Up @@ -425,6 +427,9 @@
#define USB_DEVICE_ID_UGCI_FLYING 0x0020
#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030

#define USB_VENDOR_ID_HUION 0x256c
#define USB_DEVICE_ID_HUION_580 0x006e

#define USB_VENDOR_ID_IDEACOM 0x1cb6
#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650
#define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651
Expand All @@ -449,6 +454,10 @@
#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615
#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070

#define USB_VENDOR_ID_JABRA 0x0b0e
#define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412
#define USB_DEVICE_ID_JABRA_SPEAK_510 0x0420

#define USB_VENDOR_ID_JESS 0x0c45
#define USB_DEVICE_ID_JESS_YUREX 0x1010

Expand All @@ -469,6 +478,7 @@

#define USB_VENDOR_ID_KYE 0x0458
#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
#define USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE 0x0138
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
#define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010
#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011
Expand Down Expand Up @@ -736,6 +746,8 @@
#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
#define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002
#define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER 0x1000

#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034
Expand Down
7 changes: 6 additions & 1 deletion drivers/hid/hid-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,9 +1042,14 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct

/*
* Ignore out-of-range values as per HID specification,
* section 5.10 and 6.2.25
* section 5.10 and 6.2.25.
*
* The logical_minimum < logical_maximum check is done so that we
* don't unintentionally discard values sent by devices which
* don't specify logical min and max.
*/
if ((field->flags & HID_MAIN_ITEM_VARIABLE) &&
(field->logical_minimum < field->logical_maximum) &&
(value < field->logical_minimum ||
value > field->logical_maximum)) {
dbg_hid("Ignoring out-of-range value %x\n", value);
Expand Down
Loading

0 comments on commit 08ec2dc

Please sign in to comment.