Commit ecb4d529 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID fixes from Jiri Kosina:

 - hid.git is moving towards group maintainership (where group is myself
   and Benjamin Tissoires), therefore this pull request updates
   MAINTAINERS accordingly

 - fix for hid-asus config dependency from Arnd Bergmann

 - two device-specific quirks for i2c-hid from Julian Sax and Kai-Heng
   Feng

 - other few small assorted fixes

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
  HID: fix up .raw_event() documentation
  HID: asus: fix build warning wiht CONFIG_ASUS_WMI disabled
  HID: i2c-hid: add Direkt-Tek DTLAPY133-1 to descriptor override
  HID: moving to group maintainership model
  HID: alps: allow incoming reports when only the trackstick is opened
  Revert "HID: add NOGET quirk for Eaton Ellipse MAX UPS"
  HID: i2c-hid: Add a small delay after sleep command for Raydium touchpanel
  HID: hiddev: fix potential Spectre v1
parents 8053e5b9 aa9b760c
...@@ -6607,9 +6607,9 @@ F: arch/*/include/asm/suspend*.h ...@@ -6607,9 +6607,9 @@ F: arch/*/include/asm/suspend*.h
HID CORE LAYER HID CORE LAYER
M: Jiri Kosina <jikos@kernel.org> M: Jiri Kosina <jikos@kernel.org>
R: Benjamin Tissoires <benjamin.tissoires@redhat.com> M: Benjamin Tissoires <benjamin.tissoires@redhat.com>
L: linux-input@vger.kernel.org L: linux-input@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git
S: Maintained S: Maintained
F: drivers/hid/ F: drivers/hid/
F: include/linux/hid* F: include/linux/hid*
...@@ -15436,9 +15436,9 @@ F: include/linux/usb/gadget* ...@@ -15436,9 +15436,9 @@ F: include/linux/usb/gadget*
USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...) USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...)
M: Jiri Kosina <jikos@kernel.org> M: Jiri Kosina <jikos@kernel.org>
R: Benjamin Tissoires <benjamin.tissoires@redhat.com> M: Benjamin Tissoires <benjamin.tissoires@redhat.com>
L: linux-usb@vger.kernel.org L: linux-usb@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git
S: Maintained S: Maintained
F: Documentation/hid/hiddev.txt F: Documentation/hid/hiddev.txt
F: drivers/hid/usbhid/ F: drivers/hid/usbhid/
......
...@@ -660,6 +660,20 @@ static int T4_init(struct hid_device *hdev, struct alps_dev *pri_data) ...@@ -660,6 +660,20 @@ static int T4_init(struct hid_device *hdev, struct alps_dev *pri_data)
return ret; return ret;
} }
static int alps_sp_open(struct input_dev *dev)
{
struct hid_device *hid = input_get_drvdata(dev);
return hid_hw_open(hid);
}
static void alps_sp_close(struct input_dev *dev)
{
struct hid_device *hid = input_get_drvdata(dev);
hid_hw_close(hid);
}
static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi) static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi)
{ {
struct alps_dev *data = hid_get_drvdata(hdev); struct alps_dev *data = hid_get_drvdata(hdev);
...@@ -733,6 +747,10 @@ static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi) ...@@ -733,6 +747,10 @@ static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi)
input2->id.version = input->id.version; input2->id.version = input->id.version;
input2->dev.parent = input->dev.parent; input2->dev.parent = input->dev.parent;
input_set_drvdata(input2, hdev);
input2->open = alps_sp_open;
input2->close = alps_sp_close;
__set_bit(EV_KEY, input2->evbit); __set_bit(EV_KEY, input2->evbit);
data->sp_btn_cnt = (data->sp_btn_info & 0x0F); data->sp_btn_cnt = (data->sp_btn_info & 0x0F);
for (i = 0; i < data->sp_btn_cnt; i++) for (i = 0; i < data->sp_btn_cnt; i++)
......
...@@ -359,6 +359,9 @@ static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev) ...@@ -359,6 +359,9 @@ static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
u32 value; u32 value;
int ret; int ret;
if (!IS_ENABLED(CONFIG_ASUS_WMI))
return false;
ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2, ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2,
ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value); ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value); hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
......
...@@ -927,6 +927,9 @@ ...@@ -927,6 +927,9 @@
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003 0x3003 #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003 0x3003
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008 #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008
#define I2C_VENDOR_ID_RAYDIUM 0x2386
#define I2C_PRODUCT_ID_RAYDIUM_4B33 0x4b33
#define USB_VENDOR_ID_RAZER 0x1532 #define USB_VENDOR_ID_RAZER 0x1532
#define USB_DEVICE_ID_RAZER_BLADE_14 0x011D #define USB_DEVICE_ID_RAZER_BLADE_14 0x011D
......
...@@ -107,7 +107,6 @@ static const struct hid_device_id hid_quirks[] = { ...@@ -107,7 +107,6 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS },
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0)
#define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1)
#define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2) #define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2)
#define I2C_HID_QUIRK_DELAY_AFTER_SLEEP BIT(3)
/* flags */ /* flags */
#define I2C_HID_STARTED 0 #define I2C_HID_STARTED 0
...@@ -158,6 +159,8 @@ struct i2c_hid { ...@@ -158,6 +159,8 @@ struct i2c_hid {
bool irq_wake_enabled; bool irq_wake_enabled;
struct mutex reset_lock; struct mutex reset_lock;
unsigned long sleep_delay;
}; };
static const struct i2c_hid_quirks { static const struct i2c_hid_quirks {
...@@ -172,6 +175,8 @@ static const struct i2c_hid_quirks { ...@@ -172,6 +175,8 @@ static const struct i2c_hid_quirks {
{ I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET | I2C_HID_QUIRK_NO_IRQ_AFTER_RESET |
I2C_HID_QUIRK_NO_RUNTIME_PM }, I2C_HID_QUIRK_NO_RUNTIME_PM },
{ I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33,
I2C_HID_QUIRK_DELAY_AFTER_SLEEP },
{ 0, 0 } { 0, 0 }
}; };
...@@ -387,6 +392,7 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) ...@@ -387,6 +392,7 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state)
{ {
struct i2c_hid *ihid = i2c_get_clientdata(client); struct i2c_hid *ihid = i2c_get_clientdata(client);
int ret; int ret;
unsigned long now, delay;
i2c_hid_dbg(ihid, "%s\n", __func__); i2c_hid_dbg(ihid, "%s\n", __func__);
...@@ -404,9 +410,22 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) ...@@ -404,9 +410,22 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state)
goto set_pwr_exit; goto set_pwr_exit;
} }
if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP &&
power_state == I2C_HID_PWR_ON) {
now = jiffies;
if (time_after(ihid->sleep_delay, now)) {
delay = jiffies_to_usecs(ihid->sleep_delay - now);
usleep_range(delay, delay + 1);
}
}
ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state,
0, NULL, 0, NULL, 0); 0, NULL, 0, NULL, 0);
if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP &&
power_state == I2C_HID_PWR_SLEEP)
ihid->sleep_delay = jiffies + msecs_to_jiffies(20);
if (ret) if (ret)
dev_err(&client->dev, "failed to change power setting.\n"); dev_err(&client->dev, "failed to change power setting.\n");
......
...@@ -330,6 +330,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { ...@@ -330,6 +330,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
}, },
.driver_data = (void *)&sipodev_desc .driver_data = (void *)&sipodev_desc
}, },
{
.ident = "Direkt-Tek DTLAPY133-1",
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "DTLAPY133-1"),
},
.driver_data = (void *)&sipodev_desc
},
{ {
.ident = "Mediacom Flexbook Edge 11", .ident = "Mediacom Flexbook Edge 11",
.matches = { .matches = {
......
...@@ -512,15 +512,25 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, ...@@ -512,15 +512,25 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
if (cmd == HIDIOCGCOLLECTIONINDEX) { if (cmd == HIDIOCGCOLLECTIONINDEX) {
if (uref->usage_index >= field->maxusage) if (uref->usage_index >= field->maxusage)
goto inval; goto inval;
uref->usage_index =
array_index_nospec(uref->usage_index,
field->maxusage);
} else if (uref->usage_index >= field->report_count) } else if (uref->usage_index >= field->report_count)
goto inval; goto inval;
} }
if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) && if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
(uref_multi->num_values > HID_MAX_MULTI_USAGES || if (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
uref->usage_index + uref_multi->num_values > field->report_count)) uref->usage_index + uref_multi->num_values >
field->report_count)
goto inval; goto inval;
uref->usage_index =
array_index_nospec(uref->usage_index,
field->report_count -
uref_multi->num_values);
}
switch (cmd) { switch (cmd) {
case HIDIOCGUSAGE: case HIDIOCGUSAGE:
uref->value = field->value[uref->usage_index]; uref->value = field->value[uref->usage_index];
......
...@@ -722,8 +722,8 @@ struct hid_usage_id { ...@@ -722,8 +722,8 @@ struct hid_usage_id {
* input will not be passed to raw_event unless hid_device_io_start is * input will not be passed to raw_event unless hid_device_io_start is
* called. * called.
* *
* raw_event and event should return 0 on no action performed, 1 when no * raw_event and event should return negative on error, any other value will
* further processing should be done and negative on error * pass the event on to .event() typically return 0 for success.
* *
* input_mapping shall return a negative value to completely ignore this usage * input_mapping shall return a negative value to completely ignore this usage
* (e.g. doubled or invalid usage), zero to continue with parsing of this * (e.g. doubled or invalid usage), zero to continue with parsing of this
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment