Commit 0aad9c95 authored by Basavaraj Natikar's avatar Basavaraj Natikar Committed by Jiri Kosina

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: default avatarBasavaraj Natikar <Basavaraj.Natikar@amd.com>
Reviewed-by: default avatarNehal Shah <nehal-bakulchandra.shah@amd.com>
Reviewed-by: default avatarShyam Sundar S K <Shyam-sundar.S-k@amd.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent f264481a
......@@ -77,6 +77,7 @@ int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type)
static void amd_sfh_work(struct work_struct *work)
{
struct amdtp_cl_data *cli_data = container_of(work, struct amdtp_cl_data, work.work);
struct amd_input_data *in_data = cli_data->in_data;
struct request_list *req_node;
u8 current_index, sensor_index;
u8 report_id, node_type;
......@@ -101,13 +102,11 @@ static void amd_sfh_work(struct work_struct *work)
pr_err("AMDSFH: Invalid report size\n");
} else if (node_type == HID_INPUT_REPORT) {
report_size = get_input_report(sensor_index, report_id,
cli_data->input_report[current_index],
cli_data->sensor_virt_addr[current_index]);
report_size = get_input_report(current_index, sensor_index, report_id, in_data);
if (report_size)
hid_input_report(cli_data->hid_sensor_hubs[current_index],
cli_data->report_type[current_index],
cli_data->input_report[current_index], report_size, 0);
in_data->input_report[current_index], report_size, 0);
else
pr_err("AMDSFH: Invalid report size\n");
}
......@@ -119,21 +118,22 @@ static void amd_sfh_work(struct work_struct *work)
static void amd_sfh_work_buffer(struct work_struct *work)
{
struct amdtp_cl_data *cli_data = container_of(work, struct amdtp_cl_data, work_buffer.work);
struct amd_input_data *in_data = cli_data->in_data;
u8 report_size;
int i;
for (i = 0; i < cli_data->num_hid_devices; i++) {
report_size = get_input_report(cli_data->sensor_idx[i], cli_data->report_id[i],
cli_data->input_report[i],
cli_data->sensor_virt_addr[i]);
report_size = get_input_report(i, cli_data->sensor_idx[i], cli_data->report_id[i],
in_data);
hid_input_report(cli_data->hid_sensor_hubs[i], HID_INPUT_REPORT,
cli_data->input_report[i], report_size, 0);
in_data->input_report[i], report_size, 0);
}
schedule_delayed_work(&cli_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
}
int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
{
struct amd_input_data *in_data = &privdata->in_data;
struct amdtp_cl_data *cl_data = privdata->cl_data;
struct amd_mp2_sensor_info info;
struct device *dev;
......@@ -143,18 +143,16 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
int rc, i;
dev = &privdata->pdev->dev;
cl_data = devm_kzalloc(dev, sizeof(*cl_data), GFP_KERNEL);
if (!cl_data)
return -ENOMEM;
cl_data->num_hid_devices = amd_mp2_get_sensor_num(privdata, &cl_data->sensor_idx[0]);
INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work);
INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer);
INIT_LIST_HEAD(&req_list.list);
cl_data->in_data = in_data;
for (i = 0; i < cl_data->num_hid_devices; i++) {
cl_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
&cl_data->sensor_dma_addr[i],
GFP_KERNEL);
cl_data->sensor_sts[i] = 0;
......@@ -181,8 +179,8 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
rc = -ENOMEM;
goto cleanup;
}
cl_data->input_report[i] = devm_kzalloc(dev, input_report_size, GFP_KERNEL);
if (!cl_data->input_report[i]) {
in_data->input_report[i] = devm_kzalloc(dev, input_report_size, GFP_KERNEL);
if (!in_data->input_report[i]) {
rc = -ENOMEM;
goto cleanup;
}
......@@ -205,28 +203,27 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
privdata->mp2_ops->start(privdata, info);
cl_data->sensor_sts[i] = 1;
}
privdata->cl_data = cl_data;
schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
return 0;
cleanup:
for (i = 0; i < cl_data->num_hid_devices; i++) {
if (cl_data->sensor_virt_addr[i]) {
if (in_data->sensor_virt_addr[i]) {
dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int),
cl_data->sensor_virt_addr[i],
in_data->sensor_virt_addr[i],
cl_data->sensor_dma_addr[i]);
}
devm_kfree(dev, cl_data->feature_report[i]);
devm_kfree(dev, cl_data->input_report[i]);
devm_kfree(dev, in_data->input_report[i]);
devm_kfree(dev, cl_data->report_descr[i]);
}
devm_kfree(dev, cl_data);
return rc;
}
int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
{
struct amdtp_cl_data *cl_data = privdata->cl_data;
struct amd_input_data *in_data = cl_data->in_data;
int i;
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)
amdtp_hid_remove(cl_data);
for (i = 0; i < cl_data->num_hid_devices; i++) {
if (cl_data->sensor_virt_addr[i]) {
if (in_data->sensor_virt_addr[i]) {
dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int),
cl_data->sensor_virt_addr[i],
in_data->sensor_virt_addr[i],
cl_data->sensor_dma_addr[i]);
}
}
......
......@@ -14,6 +14,11 @@
#define AMD_SFH_HID_VENDOR 0x1022
#define AMD_SFH_HID_PRODUCT 0x0001
struct amd_input_data {
u32 *sensor_virt_addr[MAX_HID_DEVICES];
u8 *input_report[MAX_HID_DEVICES];
};
struct amdtp_cl_data {
u8 init_done;
u32 cur_hid_dev;
......@@ -26,7 +31,6 @@ struct amdtp_cl_data {
u8 *hid_descr[MAX_HID_DEVICES];
int hid_descr_size[MAX_HID_DEVICES];
phys_addr_t phys_addr_base;
u32 *sensor_virt_addr[MAX_HID_DEVICES];
dma_addr_t sensor_dma_addr[MAX_HID_DEVICES];
u32 sensor_sts[MAX_HID_DEVICES];
u32 sensor_requested_cnt[MAX_HID_DEVICES];
......@@ -34,8 +38,8 @@ struct amdtp_cl_data {
u8 report_id[MAX_HID_DEVICES];
u8 sensor_idx[MAX_HID_DEVICES];
u8 *feature_report[MAX_HID_DEVICES];
u8 *input_report[MAX_HID_DEVICES];
u8 request_done[MAX_HID_DEVICES];
struct amd_input_data *in_data;
struct delayed_work work;
struct delayed_work work_buffer;
};
......@@ -64,4 +68,6 @@ void amdtp_hid_remove(struct amdtp_cl_data *cli_data);
int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type);
void amd_sfh_set_report(struct hid_device *hid, int report_id, int report_type);
void amdtp_hid_wakeup(struct hid_device *hid);
u8 get_input_report(u8 current_index, int sensor_idx, int report_id,
struct amd_input_data *in_data);
#endif
......@@ -230,6 +230,11 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
return rc;
}
privdata->cl_data = devm_kzalloc(&pdev->dev, sizeof(struct amdtp_cl_data), GFP_KERNEL);
if (!privdata->cl_data)
return -ENOMEM;
rc = devm_add_action_or_reset(&pdev->dev, amd_mp2_pci_remove, privdata);
if (rc)
return rc;
......
......@@ -10,6 +10,7 @@
#define PCIE_MP2_AMD_H
#include <linux/pci.h>
#include "amd_sfh_hid.h"
#define PCI_DEVICE_ID_AMD_MP2 0x15E4
......@@ -75,6 +76,7 @@ struct amd_mp2_dev {
struct amdtp_cl_data *cl_data;
void __iomem *mmio;
const struct amd_mp2_ops *mp2_ops;
struct amd_input_data in_data;
/* mp2 active control status */
u32 mp2_acs;
};
......
......@@ -12,6 +12,7 @@
#include "amd_sfh_pcie.h"
#include "amd_sfh_hid_desc.h"
#include "amd_sfh_hid_report_desc.h"
#include "amd_sfh_hid.h"
#define AMD_SFH_FW_MULTIPLIER (1000)
#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
common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM;
}
u8 get_input_report(int sensor_idx, int report_id, u8 *input_report, u32 *sensor_virt_addr)
u8 get_input_report(u8 current_index, int sensor_idx, int report_id, struct amd_input_data *in_data)
{
struct amd_mp2_dev *privdata = container_of(in_data, struct amd_mp2_dev, in_data);
u32 *sensor_virt_addr = in_data->sensor_virt_addr[current_index];
u8 *input_report = in_data->input_report[current_index];
u8 supported_input = privdata->mp2_acs & GENMASK(3, 0);
struct accel3_input_report acc_input;
struct gyro_input_report gyro_input;
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
break;
case als_idx: /* Als */
get_common_inputs(&als_input.common_property, report_id);
als_input.illuminance_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
/* For ALS ,V2 Platforms uses C2P_MSG5 register instead of DRAM access method */
if (supported_input == V2_STATUS)
als_input.illuminance_value = (int)readl(privdata->mmio + AMD_C2P_MSG(5));
else
als_input.illuminance_value =
(int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
report_size = sizeof(als_input);
memcpy(input_report, &als_input, sizeof(als_input));
break;
......
......@@ -103,5 +103,4 @@ struct als_input_report {
int get_report_descriptor(int sensor_idx, u8 rep_desc[]);
u32 get_descr_sz(int sensor_idx, int descriptor_name);
u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report);
u8 get_input_report(int sensor_idx, int report_id, u8 *input_report, u32 *sensor_virt_addr);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment