Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e195ca6c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull HID fixes from Jiri Kosina:

 - revert of the high-resolution scrolling feature, as it breaks certain
   hardware due to incompatibilities between Logitech and Microsoft
   worlds. Peter Hutterer is working on a fixed implementation. Until
   that is finished, revert by Benjamin Tissoires.

 - revert of incorrect strncpy->strlcpy conversion in uhid, from David
   Herrmann

 - fix for buggy sendfile() implementation on uhid device node, from
   Eric Biggers

 - a few assorted device-ID specific quirks

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
  Revert "Input: Add the `REL_WHEEL_HI_RES` event code"
  Revert "HID: input: Create a utility class for counting scroll events"
  Revert "HID: logitech: Add function to enable HID++ 1.0 "scrolling acceleration""
  Revert "HID: logitech: Enable high-resolution scrolling on Logitech mice"
  Revert "HID: logitech: Use LDJ_DEVICE macro for existing Logitech mice"
  Revert "HID: logitech: fix a used uninitialized GCC warning"
  Revert "HID: input: simplify/fix high-res scroll event handling"
  HID: Add quirk for Primax PIXART OEM mice
  HID: i2c-hid: Disable runtime PM for LG touchscreen
  HID: multitouch: Add pointstick support for Cirque Touchpad
  HID: steam: remove input device when a hid client is running.
  Revert "HID: uhid: use strlcpy() instead of strncpy()"
  HID: uhid: forbid UHID_CREATE under KERNEL_DS or elevated privileges
  HID: input: Ignore battery reported by Symbol DS4308
  HID: Add quirk for Microsoft PIXART OEM mouse
parents d146194f ffe0e7cf
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -190,16 +190,7 @@ A few EV_REL codes have special meanings:
* REL_WHEEL, REL_HWHEEL:

  - These codes are used for vertical and horizontal scroll wheels,
    respectively. The value is the number of "notches" moved on the wheel, the
    physical size of which varies by device. For high-resolution wheels (which
    report multiple events for each notch of movement, or do not have notches)
    this may be an approximation based on the high-resolution scroll events.

* REL_WHEEL_HI_RES:

  - If a vertical scroll wheel supports high-resolution scrolling, this code
    will be emitted in addition to REL_WHEEL. The value is the (approximate)
    distance travelled by the user's finger, in microns.
    respectively.

EV_ABS
------
+8 −0
Original line number Diff line number Diff line
@@ -275,6 +275,9 @@

#define USB_VENDOR_ID_CIDC		0x1677

#define I2C_VENDOR_ID_CIRQUE		0x0488
#define I2C_PRODUCT_ID_CIRQUE_121F	0x121F

#define USB_VENDOR_ID_CJTOUCH		0x24b8
#define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020	0x0020
#define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040	0x0040
@@ -707,6 +710,7 @@
#define USB_VENDOR_ID_LG		0x1fd2
#define USB_DEVICE_ID_LG_MULTITOUCH	0x0064
#define USB_DEVICE_ID_LG_MELFAS_MT	0x6007
#define I2C_DEVICE_ID_LG_8001		0x8001

#define USB_VENDOR_ID_LOGITECH		0x046d
#define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
@@ -805,6 +809,7 @@
#define USB_DEVICE_ID_MS_TYPE_COVER_2    0x07a9
#define USB_DEVICE_ID_MS_POWER_COVER     0x07da
#define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER	0x02fd
#define USB_DEVICE_ID_MS_PIXART_MOUSE    0x00cb

#define USB_VENDOR_ID_MOJO		0x8282
#define USB_DEVICE_ID_RETRO_ADAPTER	0x3201
@@ -1043,6 +1048,7 @@
#define USB_VENDOR_ID_SYMBOL		0x05e0
#define USB_DEVICE_ID_SYMBOL_SCANNER_1	0x0800
#define USB_DEVICE_ID_SYMBOL_SCANNER_2	0x1300
#define USB_DEVICE_ID_SYMBOL_SCANNER_3	0x1200

#define USB_VENDOR_ID_SYNAPTICS		0x06cb
#define USB_DEVICE_ID_SYNAPTICS_TP	0x0001
@@ -1204,6 +1210,8 @@
#define USB_DEVICE_ID_PRIMAX_MOUSE_4D22	0x4d22
#define USB_DEVICE_ID_PRIMAX_KEYBOARD	0x4e05
#define USB_DEVICE_ID_PRIMAX_REZEL	0x4e72
#define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F	0x4d0f
#define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22	0x4e22


