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

Commit 172bfe09 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull HID updates from Jiri Kosina:
 "Some highlights:

   - hid-sony improvements of Sixaxis device support by Antonio Ospite
   - hid-hyperv driven devices can now be used as wakeup source, by
     Dexuan Cui
   - hid-lenovo driver is now more generic and supports more devices, by
     Jamie Lentin
   - hid-huion now supports wider range of tablets, by Nikolai
     Kondrashov
   - other various unsorted fixes and device ID additions"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (30 commits)
  HID: hyperv: register as a wakeup source
  HID: sony: Default initialize all elements of the LED max_brightness array to 1
  HID: huion: Fix sparse warnings
  HID: usbhid: Use flag HID_DISCONNECTED when a usb device is removed
  HID: ignore jabra gn9350e
  HID: cp2112: add I2C mode
  HID: use multi input quirk for 22b9:2968
  HID: rmi: only bind the hid-rmi driver to the mouse interface of composite USB devices
  HID: rmi: check that report ids exist in the report_id_hash before accessing their size
  HID: lenovo: Add support for Compact (BT|USB) keyboard
  HID: lenovo: Don't call function in condition, show error codes
  HID: lenovo: Prepare support for adding other devices
  HID: lenovo: Rename hid-lenovo-tpkbd to hid-lenovo
  HID: huion: Handle tablets with UC-Logic vendor ID
  HID: huion: Switch to generating report descriptor
  HID: huion: Don't ignore other interfaces
  HID: huion: Use "tablet" instead of specific model
  HID: add quirk for 0x04d9:0xa096 device
  HID: i2c-hid: call the hid driver's suspend and resume callbacks
  HID: rmi: change logging level of log messages related to unexpected reports
  ...
parents a1b0a006 cf6f3976
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -4,18 +4,21 @@ Contact: linux-input@vger.kernel.org
Description:	This controls if mouse clicks should be generated if the trackpoint is quickly pressed. How fast this press has to be
		is being controlled by press_speed.
		Values are 0 or 1.
		Applies to Thinkpad USB Keyboard with TrackPoint.

What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/dragging
Date:		July 2011
Contact:	linux-input@vger.kernel.org
Description:	If this setting is enabled, it is possible to do dragging by pressing the trackpoint. This requires press_to_select to be enabled.
		Values are 0 or 1.
		Applies to Thinkpad USB Keyboard with TrackPoint.

What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/release_to_select
Date:		July 2011
Contact:	linux-input@vger.kernel.org
Description:	For details regarding this setting please refer to http://www.pc.ibm.com/ww/healthycomputing/trkpntb.html
		Values are 0 or 1.
		Applies to Thinkpad USB Keyboard with TrackPoint.

What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/select_right
Date:		July 2011
@@ -23,16 +26,25 @@ Contact: linux-input@vger.kernel.org
Description:	This setting controls if the mouse click events generated by pressing the trackpoint (if press_to_select is enabled) generate
		a left or right mouse button click.
		Values are 0 or 1.
		Applies to Thinkpad USB Keyboard with TrackPoint.

What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/sensitivity
Date:		July 2011
Contact:	linux-input@vger.kernel.org
Description:	This file contains the trackpoint sensitivity.
		Values are decimal integers from 1 (lowest sensitivity) to 255 (highest sensitivity).
		Applies to Thinkpad USB Keyboard with TrackPoint.

What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/press_speed
Date:		July 2011
Contact:	linux-input@vger.kernel.org
Description:	This setting controls how fast the trackpoint needs to be pressed to generate a mouse click if press_to_select is enabled.
		Values are decimal integers from 1 (slowest) to 255 (fastest).
		Applies to Thinkpad USB Keyboard with TrackPoint.

What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/fn_lock
Date:		July 2014
Contact:	linux-input@vger.kernel.org
Description:	This setting controls whether Fn Lock is enabled on the keyboard (i.e. if F1 is Mute or F1)
		Values are 0 or 1
		Applies to ThinkPad Compact (USB|Bluetooth) Keyboard with TrackPoint.
