瀏覽代碼

Merge branch 'for-4.15/upstream' into for-linus

- cp2112: GPIO error handling and Kconfig fixes from Sébastien Szymanski
- i2c-hid: fixup / quirk for Apollo-Lake based laptops, from Hans de Goede
- Input/Core: add eraser tool support, from Ping Cheng
- small assorted code fixes

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Jiri Kosina 7 年之前
父節點
當前提交
6ed7a70be5
共有 7 個文件被更改,包括 29 次插入8 次删除
  1. 2 3
      drivers/hid/Kconfig
  2. 1 1
      drivers/hid/hid-core.c
  3. 7 3
      drivers/hid/hid-cp2112.c
  4. 3 0
      drivers/hid/hid-ids.h
  5. 9 0
      drivers/hid/hid-input.c
  6. 6 1
      drivers/hid/i2c-hid/i2c-hid.c
  7. 1 0
      include/linux/hid.h

+ 2 - 3
drivers/hid/Kconfig

@@ -230,7 +230,7 @@ config HID_CMEDIA
 
 
 config HID_CP2112
 config HID_CP2112
 	tristate "Silicon Labs CP2112 HID USB-to-SMBus Bridge support"
 	tristate "Silicon Labs CP2112 HID USB-to-SMBus Bridge support"
-	depends on USB_HID && I2C && GPIOLIB
+	depends on USB_HID && HIDRAW && I2C && GPIOLIB
 	select GPIOLIB_IRQCHIP
 	select GPIOLIB_IRQCHIP
 	---help---
 	---help---
 	Support for Silicon Labs CP2112 HID USB to SMBus Master Bridge.
 	Support for Silicon Labs CP2112 HID USB to SMBus Master Bridge.
@@ -750,11 +750,10 @@ config HID_PRIMAX
 	HID standard.
 	HID standard.
 
 
 config HID_RETRODE
 config HID_RETRODE
-	tristate "Retrode"
+	tristate "Retrode 2 USB adapter for vintage video games"
 	depends on USB_HID
 	depends on USB_HID
 	---help---
 	---help---
 	Support for
 	Support for
-
 	  * Retrode 2 cartridge and controller adapter
 	  * Retrode 2 cartridge and controller adapter
 
 
 config HID_ROCCAT
 config HID_ROCCAT

+ 1 - 1
drivers/hid/hid-core.c

@@ -1662,7 +1662,7 @@ static struct bin_attribute dev_bin_attr_report_desc = {
 	.size = HID_MAX_DESCRIPTOR_SIZE,
 	.size = HID_MAX_DESCRIPTOR_SIZE,
 };
 };
 
 
-static struct device_attribute dev_attr_country = {
+static const struct device_attribute dev_attr_country = {
 	.attr = { .name = "country", .mode = 0444 },
 	.attr = { .name = "country", .mode = 0444 },
 	.show = show_country,
 	.show = show_country,
 };
 };

+ 7 - 3
drivers/hid/hid-cp2112.c

@@ -21,7 +21,7 @@
  * Data Sheet:
  * Data Sheet:
  *   http://www.silabs.com/Support%20Documents/TechnicalDocs/CP2112.pdf
  *   http://www.silabs.com/Support%20Documents/TechnicalDocs/CP2112.pdf
  * Programming Interface Specification:
  * Programming Interface Specification:
- *   http://www.silabs.com/Support%20Documents/TechnicalDocs/AN495.pdf
+ *   https://www.silabs.com/documents/public/application-notes/an495-cp2112-interface-specification.pdf
  */
  */
 
 
 #include <linux/gpio.h>
 #include <linux/gpio.h>
@@ -196,6 +196,8 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 				 HID_REQ_GET_REPORT);
 				 HID_REQ_GET_REPORT);
 	if (ret != CP2112_GPIO_CONFIG_LENGTH) {
 	if (ret != CP2112_GPIO_CONFIG_LENGTH) {
 		hid_err(hdev, "error requesting GPIO config: %d\n", ret);
 		hid_err(hdev, "error requesting GPIO config: %d\n", ret);
+		if (ret >= 0)
+			ret = -EIO;
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -205,8 +207,10 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 	ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
 	ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
 				 CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
 				 CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
 				 HID_REQ_SET_REPORT);
 				 HID_REQ_SET_REPORT);
