From e24456115c87b96401647029049d9487b62a0fe4 Mon Sep 17 00:00:00 2001 From: Helge Bahmann Date: Wed, 2 Sep 2026 19:14:28 +0530 Subject: [PATCH 1/8] HID: amd_sfh: Add DMI quirk and module param to disable interrupts Expose intr_disable as a module parameter to allow runtime override. Add DMI quirk for ASUSTeK VivoBook TP420UA/TM420UA which requires interrupts disabled for correct sensor operation. Signed-off-by: Helge Bahmann Signed-off-by: Basavaraj Natikar Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Jiri Kosina --- drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c index eda26a094d3f..92486f25460b 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c @@ -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"), + }, + }, {} }; From 732f7086afb20a605e3041eaff025119d7085c3f Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Wed, 2 Sep 2026 19:14:29 +0530 Subject: [PATCH 2/8] HID: amd_sfh: Add support for newer AMD SoCs Add PCI device ID 0x1152 for AMD Sensor Fusion Hub on newer AMD SoCs. MP2 1.2 shares the same initialization and operations as MP2 1.1. Co-developed-by: Guruvendra Punugupati Signed-off-by: Guruvendra Punugupati Signed-off-by: Basavaraj Natikar Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Jiri Kosina --- drivers/hid/amd-sfh-hid/amd_sfh_common.h | 2 ++ drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_common.h b/drivers/hid/amd-sfh-hid/amd_sfh_common.h index f8c6b7fc34fb..a455bb30fc47 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_common.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_common.h @@ -17,6 +17,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 #define AMD_C2P_MSG(regno) (0x10500 + ((regno) * 4)) #define AMD_P2C_MSG(regno) (0x10680 + ((regno) * 4)) @@ -39,6 +40,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 92486f25460b..fe4b00227eca 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c @@ -597,6 +597,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); From 6d7898e93937d2cb54fd0564a10f8da1cdcf6e5e Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Wed, 2 Sep 2026 19:14:30 +0530 Subject: [PATCH 3/8] HID: amd_sfh: Add HPD support for new AMD SOC Use HPD data from DRAM instead of reading from the C2P4 register path in latest AMD SOC. Co-developed-by: Guruvendra Punugupati Signed-off-by: Guruvendra Punugupati Signed-off-by: Basavaraj Natikar Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Jiri Kosina --- drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c | 13 +++++++++++-- drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c | 14 ++++++++++++-- drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h | 6 ++++++ 3 files changed, 29 insertions(+), 4 deletions(-) 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..034ec237659a 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 @@ -160,7 +160,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 +170,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..11c7a86ac52e 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 @@ -165,6 +165,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; From 00ea7767d71900ee4053b17966c6425411757295 Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Wed, 2 Sep 2026 19:14:31 +0530 Subject: [PATCH 4/8] HID: amd_sfh: Add device mode support for latest AMD SOC. Use device mode data from DRAM instead of reading from the C2P register in latest AMD SOC. Co-developed-by: Guruvendra Punugupati Signed-off-by: Guruvendra Punugupati Signed-off-by: Basavaraj Natikar Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Jiri Kosina --- .../amd-sfh-hid/sfh1_1/amd_sfh_interface.c | 23 +++++++++++++++++-- .../amd-sfh-hid/sfh1_1/amd_sfh_interface.h | 1 + 2 files changed, 22 insertions(+), 2 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 index 034ec237659a..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; 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 11c7a86ac52e..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 { From a06165477d3fbe6c8db1dc88d67b62b8490f2868 Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Tue, 6 Oct 2026 16:07:51 +0530 Subject: [PATCH 5/8] HID: amd_sfh: Move sysfs attributes to a separate file The sysfs attribute handling is defined in amd_sfh_pcie.c along with the PCIe transport code. More attributes will be added and the same handling is useful across SFH versions. Therefore, move the attribute definitions, the visibility callback and the group update helper into a dedicated amd_sfh_sysfs.c file. No functional change intended. Signed-off-by: Basavaraj Natikar Signed-off-by: Jiri Kosina --- drivers/hid/amd-sfh-hid/Makefile | 1 + drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 55 +------------------ drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c | 73 +++++++++++++++++++++++++ drivers/hid/amd-sfh-hid/amd_sfh_sysfs.h | 19 +++++++ 4 files changed, 95 insertions(+), 53 deletions(-) create mode 100644 drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c create mode 100644 drivers/hid/amd-sfh-hid/amd_sfh_sysfs.h 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_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c index fe4b00227eca..477e9cacfefa 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 #include #include -#include #include "amd_sfh_pcie.h" +#include "amd_sfh_sysfs.h" #include "sfh1_1/amd_sfh_init.h" #define DRIVER_NAME "pcie_mp2_amd" @@ -340,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) @@ -448,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"); 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..db1cc205d25b --- /dev/null +++ b/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c @@ -0,0 +1,73 @@ +// 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 + */ +#include +#include +#include +#include + +#include "amd_sfh_common.h" +#include "amd_sfh_sysfs.h" +#include "sfh1_1/amd_sfh_init.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); + +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, +}; + +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 + */ +#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 From 912f942b3bc69dab354dd43cb28fef860402e6be Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Tue, 6 Oct 2026 16:07:52 +0530 Subject: [PATCH 6/8] HID: amd_sfh: Add operating-mode telemetry sysfs attributes The Sensor Fusion Hub reports additional operating-mode telemetry through the SRA sensor, such as in-bag and out-of-bag detection, on-table or on-lap placement, hinge angle, lid status and the platform device mode. Expose these states read-only through sysfs so that userspace can consume them. The attributes are visible only on SFH 1.1 or greater when the SRA sensor is present. Signed-off-by: Basavaraj Natikar Signed-off-by: Jiri Kosina --- .../ABI/testing/sysfs-driver-amd-sfh | 60 ++++++++++++++++++ MAINTAINERS | 1 + drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c | 63 ++++++++++++++++++- 3 files changed, 123 insertions(+), 1 deletion(-) 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 627595e245f3..a7b04ec5bd0f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1322,6 +1322,7 @@ AMD SENSOR FUSION HUB DRIVER M: Basavaraj Natikar 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/amd_sfh_sysfs.c b/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c index db1cc205d25b..8af4df09760f 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c @@ -8,6 +8,7 @@ * Author: Basavaraj Natikar */ #include +#include #include #include #include @@ -15,6 +16,7 @@ #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) { @@ -41,19 +43,78 @@ static ssize_t hpd_store(struct device *dev, } 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 || !mp2->dev_en.is_hpd_present) + 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, }; From 6ff86122906357687735dd379c6279e3b2fa26af Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Tue, 6 Oct 2026 16:07:53 +0530 Subject: [PATCH 7/8] HID: amd_sfh: Remove unsupported motion-state field from accelerometer report The accelerometer HID report descriptor declares a trailing motion-state field (usage 0x0451), but the Sensor Fusion Hub never reports this data, so each accelerometer input report is one byte shorter than the descriptor advertises. This was previously harmless because hid-core zero-padded short reports. Since commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()") such reports are rejected instead: hid-sensor-hub 0020:1022:0001.0003: Event data for report 1 was too short (15 vs 14) As a result the accelerometer input events are dropped and screen auto-rotation stops working on AMD SFH systems. Remove the motion-state field from the accelerometer report descriptor and drop the unused in_accel_shake_detection member, so the descriptor matches the report actually provided by the hardware. Fixes: 1434f9fc0e47 ("SFH: Create HID report to Enable support of AMD sensor fusion Hub (SFH)") Reported-by: Andrej Scek Closes: https://lore.kernel.org/linux-input/CADrS85612m-Hh-G4BJmOhy-y6r3Ni3kD8_GM-2QRBeWWEEZWuA@mail.gmail.com/ Cc: stable@vger.kernel.org Signed-off-by: Basavaraj Natikar Signed-off-by: Jiri Kosina --- drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h | 2 -- .../amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h | 7 ------- 2 files changed, 9 deletions(-) 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 */ }; From 85f1bea97f1909f81577cfcf3e4db9017e7f5337 Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Tue, 6 Oct 2026 16:07:54 +0530 Subject: [PATCH 8/8] HID: amd_sfh: Use report type from request node Use report type from request node while sending feature and input reports to HID core. The cli_data report type array is never assigned and feature reports are sent as input reports. Fixes: 1434f9fc0e47 ("SFH: Create HID report to Enable support of AMD sensor fusion Hub (SFH)") Closes: https://github.com/ublue-os/bazzite/issues/5796 Cc: stable@vger.kernel.org Signed-off-by: Basavaraj Natikar Signed-off-by: Jiri Kosina --- drivers/hid/amd-sfh-hid/amd_sfh_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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");