Skip to content

Commit df04fbe

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: - patch series that ensures that hid-multitouch driver disables touch and button-press reporting on hid-mt devices during suspend when the device is not configured as a wakeup-source, from Hans de Goede - support for ISH DMA on Intel EHL platform, from Even Xu - support for Renoir and Cezanne SoCs, Ambient Light Sensor and Human Presence Detection sensor for amd-sfh driver, from Basavaraj Natikar - other assorted code cleanups and device-specific fixes/quirks * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (45 commits) HID: thrustmaster: Switch to kmemdup() when allocate change_request HID: multitouch: Disable event reporting on suspend when the device is not a wakeup-source HID: logitech-dj: Implement may_wakeup ll-driver callback HID: usbhid: Implement may_wakeup ll-driver callback HID: core: Add hid_hw_may_wakeup() function HID: input: Add support for Programmable Buttons HID: wacom: Correct base usage for capacitive ExpressKey status bits HID: amd_sfh: Add initial support for HPD sensor HID: amd_sfh: Extend ALS support for newer AMD platform HID: amd_sfh: Extend driver capabilities for multi-generation support HID: surface-hid: Fix get-report request HID: sony: fix freeze when inserting ghlive ps3/wii dongles HID: usbkbd: Avoid GFP_ATOMIC when GFP_KERNEL is possible HID: amd_sfh: change in maintainer HID: intel-ish-hid: ipc: Specify that EHL no cache snooping HID: intel-ish-hid: ishtp: Add dma_no_cache_snooping() callback HID: intel-ish-hid: Set ISH driver depends on x86 HID: hid-input: add Surface Go battery quirk HID: intel-ish-hid: Fix minor typos in comments HID: usbmouse: Avoid GFP_ATOMIC when GFP_KERNEL is possible ...
2 parents 4b5e35c + b3e2964 commit df04fbe

40 files changed

+703
-219
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ F: drivers/net/ethernet/amd/xgbe/
973973

974974
AMD SENSOR FUSION HUB DRIVER
975975
M: Nehal Shah <[email protected]>
976-
M: Sandeep Singh <sandeep.singh@amd.com>
976+
M: Basavaraj Natikar <basavaraj.natikar@amd.com>
977977
978978
S: Maintained
979979
F: Documentation/hid/amd-sfh*

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

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type)
7777
static void amd_sfh_work(struct work_struct *work)
7878
{
7979
struct amdtp_cl_data *cli_data = container_of(work, struct amdtp_cl_data, work.work);
80+
struct amd_input_data *in_data = cli_data->in_data;
8081
struct request_list *req_node;
8182
u8 current_index, sensor_index;
8283
u8 report_id, node_type;
@@ -101,13 +102,11 @@ static void amd_sfh_work(struct work_struct *work)
101102
pr_err("AMDSFH: Invalid report size\n");
102103

103104
} else if (node_type == HID_INPUT_REPORT) {
104-
report_size = get_input_report(sensor_index, report_id,
105-
cli_data->input_report[current_index],
106-
cli_data->sensor_virt_addr[current_index]);
105+
report_size = get_input_report(current_index, sensor_index, report_id, in_data);
107106
if (report_size)
108107
hid_input_report(cli_data->hid_sensor_hubs[current_index],
109108
cli_data->report_type[current_index],
110-
cli_data->input_report[current_index], report_size, 0);
109+
in_data->input_report[current_index], report_size, 0);
111110
else
112111
pr_err("AMDSFH: Invalid report size\n");
113112
}
@@ -119,21 +118,22 @@ static void amd_sfh_work(struct work_struct *work)
119118
static void amd_sfh_work_buffer(struct work_struct *work)
120119
{
121120
struct amdtp_cl_data *cli_data = container_of(work, struct amdtp_cl_data, work_buffer.work);
121+
struct amd_input_data *in_data = cli_data->in_data;
122122
u8 report_size;
123123
int i;
124124

125125
for (i = 0; i < cli_data->num_hid_devices; i++) {
126-
report_size = get_input_report(cli_data->sensor_idx[i], cli_data->report_id[i],
127-
cli_data->input_report[i],
128-
cli_data->sensor_virt_addr[i]);
126+
report_size = get_input_report(i, cli_data->sensor_idx[i], cli_data->report_id[i],
127+
in_data);
129128
hid_input_report(cli_data->hid_sensor_hubs[i], HID_INPUT_REPORT,
130-
cli_data->input_report[i], report_size, 0);
129+
in_data->input_report[i], report_size, 0);
131130
}
132131
schedule_delayed_work(&cli_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
133132
}
134133

