Skip to content

Commit 83ec916

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID updates from Jiri Kosina: - Fix in i2c-hid driver for Elan touchpad quirk regression (Jim Broadus) - Quirk preventing ASUS Claymore from accidentally suspending whole system (Luke D. Jones) - Updates to the existing FW reporting mechanism, MP2 FW status checks, adding proper power management support for amd-sfh (Basavaraj Natikar) - Regression fix for an issue in HID core that got uncovered by recent USB core cleanup leading to issues when transfer_buffer_length is not in line with wLength (Alan Stern) - Memory leak fix in USB HID core (Anirudh Rayabharam) - Improvement of stylus battery reporting (Dmitry Torokhov) - Power management improvement for Goodix driver (Douglas Anderson) - High-resolution scroll support for Magicmouse devices (José Expósito) - Support for GHLive PS4 dongles (Daniel Nguyen) - Support proper EV_MSC emissions to hid-apple (Vincent Lefevre) * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (31 commits) HID: usbhid: Simplify code in hid_submit_ctrl() HID: usbhid: Fix warning caused by 0-length input reports HID: usbhid: Fix flood of "control queue full" messages HID: sony: Fix more ShanWan clone gamepads to not rumble when plugged in. HID: sony: support for the ghlive ps4 dongles HID: thrustmaster: clean up Makefile and adapt quirks HID: i2c-hid: Fix Elan touchpad regression HID: asus: Prevent Claymore sending suspend event HID: amd_sfh: Add dyndbg prints for debugging HID: amd_sfh: Add support for PM suspend and resume HID: amd_sfh: Move hid probe after sensor is enabled HID: amd_sfh: Add command response to check command status HID: amd_sfh: Fix period data field to enable sensor HID: logitech-hidpp: battery: provide CAPACITY property for newer devices HID: thrustmaster: Fix memory leak in thrustmaster_interrupts() HID: thrustmaster: Fix memory leak in remove HID: thrustmaster: Fix memory leaks in probe HID: elo: update the reference count of the usb device structure HID: logitech-hidpp: Use 'atomic_inc_return' instead of hand-writing it HID: apple: Add missing scan code event for keys handled by hid-apple ...
2 parents c793011 + 46a226b commit 83ec916

22 files changed

+564
-96
lines changed

drivers/hid/Kconfig

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,11 @@ config HID_PRODIKEYS
259259
and some additional multimedia keys.
260260

261261
config HID_CMEDIA
262-
tristate "CMedia CM6533 HID audio jack controls"
262+
tristate "CMedia audio chips"
263263
depends on HID
264264
help
265-
Support for CMedia CM6533 HID audio jack controls.
265+
Support for CMedia CM6533 HID audio jack controls
266+
and HS100B mute buttons.
266267

267268
config HID_CP2112
268269
tristate "Silicon Labs CP2112 HID USB-to-SMBus Bridge support"
@@ -952,7 +953,7 @@ config HID_SONY
952953
* Buzz controllers
953954
* Sony PS3 Blue-ray Disk Remote Control (Bluetooth)
954955
* Logitech Harmony adapter for Sony Playstation 3 (Bluetooth)
955-
* Guitar Hero Live PS3 and Wii U guitar dongles
956+
* Guitar Hero Live PS3, Wii U and PS4 guitar dongles
956957
* Guitar Hero PS3 and PC guitar dongles
957958

958959
config SONY_FF

drivers/hid/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o
115115
obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
116116
obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
117117
obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o hid-thrustmaster.o
118-
obj-$(CONFIG_HID_TMINIT) += hid-tminit.o
119118
obj-$(CONFIG_HID_TIVO) += hid-tivo.o
120119
obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
121120
obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o

drivers/hid/amd-sfh-hid/amd_sfh_client.c

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "amd_sfh_pcie.h"
1818
#include "amd_sfh_hid.h"
1919

20-
#define AMD_SFH_IDLE_LOOP 200
2120

2221
struct request_list {
2322
struct hid_device *hid;
@@ -123,14 +122,24 @@ static void amd_sfh_work_buffer(struct work_struct *work)
123122
int i;
124123

125124
for (i = 0; i < cli_data->num_hid_devices; i++) {
126-
report_size = get_input_report(i, cli_data->sensor_idx[i], cli_data->report_id[i],
127-
in_data);
128-
hid_input_report(cli_data->hid_sensor_hubs[i], HID_INPUT_REPORT,
129-
in_data->input_report[i], report_size, 0);
125+
if (cli_data->sensor_sts[i] == SENSOR_ENABLED) {
126+
report_size = get_input_report
127+
(i, cli_data->sensor_idx[i], cli_data->report_id[i], in_data);
128+
hid_input_report(cli_data->hid_sensor_hubs[i], HID_INPUT_REPORT,
129+
in_data->input_report[i], report_size, 0);
130+
}
130131
}
131132
schedule_delayed_work(&cli_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
132133
}
133134

135+
u32 amd_sfh_wait_for_response(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts)
136+
{
137+
if (mp2->mp2_ops->response)
138+
sensor_sts = mp2->mp2_ops->response(mp2, sid, sensor_sts);
139+
140+
return sensor_sts;
141+
}
142+
134143
int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
135144
{
136145
struct amd_input_data *in_data = &privdata->in_data;
@@ -139,8 +148,8 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
139148
struct device *dev;
140149
u32 feature_report_size;
141150
u32 input_report_size;
151+
int rc, i, status;
142152
u8 cl_idx;
143-
int rc, i;
144153

145154
dev = &privdata->pdev->dev;
146155

@@ -155,7 +164,7 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
155164
in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
156165
&cl_data->sensor_dma_addr[i],
157166
GFP_KERNEL);
158-
cl_data->sensor_sts[i] = 0;
167+
cl_data->sensor_sts[i] = SENSOR_DISABLED;
159168
cl_data->sensor_requested_cnt[i] = 0;
160169
cl_data->cur_hid_dev = i;
161170
cl_idx = cl_data->sensor_idx[i];
@@ -184,7 +193,7 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
184193
rc = -ENOMEM;
185194
goto cleanup;
186195
}
187-
info.period = msecs_to_jiffies(AMD_SFH_IDLE_LOOP);
196+
info.period = AMD_SFH_IDLE_LOOP;
188197
info.sensor_idx = cl_idx;
189198
info.dma_address = cl_data->sensor_dma_addr[i];
190199

