4444#include "i2c-hid.h"
4545
4646/* quirks to control the device */
47- #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0)
48- #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1)
49- #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4)
50- #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5)
51- #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(6)
52- #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(7)
47+ #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(0)
48+ #define I2C_HID_QUIRK_BOGUS_IRQ BIT(1)
49+ #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(2)
50+ #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(3)
51+ #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(4)
5352
5453/* Command opcodes */
5554#define I2C_HID_OPCODE_RESET 0x01
@@ -120,8 +119,6 @@ static const struct i2c_hid_quirks {
120119 __u16 idProduct ;
121120 __u32 quirks ;
122121} i2c_hid_quirks [] = {
123- { USB_VENDOR_ID_WEIDA , HID_ANY_ID ,
124- I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
125122 { I2C_VENDOR_ID_HANTICK , I2C_PRODUCT_ID_HANTICK_5288 ,
126123 I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
127124 { I2C_VENDOR_ID_ITE , I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15 ,
@@ -395,8 +392,7 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state)
395392 * The call will get a return value (EREMOTEIO) but device will be
396393 * triggered and activated. After that, it goes like a normal device.
397394 */
398- if (power_state == I2C_HID_PWR_ON &&
399- ihid -> quirks & I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV ) {
395+ if (power_state == I2C_HID_PWR_ON ) {
400396 ret = i2c_hid_set_power_command (ihid , I2C_HID_PWR_ON );
401397
402398 /* Device was already activated */
@@ -426,12 +422,23 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state)
426422 return ret ;
427423}
428424
429- static int i2c_hid_execute_reset (struct i2c_hid * ihid )
425+ static int i2c_hid_start_hwreset (struct i2c_hid * ihid )
430426{
431427 size_t length = 0 ;
432428 int ret ;
433429
434- i2c_hid_dbg (ihid , "resetting...\n" );
430+ i2c_hid_dbg (ihid , "%s\n" , __func__ );
431+
432+ /*
433+ * This prevents sending feature reports while the device is
434+ * being reset. Otherwise we may lose the reset complete
435+ * interrupt.
436+ */
437+ lockdep_assert_held (& ihid -> reset_lock );
438+
439+ ret = i2c_hid_set_power (ihid , I2C_HID_PWR_ON );
440+ if (ret )
441+ return ret ;
435442
436443 /* Prepare reset command. Command register goes first. */
437444 * (__le16 * )ihid -> cmdbuf = ihid -> hdesc .wCommandRegister ;
@@ -444,60 +451,40 @@ static int i2c_hid_execute_reset(struct i2c_hid *ihid)
444451
445452 ret = i2c_hid_xfer (ihid , ihid -> cmdbuf , length , NULL , 0 );
446453 if (ret ) {
447- dev_err (& ihid -> client -> dev , "failed to reset device.\n" );
448- goto out ;
449- }
450-
451- if (ihid -> quirks & I2C_HID_QUIRK_NO_IRQ_AFTER_RESET ) {
452- msleep (100 );
453- goto out ;
454+ dev_err (& ihid -> client -> dev ,
455+ "failed to reset device: %d\n" , ret );
456+ goto err_clear_reset ;
454457 }
455458
456- i2c_hid_dbg (ihid , "%s: waiting...\n" , __func__ );
457- if (!wait_event_timeout (ihid -> wait ,
458- !test_bit (I2C_HID_RESET_PENDING , & ihid -> flags ),
459- msecs_to_jiffies (5000 ))) {
460- ret = - ENODATA ;
461- goto out ;
462- }
463- i2c_hid_dbg (ihid , "%s: finished.\n" , __func__ );
459+ return 0 ;
464460
465- out :
461+ err_clear_reset :
466462 clear_bit (I2C_HID_RESET_PENDING , & ihid -> flags );
463+ i2c_hid_set_power (ihid , I2C_HID_PWR_SLEEP );
467464 return ret ;
468465}
469466
470- static int i2c_hid_hwreset (struct i2c_hid * ihid )
467+ static int i2c_hid_finish_hwreset (struct i2c_hid * ihid )
471468{
472- int ret ;
469+ int ret = 0 ;
473470
474- i2c_hid_dbg (ihid , "%s\n" , __func__ );
475-
476- /*
477- * This prevents sending feature reports while the device is
478- * being reset. Otherwise we may lose the reset complete
479- * interrupt.
480- */
481- mutex_lock (& ihid -> reset_lock );
482-
483- ret = i2c_hid_set_power (ihid , I2C_HID_PWR_ON );
484- if (ret )
485- goto out_unlock ;
471+ i2c_hid_dbg (ihid , "%s: waiting...\n" , __func__ );
486472
487- ret = i2c_hid_execute_reset (ihid );
488- if (ret ) {
489- dev_err (& ihid -> client -> dev ,
490- "failed to reset device: %d\n" , ret );
491- i2c_hid_set_power (ihid , I2C_HID_PWR_SLEEP );
492- goto out_unlock ;
473+ if (ihid -> quirks & I2C_HID_QUIRK_NO_IRQ_AFTER_RESET ) {
474+ msleep (100 );
475+ clear_bit (I2C_HID_RESET_PENDING , & ihid -> flags );
476+ } else if (!wait_event_timeout (ihid -> wait ,
477+ !test_bit (I2C_HID_RESET_PENDING , & ihid -> flags ),
478+ msecs_to_jiffies (1000 ))) {
479+ dev_warn (& ihid -> client -> dev , "device did not ack reset within 1000 ms\n" );
480+ clear_bit (I2C_HID_RESET_PENDING , & ihid -> flags );
493481 }
482+ i2c_hid_dbg (ihid , "%s: finished.\n" , __func__ );
494483
495484 /* At least some SIS devices need this after reset */
496485 if (!(ihid -> quirks & I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET ))
497486 ret = i2c_hid_set_power (ihid , I2C_HID_PWR_ON );
498487
499- out_unlock :
500- mutex_unlock (& ihid -> reset_lock );
501488 return ret ;
502489}
503490
@@ -729,11 +716,10 @@ static int i2c_hid_parse(struct hid_device *hid)
729716 struct i2c_client * client = hid -> driver_data ;
730717 struct i2c_hid * ihid = i2c_get_clientdata (client );
731718 struct i2c_hid_desc * hdesc = & ihid -> hdesc ;
719+ char * rdesc = NULL , * use_override = NULL ;
732720 unsigned int rsize ;
733- char * rdesc ;
734721 int ret ;
735722 int tries = 3 ;
736- char * use_override ;
737723
738724 i2c_hid_dbg (ihid , "entering %s\n" , __func__ );
739725
@@ -743,14 +729,15 @@ static int i2c_hid_parse(struct hid_device *hid)
743729 return - EINVAL ;
744730 }
745731
732+ mutex_lock (& ihid -> reset_lock );
746733 do {
747- ret = i2c_hid_hwreset (ihid );
734+ ret = i2c_hid_start_hwreset (ihid );
748735 if (ret )
749736 msleep (1000 );
750737 } while (tries -- > 0 && ret );
751738
752739 if (ret )
753- return ret ;
740+ goto abort_reset ;
754741
755742 use_override = i2c_hid_get_dmi_hid_report_desc_override (client -> name ,
756743 & rsize );
@@ -762,8 +749,8 @@ static int i2c_hid_parse(struct hid_device *hid)
762749 rdesc = kzalloc (rsize , GFP_KERNEL );
763750
764751 if (!rdesc ) {
765- dbg_hid ( "couldn't allocate rdesc memory\n" ) ;
766- return - ENOMEM ;
752+ ret = - ENOMEM ;
753+ goto abort_reset ;
767754 }
768755
769756 i2c_hid_dbg (ihid , "asking HID report descriptor\n" );
@@ -773,23 +760,34 @@ static int i2c_hid_parse(struct hid_device *hid)
773760 rdesc , rsize );
774761 if (ret ) {
775762 hid_err (hid , "reading report descriptor failed\n" );
776- kfree (rdesc );
777- return - EIO ;
763+ goto abort_reset ;
778764 }
779765 }
780766
767+ /*
768+ * Windows directly reads the report-descriptor after sending reset
769+ * and then waits for resets completion afterwards. Some touchpads
770+ * actually wait for the report-descriptor to be read before signalling
771+ * reset completion.
772+ */
773+ ret = i2c_hid_finish_hwreset (ihid );
774+ abort_reset :
775+ clear_bit (I2C_HID_RESET_PENDING , & ihid -> flags );
776+ mutex_unlock (& ihid -> reset_lock );
777+ if (ret )
778+ goto out ;
779+
781780 i2c_hid_dbg (ihid , "Report Descriptor: %*ph\n" , rsize , rdesc );
782781
783782 ret = hid_parse_report (hid , rdesc , rsize );
783+ if (ret )
784+ dbg_hid ("parsing report descriptor failed\n" );
785+
786+ out :
784787 if (!use_override )
785788 kfree (rdesc );
786789
787- if (ret ) {
788- dbg_hid ("parsing report descriptor failed\n" );
789- return ret ;
790- }
791-
792- return 0 ;
790+ return ret ;
793791}
794792
795793static int i2c_hid_start (struct hid_device * hid )
@@ -987,10 +985,15 @@ static int i2c_hid_core_resume(struct i2c_hid *ihid)
987985 * However some ALPS touchpads generate IRQ storm without reset, so
988986 * let's still reset them here.
989987 */
990- if (ihid -> quirks & I2C_HID_QUIRK_RESET_ON_RESUME )
991- ret = i2c_hid_hwreset (ihid );
992- else
988+ if (ihid -> quirks & I2C_HID_QUIRK_RESET_ON_RESUME ) {
989+ mutex_lock (& ihid -> reset_lock );
990+ ret = i2c_hid_start_hwreset (ihid );
991+ if (ret == 0 )
992+ ret = i2c_hid_finish_hwreset (ihid );
993+ mutex_unlock (& ihid -> reset_lock );
994+ } else {
993995 ret = i2c_hid_set_power (ihid , I2C_HID_PWR_ON );
996+ }
994997
995998 if (ret )
996999 return ret ;
0 commit comments