+10 −8
Original line number Diff line number Diff line
@@ -331,18 +331,20 @@ config HID_LCPOWER
	---help---
	Support for LC-Power RC1000MCE RF remote control.

config HID_LENOVO_TPKBD
	tristate "Lenovo ThinkPad USB Keyboard with TrackPoint"
config HID_LENOVO
	tristate "Lenovo / Thinkpad devices"
	depends on HID
	select NEW_LEDS
	select LEDS_CLASS
	---help---
	Support for the Lenovo ThinkPad USB Keyboard with TrackPoint.
	Support for Lenovo devices that are not fully compliant with HID standard.

	Say Y here if you have a Lenovo ThinkPad USB Keyboard with TrackPoint
	and would like to use device-specific features like changing the
	sensitivity of the trackpoint, using the microphone mute button or
	controlling the mute and microphone mute LEDs.
	Say Y if you want support for the non-compliant features of the Lenovo
	Thinkpad standalone keyboards, e.g:
	- ThinkPad USB Keyboard with TrackPoint (supports extra LEDs and trackpoint
	  configuration)
	- ThinkPad Compact Bluetooth Keyboard with TrackPoint (supports Fn keys)
	- ThinkPad Compact USB Keyboard with TrackPoint (supports Fn keys)

config HID_LOGITECH
	tristate "Logitech devices" if EXPERT
@@ -785,7 +787,7 @@ config HID_XINMO
	depends on HID
	---help---
	Support for Xin-Mo devices that are not fully compliant with the HID
	standard. Currently only supports the Xin-Mo Dual Arcade. Say Y here
	standard. Currently only supports the Xin-Mo Dual Arcade. Say Y here
	if you have a Xin-Mo Dual Arcade controller.

config HID_ZEROPLUS
+1 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
obj-$(CONFIG_HID_KEYTOUCH)	+= hid-keytouch.o
obj-$(CONFIG_HID_KYE)		+= hid-kye.o
obj-$(CONFIG_HID_LCPOWER)       += hid-lcpower.o
obj-$(CONFIG_HID_LENOVO_TPKBD)	+= hid-lenovo-tpkbd.o
obj-$(CONFIG_HID_LENOVO)	+= hid-lenovo.o
obj-$(CONFIG_HID_LOGITECH)	+= hid-logitech.o
obj-$(CONFIG_HID_LOGITECH_DJ)	+= hid-logitech-dj.o
obj-$(CONFIG_HID_MAGICMOUSE)    += hid-magicmouse.o
+8 −3
Original line number Diff line number Diff line
@@ -783,7 +783,9 @@ static int hid_scan_report(struct hid_device *hid)
	* Vendor specific handlings
	*/
	if ((hid->vendor == USB_VENDOR_ID_SYNAPTICS) &&
	    (hid->group == HID_GROUP_GENERIC))
	    (hid->group == HID_GROUP_GENERIC) &&
	    /* only bind to the mouse interface of composite USB devices */
	    (hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE))
		/* hid-rmi should take care of them, not hid-generic */
		hid->group = HID_GROUP_RMI;

@@ -1782,7 +1784,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
	{ 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) },
@@ -1796,8 +1798,10 @@ static const struct hid_device_id hid_have_special_driver[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
#if IS_ENABLED(CONFIG_HID_LENOVO_TPKBD)
#if IS_ENABLED(CONFIG_HID_LENOVO)
	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
#endif
	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
@@ -2266,6 +2270,7 @@ static const struct hid_device_id hid_ignore_list[] = {
	{ 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_JABRA, USB_DEVICE_ID_JABRA_GN9350E) },
	{ 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) },
+108 −3
Original line number Diff line number Diff line
@@ -240,8 +240,6 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
	u8 buf[5];
	int ret;

	cp2112_gpio_set(chip, offset, value);

	ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
				       sizeof(buf), HID_FEATURE_REPORT,
				       HID_REQ_GET_REPORT);
@@ -260,6 +258,12 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
		return ret;
	}

	/*
	 * Set gpio value when output direction is already set,
	 * as specified in AN495, Rev. 0.2, cpt. 4.4
	 */
	cp2112_gpio_set(chip, offset, value);

	return 0;
}

