summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.com>2026-10-21 21:57:39 +0200
committerJiri Kosina <jkosina@suse.com>2026-10-21 21:57:39 +0200
commit60ccbc2343d37c65a76b736eb7cf41ce0ec343b8 (patch)
treee1256bd6866c3a6559d07a53f9db460d82b8b4a2
parent5bb58a6777a3d093013305d44133967cac17b2c4 (diff)
parent85f1bea97f1909f81577cfcf3e4db9017e7f5337 (diff)
Merge branch 'for-7.4/amd_sfh' into for-linus
- support for newer AMD SoCs (Basavaraj Natikar) - sysfs attributes of operating-mode telemetry (Basavaraj Natikar)
-rw-r--r--Documentation/ABI/testing/sysfs-driver-amd-sfh60
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/hid/amd-sfh-hid/Makefile1
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_client.c4
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_common.h2
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_pcie.c65
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c134
-rw-r--r--drivers/hid/amd-sfh-hid/amd_sfh_sysfs.h19
-rw-r--r--drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h2
-rw-r--r--drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h7
-rw-r--r--drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c13
-rw-r--r--drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c37
-rw-r--r--drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h7
13 files changed, 282 insertions, 70 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-amd-sfh b/Documentation/ABI/testing/sysfs-driver-amd-sfh
index c053126a83bb..15abd994e9ee 100644
--- a/Documentation/ABI/testing/sysfs-driver-amd-sfh
+++ b/Documentation/ABI/testing/sysfs-driver-amd-sfh
@@ -11,3 +11,63 @@ Description:
Access: Read/Write
Valid values: enabled/disabled
+
+What: /sys/bus/pci/drivers/pcie_mp2_amd/*/in_bag_state
+Date: August 2026
+Contact: Basavaraj.Natikar@amd.com
+Description:
+ Operating-mode telemetry reported by the SRA sensor that
+ indicates whether the device is detected inside a bag.
+
+ Access: Read only
+ Valid values: unsigned integer
+
+What: /sys/bus/pci/drivers/pcie_mp2_amd/*/out_bag_state
+Date: August 2026
+Contact: Basavaraj.Natikar@amd.com
+Description:
+ Operating-mode telemetry reported by the SRA sensor that
+ indicates whether the device is detected outside a bag.
+
+ Access: Read only
+ Valid values: unsigned integer
+
+What: /sys/bus/pci/drivers/pcie_mp2_amd/*/on_table_state
+Date: August 2026
+Contact: Basavaraj.Natikar@amd.com
+Description:
+ Operating-mode telemetry reported by the SRA sensor that
+ indicates whether the device is placed on a table or on a lap.
+
+ Access: Read only
+ Valid values: unsigned integer
+
+What: /sys/bus/pci/drivers/pcie_mp2_amd/*/hinge_angle
+Date: August 2026
+Contact: Basavaraj.Natikar@amd.com
+Description:
+ Operating-mode telemetry reported by the SRA sensor that
+ reports the hinge angle of the device in degrees.
+
+ Access: Read only
+ Valid values: unsigned integer (degrees)
+
+What: /sys/bus/pci/drivers/pcie_mp2_amd/*/lid_status
+Date: August 2026
+Contact: Basavaraj.Natikar@amd.com
+Description:
+ Operating-mode telemetry reported by the SRA sensor that
+ indicates whether the device lid is open or closed.
+
+ Access: Read only
+ Valid values: unsigned integer
+
+What: /sys/bus/pci/drivers/pcie_mp2_amd/*/device_mode
+Date: August 2026
+Contact: Basavaraj.Natikar@amd.com
+Description:
+ Operating-mode telemetry reported by the SRA sensor that
+ reports the platform/device mode.
+
+ Access: Read only
+ Valid values: unsigned integer
diff --git a/MAINTAINERS b/MAINTAINERS
index ac42bbec04d8..c7ccc417cf43 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1322,6 +1322,7 @@ AMD SENSOR FUSION HUB DRIVER
M: Basavaraj Natikar <basavaraj.natikar@amd.com>
L: linux-input@vger.kernel.org
S: Maintained
+F: Documentation/ABI/testing/sysfs-driver-amd-sfh
F: Documentation/hid/amd-sfh*
F: drivers/hid/amd-sfh-hid/
F: drivers/input/misc/amd_sfh_tabletmode.c
diff --git a/drivers/hid/amd-sfh-hid/Makefile b/drivers/hid/amd-sfh-hid/Makefile
index 106514b54d16..a0e4113c94cb 100644
--- a/drivers/hid/amd-sfh-hid/Makefile
+++ b/drivers/hid/amd-sfh-hid/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_AMD_SFH_HID) += amd_sfh.o
amd_sfh-objs := amd_sfh_hid.o
amd_sfh-objs += amd_sfh_client.o
amd_sfh-objs += amd_sfh_pcie.o
+amd_sfh-objs += amd_sfh_sysfs.o
amd_sfh-objs += hid_descriptor/amd_sfh_hid_desc.o
amd_sfh-objs += sfh1_1/amd_sfh_init.o
amd_sfh-objs += sfh1_1/amd_sfh_interface.o
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
index ae6add0b9ce3..a68b275f0456 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
@@ -95,7 +95,7 @@ void amd_sfh_work(struct work_struct *work)
cli_data->feature_report[current_index]);
if (report_size)
hid_input_report(cli_data->hid_sensor_hubs[current_index],
- cli_data->report_type[current_index],
+ node_type,
cli_data->feature_report[current_index], report_size, 0);
else
pr_err("AMDSFH: Invalid report size\n");
@@ -104,7 +104,7 @@ void amd_sfh_work(struct work_struct *work)
report_size = mp2_ops->get_in_rep(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],
+ node_type,
in_data->input_report[current_index], report_size, 0);
else
pr_err("AMDSFH: Invalid report size\n");
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_common.h b/drivers/hid/amd-sfh-hid/amd_sfh_common.h
index 3d29119a3765..e8cc7f1d289c 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_common.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_common.h
@@ -18,6 +18,7 @@
#define PCI_DEVICE_ID_AMD_MP2 0x15E4
#define PCI_DEVICE_ID_AMD_MP2_1_1 0x164A
+#define PCI_DEVICE_ID_AMD_MP2_1_2 0x1152
/* The BAR 2 size must cover the highest register offset (0x10958) */
#define AMD_SFH_MIN_BAR_SIZE SZ_128K
@@ -43,6 +44,7 @@ enum cmd_id {
enum amd_mp2_version {
MP2_VER_V2 = 1,
MP2_VER_1_1 = 2,
+ MP2_VER_1_2 = 3,
};
struct amd_mp2_sensor_info {
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
index 061a63519d44..b3cb13b8c5e8 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
@@ -20,9 +20,9 @@
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/string_choices.h>
#include "amd_sfh_pcie.h"
+#include "amd_sfh_sysfs.h"
#include "sfh1_1/amd_sfh_init.h"
#define DRIVER_NAME "pcie_mp2_amd"
@@ -41,6 +41,8 @@ module_param_named(sensor_mask, sensor_mask_override, int, 0444);
MODULE_PARM_DESC(sensor_mask, "override the detected sensors mask");
static bool intr_disable = true;
+module_param_named(intr_disable, intr_disable, bool, 0444);
+MODULE_PARM_DESC(intr_disable, "override the interrupt disable sensor bit");
static int amd_sfh_wait_response_v2(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts)
{
@@ -313,6 +315,13 @@ static const struct dmi_system_id dmi_sfh_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook x360 435 G7"),
},
},
+ {
+ .callback = mp2_disable_intr,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VivoBook_ASUSLaptop TP420UA_TM420UA"),
+ },
+ },
{}
};
@@ -331,57 +340,6 @@ static const struct dmi_system_id dmi_nodevs[] = {
{ }
};
-static ssize_t hpd_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
-
- return sysfs_emit(buf, "%s\n", str_enabled_disabled(mp2->dev_en.is_hpd_enabled));
-}
-
-static ssize_t hpd_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
- bool enabled;
- int ret;
-
- ret = kstrtobool(buf, &enabled);
- if (ret)
- return ret;
-
- mp2->sfh1_1_ops->toggle_hpd(mp2, enabled);
-
- return count;
-}
-static DEVICE_ATTR_RW(hpd);
-
-static umode_t sfh_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
-{
- struct device *dev = kobj_to_dev(kobj);
- struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
-
- if (!mp2->sfh1_1_ops || !mp2->dev_en.is_hpd_present)
- return 0;
-
- return attr->mode;
-}
-
-static struct attribute *sfh_attrs[] = {
- &dev_attr_hpd.attr,
- NULL,
-};
-
-static struct attribute_group sfh_attr_group = {
- .attrs = sfh_attrs,
- .is_visible = sfh_attr_is_visible,
-};
-
-static const struct attribute_group *amd_sfh_groups[] = {
- &sfh_attr_group,
- NULL,
-};
-
static DEFINE_IDA(sfh_tm_ida);
static void amd_sfh_maybe_register_tm(struct amd_mp2_dev *mp2)
@@ -439,7 +397,7 @@ static void sfh1_1_init_work(struct work_struct *work)
amd_sfh_clear_intr(mp2);
mp2->init_done = 1;
- rc = sysfs_update_group(&mp2->pdev->dev.kobj, &sfh_attr_group);
+ rc = amd_sfh_update_sysfs(mp2);
if (rc)
dev_warn(&mp2->pdev->dev, "failed to update sysfs group\n");
@@ -598,6 +556,7 @@ static SIMPLE_DEV_PM_OPS(amd_mp2_pm_ops, amd_mp2_pci_suspend,
static const struct pci_device_id amd_mp2_pci_tbl[] = {
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_MP2) },
{ PCI_DEVICE_DATA(AMD, MP2_1_1, MP2_VER_1_1) },
+ { PCI_DEVICE_DATA(AMD, MP2_1_2, MP2_VER_1_2) },
{ }
};
MODULE_DEVICE_TABLE(pci, amd_mp2_pci_tbl);
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c b/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c
new file mode 100644
index 000000000000..8af4df09760f
--- /dev/null
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * AMD SFH sysfs attributes
+ *
+ * Copyright (c) 2026, Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+ */
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/string_choices.h>
+#include <linux/sysfs.h>
+
+#include "amd_sfh_common.h"
+#include "amd_sfh_sysfs.h"
+#include "sfh1_1/amd_sfh_init.h"
+#include "sfh1_1/amd_sfh_interface.h"
+
+static ssize_t hpd_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%s\n", str_enabled_disabled(mp2->dev_en.is_hpd_enabled));
+}
+
+static ssize_t hpd_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
+ bool enabled;
+ int ret;
+
+ ret = kstrtobool(buf, &enabled);
+ if (ret)
+ return ret;
+
+ mp2->sfh1_1_ops->toggle_hpd(mp2, enabled);
+
+ return count;
+}
+static DEVICE_ATTR_RW(hpd);
+
+/* Operating-mode telemetry reported by the SRA sensor, exposed read-only. */
+static int amd_sfh_read_op_mode(struct amd_mp2_dev *mp2, struct sfh_op_mode *mode)
+{
+ struct sfh_accel_data accel_data;
+ void __iomem *sensoraddr;
+
+ if (!mp2->sfh1_1_ops || !mp2->dev_en.is_sra_present)
+ return -ENODEV;
+
+ if (mp2->mp2_ver >= MP2_VER_1_2) {
+ sensoraddr = mp2->vsbase +
+ (SRA_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) +
+ OFFSET_SENSOR_DATA_DEFAULT;
+ memcpy_fromio(&accel_data, sensoraddr, sizeof(struct sfh_accel_data));
+ mode->val = accel_data.c2p3_data;
+ } else {
+ mode->val = readl(mp2->mmio + amd_get_c2p_val(mp2, 3));
+ }
+
+ return 0;
+}
+
+#define SFH_OP_MODE_ATTR(_name, _field) \
+static ssize_t _name##_show(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct amd_mp2_dev *mp2 = dev_get_drvdata(dev); \
+ struct sfh_op_mode mode; \
+ int ret; \
+ \
+ ret = amd_sfh_read_op_mode(mp2, &mode); \
+ if (ret) \
+ return ret; \
+ \
+ return sysfs_emit(buf, "%u\n", mode.op_mode._field); \
+} \
+static DEVICE_ATTR_RO(_name)
+
+SFH_OP_MODE_ATTR(in_bag_state, inbagstate);
+SFH_OP_MODE_ATTR(out_bag_state, outbagstate);
+SFH_OP_MODE_ATTR(on_table_state, ontablestate);
+SFH_OP_MODE_ATTR(hinge_angle, angle);
+SFH_OP_MODE_ATTR(lid_status, lidstatus);
+SFH_OP_MODE_ATTR(device_mode, devicemode);
+
+static umode_t sfh_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
+
+ if (!mp2->sfh1_1_ops)
+ return 0;
+
+ if (attr == &dev_attr_hpd.attr) {
+ if (!mp2->dev_en.is_hpd_present)
+ return 0;
+ } else if (!mp2->dev_en.is_sra_present) {
+ /* operating-mode telemetry requires the SRA sensor */
+ return 0;
+ }
+
+ return attr->mode;
+}
+
+static struct attribute *sfh_attrs[] = {
+ &dev_attr_hpd.attr,
+ &dev_attr_in_bag_state.attr,
+ &dev_attr_out_bag_state.attr,
+ &dev_attr_on_table_state.attr,
+ &dev_attr_hinge_angle.attr,
+ &dev_attr_lid_status.attr,
+ &dev_attr_device_mode.attr,
+ NULL,
+};
+
+static struct attribute_group sfh_attr_group = {
+ .attrs = sfh_attrs,
+ .is_visible = sfh_attr_is_visible,
+};
+
+const struct attribute_group *amd_sfh_groups[] = {
+ &sfh_attr_group,
+ NULL,
+};
+
+int amd_sfh_update_sysfs(struct amd_mp2_dev *mp2)
+{
+ return sysfs_update_group(&mp2->pdev->dev.kobj, &sfh_attr_group);
+}
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.h b/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.h
new file mode 100644
index 000000000000..941b995e2c8f
--- /dev/null
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * AMD SFH sysfs attributes
+ *
+ * Copyright (c) 2026, Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+ */
+#ifndef AMD_SFH_SYSFS_H
+#define AMD_SFH_SYSFS_H
+
+#include "amd_sfh_common.h"
+
+extern const struct attribute_group *amd_sfh_groups[];
+
+int amd_sfh_update_sysfs(struct amd_mp2_dev *mp2);
+
+#endif
diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
index 882434b1501f..230fb69cacfd 100644
--- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
+++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
@@ -48,8 +48,6 @@ struct accel3_input_report {
int in_accel_x_value;
int in_accel_y_value;
int in_accel_z_value;
- /* include if required to support the "shake" event */
- u8 in_accel_shake_detection;
} __packed;
struct gyro_feature_report {
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 67ec2d6a417d..64cff842e5f2 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
@@ -169,13 +169,6 @@ static const u8 accel3_report_descriptor[] = {
0x95, 1, /* HID report count (1) */
0x55, 0x0E, /* HID unit exponent(0x0E) */
0X81, 0x02, /* HID Input (Data_Arr_Abs) */
-
-0x0A, 0x51, 0x04, /* HID usage sensor data motion state */
-0x15, 0, /* HID logical Min_8(0) False = Still*/
-0x25, 1, /* HID logical Min_8(1) True = In motion */
-0x75, 8, /* HID report size(8) */
-0x95, 1, /* HID report count (1) */
-0X81, 0x02, /* HID Input (Data_Arr_Abs) */
0xC0 /* HID end collection */
};
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
index c8916afefa62..b81a97dbb1b0 100644
--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
@@ -187,6 +187,7 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id,
struct sfh_gyro_data gyro_data;
struct sfh_mag_data mag_data;
struct sfh_als_data als_data;
+ struct sfh_hpd_data hpd_data;
struct hpd_status hpdstatus;
struct sfh_base_info binfo;
void __iomem *sensoraddr;
@@ -251,8 +252,16 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id,
break;
case HPD_IDX:
get_common_inputs(&hpd_input.common_property, report_id);
- hpdstatus.val = readl(mp2->mmio + amd_get_c2p_val(mp2, 4));
- hpd_input.human_presence = hpdstatus.shpd.presence;
+ if (mp2->mp2_ver >= MP2_VER_1_2) {
+ sensoraddr = mp2->vsbase +
+ (HPD_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) +
+ OFFSET_SENSOR_DATA_DEFAULT;
+ memcpy_fromio(&hpd_data, sensoraddr, sizeof(struct sfh_hpd_data));
+ hpd_input.human_presence = hpd_data.status.shpd.presence;
+ } else {
+ hpdstatus.val = readl(mp2->mmio + amd_get_c2p_val(mp2, 4));
+ hpd_input.human_presence = hpdstatus.shpd.presence;
+ }
report_size = sizeof(hpd_input);
memcpy(input_report, &hpd_input, sizeof(hpd_input));
break;
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
index 60c185a9cd50..bc0adb789896 100644
--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
@@ -98,6 +98,25 @@ void sfh_interface_init(struct amd_mp2_dev *mp2)
emp2 = mp2;
}
+static unsigned int amd_sfh_read_c2p3(struct amd_mp2_dev *mp2)
+{
+ struct sfh_accel_data accel_data;
+ void __iomem *sensoraddr;
+ u32 val;
+
+ if (mp2->mp2_ver >= MP2_VER_1_2) {
+ sensoraddr = mp2->vsbase +
+ (SRA_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) +
+ OFFSET_SENSOR_DATA_DEFAULT;
+ memcpy_fromio(&accel_data, sensoraddr, sizeof(struct sfh_accel_data));
+ val = accel_data.c2p3_data;
+ } else {
+ val = readl(mp2->mmio + amd_get_c2p_val(mp2, 3));
+ }
+
+ return val;
+}
+
static int amd_sfh_op_mode_info(u32 *op_mode)
{
struct sfh_op_mode mode;
@@ -114,7 +133,7 @@ static int amd_sfh_op_mode_info(u32 *op_mode)
if (!present)
return -ENODEV;
- mode.val = readl(emp2->mmio + amd_get_c2p_val(emp2, 3));
+ mode.val = amd_sfh_read_c2p3(emp2);
dev_dbg(&emp2->pdev->dev, "op-mode: %s (mode=%u)\n",
mode.op_mode.mode == SFH_MODE_TABLET ? "tablet" : "laptop",
mode.op_mode.mode);
@@ -133,7 +152,7 @@ static int amd_sfh_mode_info(u32 *platform_type, u32 *laptop_placement)
if (!emp2 || !emp2->dev_en.is_sra_present)
return -ENODEV;
- mode.val = readl(emp2->mmio + amd_get_c2p_val(emp2, 3));
+ mode.val = amd_sfh_read_c2p3(emp2);
*platform_type = mode.op_mode.devicemode;
@@ -160,7 +179,9 @@ static int amd_sfh_mode_info(u32 *platform_type, u32 *laptop_placement)
static int amd_sfh_hpd_info(u8 *user_present)
{
+ struct sfh_hpd_data hpd_data;
struct hpd_status hpdstatus;
+ void __iomem *sensoraddr;
if (!user_present)
return -EINVAL;
@@ -168,8 +189,16 @@ static int amd_sfh_hpd_info(u8 *user_present)
if (!emp2 || !emp2->dev_en.is_hpd_present || !emp2->dev_en.is_hpd_enabled)
return -ENODEV;
- hpdstatus.val = readl(emp2->mmio + amd_get_c2p_val(emp2, 4));
- *user_present = hpdstatus.shpd.presence;
+ if (emp2->mp2_ver >= MP2_VER_1_2) {
+ sensoraddr = emp2->vsbase +
+ (HPD_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) +
+ OFFSET_SENSOR_DATA_DEFAULT;
+ memcpy_fromio(&hpd_data, sensoraddr, sizeof(struct sfh_hpd_data));
+ *user_present = hpd_data.status.shpd.presence;
+ } else {
+ hpdstatus.val = readl(emp2->mmio + amd_get_c2p_val(emp2, 4));
+ *user_present = hpdstatus.shpd.presence;
+ }
return 0;
}
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h
index 56258c4d1b3a..eaa90c689049 100644
--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h
+++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h
@@ -130,6 +130,7 @@ struct sfh_accel_data {
struct sfh_common_data commondata;
struct sfh_float32 acceldata;
u32 accelstatus;
+ u32 c2p3_data;
};
struct sfh_gyro_data {
@@ -165,6 +166,12 @@ struct hpd_status {
};
};
+struct sfh_hpd_data {
+ struct sfh_common_data commondata;
+ u32 reserved;
+ struct hpd_status status;
+};
+
struct sfh_op_mode {
union {
u32 val;