Skip to content

Commit 113521a

Browse files
Lode WillemsJiri Kosina
authored andcommitted
HID: Kysona: Add periodic online check
This patch adds a periodic online check at the same interval the battery status gets requested. With this change the driver can detect when the mouse is turned off while the dongle is still plugged in. Tested with a Kysona M600 V-HUB Special Edition. Signed-off-by: Lode Willems <me@lodewillems.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent 5e06802 commit 113521a

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

drivers/hid/hid-kysona.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#define BATTERY_TIMEOUT_MS 5000
1616

17+
#define ONLINE_REPORT_ID 3
1718
#define BATTERY_REPORT_ID 4
1819

1920
struct kysona_drvdata {
@@ -80,11 +81,46 @@ static int kysona_battery_get_property(struct power_supply *psy,
8081
return ret;
8182
}
8283

84+
static const char kysona_online_request[] = {
85+
0x08, ONLINE_REPORT_ID, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a
87+
};
88+
8389
static const char kysona_battery_request[] = {
8490
0x08, BATTERY_REPORT_ID, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8591
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49
8692
};
8793

94+
static int kysona_m600_fetch_online(struct hid_device *hdev)
95+
{
96+
u8 *write_buf;
97+
int ret;
98+
99+
/* Request online information */
100+
write_buf = kmemdup(kysona_online_request, sizeof(kysona_online_request), GFP_KERNEL);
101+
if (!write_buf)
102+
return -ENOMEM;
103+
104+
ret = hid_hw_raw_request(hdev, kysona_online_request[0],
105+
write_buf, sizeof(kysona_online_request),
106+
HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
107+
if (ret < (int)sizeof(kysona_online_request)) {
108+
hid_err(hdev, "hid_hw_raw_request() failed with %d\n", ret);
109+
ret = -ENODATA;
110+
}
111+
kfree(write_buf);
112+
return ret;
113+
}
114+
115+
static void kysona_fetch_online(struct hid_device *hdev)
116+
{
117+
int ret = kysona_m600_fetch_online(hdev);
118+
119+
if (ret < 0)
120+
hid_dbg(hdev,
121+
"Online query failed (err: %d)\n", ret);
122+
}
123+
88124
static int kysona_m600_fetch_battery(struct hid_device *hdev)
89125
{
90126
u8 *write_buf;
@@ -121,6 +157,7 @@ static void kysona_battery_timer_tick(struct work_struct *work)
121157
struct kysona_drvdata, battery_work.work);
122158
struct hid_device *hdev = drv_data->hdev;
123159

160+
kysona_fetch_online(hdev);
124161
kysona_fetch_battery(hdev);
125162
schedule_delayed_work(&drv_data->battery_work,
126163
msecs_to_jiffies(BATTERY_TIMEOUT_MS));
@@ -160,6 +197,7 @@ static int kysona_battery_probe(struct hid_device *hdev)
160197
power_supply_powers(drv_data->battery, &hdev->dev);
161198

162199
INIT_DELAYED_WORK(&drv_data->battery_work, kysona_battery_timer_tick);
200+
kysona_fetch_online(hdev);
163201
kysona_fetch_battery(hdev);
164202
schedule_delayed_work(&drv_data->battery_work,
165203
msecs_to_jiffies(BATTERY_TIMEOUT_MS));
@@ -206,12 +244,16 @@ static int kysona_raw_event(struct hid_device *hdev,
206244
{
207245
struct kysona_drvdata *drv_data = hid_get_drvdata(hdev);
208246

209-
if (drv_data->battery && size == sizeof(kysona_battery_request) &&
247+
if (size == sizeof(kysona_online_request) &&
248+
data[0] == 8 && data[1] == ONLINE_REPORT_ID) {
249+
drv_data->online = data[6];
250+
}
251+
252+
if (size == sizeof(kysona_battery_request) &&
210253
data[0] == 8 && data[1] == BATTERY_REPORT_ID) {
211254
drv_data->battery_capacity = data[6];
212255
drv_data->battery_charging = data[7];
213256
drv_data->battery_voltage = (data[8] << 8) | data[9];
214-
drv_data->online = true;
215257
}
216258

217259
return 0;

0 commit comments

Comments
 (0)