Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/hid/hid

Pull HID fixes from Jiri Kosina:

 - regression fixes (reverts) for module loading changes that turned out
   to be incompatible with some userspace, from Benjamin Tissoires

 - regression fix for special Logitech unifiying receiver 0xc52f, from
   Hans de Goede

 - a few device ID additions to logitech driver, from Hans de Goede

 - fix for Bluetooth support on 2nd-gen Wacom Intuos Pro, from Jason
   Gerecke

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
  HID: logitech-dj: Fix 064d:c52f receiver support
  Revert "HID: core: Call request_module before doing device_add"
  Revert "HID: core: Do not call request_module() in async context"
  Revert "HID: Increase maximum report size allowed by hid_field_extract()"
  HID: a4tech: fix horizontal scrolling
  HID: hyperv: Add a module description line
  HID: logitech-hidpp: Add support for the S510 remote control
  HID: multitouch: handle faulty Elo touch device
  HID: wacom: Sync INTUOSP2_BT touch state after each frame if necessary
  HID: wacom: Correct button numbering 2nd-gen Intuos Pro over Bluetooth
  HID: wacom: Send BTN_TOUCH in response to INTUOSP2_BT eraser contact
  HID: wacom: Don't report anything prior to the tool entering range
  HID: wacom: Don't set tool type until we're in range
  HID: rmi: Use SET_REPORT request on control endpoint for Acer Switch 3 and 5
  HID: logitech-hidpp: add support for the MX5500 keyboard
  HID: logitech-dj: add support for the Logitech MX5500's Bluetooth Mini-Receiver
  HID: i2c-hid: add iBall Aer3 to descriptor override
  • Loading branch information
torvalds committed Jun 13, 2019
2 parents b076173 + 3ed224e commit c11fb13
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 54 deletions.
11 changes: 8 additions & 3 deletions drivers/hid/hid-a4tech.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi,
{
struct a4tech_sc *a4 = hid_get_drvdata(hdev);

if (usage->type == EV_REL && usage->code == REL_WHEEL)
if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES) {
set_bit(REL_HWHEEL, *bit);
set_bit(REL_HWHEEL_HI_RES, *bit);
}

if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007)
return -1;
Expand All @@ -57,14 +59,16 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
input = field->hidinput->input;

if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) {
if (usage->type == EV_REL && usage->code == REL_WHEEL) {
if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES) {
a4->delayed_value = value;
return 1;
}

if (usage->hid == 0x000100b8) {
input_event(input, EV_REL, value ? REL_HWHEEL :
REL_WHEEL, a4->delayed_value);
input_event(input, EV_REL, value ? REL_HWHEEL_HI_RES :
REL_WHEEL_HI_RES, a4->delayed_value * 120);
return 1;
}
}
Expand All @@ -74,8 +78,9 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
return 1;
}