135134
int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
136135
{
136+
struct amd_input_data *in_data = &privdata->in_data;
137137
struct amdtp_cl_data *cl_data = privdata->cl_data;
138138
struct amd_mp2_sensor_info info;
139139
struct device *dev;
@@ -143,18 +143,16 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
143143
int rc, i;
144144

145145
dev = &privdata->pdev->dev;
146-
cl_data = devm_kzalloc(dev, sizeof(*cl_data), GFP_KERNEL);
147-
if (!cl_data)
148-
return -ENOMEM;
149146

150147
cl_data->num_hid_devices = amd_mp2_get_sensor_num(privdata, &cl_data->sensor_idx[0]);
151148

152149
INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work);
153150
INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer);
154151
INIT_LIST_HEAD(&req_list.list);
152+
cl_data->in_data = in_data;
155153

156154
for (i = 0; i < cl_data->num_hid_devices; i++) {
157-
cl_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
155+
in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
158156
&cl_data->sensor_dma_addr[i],
159157
GFP_KERNEL);
160158
cl_data->sensor_sts[i] = 0;
@@ -181,8 +179,8 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
181179
rc = -ENOMEM;
182180
goto cleanup;
183181
}
184-
cl_data->input_report[i] = devm_kzalloc(dev, input_report_size, GFP_KERNEL);
185-
if (!cl_data->input_report[i]) {
182+
in_data->input_report[i] = devm_kzalloc(dev, input_report_size, GFP_KERNEL);
183+
if (!in_data->input_report[i]) {
186184
rc = -ENOMEM;
187185
goto cleanup;
188186
}
@@ -202,44 +200,43 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
202200
rc = amdtp_hid_probe(cl_data->cur_hid_dev, cl_data);
203201
if (rc)
204202
return rc;
205-
amd_start_sensor(privdata, info);
203+
privdata->mp2_ops->start(privdata, info);
206204
cl_data->sensor_sts[i] = 1;
207205
}
208-
privdata->cl_data = cl_data;
209206
schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
210207
return 0;
211208

212209
cleanup:
213210
for (i = 0; i < cl_data->num_hid_devices; i++) {
214-
if (cl_data->sensor_virt_addr[i]) {
211+
if (in_data->sensor_virt_addr[i]) {
215212
dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int),
216-
cl_data->sensor_virt_addr[i],
213+
in_data->sensor_virt_addr[i],
217214
cl_data->sensor_dma_addr[i]);
218215
}
219216
devm_kfree(dev, cl_data->feature_report[i]);
220-
devm_kfree(dev, cl_data->input_report[i]);
217+
devm_kfree(dev, in_data->input_report[i]);
221218
devm_kfree(dev, cl_data->report_descr[i]);
222219
}
223-
devm_kfree(dev, cl_data);
224220
return rc;
225221
}
226222

