summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2022-05-24 11:54:42 +0300
committerJiri Kosina <jkosina@suse.cz>2022-05-24 11:54:42 +0300
commit8959f00799a174af300f88bf8360b903976363c9 (patch)
tree0afcd4fa6f94b8060750749cdfa1f419e897f7fb
parentfc4ef9d5724973193bfa5ebed181dba6de3a56db (diff)
parent806fc359a39458c54dedc28b904ca27b3fc79b19 (diff)
downloadlinux-8959f00799a174af300f88bf8360b903976363c9.tar.xz
Merge branch 'for-5.19/amd-sfh' into for-linus
- support for sensor discovery and code cleanups (Basavaraj Natikar)
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_client.c45
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_hid.c9
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_hid.h1
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_pcie.c17
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_pcie.h5
-rw-r--r--drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h6
-rw-r--r--drivers/hid/hid-core.c4
-rw-r--r--include/uapi/linux/input.h1
8 files changed, 72 insertions, 16 deletions
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
index c5de0ec4f9d0..0f770a2b47ff 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
@@ -141,6 +141,24 @@ u32 amd_sfh_wait_for_response(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts)
return sensor_sts;
}
+const char *get_sensor_name(int idx)
+{
+ switch (idx) {
+ case accel_idx:
+ return "accelerometer";
+ case gyro_idx:
+ return "gyroscope";
+ case mag_idx:
+ return "magnetometer";
+ case als_idx:
+ return "ALS";
+ case HPD_IDX:
+ return "HPD";
+ default:
+ return "unknown sensor type";
+ }
+}
+
int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
{
struct amd_input_data *in_data = &privdata->in_data;
@@ -219,13 +237,27 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
(privdata, cl_data->sensor_idx[i], SENSOR_DISABLED);
if (status != SENSOR_ENABLED)
cl_data->sensor_sts[i] = SENSOR_DISABLED;
- dev_dbg(dev, "sid 0x%x status 0x%x\n",
- cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
+ dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n",
+ cl_data->sensor_idx[i],
+ get_sensor_name(cl_data->sensor_idx[i]),
+ cl_data->sensor_sts[i]);
goto cleanup;
}
}
- dev_dbg(dev, "sid 0x%x status 0x%x\n",
- cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
+ dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n",
+ cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
+ cl_data->sensor_sts[i]);
+ }
+ if (privdata->mp2_ops->discovery_status &&
+ privdata->mp2_ops->discovery_status(privdata) == 0) {
+ amd_sfh_hid_client_deinit(privdata);
+ for (i = 0; i < cl_data->num_hid_devices; i++) {
+ devm_kfree(dev, cl_data->feature_report[i]);
+ devm_kfree(dev, in_data->input_report[i]);
+ devm_kfree(dev, cl_data->report_descr[i]);
+ }
+ dev_warn(dev, "Failed to discover, sensors not enabled\n");
+ return -EOPNOTSUPP;
}
schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
return 0;
@@ -257,8 +289,9 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
(privdata, cl_data->sensor_idx[i], SENSOR_DISABLED);
if (status != SENSOR_ENABLED)
cl_data->sensor_sts[i] = SENSOR_DISABLED;
- dev_dbg(&privdata->pdev->dev, "stopping sid 0x%x status 0x%x\n",
- cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
+ dev_dbg(&privdata->pdev->dev, "stopping sid 0x%x (%s) status 0x%x\n",
+ cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
+ cl_data->sensor_sts[i]);
}
}
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
index 2bf97b6ac973..1089134030b0 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
@@ -12,6 +12,7 @@
#include <linux/sched.h>
#include "amd_sfh_hid.h"
+#include "amd_sfh_pcie.h"
#define AMD_SFH_RESPONSE_TIMEOUT 1500
@@ -120,6 +121,8 @@ static struct hid_ll_driver amdtp_hid_ll_driver = {
int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data)
{
+ struct amd_mp2_dev *mp2 = container_of(cli_data->in_data, struct amd_mp2_dev, in_data);
+ struct device *dev = &mp2->pdev->dev;
struct hid_device *hid;
struct amdtp_hid_data *hid_data;
int rc;
@@ -141,10 +144,12 @@ int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data)
hid->driver_data = hid_data;
cli_data->hid_sensor_hubs[cur_hid_dev] = hid;
- hid->bus = BUS_AMD_AMDTP;
+ strscpy(hid->phys, dev->driver ? dev->driver->name : dev_name(dev),
+ sizeof(hid->phys));
+ hid->bus = BUS_AMD_SFH;
hid->vendor = AMD_SFH_HID_VENDOR;
hid->product = AMD_SFH_HID_PRODUCT;
- snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-amdtp",
+ snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-amdsfh",
hid->vendor, hid->product);
rc = hid_add_device(hid);
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h
index c60abd38054c..ad264db63180 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h
@@ -12,7 +12,6 @@
#define AMDSFH_HID_H
#define MAX_HID_DEVICES 5
-#define BUS_AMD_AMDTP 0x20
#define AMD_SFH_HID_VENDOR 0x1022
#define AMD_SFH_HID_PRODUCT 0x0001
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
index 6b5fd90b0bd1..dadc491bbf6b 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
@@ -130,6 +130,12 @@ static int amd_sfh_irq_init_v2(struct amd_mp2_dev *privdata)
return 0;
}
+static int amd_sfh_dis_sts_v2(struct amd_mp2_dev *privdata)
+{
+ return (readl(privdata->mmio + AMD_P2C_MSG(1)) &
+ SENSOR_DISCOVERY_STATUS_MASK) >> SENSOR_DISCOVERY_STATUS_SHIFT;
+}
+
void amd_start_sensor(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info)
{
union sfh_cmd_param cmd_param;
@@ -245,6 +251,7 @@ static const struct amd_mp2_ops amd_sfh_ops_v2 = {
.response = amd_sfh_wait_response_v2,
.clear_intr = amd_sfh_clear_intr_v2,
.init_intr = amd_sfh_irq_init_v2,
+ .discovery_status = amd_sfh_dis_sts_v2,
};
static const struct amd_mp2_ops amd_sfh_ops = {
@@ -346,8 +353,9 @@ static int __maybe_unused amd_mp2_pci_resume(struct device *dev)
(mp2, cl_data->sensor_idx[i], SENSOR_ENABLED);
if (status == SENSOR_ENABLED)
cl_data->sensor_sts[i] = SENSOR_ENABLED;
- dev_dbg(dev, "resume sid 0x%x status 0x%x\n",
- cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
+ dev_dbg(dev, "suspend sid 0x%x (%s) status 0x%x\n",
+ cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
+ cl_data->sensor_sts[i]);
}
}
@@ -371,8 +379,9 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev)
(mp2, cl_data->sensor_idx[i], SENSOR_DISABLED);
if (status != SENSOR_ENABLED)
cl_data->sensor_sts[i] = SENSOR_DISABLED;
- dev_dbg(dev, "suspend sid 0x%x status 0x%x\n",
- cl_data->sensor_idx[i], cl_data->sensor_sts[i]);
+ dev_dbg(dev, "suspend sid 0x%x (%s) status 0x%x\n",
+ cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
+ cl_data->sensor_sts[i]);
}
}
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
index 97b99861fae2..8c760526132a 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
@@ -39,6 +39,9 @@
#define AMD_SFH_IDLE_LOOP 200
+#define SENSOR_DISCOVERY_STATUS_MASK GENMASK(5, 3)
+#define SENSOR_DISCOVERY_STATUS_SHIFT 3
+
/* SFH Command register */
union sfh_cmd_base {
u32 ul;
@@ -135,6 +138,7 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata);
u32 amd_sfh_wait_for_response(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts);
void amd_mp2_suspend(struct amd_mp2_dev *mp2);
void amd_mp2_resume(struct amd_mp2_dev *mp2);
+const char *get_sensor_name(int idx);
struct amd_mp2_ops {
void (*start)(struct amd_mp2_dev *privdata, struct amd_mp2_sensor_info info);
@@ -143,5 +147,6 @@ struct amd_mp2_ops {
int (*response)(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts);
void (*clear_intr)(struct amd_mp2_dev *privdata);
int (*init_intr)(struct amd_mp2_dev *privdata);
+ int (*discovery_status)(struct amd_mp2_dev *privdata);
};
#endif
diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
index 8d97ca0f9b52..697f2791ea9c 100644
--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
+++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
@@ -179,7 +179,7 @@ static const u8 accel3_report_descriptor[] = {
0xC0 /* HID end collection */
};
-const u8 gyro3_report_descriptor[] = {
+static const u8 gyro3_report_descriptor[] = {
0x05, 0x20, /* Usage page */
0x09, 0x76, /* Motion type Gyro3D */
0xA1, 0x00, /* HID Collection (Physical) */
@@ -340,7 +340,7 @@ const u8 gyro3_report_descriptor[] = {
0xC0, /* HID end collection */
};
-const u8 comp3_report_descriptor[] = {
+static const u8 comp3_report_descriptor[] = {
0x05, 0x20, /* Usage page */
0x09, 0x83, /* Motion type Orientation compass 3D */
0xA1, 0x00, /* HID Collection (Physical) */
@@ -512,7 +512,7 @@ const u8 comp3_report_descriptor[] = {
0xC0 /* HID end collection */
};
-const u8 als_report_descriptor[] = {
+static const u8 als_report_descriptor[] = {
0x05, 0x20, /* HID usage page sensor */
0x09, 0x41, /* HID usage sensor type Ambientlight */
0xA1, 0x00, /* HID Collection (Physical) */
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index db925794fbe6..00154a1cd2d8 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2222,6 +2222,10 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
case BUS_VIRTUAL:
bus = "VIRTUAL";
break;
+ case BUS_INTEL_ISHTP:
+ case BUS_AMD_SFH:
+ bus = "SENSOR HUB";
+ break;
default:
bus = "<UNKNOWN>";
}
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index ee3127461ee0..ef4257ab3026 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -271,6 +271,7 @@ struct input_mask {
#define BUS_RMI 0x1D
#define BUS_CEC 0x1E
#define BUS_INTEL_ISHTP 0x1F
+#define BUS_AMD_SFH 0x20
/*
* MT_TOOL types