summaryrefslogtreecommitdiffstats
path: root/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
diff options
context:
space:
mode:
authorBasavaraj Natikar <Basavaraj.Natikar@amd.com>2021-06-18 13:48:36 +0530
committerJiri Kosina <jkosina@suse.cz>2021-06-24 14:28:03 +0200
commitf264481ad614dfd9aae59eeefa5fc664cdf173ae (patch)
treee68879edbbe2fa346468399208795e66ef2d31e5 /drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
parent231bc539066760aaa44d46818c85b14ca2f56d9f (diff)
downloadlinux-stable-f264481ad614dfd9aae59eeefa5fc664cdf173ae.tar.gz
linux-stable-f264481ad614dfd9aae59eeefa5fc664cdf173ae.tar.bz2
linux-stable-f264481ad614dfd9aae59eeefa5fc664cdf173ae.zip
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 <Basavaraj.Natikar@amd.com> Reviewed-by: Nehal Shah <nehal-bakulchandra.shah@amd.com> Reviewed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/amd-sfh-hid/amd_sfh_pcie.c')
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_pcie.c80
1 files changed, 76 insertions, 4 deletions
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
index ddecc84fd6f0..48ff54dc5d70 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
@@ -30,6 +30,48 @@ static int sensor_mask_override = -1;
module_param_named(sensor_mask, sensor_mask_override, int, 0444);
MODULE_PARM_DESC(sensor_mask, "override the detected sensors mask");
+static void amd_start_sensor_v2(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
+{
+ union sfh_cmd_base cmd_base;
+
+ cmd_base.ul = 0;
+ cmd_base.cmd_v2.cmd_id = ENABLE_SENSOR;
+ cmd_base.cmd_v2.period = info.period;
+ cmd_base.cmd_v2.sensor_id = info.sensor_idx;
+ cmd_base.cmd_v2.length = 16;
+
+ if (info.sensor_idx == als_idx)
+ cmd_base.cmd_v2.mem_type = USE_C2P_REG;
+
+ writeq(info.dma_address, privdata->mmio + AMD_C2P_MSG1);
+ writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0);
+}
+
+static void amd_stop_sensor_v2(struct amd_mp2_dev *privdata, u16 sensor_idx)
+{
+ union sfh_cmd_base cmd_base;
+
+ cmd_base.ul = 0;
+ cmd_base.cmd_v2.cmd_id = DISABLE_SENSOR;
+ cmd_base.cmd_v2.period = 0;
+ cmd_base.cmd_v2.sensor_id = sensor_idx;
+ cmd_base.cmd_v2.length = 16;
+
+ writeq(0x0, privdata->mmio + AMD_C2P_MSG2);
+ writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0);
+}
+
+static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata)
+{
+ union sfh_cmd_base cmd_base;
+
+ cmd_base.cmd_v2.cmd_id = STOP_ALL_SENSORS;
+ cmd_base.cmd_v2.period = 0;
+ cmd_base.cmd_v2.sensor_id = 0;
+
+ writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG0);
+}
+
void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
{
union sfh_cmd_param cmd_param;
@@ -98,7 +140,6 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id)
{
int activestatus, num_of_sensors = 0;
const struct dmi_system_id *dmi_id;
- u32 activecontrolstatus;
if (sensor_mask_override == -1) {
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)
if (sensor_mask_override >= 0) {
activestatus = sensor_mask_override;
} else {
- activecontrolstatus = readl(privdata->mmio + AMD_P2C_MSG3);
- activestatus = activecontrolstatus >> 4;
+ activestatus = privdata->mp2_acs >> 4;
}
if (ACEL_EN & activestatus)
@@ -130,8 +170,38 @@ int amd_mp2_get_sensor_num(struct amd_mp2_dev *privdata, u8 *sensor_id)
static void amd_mp2_pci_remove(void *privdata)
{
+ struct amd_mp2_dev *mp2 = privdata;
amd_sfh_hid_client_deinit(privdata);
- amd_stop_all_sensors(privdata);
+ mp2->mp2_ops->stop_all(mp2);
+}
+
+static const struct amd_mp2_ops amd_sfh_ops_v2 = {
+ .start = amd_start_sensor_v2,
+ .stop = amd_stop_sensor_v2,
+ .stop_all = amd_stop_all_sensor_v2,
+};
+
+static const struct amd_mp2_ops amd_sfh_ops = {
+ .start = amd_start_sensor,
+ .stop = amd_stop_sensor,
+ .stop_all = amd_stop_all_sensors,
+};
+
+static void mp2_select_ops(struct amd_mp2_dev *privdata)
+{
+ u8 acs;
+
+ privdata->mp2_acs = readl(privdata->mmio + AMD_P2C_MSG3);
+ acs = privdata->mp2_acs & GENMASK(3, 0);
+
+ switch (acs) {
+ case V2_STATUS:
+ privdata->mp2_ops = &amd_sfh_ops_v2;
+ break;
+ default:
+ privdata->mp2_ops = &amd_sfh_ops;
+ break;
+ }
}
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
if (rc)
return rc;
+ mp2_select_ops(privdata);
+
return amd_sfh_hid_client_init(privdata);
}