Skip to content

Commit 31fa4fc

Browse files
author
Herton R. Krzesinski
committed
Merge: Input and HID backport to 6.0.x
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/1809 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2122844 Tested: by me with the hid-tools test suite and a wide range of devices This is the usual Input and HID backport to 6.0.x for RHEL 9.2. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Approved-by: Tony Camuso <tcamuso@redhat.com> Approved-by: David Arcari <darcari@redhat.com> Approved-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
2 parents 978c962 + 225ee68 commit 31fa4fc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+4309
-1056
lines changed

drivers/hid/.kunitconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CONFIG_KUNIT=y
2+
CONFIG_USB=y
3+
CONFIG_USB_HID=y
4+
CONFIG_HID_UCLOGIC=y
5+
CONFIG_HID_KUNIT_TEST=y

drivers/hid/Kconfig

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,14 @@ config HID_MAYFLASH
697697
Say Y here if you have HJZ Mayflash PS3 game controller adapters
698698
and want to enable force feedback support.
699699

700+
config HID_MEGAWORLD_FF
701+
tristate "Mega World based game controller force feedback support"
702+
depends on USB_HID
703+
select INPUT_FF_MEMLESS
704+
help
705+
Say Y here if you have a Mega World based game controller and want
706+
to have force feedback support for it.
707+
700708
config HID_REDRAGON
701709
tristate "Redragon keyboards"
702710
depends on HID
@@ -1133,6 +1141,12 @@ config HID_TOPSEED
11331141
Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
11341142
CLLRCMCE remote control.
11351143

1144+
config HID_TOPRE
1145+
tristate "Topre REALFORCE keyboards"
1146+
depends on HID
1147+
help
1148+
Say Y for N-key rollover support on Topre REALFORCE R2 108 key keyboards.
1149+
11361150
config HID_THINGM
11371151
tristate "ThingM blink(1) USB RGB LED"
11381152
depends on HID
@@ -1298,6 +1312,22 @@ config HID_MCP2221
12981312
To compile this driver as a module, choose M here: the module
12991313
will be called hid-mcp2221.ko.
13001314

1315+
config HID_KUNIT_TEST
1316+
bool "KUnit tests for HID" if !KUNIT_ALL_TESTS
1317+
depends on KUNIT=y
1318+
depends on HID_UCLOGIC
1319+
default KUNIT_ALL_TESTS
1320+
help
1321+
This builds unit tests for HID. This option is not useful for
1322+
distributions or general kernels, but only for kernel
1323+
developers working on HID and associated drivers.
1324+
1325+
For more information on KUnit and unit tests in general,
1326+
please refer to the KUnit documentation in
1327+
Documentation/dev-tools/kunit/.
1328+
1329+
If in doubt, say "N".
1330+
13011331
endmenu
13021332

13031333
endif # HID

drivers/hid/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
7777
obj-$(CONFIG_HID_MALTRON) += hid-maltron.o
7878
obj-$(CONFIG_HID_MCP2221) += hid-mcp2221.o
7979
obj-$(CONFIG_HID_MAYFLASH) += hid-mf.o
80+
obj-$(CONFIG_HID_MEGAWORLD_FF) += hid-megaworld.o
8081
obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
8182
obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
8283
obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o
@@ -122,6 +123,7 @@ obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
122123
obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o hid-thrustmaster.o
123124
obj-$(CONFIG_HID_TIVO) += hid-tivo.o
124125
obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
126+
obj-$(CONFIG_HID_TOPRE) += hid-topre.o
125127
obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o
126128
obj-$(CONFIG_HID_U2FZERO) += hid-u2fzero.o
127129
hid-uclogic-objs := hid-uclogic-core.o \
@@ -143,6 +145,9 @@ obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o
143145
obj-$(CONFIG_HID_SENSOR_HUB) += hid-sensor-hub.o
144146
obj-$(CONFIG_HID_SENSOR_CUSTOM_SENSOR) += hid-sensor-custom.o
145147

148+
obj-$(CONFIG_HID_KUNIT_TEST) += hid-uclogic-rdesc.o \
149+
hid-uclogic-rdesc-test.o
150+
146151
obj-$(CONFIG_USB_HID) += usbhid/
147152
obj-$(CONFIG_USB_MOUSE) += usbhid/
148153
obj-$(CONFIG_USB_KBD) += usbhid/

drivers/hid/amd-sfh-hid/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,8 @@ amd_sfh-objs := amd_sfh_hid.o
99
amd_sfh-objs += amd_sfh_client.o
1010
amd_sfh-objs += amd_sfh_pcie.o
1111
amd_sfh-objs += hid_descriptor/amd_sfh_hid_desc.o
12+
amd_sfh-objs += sfh1_1/amd_sfh_init.o
13+
amd_sfh-objs += sfh1_1/amd_sfh_interface.o
14+
amd_sfh-objs += sfh1_1/amd_sfh_desc.o
1215