if (usage->code == REL_WHEEL && a4->hw_wheel) {
if (usage->code == REL_WHEEL_HI_RES && a4->hw_wheel) {
input_event(input, usage->type, REL_HWHEEL, value);
input_event(input, usage->type, REL_HWHEEL_HI_RES, value * 120);
return 1;
}

Expand Down
16 changes: 3 additions & 13 deletions drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <linux/semaphore.h>
#include <linux/async.h>

#include <linux/hid.h>
#include <linux/hiddev.h>
Expand Down Expand Up @@ -1311,10 +1310,10 @@ static u32 __extract(u8 *report, unsigned offset, int n)
u32 hid_field_extract(const struct hid_device *hid, u8 *report,
unsigned offset, unsigned n)
{
if (n > 256) {
hid_warn(hid, "hid_field_extract() called with n (%d) > 256! (%s)\n",
if (n > 32) {
hid_warn(hid, "hid_field_extract() called with n (%d) > 32! (%s)\n",
n, current->comm);
n = 256;
n = 32;
}

return __extract(report, offset, n);
Expand Down Expand Up @@ -2362,15 +2361,6 @@ int hid_add_device(struct hid_device *hdev)
dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
hdev->vendor, hdev->product, atomic_inc_return(&id));

/*
* Try loading the module for the device before the add, so that we do
* not first have hid-generic binding only to have it replaced
* immediately afterwards with a specialized driver.
*/
if (!current_is_async())
request_module("hid:b%04Xg%04Xv%08Xp%08X", hdev->bus,
hdev->group, hdev->vendor, hdev->product);

hid_debug_register(hdev, dev_name(&hdev->dev));
ret = device_add(&hdev->dev);
if (!ret)
Expand Down
2 changes: 2 additions & 0 deletions drivers/hid/hid-hyperv.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,5 +606,7 @@ static void __exit mousevsc_exit(void)
}

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic HID Driver");

module_init(mousevsc_init);
module_exit(mousevsc_exit);
1 change: 1 addition & 0 deletions drivers/hid/hid-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,7 @@
#define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3
#define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3
#define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710
#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7

#define USB_VENDOR_ID_TEXAS_INSTRUMENTS 0x2047
#define USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA 0x0855
Expand Down
50 changes: 35 additions & 15 deletions drivers/hid/hid-logitech-dj.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ enum recvr_type {
recvr_type_dj,
recvr_type_hidpp,
recvr_type_gaming_hidpp,
recvr_type_mouse_only,
recvr_type_27mhz,
recvr_type_bluetooth,
};
Expand Down Expand Up @@ -864,9 +865,12 @@ static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev,
schedule_work(&djrcv_dev->work);
}

static void logi_hidpp_dev_conn_notif_equad(struct hidpp_event *hidpp_report,
static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev,
struct hidpp_event *hidpp_report,
struct dj_workitem *workitem)
{
struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);

workitem->type = WORKITEM_TYPE_PAIRED;
workitem->device_type = hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] &
HIDPP_DEVICE_TYPE_MASK;
Expand All @@ -880,6 +884,8 @@ static void logi_hidpp_dev_conn_notif_equad(struct hidpp_event *hidpp_report,
break;
case REPORT_TYPE_MOUSE:
workitem->reports_supported |= STD_MOUSE | HIDPP;
if (djrcv_dev->type == recvr_type_mouse_only)
workitem->reports_supported |= MULTIMEDIA;
break;
}
}
Expand Down Expand Up @@ -923,7 +929,7 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev,
case 0x01:
device_type = "Bluetooth";
/* Bluetooth connect packet contents is the same as (e)QUAD */
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
if (!(hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] &
HIDPP_MANUFACTURER_MASK)) {
hid_info(hdev, "Non Logitech device connected on slot %d\n",
Expand All @@ -937,18 +943,18 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev,
break;
case 0x03:
device_type = "QUAD or eQUAD";
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
break;
case 0x04:
device_type = "eQUAD step 4 DJ";
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
break;
case 0x05:
device_type = "DFU Lite";
break;
case 0x06:
device_type = "eQUAD step 4 Lite";
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
break;
case 0x07:
device_type = "eQUAD step 4 Gaming";
Expand All @@ -958,11 +964,11 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev,
break;
case 0x0a:
device_type = "eQUAD nano Lite";
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
break;
case 0x0c:
device_type = "eQUAD Lightspeed";
logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem);
logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem);
workitem.reports_supported |= STD_KEYBOARD;
break;
}
Expand Down Expand Up @@ -1313,7 +1319,8 @@ static int logi_dj_ll_parse(struct hid_device *hid)
if (djdev->reports_supported & STD_MOUSE) {
dbg_hid("%s: sending a mouse descriptor, reports_supported: %llx\n",
__func__, djdev->reports_supported);
if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp)
if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp ||
djdev->dj_receiver_dev->type == recvr_type_mouse_only)
rdcat(rdesc, &rsize, mse_high_res_descriptor,
sizeof(mse_high_res_descriptor));
else if (djdev->dj_receiver_dev->type == recvr_type_27mhz)
Expand Down Expand Up @@ -1556,15 +1563,19 @@ static int logi_dj_raw_event(struct hid_device *hdev,
data[0] = data[1];
data[1] = 0;
}
/* The 27 MHz mouse-only receiver sends unnumbered mouse data */
/*
* Mouse-only receivers send unnumbered mouse data. The 27 MHz
* receiver uses 6 byte packets, the nano receiver 8 bytes.
*/
if (djrcv_dev->unnumbered_application == HID_GD_MOUSE &&
size == 6) {
u8 mouse_report[7];
size <= 8) {
u8 mouse_report[9];

/* Prepend report id */
mouse_report[0] = REPORT_TYPE_MOUSE;
memcpy(mouse_report + 1, data, 6);
logi_dj_recv_forward_input_report(hdev, mouse_report, 7);
memcpy(mouse_report + 1, data, size);
logi_dj_recv_forward_input_report(hdev, mouse_report,
size + 1);
}

