diff options
| -rw-r--r-- | drivers/hid/hid-apple.c | 2 | ||||
| -rw-r--r-- | drivers/hid/hid-asus.c | 27 | ||||
| -rw-r--r-- | drivers/hid/hid-core.c | 12 | ||||
| -rw-r--r-- | drivers/hid/hid-debug.c | 3 | ||||
| -rw-r--r-- | drivers/hid/hid-glorious.c | 16 | ||||
| -rw-r--r-- | drivers/hid/hid-ids.h | 12 | ||||
| -rw-r--r-- | drivers/hid/hid-logitech-dj.c | 11 | ||||
| -rw-r--r-- | drivers/hid/hid-mcp2221.c | 4 | ||||
| -rw-r--r-- | drivers/hid/hid-multitouch.c | 5 | ||||
| -rw-r--r-- | drivers/hid/hid-quirks.c | 1 | ||||
| -rw-r--r-- | include/linux/hid.h | 3 | 
11 files changed, 74 insertions, 22 deletions
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 3ca45975c686..d9e9829b2200 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -345,6 +345,8 @@ static const struct apple_non_apple_keyboard non_apple_keyboards[] = {  	{ "AONE" },  	{ "GANSS" },  	{ "Hailuck" }, +	{ "Jamesdonkey" }, +	{ "A3R" },  };  static bool apple_is_non_apple_keyboard(struct hid_device *hdev) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index fd61dba88233..78cdfb8b9a7a 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -381,7 +381,7 @@ static int asus_raw_event(struct hid_device *hdev,  	return 0;  } -static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size) +static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size)  {  	unsigned char *dmabuf;  	int ret; @@ -404,7 +404,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size  static int asus_kbd_init(struct hid_device *hdev)  { -	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, +	const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,  		     0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };  	int ret; @@ -418,7 +418,7 @@ static int asus_kbd_init(struct hid_device *hdev)  static int asus_kbd_get_functions(struct hid_device *hdev,  				  unsigned char *kbd_func)  { -	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; +	const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 };  	u8 *readbuf;  	int ret; @@ -449,7 +449,7 @@ static int asus_kbd_get_functions(struct hid_device *hdev,  static int rog_nkey_led_init(struct hid_device *hdev)  { -	u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 }; +	const u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 };  	u8 buf_init2[] = { FEATURE_KBD_LED_REPORT_ID1, 0x41, 0x53, 0x55, 0x53, 0x20,  				0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };  	u8 buf_init3[] = { FEATURE_KBD_LED_REPORT_ID1, @@ -1000,6 +1000,24 @@ static int asus_start_multitouch(struct hid_device *hdev)  	return 0;  } +static int __maybe_unused asus_resume(struct hid_device *hdev) { +	struct asus_drvdata *drvdata = hid_get_drvdata(hdev); +	int ret = 0; + +	if (drvdata->kbd_backlight) { +		const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, +				drvdata->kbd_backlight->cdev.brightness }; +		ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); +		if (ret < 0) { +			hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret); +			goto asus_resume_err; +		} +	} + +asus_resume_err: +	return ret; +} +  static int __maybe_unused asus_reset_resume(struct hid_device *hdev)  {  	struct asus_drvdata *drvdata = hid_get_drvdata(hdev); @@ -1294,6 +1312,7 @@ static struct hid_driver asus_driver = {  	.input_configured       = asus_input_configured,  #ifdef CONFIG_PM  	.reset_resume           = asus_reset_resume, +	.resume					= asus_resume,  #endif  	.event			= asus_event,  	.raw_event		= asus_raw_event diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 8992e3c1e769..e0181218ad85 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -702,15 +702,22 @@ static void hid_close_report(struct hid_device *device)   * Free a device structure, all reports, and all fields.   */ -static void hid_device_release(struct device *dev) +void hiddev_free(struct kref *ref)  { -	struct hid_device *hid = to_hid_device(dev); +	struct hid_device *hid = container_of(ref, struct hid_device, ref);  	hid_close_report(hid);  	kfree(hid->dev_rdesc);  	kfree(hid);  } +static void hid_device_release(struct device *dev) +{ +	struct hid_device *hid = to_hid_device(dev); + +	kref_put(&hid->ref, hiddev_free); +} +  /*   * Fetch a report description item from the data stream. We support long   * items, though they are not used yet. @@ -2846,6 +2853,7 @@ struct hid_device *hid_allocate_device(void)  	spin_lock_init(&hdev->debug_list_lock);  	sema_init(&hdev->driver_input_lock, 1);  	mutex_init(&hdev->ll_open_lock); +	kref_init(&hdev->ref);  	hid_bpf_device_init(hdev); diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index e7ef1ea107c9..7dd83ec74f8a 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -1135,6 +1135,7 @@ static int hid_debug_events_open(struct inode *inode, struct file *file)  		goto out;  	}  	list->hdev = (struct hid_device *) inode->i_private; +	kref_get(&list->hdev->ref);  	file->private_data = list;  	mutex_init(&list->read_mutex); @@ -1227,6 +1228,8 @@ static int hid_debug_events_release(struct inode *inode, struct file *file)  	list_del(&list->node);  	spin_unlock_irqrestore(&list->hdev->debug_list_lock, flags);  	kfifo_free(&list->hid_debug_fifo); + +	kref_put(&list->hdev->ref, hiddev_free);  	kfree(list);  	return 0; diff --git a/drivers/hid/hid-glorious.c b/drivers/hid/hid-glorious.c index 558eb08c19ef..281b3a7187ce 100644 --- a/drivers/hid/hid-glorious.c +++ b/drivers/hid/hid-glorious.c @@ -21,6 +21,10 @@ MODULE_DESCRIPTION("HID driver for Glorious PC Gaming Race mice");   * Glorious Model O and O- specify the const flag in the consumer input   * report descriptor, which leads to inputs being ignored. Fix this   * by patching the descriptor. + * + * Glorious Model I incorrectly specifes the Usage Minimum for its + * keyboard HID report, causing keycodes to be misinterpreted. + * Fix this by setting Usage Minimum to 0 in that report.   */  static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc,  		unsigned int *rsize) @@ -32,6 +36,10 @@ static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc,  		rdesc[85] = rdesc[113] = rdesc[141] = \  			HID_MAIN_ITEM_VARIABLE | HID_MAIN_ITEM_RELATIVE;  	} +	if (*rsize == 156 && rdesc[41] == 1) { +		hid_info(hdev, "patching Glorious Model I keyboard report descriptor\n"); +		rdesc[41] = 0; +	}  	return rdesc;  } @@ -44,6 +52,8 @@ static void glorious_update_name(struct hid_device *hdev)  		model = "Model O"; break;  	case USB_DEVICE_ID_GLORIOUS_MODEL_D:  		model = "Model D"; break; +	case USB_DEVICE_ID_GLORIOUS_MODEL_I: +		model = "Model I"; break;  	}  	snprintf(hdev->name, sizeof(hdev->name), "%s %s", "Glorious", model); @@ -66,10 +76,12 @@ static int glorious_probe(struct hid_device *hdev,  }  static const struct hid_device_id glorious_devices[] = { -	{ HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS, +	{ HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH,  		USB_DEVICE_ID_GLORIOUS_MODEL_O) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS, +	{ HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH,  		USB_DEVICE_ID_GLORIOUS_MODEL_D) }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_LAVIEW, +		USB_DEVICE_ID_GLORIOUS_MODEL_I) },  	{ }  };  MODULE_DEVICE_TABLE(hid, glorious_devices); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f7973ccd84a2..c6e4e0d1f214 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -511,10 +511,6 @@  #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a  #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100 -#define USB_VENDOR_ID_GLORIOUS  0x258a -#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033 -#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036 -  #define I2C_VENDOR_ID_GOODIX		0x27c6  #define I2C_DEVICE_ID_GOODIX_01F0	0x01f0 @@ -745,6 +741,9 @@  #define USB_VENDOR_ID_LABTEC		0x1020  #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD	0x0006 +#define USB_VENDOR_ID_LAVIEW		0x22D4 +#define USB_DEVICE_ID_GLORIOUS_MODEL_I	0x1503 +  #define USB_VENDOR_ID_LCPOWER		0x1241  #define USB_DEVICE_ID_LCPOWER_LC1000	0xf767 @@ -869,7 +868,6 @@  #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2		0xc534  #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1	0xc539  #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1	0xc53f -#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2	0xc547  #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY	0xc53a  #define USB_DEVICE_ID_SPACETRAVELLER	0xc623  #define USB_DEVICE_ID_SPACENAVIGATOR	0xc626 @@ -1160,6 +1158,10 @@  #define USB_VENDOR_ID_SIGMATEL		0x066F  #define USB_DEVICE_ID_SIGMATEL_STMP3780	0x3780 +#define USB_VENDOR_ID_SINOWEALTH  0x258a +#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033 +#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036 +  #define USB_VENDOR_ID_SIS_TOUCH		0x0457  #define USB_DEVICE_ID_SIS9200_TOUCH	0x9200  #define USB_DEVICE_ID_SIS817_TOUCH	0x0817 diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 8afe3be683ba..e6a8b6d8eab7 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -1695,12 +1695,11 @@ static int logi_dj_raw_event(struct hid_device *hdev,  		}  		/*  		 * Mouse-only receivers send unnumbered mouse data. The 27 MHz -		 * receiver uses 6 byte packets, the nano receiver 8 bytes, -		 * the lightspeed receiver (Pro X Superlight) 13 bytes. +		 * receiver uses 6 byte packets, the nano receiver 8 bytes.  		 */  		if (djrcv_dev->unnumbered_application == HID_GD_MOUSE && -		    size <= 13){ -			u8 mouse_report[14]; +		    size <= 8) { +			u8 mouse_report[9];  			/* Prepend report id */  			mouse_report[0] = REPORT_TYPE_MOUSE; @@ -1984,10 +1983,6 @@ static const struct hid_device_id logi_dj_receivers[] = {  	  HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,  		USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),  	 .driver_data = recvr_type_gaming_hidpp}, -	{ /* Logitech lightspeed receiver (0xc547) */ -	  HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, -		USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2), -	 .driver_data = recvr_type_gaming_hidpp},  	{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */  	  HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER), diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c index 72883e0ce757..aef0785c91cc 100644 --- a/drivers/hid/hid-mcp2221.c +++ b/drivers/hid/hid-mcp2221.c @@ -1142,6 +1142,8 @@ static int mcp2221_probe(struct hid_device *hdev,  	if (ret)  		return ret; +	hid_device_io_start(hdev); +  	/* Set I2C bus clock diviser */  	if (i2c_clk_freq > 400)  		i2c_clk_freq = 400; @@ -1157,12 +1159,12 @@ static int mcp2221_probe(struct hid_device *hdev,  	snprintf(mcp->adapter.name, sizeof(mcp->adapter.name),  			"MCP2221 usb-i2c bridge"); +	i2c_set_adapdata(&mcp->adapter, mcp);  	ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter);  	if (ret) {  		hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret);  		return ret;  	} -	i2c_set_adapdata(&mcp->adapter, mcp);  #if IS_REACHABLE(CONFIG_GPIOLIB)  	/* Setup GPIO chip */ diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index e098cc7b3944..fd5b0637dad6 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -2046,6 +2046,11 @@ static const struct hid_device_id mt_devices[] = {  		MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT,  			USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) }, +	/* HONOR GLO-GXXX panel */ +	{ .driver_data = MT_CLS_VTL, +		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, +			0x347d, 0x7853) }, +  	/* Ilitek dual touch panel */  	{  .driver_data = MT_CLS_NSMU,  		MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 5a48fcaa32f0..ea472923fab0 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -33,6 +33,7 @@ static const struct hid_device_id hid_quirks[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD },  	{ HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL }, +	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), HID_QUIRK_ALWAYS_POLL },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET }, diff --git a/include/linux/hid.h b/include/linux/hid.h index 5a8387a4a712..bf43f3ff6664 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -679,6 +679,7 @@ struct hid_device {							/* device report descriptor */  	struct list_head debug_list;  	spinlock_t  debug_list_lock;  	wait_queue_head_t debug_wait; +	struct kref			ref;  	unsigned int id;						/* system unique id */ @@ -687,6 +688,8 @@ struct hid_device {							/* device report descriptor */  #endif /* CONFIG_BPF */  }; +void hiddev_free(struct kref *ref); +  #define to_hid_device(pdev) \  	container_of(pdev, struct hid_device, dev)  | 
