Skip to content

Commit 00b790e

Browse files
khfengJiri Kosina
authored andcommitted
HID: i2c-hid: Add a small delay after sleep command for Raydium touchpanel
Raydium touchpanel (2386:4B33) sometimes does not work in desktop session although it works in display manager. During user logging, the display manager exits, close the HID device, then the device gets runtime suspended and powered off. The desktop session begins shortly after, opens the HID device, then the device gets runtime resumed and powered on. If the trasition from display manager to desktop sesesion is fast, the touchpanel cannot switch from powered off to powered on in short timeframe. So add a small delay to workaround the issue. Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
1 parent f112743 commit 00b790e

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

drivers/hid/hid-ids.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,9 @@
927927
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003 0x3003
928928
#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008
929929

930+
#define I2C_VENDOR_ID_RAYDIUM 0x2386
931+
#define I2C_PRODUCT_ID_RAYDIUM_4B33 0x4b33
932+
930933
#define USB_VENDOR_ID_RAZER 0x1532
931934
#define USB_DEVICE_ID_RAZER_BLADE_14 0x011D
932935

drivers/hid/i2c-hid/i2c-hid-core.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0)
5050
#define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1)
5151
#define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2)
52+
#define I2C_HID_QUIRK_DELAY_AFTER_SLEEP BIT(3)
5253

5354
/* flags */
5455
#define I2C_HID_STARTED 0
@@ -158,6 +159,8 @@ struct i2c_hid {
158159

159160
bool irq_wake_enabled;
160161
struct mutex reset_lock;
162+
163+
unsigned long sleep_delay;
161164
};
162165

163166
static const struct i2c_hid_quirks {
@@ -172,6 +175,8 @@ static const struct i2c_hid_quirks {
172175
{ I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
173176
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET |
174177
I2C_HID_QUIRK_NO_RUNTIME_PM },
178+
{ I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33,
179+
I2C_HID_QUIRK_DELAY_AFTER_SLEEP },
175180
{ 0, 0 }
176181
};
177182

@@ -387,6 +392,7 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state)
387392
{
388393
struct i2c_hid *ihid = i2c_get_clientdata(client);
389394
int ret;
395+
unsigned long now, delay;
390396

391397
i2c_hid_dbg(ihid, "%s\n", __func__);
392398

@@ -404,9 +410,22 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state)
404410
goto set_pwr_exit;
405411
}
406412

413+
if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP &&
414+
power_state == I2C_HID_PWR_ON) {
415+
now = jiffies;
416+
if (time_after(ihid->sleep_delay, now)) {
417+
delay = jiffies_to_usecs(ihid->sleep_delay - now);
418+
usleep_range(delay, delay + 1);
419+
}
420+
}
421+
407422
ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state,
408423
0, NULL, 0, NULL, 0);
409424

425+
if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP &&
426+
power_state == I2C_HID_PWR_SLEEP)
427+
ihid->sleep_delay = jiffies + msecs_to_jiffies(20);
428+
410429
if (ret)
411430
dev_err(&client->dev, "failed to change power setting.\n");
412431

0 commit comments

Comments
 (0)