#define USB_VENDOR_ID_RISO_KAGAKU	0x1294	/* Riso Kagaku Corp. */
+3 −44
Original line number Diff line number Diff line
@@ -325,6 +325,9 @@ static const struct hid_device_id hid_battery_quirks[] = {
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM,
		USB_DEVICE_ID_ELECOM_BM084),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL,
		USB_DEVICE_ID_SYMBOL_SCANNER_3),
	  HID_BATTERY_QUIRK_IGNORE },
	{}
};

@@ -1838,47 +1841,3 @@ void hidinput_disconnect(struct hid_device *hid)
}
EXPORT_SYMBOL_GPL(hidinput_disconnect);
/**
 * hid_scroll_counter_handle_scroll() - Send high- and low-resolution scroll
 *                                      events given a high-resolution wheel
 *                                      movement.
 * @counter: a hid_scroll_counter struct describing the wheel.
 * @hi_res_value: the movement of the wheel, in the mouse's high-resolution
 *                units.
 *
 * Given a high-resolution movement, this function converts the movement into
 * microns and emits high-resolution scroll events for the input device. It also
 * uses the multiplier from &struct hid_scroll_counter to emit low-resolution
 * scroll events when appropriate for backwards-compatibility with userspace
 * input libraries.
 */
void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter,
				      int hi_res_value)
{
	int low_res_value, remainder, multiplier;

	input_report_rel(counter->dev, REL_WHEEL_HI_RES,
			 hi_res_value * counter->microns_per_hi_res_unit);

	/*
	 * Update the low-res remainder with the high-res value,
	 * but reset if the direction has changed.
	 */
	remainder = counter->remainder;
	if ((remainder ^ hi_res_value) < 0)
		remainder = 0;
	remainder += hi_res_value;

	/*
	 * Then just use the resolution multiplier to see if
	 * we should send a low-res (aka regular wheel) event.
	 */
	multiplier = counter->resolution_multiplier;
	low_res_value = remainder / multiplier;
	remainder -= low_res_value * multiplier;
	counter->remainder = remainder;

	if (low_res_value)
		input_report_rel(counter->dev, REL_WHEEL, low_res_value);
}
EXPORT_SYMBOL_GPL(hid_scroll_counter_handle_scroll);
+27 −282
Original line number Diff line number Diff line
@@ -64,14 +64,6 @@ MODULE_PARM_DESC(disable_tap_to_click,
#define HIDPP_QUIRK_NO_HIDINPUT			BIT(23)
#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS	BIT(24)
#define HIDPP_QUIRK_UNIFYING			BIT(25)
#define HIDPP_QUIRK_HI_RES_SCROLL_1P0		BIT(26)
#define HIDPP_QUIRK_HI_RES_SCROLL_X2120		BIT(27)
#define HIDPP_QUIRK_HI_RES_SCROLL_X2121		BIT(28)

/* Convenience constant to check for any high-res support. */
#define HIDPP_QUIRK_HI_RES_SCROLL	(HIDPP_QUIRK_HI_RES_SCROLL_1P0 | \
					 HIDPP_QUIRK_HI_RES_SCROLL_X2120 | \
					 HIDPP_QUIRK_HI_RES_SCROLL_X2121)

#define HIDPP_QUIRK_DELAYED_INIT		HIDPP_QUIRK_NO_HIDINPUT

@@ -157,7 +149,6 @@ struct hidpp_device {
	unsigned long capabilities;

	struct hidpp_battery battery;
	struct hid_scroll_counter vertical_wheel_counter;
};

/* HID++ 1.0 error codes */
@@ -409,15 +400,9 @@ static void hidpp_prefix_name(char **name, int name_length)
#define HIDPP_SET_LONG_REGISTER				0x82
#define HIDPP_GET_LONG_REGISTER				0x83

/**
 * hidpp10_set_register_bit() - Sets a single bit in a HID++ 1.0 register.
 * @hidpp_dev: the device to set the register on.
 * @register_address: the address of the register to modify.
 * @byte: the byte of the register to modify. Should be less than 3.
 * Return: 0 if successful, otherwise a negative error code.
 */
static int hidpp10_set_register_bit(struct hidpp_device *hidpp_dev,
	u8 register_address, u8 byte, u8 bit)
#define HIDPP_REG_GENERAL				0x00

