GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / hid / amd-sfh-hid / sfh1_1 / amd_sfh_interface.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * AMD MP2 1.1 communication interfaces
4  *
5  * Copyright (c) 2022, Advanced Micro Devices, Inc.
6  * All Rights Reserved.
7  *
8  * Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
9  */
10 #include <linux/io-64-nonatomic-lo-hi.h>
11 #include <linux/iopoll.h>
12
13 #include "amd_sfh_interface.h"
14
15 static int amd_sfh_wait_response(struct amd_mp2_dev *mp2, u8 sid, u32 cmd_id)
16 {
17         struct sfh_cmd_response cmd_resp;
18
19         /* Get response with status within a max of 10000 ms timeout */
20         if (!readl_poll_timeout(mp2->mmio + AMD_P2C_MSG(0), cmd_resp.resp,
21                                 (cmd_resp.response.response == 0 &&
22                                 cmd_resp.response.cmd_id == cmd_id && (sid == 0xff ||
23                                 cmd_resp.response.sensor_id == sid)), 500, 10000000))
24                 return cmd_resp.response.response;
25
26         return -1;
27 }
28
29 static void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
30 {
31         struct sfh_cmd_base cmd_base;
32
33         cmd_base.ul = 0;
34         cmd_base.cmd.cmd_id = ENABLE_SENSOR;
35         cmd_base.cmd.intr_disable = 0;
36         cmd_base.cmd.sub_cmd_value = 1;
37         cmd_base.cmd.sensor_id = info.sensor_idx;
38
39         writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
40 }
41
42 static void amd_stop_sensor(struct amd_mp2_dev *privdata, u16 sensor_idx)
43 {
44         struct sfh_cmd_base cmd_base;
45
46         cmd_base.ul = 0;
47         cmd_base.cmd.cmd_id = DISABLE_SENSOR;
48         cmd_base.cmd.intr_disable = 0;
49         cmd_base.cmd.sub_cmd_value = 1;
50         cmd_base.cmd.sensor_id = sensor_idx;
51
52         writeq(0x0, privdata->mmio + AMD_C2P_MSG(1));
53         writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
54 }
55
56 static void amd_stop_all_sensor(struct amd_mp2_dev *privdata)
57 {
58         struct sfh_cmd_base cmd_base;
59
60         cmd_base.ul = 0;
61         cmd_base.cmd.cmd_id = DISABLE_SENSOR;
62         cmd_base.cmd.intr_disable = 0;
63         /* 0xf indicates all sensors */
64         cmd_base.cmd.sensor_id = 0xf;
65
66         writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
67 }
68
69 static struct amd_mp2_ops amd_sfh_ops = {
70         .start = amd_start_sensor,
71         .stop = amd_stop_sensor,
72         .stop_all = amd_stop_all_sensor,
73         .response = amd_sfh_wait_response,
74 };
75
76 void sfh_interface_init(struct amd_mp2_dev *mp2)
77 {
78         mp2->mp2_ops = &amd_sfh_ops;
79 }