diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
commit | 2c3c1048746a4622d8c89a29670120dc8fab93c4 (patch) | |
tree | 848558de17fb3008cdf4d861b01ac7781903ce39 /drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c | |
parent | Initial commit. (diff) | |
download | linux-upstream.tar.xz linux-upstream.zip |
Adding upstream version 6.1.76.upstream/6.1.76upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c')
-rw-r--r-- | drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c new file mode 100644 index 000000000..4f81ef2d4 --- /dev/null +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AMD MP2 1.1 communication interfaces + * + * Copyright (c) 2022, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com> + */ +#include <linux/io-64-nonatomic-lo-hi.h> +#include <linux/iopoll.h> + +#include "amd_sfh_interface.h" + +static int amd_sfh_wait_response(struct amd_mp2_dev *mp2, u8 sid, u32 cmd_id) +{ + struct sfh_cmd_response cmd_resp; + + /* Get response with status within a max of 10000 ms timeout */ + if (!readl_poll_timeout(mp2->mmio + AMD_P2C_MSG(0), cmd_resp.resp, + (cmd_resp.response.response == 0 && + cmd_resp.response.cmd_id == cmd_id && (sid == 0xff || + cmd_resp.response.sensor_id == sid)), 500, 10000000)) + return cmd_resp.response.response; + + return -1; +} + +static void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info) +{ + struct sfh_cmd_base cmd_base; + + cmd_base.ul = 0; + cmd_base.cmd.cmd_id = ENABLE_SENSOR; + cmd_base.cmd.intr_disable = 0; + cmd_base.cmd.sub_cmd_value = 1; + cmd_base.cmd.sensor_id = info.sensor_idx; + + writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0)); +} + +static void amd_stop_sensor(struct amd_mp2_dev *privdata, u16 sensor_idx) +{ + struct sfh_cmd_base cmd_base; + + cmd_base.ul = 0; + cmd_base.cmd.cmd_id = DISABLE_SENSOR; + cmd_base.cmd.intr_disable = 0; + cmd_base.cmd.sub_cmd_value = 1; + cmd_base.cmd.sensor_id = sensor_idx; + + writeq(0x0, privdata->mmio + AMD_C2P_MSG(1)); + writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0)); +} + +static void amd_stop_all_sensor(struct amd_mp2_dev *privdata) +{ + struct sfh_cmd_base cmd_base; + + cmd_base.ul = 0; + cmd_base.cmd.cmd_id = DISABLE_SENSOR; + cmd_base.cmd.intr_disable = 0; + /* 0xf indicates all sensors */ + cmd_base.cmd.sensor_id = 0xf; + + writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0)); +} + +static struct amd_mp2_ops amd_sfh_ops = { + .start = amd_start_sensor, + .stop = amd_stop_sensor, + .stop_all = amd_stop_all_sensor, + .response = amd_sfh_wait_response, +}; + +void sfh_interface_init(struct amd_mp2_dev *mp2) +{ + mp2->mp2_ops = &amd_sfh_ops; +} |