-	if (ret < 0) {
+	if (ret != CP2112_GPIO_CONFIG_LENGTH) {
 		hid_err(hdev, "error setting GPIO config: %d\n", ret);
 		hid_err(hdev, "error setting GPIO config: %d\n", ret);
+		if (ret >= 0)
+			ret = -EIO;
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -214,7 +218,7 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 
 
 exit:
 exit:
 	mutex_unlock(&dev->lock);
 	mutex_unlock(&dev->lock);
-	return ret < 0 ? ret : -EIO;
+	return ret;
 }
 }
 
 
 static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value)

+ 3 - 0
drivers/hid/hid-ids.h

@@ -513,6 +513,9 @@
 #define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003
 #define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003
 #define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008
 #define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008
 
 
+#define I2C_VENDOR_ID_HANTICK		0x0911
+#define I2C_PRODUCT_ID_HANTICK_5288	0x5288
+
 #define USB_VENDOR_ID_HANWANG		0x0b57
 #define USB_VENDOR_ID_HANWANG		0x0b57
 #define USB_DEVICE_ID_HANWANG_TABLET_FIRST	0x5000
 #define USB_DEVICE_ID_HANWANG_TABLET_FIRST	0x5000
 #define USB_DEVICE_ID_HANWANG_TABLET_LAST	0x8fff
 #define USB_DEVICE_ID_HANWANG_TABLET_LAST	0x8fff

+ 9 - 0
drivers/hid/hid-input.c

@@ -797,6 +797,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 			map_key_clear(BTN_STYLUS);
 			map_key_clear(BTN_STYLUS);
 			break;
 			break;
 
 
+		case 0x45: /* ERASER */
+			/*
+			 * This event is reported when eraser tip touches the surface.
+			 * Actual eraser (BTN_TOOL_RUBBER) is set by Invert usage when
+			 * tool gets in proximity.
+			 */
+			map_key_clear(BTN_TOUCH);
+			break;
+
 		case 0x46: /* TabletPick */
 		case 0x46: /* TabletPick */
 		case 0x5a: /* SecondaryBarrelSwitch */
 		case 0x5a: /* SecondaryBarrelSwitch */
 			map_key_clear(BTN_STYLUS2);
 			map_key_clear(BTN_STYLUS2);

+ 6 - 1
drivers/hid/i2c-hid/i2c-hid.c

@@ -46,6 +46,7 @@
 
 
 /* quirks to control the device */
 /* quirks to control the device */
 #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)
 
 
 /* flags */
 /* flags */
 #define I2C_HID_STARTED		0
 #define I2C_HID_STARTED		0
@@ -168,6 +169,8 @@ static const struct i2c_hid_quirks {
 		I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
 		I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
 	{ USB_VENDOR_ID_WEIDA, USB_DEVICE_ID_WEIDA_8755,
 	{ USB_VENDOR_ID_WEIDA, USB_DEVICE_ID_WEIDA_8755,
 		I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
 		I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
+	{ I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
+		I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
 	{ 0, 0 }
 	{ 0, 0 }
 };
 };
 
 
@@ -252,7 +255,9 @@ static int __i2c_hid_command(struct i2c_client *client,
 
 
 	ret = 0;
 	ret = 0;
 
 
-	if (wait) {
+	if (wait && (ihid->quirks & I2C_HID_QUIRK_NO_IRQ_AFTER_RESET)) {
+		msleep(100);
+	} else if (wait) {
 		i2c_hid_dbg(ihid, "%s: waiting...\n", __func__);
 		i2c_hid_dbg(ihid, "%s: waiting...\n", __func__);
 		if (!wait_event_timeout(ihid->wait,
 		if (!wait_event_timeout(ihid->wait,
 				!test_bit(I2C_HID_RESET_PENDING, &ihid->flags),
 				!test_bit(I2C_HID_RESET_PENDING, &ihid->flags),

+ 1 - 0
include/linux/hid.h

@@ -754,6 +754,7 @@ struct hid_driver {
  * @stop: called on remove
  * @stop: called on remove
  * @open: called by input layer on open
  * @open: called by input layer on open
  * @close: called by input layer on close
  * @close: called by input layer on close
+ * @power: request underlying hardware to enter requested power mode
  * @parse: this method is called only once to parse the device data,
  * @parse: this method is called only once to parse the device data,
  *	   shouldn't allocate anything to not leak memory
  *	   shouldn't allocate anything to not leak memory
  * @request: send report request to device (e.g. feature report)
  * @request: send report request to device (e.g. feature report)