227223
int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
228224
{
229225
struct amdtp_cl_data *cl_data = privdata->cl_data;
226+
struct amd_input_data *in_data = cl_data->in_data;
230227
int i;
231228

232229
for (i = 0; i < cl_data->num_hid_devices; i++)
233-
amd_stop_sensor(privdata, i);
230+
privdata->mp2_ops->stop(privdata, i);
234231

235232
cancel_delayed_work_sync(&cl_data->work);
236233
cancel_delayed_work_sync(&cl_data->work_buffer);
237234
amdtp_hid_remove(cl_data);
238235

239236
for (i = 0; i < cl_data->num_hid_devices; i++) {
240-
if (cl_data->sensor_virt_addr[i]) {
237+
if (in_data->sensor_virt_addr[i]) {
241238
dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int),
242-
cl_data->sensor_virt_addr[i],
239+
in_data->sensor_virt_addr[i],
243240
cl_data->sensor_dma_addr[i]);
244241
}
245242
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@
99
#ifndef AMDSFH_HID_H
1010
#define AMDSFH_HID_H
1111

12-
#define MAX_HID_DEVICES 4
12+
#define MAX_HID_DEVICES 5
1313
#define BUS_AMD_AMDTP 0x20
1414
#define AMD_SFH_HID_VENDOR 0x1022
1515
#define AMD_SFH_HID_PRODUCT 0x0001
1616

17+
struct amd_input_data {
18+
u32 *sensor_virt_addr[MAX_HID_DEVICES];
19+
u8 *input_report[MAX_HID_DEVICES];
20+
};
21+
1722
struct amdtp_cl_data {
1823
u8 init_done;
1924
u32 cur_hid_dev;
@@ -26,16 +31,15 @@ struct amdtp_cl_data {
2631
u8 *hid_descr[MAX_HID_DEVICES];
2732
int hid_descr_size[MAX_HID_DEVICES];
2833
phys_addr_t phys_addr_base;
29-
u32 *sensor_virt_addr[MAX_HID_DEVICES];
3034
dma_addr_t sensor_dma_addr[MAX_HID_DEVICES];
3135
u32 sensor_sts[MAX_HID_DEVICES];
3236
u32 sensor_requested_cnt[MAX_HID_DEVICES];
3337
u8 report_type[MAX_HID_DEVICES];
3438
u8 report_id[MAX_HID_DEVICES];
3539
u8 sensor_idx[MAX_HID_DEVICES];
3640
u8 *feature_report[MAX_HID_DEVICES];
37-
u8 *input_report[MAX_HID_DEVICES];
3841
u8 request_done[MAX_HID_DEVICES];
42+
struct amd_input_data *in_data;
3943
struct delayed_work work;
4044
struct delayed_work work_buffer;
4145
};
@@ -64,4 +68,6 @@ void amdtp_hid_remove(struct amdtp_cl_data *cli_data);
6468
int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type);
6569
void amd_sfh_set_report(struct hid_device *hid, int report_id, int report_type);
6670
void amdtp_hid_wakeup(struct hid_device *hid);
71+
u8 get_input_report(u8 current_index, int sensor_idx, int report_id,
72+
struct amd_input_data *in_data);
6773
#endif

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

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,55 @@
2424
#define ACEL_EN BIT(0)
2525
#define GYRO_EN BIT(1)
2626
#define MAGNO_EN BIT(2)
27+
#define HPD_EN BIT(16)
2728
#define ALS_EN BIT(19)
2829

2930
static int sensor_mask_override = -1;
3031
module_param_named(sensor_mask, sensor_mask_override, int, 0444);
3132
MODULE_PARM_DESC(sensor_mask, "override the detected sensors mask");
3233

34+
static void amd_start_sensor_v2(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
35+
{
36+
union sfh_cmd_base cmd_base;
37+
38+
cmd_base.ul = 0;
39+
cmd_base.cmd_v2.cmd_id = ENABLE_SENSOR;
40+
cmd_base.cmd_v2.period = info.period;
41+
cmd_base.cmd_v2.sensor_id = info.sensor_idx;
42+
cmd_base.cmd_v2.length = 16;
43+
44+
if (info.sensor_idx == als_idx)
45+
cmd_base.cmd_v2.mem_type = USE_C2P_REG;
46+
47+
writeq(info.dma_address, privdata->mmio + AMD_C2P_MSG1);
48+
writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0);
49+
}
50+
51+
static void amd_stop_sensor_v2(struct amd_mp2_dev *privdata, u16 sensor_idx)
52+
{
53+
union sfh_cmd_base cmd_base;
54+
55+
cmd_base.ul = 0;
56+
cmd_base.cmd_v2.cmd_id = DISABLE_SENSOR;
57+
cmd_base.cmd_v2.period = 0;
58+
cmd_base.cmd_v2.sensor_id = sensor_idx;
59+
cmd_base.cmd_v2.length = 16;
60+
61+
writeq(0x0, privdata->mmio + AMD_C2P_MSG2);
62+
writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0);
63+
}
64+
65+
static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata)
66+
{
67+
union sfh_cmd_base cmd_base;
68+
69+
cmd_base.cmd_v2.cmd_id = STOP_ALL_SENSORS;
70+
cmd_base.cmd_v2.period = 0;
71+
cmd_base.cmd_v2.sensor_id = 0;
72+
73+
writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0);
74+
}
75+
3376
void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
3477
{
3578
union sfh_cmd_param cmd_param;
@@ -98,7 +141,6 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id)
98141
{
99142
int activestatus, num_of_sensors = 0;
100143
const struct dmi_system_id *dmi_id;
101-
u32 activecontrolstatus;
102144

103145
if (sensor_mask_override == -1) {
104146
dmi_id = dmi_first_match(dmi_sensor_mask_overrides);
@@ -109,8 +151,7 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id)
109151
if (sensor_mask_override >= 0) {
110152
activestatus = sensor_mask_override;
111153
} else {
112-
activecontrolstatus = readl(privdata->mmio + AMD_P2C_MSG3);
113-
activestatus = activecontrolstatus >> 4;
154+
activestatus = privdata->mp2_acs >> 4;
114155
}
115156

116157
if (ACEL_EN & activestatus)
@@ -125,13 +166,46 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id)
125166
if (ALS_EN & activestatus)
126167
sensor_id[num_of_sensors++] = als_idx;
127168