1316
ccflags-y += -I $(srctree)/$(src)/

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

Lines changed: 117 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,6 @@
1818
#include "amd_sfh_pcie.h"
1919
#include "amd_sfh_hid.h"
2020

21-
22-
struct request_list {
23-
struct hid_device *hid;
24-
struct list_head list;
25-
u8 report_id;
26-
u8 sensor_idx;
27-
u8 report_type;
28-
u8 current_index;
29-
};
30-
31-
static struct request_list req_list;
32-
3321
void amd_sfh_set_report(struct hid_device *hid, int report_id,
3422
int report_type)
3523
{
@@ -50,6 +38,7 @@ int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type)
5038
{
5139
struct amdtp_hid_data *hid_data = hid->driver_data;
5240
struct amdtp_cl_data *cli_data = hid_data->cli_data;
41+
struct request_list *req_list = &cli_data->req_list;
5342
int i;
5443

5544
for (i = 0; i < cli_data->num_hid_devices; i++) {
@@ -66,34 +55,39 @@ int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type)
6655
new->report_id = report_id;
6756
cli_data->report_id[i] = report_id;
6857
cli_data->request_done[i] = false;
69-
list_add(&new->list, &req_list.list);
58+
list_add(&new->list, &req_list->list);
7059
break;
7160
}
7261
}
7362
schedule_delayed_work(&cli_data->work, 0);
7463
return 0;
7564
}
7665