return false;
Expand Down Expand Up @@ -1635,6 +1646,7 @@ static int logi_dj_probe(struct hid_device *hdev,
case recvr_type_dj: no_dj_interfaces = 3; break;
case recvr_type_hidpp: no_dj_interfaces = 2; break;
case recvr_type_gaming_hidpp: no_dj_interfaces = 3; break;
case recvr_type_mouse_only: no_dj_interfaces = 2; break;
case recvr_type_27mhz: no_dj_interfaces = 2; break;
case recvr_type_bluetooth: no_dj_interfaces = 2; break;
}
Expand Down Expand Up @@ -1808,10 +1820,10 @@ static const struct hid_device_id logi_dj_receivers[] = {
{HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2),
.driver_data = recvr_type_dj},
{ /* Logitech Nano (non DJ) receiver */
{ /* Logitech Nano mouse only receiver */
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER),
.driver_data = recvr_type_hidpp},
.driver_data = recvr_type_mouse_only},
{ /* Logitech Nano (non DJ) receiver */
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2),
Expand All @@ -1836,6 +1848,14 @@ static const struct hid_device_id logi_dj_receivers[] = {
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
0xc70a),
.driver_data = recvr_type_bluetooth},
{ /* Logitech MX5500 HID++ / bluetooth receiver keyboard intf. */
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
0xc71b),
.driver_data = recvr_type_bluetooth},
{ /* Logitech MX5500 HID++ / bluetooth receiver mouse intf. */
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
0xc71c),
.driver_data = recvr_type_bluetooth},
{}
};

Expand Down
9 changes: 9 additions & 0 deletions drivers/hid/hid-logitech-hidpp.c
Original file line number Diff line number Diff line change
Expand Up @@ -3728,6 +3728,9 @@ static const struct hid_device_id hidpp_devices[] = {
{ /* Keyboard MX5000 (Bluetooth-receiver in HID proxy mode) */
LDJ_DEVICE(0xb305),
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
{ /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */
LDJ_DEVICE(0xb30b),
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },

{ LDJ_DEVICE(HID_ANY_ID) },

Expand All @@ -3740,6 +3743,9 @@ static const struct hid_device_id hidpp_devices[] = {
{ /* Keyboard MX3200 (Y-RAV80) */
L27MHZ_DEVICE(0x005c),
.driver_data = HIDPP_QUIRK_KBD_ZOOM_WHEEL },
{ /* S510 Media Remote */
L27MHZ_DEVICE(0x00fe),
.driver_data = HIDPP_QUIRK_KBD_SCROLL_WHEEL },

{ L27MHZ_DEVICE(HID_ANY_ID) },

Expand All @@ -3756,6 +3762,9 @@ static const struct hid_device_id hidpp_devices[] = {
{ /* MX5000 keyboard over Bluetooth */
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb305),
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
{ /* MX5500 keyboard over Bluetooth */
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b),
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
{}
};

Expand Down
7 changes: 7 additions & 0 deletions drivers/hid/hid-multitouch.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,13 @@ static void mt_store_field(struct hid_device *hdev,
if (*target != DEFAULT_TRUE &&
*target != DEFAULT_FALSE &&
*target != DEFAULT_ZERO) {
if (usage->contactid == DEFAULT_ZERO ||
usage->x == DEFAULT_ZERO ||
usage->y == DEFAULT_ZERO) {
hid_dbg(hdev,
"ignoring duplicate usage on incomplete");
return;
}
usage = mt_allocate_usage(hdev, application);
if (!usage)
return;
Expand Down
15 changes: 14 additions & 1 deletion drivers/hid/hid-rmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
/* device flags */
#define RMI_DEVICE BIT(0)
#define RMI_DEVICE_HAS_PHYS_BUTTONS BIT(1)
#define RMI_DEVICE_OUTPUT_SET_REPORT BIT(2)

/*
* retrieve the ctrl registers
Expand Down Expand Up @@ -163,9 +164,19 @@ static int rmi_set_mode(struct hid_device *hdev, u8 mode)

static int rmi_write_report(struct hid_device *hdev, u8 *report, int len)
{
struct rmi_data *data = hid_get_drvdata(hdev);
int ret;

ret = hid_hw_output_report(hdev, (void *)report, len);
if (data->device_flags & RMI_DEVICE_OUTPUT_SET_REPORT) {
/*
* Talk to device by using SET_REPORT requests instead.
*/
ret = hid_hw_raw_request(hdev, report[0], report,
len, HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
} else {
ret = hid_hw_output_report(hdev, (void *)report, len);
}

if (ret < 0) {
dev_err(&hdev->dev, "failed to write hid report (%d)\n", ret);
return ret;
Expand Down Expand Up @@ -747,6 +758,8 @@ static const struct hid_device_id rmi_id[] = {
.driver_data = RMI_DEVICE_HAS_PHYS_BUTTONS },
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_REZEL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5),
.driver_data = RMI_DEVICE_OUTPUT_SET_REPORT },
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_RMI, HID_ANY_ID, HID_ANY_ID) },
{ }
};
Expand Down
8 changes: 8 additions & 0 deletions drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
},
.driver_data = (void *)&sipodev_desc
},
{
.ident = "iBall Aer3",
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "iBall"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Aer3"),
},
.driver_data = (void *)&sipodev_desc
},
{ } /* Terminate list */
};

Expand Down
Loading

0 comments on commit c11fb13

Please sign in to comment.