static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
{
	struct hidpp_report response;
	int ret;
@@ -426,38 +411,23 @@ static int hidpp10_set_register_bit(struct hidpp_device *hidpp_dev,
	ret = hidpp_send_rap_command_sync(hidpp_dev,
					REPORT_ID_HIDPP_SHORT,
					HIDPP_GET_REGISTER,
					  register_address,
					HIDPP_REG_GENERAL,
					NULL, 0, &response);
	if (ret)
		return ret;

	memcpy(params, response.rap.params, 3);

	params[byte] |= BIT(bit);
	/* Set the battery bit */
	params[0] |= BIT(4);

	return hidpp_send_rap_command_sync(hidpp_dev,
					REPORT_ID_HIDPP_SHORT,
					HIDPP_SET_REGISTER,
					   register_address,
					HIDPP_REG_GENERAL,
					params, 3, &response);
}


#define HIDPP_REG_GENERAL				0x00

static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
{
	return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_GENERAL, 0, 4);
}

#define HIDPP_REG_FEATURES				0x01

/* On HID++ 1.0 devices, high-res scroll was called "scrolling acceleration". */
static int hidpp10_enable_scrolling_acceleration(struct hidpp_device *hidpp_dev)
{
	return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_FEATURES, 0, 6);
}

#define HIDPP_REG_BATTERY_STATUS			0x07

static int hidpp10_battery_status_map_level(u8 param)
@@ -1166,100 +1136,6 @@ static int hidpp_battery_get_property(struct power_supply *psy,
	return ret;
}

/* -------------------------------------------------------------------------- */
/* 0x2120: Hi-resolution scrolling                                            */
/* -------------------------------------------------------------------------- */

#define HIDPP_PAGE_HI_RESOLUTION_SCROLLING			0x2120

#define CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE	0x10

static int hidpp_hrs_set_highres_scrolling_mode(struct hidpp_device *hidpp,
	bool enabled, u8 *multiplier)
{
	u8 feature_index;
	u8 feature_type;
	int ret;
	u8 params[1];
	struct hidpp_report response;

	ret = hidpp_root_get_feature(hidpp,
				     HIDPP_PAGE_HI_RESOLUTION_SCROLLING,
				     &feature_index,
				     &feature_type);
	if (ret)
		return ret;

	params[0] = enabled ? BIT(0) : 0;
	ret = hidpp_send_fap_command_sync(hidpp, feature_index,
					  CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE,
					  params, sizeof(params), &response);
	if (ret)
		return ret;
	*multiplier = response.fap.params[1];
	return 0;
}

/* -------------------------------------------------------------------------- */
/* 0x2121: HiRes Wheel                                                        */
/* -------------------------------------------------------------------------- */

#define HIDPP_PAGE_HIRES_WHEEL		0x2121

#define CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY	0x00
#define CMD_HIRES_WHEEL_SET_WHEEL_MODE		0x20

static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp,
	u8 *multiplier)
{
	u8 feature_index;
	u8 feature_type;
	int ret;
	struct hidpp_report response;

	ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
				     &feature_index, &feature_type);
	if (ret)
		goto return_default;

	ret = hidpp_send_fap_command_sync(hidpp, feature_index,
					  CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY,
					  NULL, 0, &response);
	if (ret)
		goto return_default;

	*multiplier = response.fap.params[0];
	return 0;
return_default:
	hid_warn(hidpp->hid_dev,
		 "Couldn't get wheel multiplier (error %d), assuming %d.\n",
		 ret, *multiplier);
	return ret;
}

static int hidpp_hrw_set_wheel_mode(struct hidpp_device *hidpp, bool invert,
	bool high_resolution, bool use_hidpp)
{
	u8 feature_index;
	u8 feature_type;
	int ret;
	u8 params[1];
	struct hidpp_report response;

	ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
				     &feature_index, &feature_type);
	if (ret)
		return ret;

	params[0] = (invert          ? BIT(2) : 0) |
		    (high_resolution ? BIT(1) : 0) |
		    (use_hidpp       ? BIT(0) : 0);

	return hidpp_send_fap_command_sync(hidpp, feature_index,
					   CMD_HIRES_WHEEL_SET_WHEEL_MODE,
					   params, sizeof(params), &response);
}

/* -------------------------------------------------------------------------- */
/* 0x4301: Solar Keyboard                                                     */
/* -------------------------------------------------------------------------- */
@@ -2523,8 +2399,7 @@ static int m560_raw_event(struct hid_device *hdev, u8 *data, int size)
		input_report_rel(mydata->input, REL_Y, v);

		v = hid_snto32(data[6], 8);
		hid_scroll_counter_handle_scroll(
				&hidpp->vertical_wheel_counter, v);
		input_report_rel(mydata->input, REL_WHEEL, v);

		input_sync(mydata->input);
	}