77-
static void amd_sfh_work(struct work_struct *work)
66+
void amd_sfh_work(struct work_struct *work)
7867
{
7968
struct amdtp_cl_data *cli_data = container_of(work, struct amdtp_cl_data, work.work);
69+
struct request_list *req_list = &cli_data->req_list;
8070
struct amd_input_data *in_data = cli_data->in_data;
8171
struct request_list *req_node;
8272
u8 current_index, sensor_index;
73+
struct amd_mp2_ops *mp2_ops;
74+
struct amd_mp2_dev *mp2;
8375
u8 report_id, node_type;
8476
u8 report_size = 0;
8577

86-
req_node = list_last_entry(&req_list.list, struct request_list, list);
78+
req_node = list_last_entry(&req_list->list, struct request_list, list);
8779
list_del(&req_node->list);
8880
current_index = req_node->current_index;
8981
sensor_index = req_node->sensor_idx;
9082
report_id = req_node->report_id;
9183
node_type = req_node->report_type;
9284
kfree(req_node);
9385

86+
mp2 = container_of(in_data, struct amd_mp2_dev, in_data);
87+
mp2_ops = mp2->mp2_ops;
9488
if (node_type == HID_FEATURE_REPORT) {
95-
report_size = get_feature_report(sensor_index, report_id,
96-
cli_data->feature_report[current_index]);
89+
report_size = mp2_ops->get_feat_rep(sensor_index, report_id,
90+
cli_data->feature_report[current_index]);
9791
if (report_size)
9892
hid_input_report(cli_data->hid_sensor_hubs[current_index],
9993
cli_data->report_type[current_index],
@@ -102,7 +96,7 @@ static void amd_sfh_work(struct work_struct *work)
10296
pr_err("AMDSFH: Invalid report size\n");
10397

10498
} else if (node_type == HID_INPUT_REPORT) {
105-
report_size = get_input_report(current_index, sensor_index, report_id, in_data);
99+
report_size = mp2_ops->get_in_rep(current_index, sensor_index, report_id, in_data);
106100
if (report_size)
107101
hid_input_report(cli_data->hid_sensor_hubs[current_index],
108102
cli_data->report_type[current_index],
@@ -115,71 +109,153 @@ static void amd_sfh_work(struct work_struct *work)
115109
amdtp_hid_wakeup(cli_data->hid_sensor_hubs[current_index]);
116110
}
117111

118-
static void amd_sfh_work_buffer(struct work_struct *work)
112+
void amd_sfh_work_buffer(struct work_struct *work)
119113
{
120114
struct amdtp_cl_data *cli_data = container_of(work, struct amdtp_cl_data, work_buffer.work);
121115
struct amd_input_data *in_data = cli_data->in_data;
116+
struct amd_mp2_dev *mp2;
122117
u8 report_size;
123118
int i;
124119

125120
for (i = 0; i < cli_data->num_hid_devices; i++) {
126121
if (cli_data->sensor_sts[i] == SENSOR_ENABLED) {
127-
report_size = get_input_report
128-
(i, cli_data->sensor_idx[i], cli_data->report_id[i], in_data);
122+
mp2 = container_of(in_data, struct amd_mp2_dev, in_data);
123+
report_size = mp2->mp2_ops->get_in_rep(i, cli_data->sensor_idx[i],
124+
cli_data->report_id[i], in_data);
129125
hid_input_report(cli_data->hid_sensor_hubs[i], HID_INPUT_REPORT,
130126
in_data->input_report[i], report_size, 0);
131127
}
132128
}
133129
schedule_delayed_work(&cli_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
134130
}
135131

136-
u32 amd_sfh_wait_for_response(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts)
132+
static u32 amd_sfh_wait_for_response(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts)
137133
{
138134
if (mp2->mp2_ops->response)
139135
sensor_sts = mp2->mp2_ops->response(mp2, sid, sensor_sts);
140136

141137
return sensor_sts;
142138
}
143139

140+
static const char *get_sensor_name(int idx)
141+
{
142+
switch (idx) {
143+
case accel_idx:
144+
return "accelerometer";
145+
case gyro_idx:
146+
return "gyroscope";
147+
case mag_idx:
148+
return "magnetometer";
149+
case als_idx:
150+
return "ALS";
151+
case HPD_IDX:
152+
return "HPD";
153+
default:
154+
return "unknown sensor type";
155+
}
156+
}
157+
158+
static void amd_sfh_resume(struct amd_mp2_dev *mp2)
159+
{
160+
struct amdtp_cl_data *cl_data = mp2->cl_data;
161+
struct amd_mp2_sensor_info info;
162+
int i, status;
163+
164+
for (i = 0; i < cl_data->num_hid_devices; i++) {
165+
if (cl_data->sensor_sts[i] == SENSOR_DISABLED) {
166+
info.period = AMD_SFH_IDLE_LOOP;
167+
info.sensor_idx = cl_data->sensor_idx[i];
168+
info.dma_address = cl_data->sensor_dma_addr[i];
169+
mp2->mp2_ops->start(mp2, info);
170+
status = amd_sfh_wait_for_response
171+
(mp2, cl_data->sensor_idx[i], SENSOR_ENABLED);
172+
if (status == SENSOR_ENABLED)
173+
cl_data->sensor_sts[i] = SENSOR_ENABLED;
174+
dev_dbg(&mp2->pdev->dev, "resume sid 0x%x (%s) status 0x%x\n",
175+
cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
176+
cl_data->sensor_sts[i]);
177+
}
178+
}
179+
180+
schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
181+
amd_sfh_clear_intr(mp2);
182+
}
183+
184+
static void amd_sfh_suspend(struct amd_mp2_dev *mp2)
185+
{
186+
struct amdtp_cl_data *cl_data = mp2->cl_data;
187+
int i, status;
188+
189+
for (i = 0; i < cl_data->num_hid_devices; i++) {
190+
if (cl_data->sensor_idx[i] != HPD_IDX &&
191+
cl_data->sensor_sts[i] == SENSOR_ENABLED) {
192+
mp2->mp2_ops->stop(mp2, cl_data->sensor_idx[i]);
193+
status = amd_sfh_wait_for_response
194+
(mp2, cl_data->sensor_idx[i], SENSOR_DISABLED);
195+
if (status != SENSOR_ENABLED)
196+
cl_data->sensor_sts[i] = SENSOR_DISABLED;
197+
dev_dbg(&mp2->pdev->dev, "suspend sid 0x%x (%s) status 0x%x\n",
198+
cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
199+
cl_data->sensor_sts[i]);
200+
}
201+
}
202+
203+
cancel_delayed_work_sync(&cl_data->work_buffer);
204+
amd_sfh_clear_intr(mp2);
205+
}
206+
144207
int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
145208
{
146209
struct amd_input_data *in_data = &privdata->in_data;
147210
struct amdtp_cl_data *cl_data = privdata->cl_data;
211+
struct amd_mp2_ops *mp2_ops = privdata->mp2_ops;
148212
struct amd_mp2_sensor_info info;
213+
struct request_list *req_list;
149214
struct device *dev;
150215
u32 feature_report_size;
151216
u32 input_report_size;
152217
int rc, i, status;
153218
u8 cl_idx;
154219

220+
req_list = &cl_data->req_list;
155221
dev = &privdata->pdev->dev;
222+
amd_sfh_set_desc_ops(mp2_ops);
223+
224+
mp2_ops->suspend = amd_sfh_suspend;
225+
mp2_ops->resume = amd_sfh_resume;
156226

157227
cl_data->num_hid_devices = amd_mp2_get_sensor_num(privdata, &cl_data->sensor_idx[0]);
228+
if (cl_data->num_hid_devices == 0)
229+
return -ENODEV;
158230

159231
INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work);
160232
INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer);
161-
INIT_LIST_HEAD(&req_list.list);
233+
INIT_LIST_HEAD(&req_list->list);
162234
cl_data->in_data = in_data;
163235

164236
for (i = 0; i < cl_data->num_hid_devices; i++) {
165237
in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
166238
&cl_data->sensor_dma_addr[i],
167239
GFP_KERNEL);
240+
if (!in_data->sensor_virt_addr[i]) {
241+
rc = -ENOMEM;
242+
goto cleanup;
243+
}
168244
cl_data->sensor_sts[i] = SENSOR_DISABLED;
169245
cl_data->sensor_requested_cnt[i] = 0;
170246
cl_data->cur_hid_dev = i;
171247
cl_idx = cl_data->sensor_idx[i];
172-
cl_data->report_descr_sz[i] = get_descr_sz(cl_idx, descr_size);
248+
cl_data->report_descr_sz[i] = mp2_ops->get_desc_sz(cl_idx, descr_size);
173249
if (!cl_data->report_descr_sz[i]) {
174250
rc = -EINVAL;
175251
goto cleanup;
176252
}
177-
feature_report_size = get_descr_sz(cl_idx, feature_size);
253+
feature_report_size = mp2_ops->get_desc_sz(cl_idx, feature_size);
178254
if (!feature_report_size) {
179255
rc = -EINVAL;
180256
goto cleanup;
181257
}
182-
input_report_size = get_descr_sz(cl_idx, input_size);
258+
input_report_size = mp2_ops->get_desc_sz(cl_idx, input_size);
183259
if (!input_report_size) {
184260
rc = -EINVAL;
185261
goto cleanup;
@@ -204,31 +280,33 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
204280
rc = -ENOMEM;
205281
goto cleanup;
206282
}
207-
rc = get_report_descriptor(cl_idx, cl_data->report_descr[i]);
283+
rc = mp2_ops->get_rep_desc(cl_idx, cl_data->report_descr[i]);
208284
if (rc)
209-
return rc;
210-
privdata->mp2_ops->start(privdata, info);
285+
goto cleanup;
286+
mp2_ops->start(privdata, info);
211287
status = amd_sfh_wait_for_response
212288
(privdata, cl_data->sensor_idx[i], SENSOR_ENABLED);
213289
if (status == SENSOR_ENABLED) {
214290
cl_data->sensor_sts[i] = SENSOR_ENABLED;
215291
rc = amdtp_hid_probe(cl_data->cur_hid_dev, cl_data);
216292
if (rc) {
217-
privdata->mp2_ops->stop(privdata, cl_data->sensor_idx[i]);
293+
mp2_ops->stop(privdata, cl_data->sensor_idx[i]);
218294
status = amd_sfh_wait_for_response
219295
(privdata, cl_data->sensor_idx[i], SENSOR_DISABLED);
220296
if (status != SENSOR_ENABLED)
221297
cl_data->sensor_sts[i] = SENSOR_DISABLED;
222-
dev_dbg(dev, "sid 0x%x status 0x%x\n",
223-
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
298+
dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n",
299+
cl_data->sensor_idx[i],
300+
get_sensor_name(cl_data->sensor_idx[i]),
301+
cl_data->sensor_sts[i]);
224302
goto cleanup;
225303
}
226304
}
227-
dev_dbg(dev, "sid 0x%x status 0x%x\n",
228-
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
305+
dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n",
306+
cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
307+
cl_data->sensor_sts[i]);
229308
}
230-
if (privdata->mp2_ops->discovery_status &&
231-
privdata->mp2_ops->discovery_status(privdata) == 0) {
309+
if (mp2_ops->discovery_status && mp2_ops->discovery_status(privdata) == 0) {
232310
amd_sfh_hid_client_deinit(privdata);
233311
for (i = 0; i < cl_data->num_hid_devices; i++) {
234312
devm_kfree(dev, cl_data->feature_report[i]);
@@ -268,8 +346,9 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
268346
(privdata, cl_data->sensor_idx[i], SENSOR_DISABLED);
269347
if (status != SENSOR_ENABLED)
270348
cl_data->sensor_sts[i] = SENSOR_DISABLED;
271-
dev_dbg(&privdata->pdev->dev, "stopping sid 0x%x status 0x%x\n",
272-
cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
349+
dev_dbg(&privdata->pdev->dev, "stopping sid 0x%x (%s) status 0x%x\n",
350+
cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
351+
cl_data->sensor_sts[i]);
273352
}
274353
}
275354

0 commit comments

Comments
 (0)