Skip to content

Commit f264481

Browse files
basuamdJiri Kosina
authored andcommitted
HID: amd_sfh: Extend driver capabilities for multi-generation support
Initial driver support only covered the first generation of SFH platforms. In order to support the future generations introduce ops selection to distinguish the different platforms. Signed-off-by: Basavaraj Natikar <[email protected]> Reviewed-by: Nehal Shah <[email protected]> Reviewed-by: Shyam Sundar S K <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 231bc53 commit f264481

File tree

3 files changed

+105
-6
lines changed

3 files changed

+105
-6
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
202202
rc = amdtp_hid_probe(cl_data->cur_hid_dev, cl_data);
203203
if (rc)
204204
return rc;
205-
amd_start_sensor(privdata, info);
205+
privdata->mp2_ops->start(privdata, info);
206206
cl_data->sensor_sts[i] = 1;
207207
}
208208
privdata->cl_data = cl_data;
@@ -230,7 +230,7 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
230230
int i;
231231

232232
for (i = 0; i < cl_data->num_hid_devices; i++)
233-
amd_stop_sensor(privdata, i);
233+
privdata->mp2_ops->stop(privdata, i);
234234

235235
cancel_delayed_work_sync(&cl_data->work);
236236
cancel_delayed_work_sync(&cl_data->work_buffer);

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

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,48 @@ static int sensor_mask_override = -1;
3030
module_param_named(sensor_mask, sensor_mask_override, int, 0444);
3131
MODULE_PARM_DESC(sensor_mask, "override the detected sensors mask");
3232

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

103144
if (sensor_mask_override == -1) {
104145
dmi_id = dmi_first_match(dmi_sensor_mask_overrides);
@@ -109,8 +150,7 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id)
109150
if (sensor_mask_override >= 0) {
110151
activestatus = sensor_mask_override;
111152
} else {
112-
activecontrolstatus = readl(privdata->mmio + AMD_P2C_MSG3);
113-
activestatus = activecontrolstatus >> 4;
153+
activestatus = privdata->mp2_acs >> 4;
114154
}
115155

116156
if (ACEL_EN & activestatus)
@@ -130,8 +170,38 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id)
130170

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

137207
static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -164,6 +234,8 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
164234
if (rc)
165235
return rc;
166236

237+
mp2_select_ops(privdata);
238+
167239
return amd_sfh_hid_client_init(privdata);
168240
}
169241

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@
2222
#define AMD_C2P_MSG1 0x10504
2323
#define AMD_C2P_MSG2 0x10508
2424

25+
#define AMD_C2P_MSG(regno) (0x10500 + ((regno) * 4))
26+
2527
/* MP2 P2C Message Registers */
2628
#define AMD_P2C_MSG3 0x1068C /* Supported Sensors info */
2729

30+
#define V2_STATUS 0x2
31+
2832
/* SFH Command register */
2933
union sfh_cmd_base {
3034
u32 ul;
@@ -33,6 +37,15 @@ union sfh_cmd_base {
3337
u32 sensor_id : 8;
3438
u32 period : 16;
3539
} s;
40+
struct {
41+
u32 cmd_id : 4;
42+
u32 intr_enable : 1;
43+
u32 rsvd1 : 3;
44+
u32 length : 7;
45+
u32 mem_type : 1;
46+
u32 sensor_id : 8;
47+
u32 period : 8;
48+
} cmd_v2;
3649
};
3750

3851
union sfh_cmd_param {
@@ -61,6 +74,9 @@ struct amd_mp2_dev {
6174
struct pci_dev *pdev;
6275
struct amdtp_cl_data *cl_data;
6376
void __iomem *mmio;
77+
const struct amd_mp2_ops *mp2_ops;
78+
/* mp2 active control status */
79+
u32 mp2_acs;
6480
};
6581

6682
struct amd_mp2_sensor_info {
@@ -69,10 +85,21 @@ struct amd_mp2_sensor_info {
6985
dma_addr_t dma_address;
7086
};
7187

88+
enum mem_use_type {
89+
USE_DRAM,
90+
USE_C2P_REG,
91+
};
92+
7293
void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info);
7394
void amd_stop_sensor(struct amd_mp2_dev *privdata, u16 sensor_idx);
7495
void amd_stop_all_sensors(struct amd_mp2_dev *privdata);
7596
int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id);
7697
int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata);
7798
int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata);
99+
100+
struct amd_mp2_ops {
101+
void (*start)(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info);
102+
void (*stop)(struct amd_mp2_dev *privdata, u16 sensor_idx);
103+
void (*stop_all)(struct amd_mp2_dev *privdata);
104+
};
78105
#endif

0 commit comments

Comments
 (0)