@@ -2652,72 +2527,6 @@ static int g920_get_config(struct hidpp_device *hidpp)
	return 0;
}

/* -------------------------------------------------------------------------- */
/* High-resolution scroll wheels                                              */
/* -------------------------------------------------------------------------- */

/**
 * struct hi_res_scroll_info - Stores info on a device's high-res scroll wheel.
 * @product_id: the HID product ID of the device being described.
 * @microns_per_hi_res_unit: the distance moved by the user's finger for each
 *                         high-resolution unit reported by the device, in
 *                         256ths of a millimetre.
 */
struct hi_res_scroll_info {
	__u32 product_id;
	int microns_per_hi_res_unit;
};

static struct hi_res_scroll_info hi_res_scroll_devices[] = {
	{ /* Anywhere MX */
	  .product_id = 0x1017, .microns_per_hi_res_unit = 445 },
	{ /* Performance MX */
	  .product_id = 0x101a, .microns_per_hi_res_unit = 406 },
	{ /* M560 */
	  .product_id = 0x402d, .microns_per_hi_res_unit = 435 },
	{ /* MX Master 2S */
	  .product_id = 0x4069, .microns_per_hi_res_unit = 406 },
};

static int hi_res_scroll_look_up_microns(__u32 product_id)
{
	int i;
	int num_devices = sizeof(hi_res_scroll_devices)
			  / sizeof(hi_res_scroll_devices[0]);
	for (i = 0; i < num_devices; i++) {
		if (hi_res_scroll_devices[i].product_id == product_id)
			return hi_res_scroll_devices[i].microns_per_hi_res_unit;
	}
	/* We don't have a value for this device, so use a sensible default. */
	return 406;
}

static int hi_res_scroll_enable(struct hidpp_device *hidpp)
{
	int ret;
	u8 multiplier = 8;

	if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2121) {
		ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false);
		hidpp_hrw_get_wheel_capability(hidpp, &multiplier);
	} else if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2120) {
		ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true,
							   &multiplier);
	} else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */
		ret = hidpp10_enable_scrolling_acceleration(hidpp);

	if (ret)
		return ret;

	hidpp->vertical_wheel_counter.resolution_multiplier = multiplier;
	hidpp->vertical_wheel_counter.microns_per_hi_res_unit =
		hi_res_scroll_look_up_microns(hidpp->hid_dev->product);
	hid_info(hidpp->hid_dev, "multiplier = %d, microns = %d\n",
		 multiplier,
		 hidpp->vertical_wheel_counter.microns_per_hi_res_unit);
	return 0;
}

/* -------------------------------------------------------------------------- */
/* Generic HID++ devices                                                      */
/* -------------------------------------------------------------------------- */
@@ -2763,11 +2572,6 @@ static void hidpp_populate_input(struct hidpp_device *hidpp,
		wtp_populate_input(hidpp, input, origin_is_hid_core);
	else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560)
		m560_populate_input(hidpp, input, origin_is_hid_core);

	if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) {
		input_set_capability(input, EV_REL, REL_WHEEL_HI_RES);
		hidpp->vertical_wheel_counter.dev = input;
	}
}

static int hidpp_input_configured(struct hid_device *hdev,
@@ -2886,27 +2690,6 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
	return 0;
}

static int hidpp_event(struct hid_device *hdev, struct hid_field *field,
	struct hid_usage *usage, __s32 value)
{
	/* This function will only be called for scroll events, due to the
	 * restriction imposed in hidpp_usages.
	 */
	struct hidpp_device *hidpp = hid_get_drvdata(hdev);
	struct hid_scroll_counter *counter = &hidpp->vertical_wheel_counter;
	/* A scroll event may occur before the multiplier has been retrieved or
	 * the input device set, or high-res scroll enabling may fail. In such
	 * cases we must return early (falling back to default behaviour) to
	 * avoid a crash in hid_scroll_counter_handle_scroll.
	 */
	if (!(hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) || value == 0
	    || counter->dev == NULL || counter->resolution_multiplier == 0)
		return 0;

	hid_scroll_counter_handle_scroll(counter, value);
	return 1;
}

