Skip to content

Commit 0aad9c9

Browse files
basuamdJiri Kosina
authored andcommitted
HID: amd_sfh: Extend ALS support for newer AMD platform
Extend ALS support for AMD next generation SoC's like Renoir, Cezanne. AMD next generation platforms use C2P message register to read ALS sensor data instead of DRAM address. 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 f264481 commit 0aad9c9

File tree

6 files changed

+45
-26
lines changed

6 files changed

+45
-26
lines changed

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

Lines changed: 18 additions & 21 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
}
@@ -205,28 +203,27 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
205203
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++)
@@ -237,9 +234,9 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
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: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
230230
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
231231
return rc;
232232
}
233+
234+
privdata->cl_data = devm_kzalloc(&pdev->dev, sizeof(struct amdtp_cl_data), GFP_KERNEL);
235+
if (!privdata->cl_data)
236+
return -ENOMEM;
237+
233238
rc = devm_add_action_or_reset(&pdev->dev, amd_mp2_pci_remove, privdata);
234239
if (rc)
235240
return rc;

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define PCIE_MP2_AMD_H
1111

1212
#include <linux/pci.h>
13+
#include "amd_sfh_hid.h"
1314

1415
#define PCI_DEVICE_ID_AMD_MP2 0x15E4
1516

@@ -75,6 +76,7 @@ struct amd_mp2_dev {
7576
struct amdtp_cl_data *cl_data;
7677
void __iomem *mmio;
7778
const struct amd_mp2_ops *mp2_ops;
79+
struct amd_input_data in_data;
7880
/* mp2 active control status */
7981
u32 mp2_acs;
8082
};

drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "amd_sfh_pcie.h"
1313
#include "amd_sfh_hid_desc.h"
1414
#include "amd_sfh_hid_report_desc.h"
15+
#include "amd_sfh_hid.h"
1516

1617
#define AMD_SFH_FW_MULTIPLIER (1000)
1718
#define HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM 0x41
@@ -174,8 +175,12 @@ static void get_common_inputs(struct common_input_property *common, int report_i
174175
common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM;
175176
}
176177

177-
u8 get_input_report(int sensor_idx, int report_id, u8 *input_report, u32 *sensor_virt_addr)
178+
u8 get_input_report(u8 current_index, int sensor_idx, int report_id, struct amd_input_data *in_data)
178179
{
180+
struct amd_mp2_dev *privdata = container_of(in_data, struct amd_mp2_dev, in_data);
181+
u32 *sensor_virt_addr = in_data->sensor_virt_addr[current_index];
182+
u8 *input_report = in_data->input_report[current_index];
183+
u8 supported_input = privdata->mp2_acs & GENMASK(3, 0);
179184
struct accel3_input_report acc_input;
180185
struct gyro_input_report gyro_input;
181186
struct magno_input_report magno_input;
@@ -213,7 +218,12 @@ u8 get_input_report(int sensor_idx, int report_id, u8 *input_report, u32 *sensor
213218
break;
214219
case als_idx: /* Als */
215220
get_common_inputs(&als_input.common_property, report_id);
216-
als_input.illuminance_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
221+
/* For ALS ,V2 Platforms uses C2P_MSG5 register instead of DRAM access method */
222+
if (supported_input == V2_STATUS)
223+
als_input.illuminance_value = (int)readl(privdata->mmio + AMD_C2P_MSG(5));
224+
else
225+
als_input.illuminance_value =
226+
(int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
217227
report_size = sizeof(als_input);
218228
memcpy(input_report, &als_input, sizeof(als_input));
219229
break;

drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,4 @@ struct als_input_report {
103103
int get_report_descriptor(int sensor_idx, u8 rep_desc[]);
104104
u32 get_descr_sz(int sensor_idx, int descriptor_name);
105105
u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report);
106-
u8 get_input_report(int sensor_idx, int report_id, u8 *input_report, u32 *sensor_virt_addr);
107106
#endif

0 commit comments

Comments
 (0)