@@ -195,13 +204,27 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
195204
goto cleanup;
196205
}
197206
rc = get_report_descriptor(cl_idx, cl_data->report_descr[i]);
198-
if (rc)
199-
return rc;
200-
rc = amdtp_hid_probe(cl_data->cur_hid_dev, cl_data);
201207
if (rc)
202208
return rc;
203209
privdata->mp2_ops->start(privdata, info);
204-
cl_data->sensor_sts[i] = 1;
210+
status = amd_sfh_wait_for_response
211+
(privdata, cl_data->sensor_idx[i], SENSOR_ENABLED);
212+
if (status == SENSOR_ENABLED) {
213+
cl_data->sensor_sts[i] = SENSOR_ENABLED;
214+
rc = amdtp_hid_probe(cl_data->cur_hid_dev, cl_data);
215+
if (rc) {
216+
privdata->mp2_ops->stop(privdata, cl_data->sensor_idx[i]);
217+
status = amd_sfh_wait_for_response
218+
(privdata, cl_data->sensor_idx[i], SENSOR_DISABLED);
219+
if (status != SENSOR_ENABLED)
220+
cl_data->sensor_sts[i] = SENSOR_DISABLED;
221+
dev_dbg(dev, "sid 0x%x status 0x%x\n",
222+
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
223+
goto cleanup;
224+
}
225+
}
226+
dev_dbg(dev, "sid 0x%x status 0x%x\n",
227+
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
205228
}
206229
schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
207230
return 0;
@@ -224,10 +247,19 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
224247
{
225248
struct amdtp_cl_data *cl_data = privdata->cl_data;
226249
struct amd_input_data *in_data = cl_data->in_data;
227-
int i;
250+
int i, status;
228251

229-
for (i = 0; i < cl_data->num_hid_devices; i++)
230-
privdata->mp2_ops->stop(privdata, i);
252+
for (i = 0; i < cl_data->num_hid_devices; i++) {
253+
if (cl_data->sensor_sts[i] == SENSOR_ENABLED) {
254+
privdata->mp2_ops->stop(privdata, cl_data->sensor_idx[i]);
255+
status = amd_sfh_wait_for_response
256+
(privdata, cl_data->sensor_idx[i], SENSOR_DISABLED);
257+
if (status != SENSOR_ENABLED)
258+
cl_data->sensor_sts[i] = SENSOR_DISABLED;
259+
dev_dbg(&privdata->pdev->dev, "stopping sid 0x%x status 0x%x\n",
260+
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
261+
}
262+
}
231263

232264
cancel_delayed_work_sync(&cl_data->work);
233265
cancel_delayed_work_sync(&cl_data->work_buffer);

drivers/hid/amd-sfh-hid/amd_sfh_pcie.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/dmi.h>
1414
#include <linux/interrupt.h>
1515
#include <linux/io-64-nonatomic-lo-hi.h>
16+
#include <linux/iopoll.h>
1617
#include <linux/module.h>
1718
#include <linux/slab.h>
1819

@@ -31,6 +32,20 @@ static int sensor_mask_override = -1;
3132
module_param_named(sensor_mask, sensor_mask_override, int, 0444);
3233
MODULE_PARM_DESC(sensor_mask, "override the detected sensors mask");
3334

35+
static int amd_sfh_wait_response_v2(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts)
36+
{
37+
union cmd_response cmd_resp;
38+
39+
/* Get response with status within a max of 800 ms timeout */
40+
if (!readl_poll_timeout(mp2->mmio + AMD_P2C_MSG(0), cmd_resp.resp,
41+
(cmd_resp.response_v2.response == sensor_sts &&
42+
cmd_resp.response_v2.status == 0 && (sid == 0xff ||
43+
cmd_resp.response_v2.sensor_id == sid)), 500, 800000))
44+
return cmd_resp.response_v2.response;
45+
46+
return SENSOR_DISABLED;
47+
}
48+
3449
static void amd_start_sensor_v2(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
3550
{
3651
union sfh_cmd_base cmd_base;
@@ -183,6 +198,7 @@ static const struct amd_mp2_ops amd_sfh_ops_v2 = {
183198
.start = amd_start_sensor_v2,
184199
.stop = amd_stop_sensor_v2,
185200
.stop_all = amd_stop_all_sensor_v2,
201+
.response = amd_sfh_wait_response_v2,
186202
};
187203

188204
static const struct amd_mp2_ops amd_sfh_ops = {
@@ -248,6 +264,58 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
248264
return amd_sfh_hid_client_init(privdata);
249265
}
250266

267+
static int __maybe_unused amd_mp2_pci_resume(struct device *dev)
268+
{
269+
struct pci_dev *pdev = to_pci_dev(dev);
270+
struct amd_mp2_dev *mp2 = pci_get_drvdata(pdev);
271+
struct amdtp_cl_data *cl_data = mp2->cl_data;
272+
struct amd_mp2_sensor_info info;
273+
int i, status;
274+
275+
for (i = 0; i < cl_data->num_hid_devices; i++) {
276+
if (cl_data->sensor_sts[i] == SENSOR_DISABLED) {
277+
info.period = AMD_SFH_IDLE_LOOP;
278+
info.sensor_idx = cl_data->sensor_idx[i];
279+
info.dma_address = cl_data->sensor_dma_addr[i];
280+
mp2->mp2_ops->start(mp2, info);
281+
status = amd_sfh_wait_for_response
282+
(mp2, cl_data->sensor_idx[i], SENSOR_ENABLED);
283+
if (status == SENSOR_ENABLED)
284+
cl_data->sensor_sts[i] = SENSOR_ENABLED;
285+
dev_dbg(dev, "resume sid 0x%x status 0x%x\n",
286+
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
287+
}
288+
}
289+
290+
return 0;
291+
}
292+
293+
static int __maybe_unused amd_mp2_pci_suspend(struct device *dev)
294+
{
295+
struct pci_dev *pdev = to_pci_dev(dev);
296+
struct amd_mp2_dev *mp2 = pci_get_drvdata(pdev);
297+
struct amdtp_cl_data *cl_data = mp2->cl_data;
298+
int i, status;
299+
300+
for (i = 0; i < cl_data->num_hid_devices; i++) {
301+
if (cl_data->sensor_idx[i] != HPD_IDX &&
302+
cl_data->sensor_sts[i] == SENSOR_ENABLED) {
303+
mp2->mp2_ops->stop(mp2, cl_data->sensor_idx[i]);
304+
status = amd_sfh_wait_for_response
305+
(mp2, cl_data->sensor_idx[i], SENSOR_DISABLED);
306+
if (status != SENSOR_ENABLED)
307+
cl_data->sensor_sts[i] = SENSOR_DISABLED;
308+
dev_dbg(dev, "suspend sid 0x%x status 0x%x\n",
309+
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
310+
}
311+
}
312+
313+
return 0;
314+
}
315+
316+
static SIMPLE_DEV_PM_OPS(amd_mp2_pm_ops, amd_mp2_pci_suspend,
317+
amd_mp2_pci_resume);
318+
251319
static const struct pci_device_id amd_mp2_pci_tbl[] = {
252320
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_MP2) },
253321
{ }
@@ -258,6 +326,7 @@ static struct pci_driver amd_mp2_pci_driver = {
258326
.name = DRIVER_NAME,
259327
.id_table = amd_mp2_pci_tbl,
260328
.probe = amd_mp2_pci_probe,
329+
.driver.pm = &amd_mp2_pm_ops,
261330
};
262331
module_pci_driver(amd_mp2_pci_driver);
263332

drivers/hid/amd-sfh-hid/amd_sfh_pcie.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,20 @@
2424
#define AMD_C2P_MSG2 0x10508
2525

2626
#define AMD_C2P_MSG(regno) (0x10500 + ((regno) * 4))
27+
#define AMD_P2C_MSG(regno) (0x10680 + ((regno) * 4))
2728

2829
/* MP2 P2C Message Registers */
2930
#define AMD_P2C_MSG3 0x1068C /* Supported Sensors info */
3031

3132
#define V2_STATUS 0x2
3233

34+
#define SENSOR_ENABLED 4
35+
#define SENSOR_DISABLED 5
36+
3337
#define HPD_IDX 16
3438

39+
#define AMD_SFH_IDLE_LOOP 200
40+
3541
/* SFH Command register */
3642
union sfh_cmd_base {
3743
u32 ul;
@@ -51,6 +57,19 @@ union sfh_cmd_base {
5157
} cmd_v2;
5258
};
5359

60+
union cmd_response {
61+
u32 resp;
62+
struct {
63+
u32 status : 2;
64+
u32 out_in_c2p : 1;
65+
u32 rsvd1 : 1;
66+
u32 response : 4;
67+
u32 sub_cmd : 8;
68+
u32 sensor_id : 6;
69+
u32 rsvd2 : 10;
70+
} response_v2;
71+
};
72+
5473
union sfh_cmd_param {
5574
u32 ul;
5675
struct {
@@ -112,10 +131,14 @@ void amd_stop_all_sensors(struct amd_mp2_dev *privdata);
112131
int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id);
113132
int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata);
114133
int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata);
134+
u32 amd_sfh_wait_for_response(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts);
135+
void amd_mp2_suspend(struct amd_mp2_dev *mp2);
136+
void amd_mp2_resume(struct amd_mp2_dev *mp2);
115137

116138
struct amd_mp2_ops {
117139
void (*start)(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info);
118140
void (*stop)(struct amd_mp2_dev *privdata, u16 sensor_idx);
119141
void (*stop_all)(struct amd_mp2_dev *privdata);
142+
int (*response)(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts);
120143
};
121144
#endif

drivers/hid/hid-apple.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,15 @@ static const struct apple_key_translation *apple_find_translation(
187187
return NULL;
188188
}
189189

190+
static void input_event_with_scancode(struct input_dev *input,
191+
__u8 type, __u16 code, unsigned int hid, __s32 value)
192+
{
193+
if (type == EV_KEY &&
194+
(!test_bit(code, input->key)) == value)
195+
input_event(input, EV_MSC, MSC_SCAN, hid);
196+
input_event(input, type, code, value);
197+
}
198+
190199
static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
191200
struct hid_usage *usage, __s32 value)
192201
{
@@ -199,7 +208,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
199208

200209
if (usage->code == fn_keycode) {
201210
asc->fn_on = !!value;
202-
input_event(input, usage->type, KEY_FN, value);
211+
input_event_with_scancode(input, usage->type, KEY_FN,
212+
usage->hid, value);
203213
return 1;
204214
}
205215

@@ -240,7 +250,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
240250
code = do_translate ? trans->to : trans->from;
241251
}
242252

243-
input_event(input, usage->type, code, value);
253+
input_event_with_scancode(input, usage->type, code,
254+
usage->hid, value);
244255
return 1;
245256
}
246257

@@ -258,8 +269,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
258269
clear_bit(usage->code,
259270
asc->pressed_numlock);
260271

261-
input_event(input, usage->type, trans->to,
262-
value);
272+
input_event_with_scancode(input, usage->type,
273+
trans->to, usage->hid, value);
263274
}
264275

265276
return 1;
@@ -270,7 +281,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
270281
if (hid->country == HID_COUNTRY_INTERNATIONAL_ISO) {
271282
trans = apple_find_translation(apple_iso_keyboard, usage->code);
272283
if (trans) {
273-
input_event(input, usage->type, trans->to, value);
284+
input_event_with_scancode(input, usage->type,
285+
trans->to, usage->hid, value);
274286
return 1;
275287
}
276288
}
@@ -279,15 +291,17 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
279291
if (swap_opt_cmd) {
280292
trans = apple_find_translation(swapped_option_cmd_keys, usage->code);
281293
if (trans) {
282-
input_event(input, usage->type, trans->to, value);
294+
input_event_with_scancode(input, usage->type,
295+
trans->to, usage->hid, value);
283296
return 1;
284297
}
285298
}
286299

287300
if (swap_fn_leftctrl) {
288301
trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code);
289302
if (trans) {
290-
input_event(input, usage->type, trans->to, value);
303+
input_event_with_scancode(input, usage->type,
304+
trans->to, usage->hid, value);
291305
return 1;
292306
}
293307
}
@@ -306,8 +320,8 @@ static int apple_event(struct hid_device *hdev, struct hid_field *field,
306320

307321
if ((asc->quirks & APPLE_INVERT_HWHEEL) &&
308322
usage->code == REL_HWHEEL) {
309-
input_event(field->hidinput->input, usage->type, usage->code,
310-
-value);
323+
input_event_with_scancode(field->hidinput->input, usage->type,
324+
usage->code, usage->hid, -value);
311325
return 1;
312326
}
313327

0 commit comments

Comments
 (0)