static int hidpp_initialize_battery(struct hidpp_device *hidpp)
{
	static atomic_t battery_no = ATOMIC_INIT(0);
@@ -3118,9 +2901,6 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
	if (hidpp->battery.ps)
		power_supply_changed(hidpp->battery.ps);

	if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL)
		hi_res_scroll_enable(hidpp);

	if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input)
		/* if the input nodes are already created, we can stop now */
		return;
@@ -3306,63 +3086,35 @@ static void hidpp_remove(struct hid_device *hdev)
	mutex_destroy(&hidpp->send_mutex);
}

#define LDJ_DEVICE(product) \
	HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, \
		   USB_VENDOR_ID_LOGITECH, (product))

static const struct hid_device_id hidpp_devices[] = {
	{ /* wireless touchpad */
	  LDJ_DEVICE(0x4011),
	  HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
		USB_VENDOR_ID_LOGITECH, 0x4011),
	  .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
			 HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
	{ /* wireless touchpad T650 */
	  LDJ_DEVICE(0x4101),
	  HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
		USB_VENDOR_ID_LOGITECH, 0x4101),
	  .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
	{ /* wireless touchpad T651 */
	  HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
		USB_DEVICE_ID_LOGITECH_T651),
	  .driver_data = HIDPP_QUIRK_CLASS_WTP },
	{ /* Mouse Logitech Anywhere MX */
	  LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
	{ /* Mouse Logitech Cube */
	  LDJ_DEVICE(0x4010), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
	{ /* Mouse Logitech M335 */
	  LDJ_DEVICE(0x4050), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ /* Mouse Logitech M515 */
	  LDJ_DEVICE(0x4007), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
	{ /* Mouse logitech M560 */
	  LDJ_DEVICE(0x402d),
	  .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560
		| HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
	{ /* Mouse Logitech M705 (firmware RQM17) */
	  LDJ_DEVICE(0x101b), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
	{ /* Mouse Logitech M705 (firmware RQM67) */
	  LDJ_DEVICE(0x406d), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ /* Mouse Logitech M720 */
	  LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ /* Mouse Logitech MX Anywhere 2 */
	  LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ /* Mouse Logitech MX Anywhere 2S */
	  LDJ_DEVICE(0x406a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ /* Mouse Logitech MX Master */
	  LDJ_DEVICE(0x4041), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ LDJ_DEVICE(0x4060), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ LDJ_DEVICE(0x4071), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ /* Mouse Logitech MX Master 2S */
	  LDJ_DEVICE(0x4069), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
	{ /* Mouse Logitech Performance MX */
	  LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
	  HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
		USB_VENDOR_ID_LOGITECH, 0x402d),
	  .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 },
	{ /* Keyboard logitech K400 */
	  LDJ_DEVICE(0x4024),
	  HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
		USB_VENDOR_ID_LOGITECH, 0x4024),
	  .driver_data = HIDPP_QUIRK_CLASS_K400 },
	{ /* Solar Keyboard Logitech K750 */
	  LDJ_DEVICE(0x4002),
	  HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
		USB_VENDOR_ID_LOGITECH, 0x4002),
	  .driver_data = HIDPP_QUIRK_CLASS_K750 },

	{ LDJ_DEVICE(HID_ANY_ID) },
	{ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
		USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},

	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
		.driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS},
@@ -3371,19 +3123,12 @@ static const struct hid_device_id hidpp_devices[] = {

MODULE_DEVICE_TABLE(hid, hidpp_devices);

static const struct hid_usage_id hidpp_usages[] = {
	{ HID_GD_WHEEL, EV_REL, REL_WHEEL },
	{ HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
};

static struct hid_driver hidpp_driver = {
	.name = "logitech-hidpp-device",
	.id_table = hidpp_devices,
	.probe = hidpp_probe,
	.remove = hidpp_remove,
	.raw_event = hidpp_raw_event,
	.usage_table = hidpp_usages,
	.event = hidpp_event,
	.input_configured = hidpp_input_configured,
	.input_mapping = hidpp_input_mapping,
	.input_mapped = hidpp_input_mapped,
+6 −0
Original line number Diff line number Diff line
@@ -1814,6 +1814,12 @@ static const struct hid_device_id mt_devices[] = {
		MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT,
			USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },

	/* Cirque devices */
	{ .driver_data = MT_CLS_WIN_8_DUAL,
		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
			I2C_VENDOR_ID_CIRQUE,
			I2C_PRODUCT_ID_CIRQUE_121F) },

	/* CJTouch panels */
	{ .driver_data = MT_CLS_NSMU,
		MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH,
Loading