169+
if (HPD_EN & activestatus)
170+
sensor_id[num_of_sensors++] = HPD_IDX;
171+
128172
return num_of_sensors;
129173
}
130174

131175
static void amd_mp2_pci_remove(void *privdata)
132176
{
177+
struct amd_mp2_dev *mp2 = privdata;
133178
amd_sfh_hid_client_deinit(privdata);
134-
amd_stop_all_sensors(privdata);
179+
mp2->mp2_ops->stop_all(mp2);
180+
}
181+
182+
static const struct amd_mp2_ops amd_sfh_ops_v2 = {
183+
.start = amd_start_sensor_v2,
184+
.stop = amd_stop_sensor_v2,
185+
.stop_all = amd_stop_all_sensor_v2,
186+
};
187+
188+
static const struct amd_mp2_ops amd_sfh_ops = {
189+
.start = amd_start_sensor,
190+
.stop = amd_stop_sensor,
191+
.stop_all = amd_stop_all_sensors,
192+
};
193+
194+
static void mp2_select_ops(struct amd_mp2_dev *privdata)
195+
{
196+
u8 acs;
197+
198+
privdata->mp2_acs = readl(privdata->mmio + AMD_P2C_MSG3);
199+
acs = privdata->mp2_acs & GENMASK(3, 0);
200+
201+
switch (acs) {
202+
case V2_STATUS:
203+
privdata->mp2_ops = &amd_sfh_ops_v2;
204+
break;
205+
default:
206+
privdata->mp2_ops = &amd_sfh_ops;
207+
break;
208+
}
135209
}
136210

137211
static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -160,10 +234,17 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
160234
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
161235
return rc;
162236
}
237+
238+
privdata->cl_data = devm_kzalloc(&pdev->dev, sizeof(struct amdtp_cl_data), GFP_KERNEL);
239+
if (!privdata->cl_data)
240+
return -ENOMEM;
241+
163242
rc = devm_add_action_or_reset(&pdev->dev, amd_mp2_pci_remove, privdata);
164243
if (rc)
165244
return rc;
166245

246+
mp2_select_ops(privdata);
247+
167248
return amd_sfh_hid_client_init(privdata);
168249
}
169250

0 commit comments

Comments
 (0)