@@ -425,6 +429,105 @@ static int cp2112_write_req(void *buf, u8 slave_address, u8 command, u8 *data,
	return data_length + 4;
}

static int cp2112_i2c_write_req(void *buf, u8 slave_address, u8 *data,
				u8 data_length)
{
	struct cp2112_write_req_report *report = buf;

	if (data_length > sizeof(report->data))
		return -EINVAL;

	report->report = CP2112_DATA_WRITE_REQUEST;
	report->slave_address = slave_address << 1;
	report->length = data_length;
	memcpy(report->data, data, data_length);
	return data_length + 3;
}

static int cp2112_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
			   int num)
{
	struct cp2112_device *dev = (struct cp2112_device *)adap->algo_data;
	struct hid_device *hdev = dev->hdev;
	u8 buf[64];
	ssize_t count;
	unsigned int retries;
	int ret;

	hid_dbg(hdev, "I2C %d messages\n", num);

	if (num != 1) {
		hid_err(hdev,
			"Multi-message I2C transactions not supported\n");
		return -EOPNOTSUPP;
	}

	if (msgs->flags & I2C_M_RD)
		count = cp2112_read_req(buf, msgs->addr, msgs->len);
	else
		count = cp2112_i2c_write_req(buf, msgs->addr, msgs->buf,
					     msgs->len);

	if (count < 0)
		return count;

	ret = hid_hw_power(hdev, PM_HINT_FULLON);
	if (ret < 0) {
		hid_err(hdev, "power management error: %d\n", ret);
		return ret;
	}

	ret = cp2112_hid_output(hdev, buf, count, HID_OUTPUT_REPORT);
	if (ret < 0) {
		hid_warn(hdev, "Error starting transaction: %d\n", ret);
		goto power_normal;
	}

	for (retries = 0; retries < XFER_STATUS_RETRIES; ++retries) {
		ret = cp2112_xfer_status(dev);
		if (-EBUSY == ret)
			continue;
		if (ret < 0)
			goto power_normal;
		break;
	}

	if (XFER_STATUS_RETRIES <= retries) {
		hid_warn(hdev, "Transfer timed out, cancelling.\n");
		buf[0] = CP2112_CANCEL_TRANSFER;
		buf[1] = 0x01;

		ret = cp2112_hid_output(hdev, buf, 2, HID_OUTPUT_REPORT);
		if (ret < 0)
			hid_warn(hdev, "Error cancelling transaction: %d\n",
				 ret);

		ret = -ETIMEDOUT;
		goto power_normal;
	}

	if (!(msgs->flags & I2C_M_RD))
		goto finish;

	ret = cp2112_read(dev, msgs->buf, msgs->len);
	if (ret < 0)
		goto power_normal;
	if (ret != msgs->len) {
		hid_warn(hdev, "short read: %d < %d\n", ret, msgs->len);
		ret = -EIO;
		goto power_normal;
	}

finish:
	/* return the number of transferred messages */
	ret = 1;

power_normal:
	hid_hw_power(hdev, PM_HINT_NORMAL);
	hid_dbg(hdev, "I2C transfer finished: %d\n", ret);
	return ret;
}

static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,
		       unsigned short flags, char read_write, u8 command,
		       int size, union i2c_smbus_data *data)
@@ -591,7 +694,8 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,

static u32 cp2112_functionality(struct i2c_adapter *adap)
{
	return I2C_FUNC_SMBUS_BYTE |
	return I2C_FUNC_I2C |
		I2C_FUNC_SMBUS_BYTE |
		I2C_FUNC_SMBUS_BYTE_DATA |
		I2C_FUNC_SMBUS_WORD_DATA |
		I2C_FUNC_SMBUS_BLOCK_DATA |
@@ -601,6 +705,7 @@ static u32 cp2112_functionality(struct i2c_adapter *adap)
}

static const struct i2c_algorithm smbus_algorithm = {
	.master_xfer	= cp2112_i2c_xfer,
	.smbus_xfer	= cp2112_xfer,
	.functionality	= cp2112_functionality,
};
Loading