[PATCH v2 4/5] HID: amd_sfh: Register tablet-mode auxiliary device
Basavaraj Natikar <[email protected]> Mon, 3 Aug 2026 20:28:00 +0530
| Newsgroups | org.kernel.vger.linux-input |
|---|---|
| Message-ID | <[email protected]> |
Register an auxiliary device when the operating-mode sensor is present, so a dedicated input driver can bind to it and report the device posture. This keeps the input handling out of the sensor transport driver. Signed-off-by: Basavaraj Natikar <[email protected]> --- drivers/hid/amd-sfh-hid/Kconfig | 1 + drivers/hid/amd-sfh-hid/amd_sfh_common.h | 2 + drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 48 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/drivers/hid/amd-sfh-hid/Kconfig b/drivers/hid/amd-sfh-hid/Kconfig index 3291786a5ee6..d86d83ffebd7 100644 --- a/drivers/hid/amd-sfh-hid/Kconfig +++ b/drivers/hid/amd-sfh-hid/Kconfig @@ -6,6 +6,7 @@ menu "AMD SFH HID Support" config AMD_SFH_HID tristate "AMD Sensor Fusion Hub" depends on X86 + select AUXILIARY_BUS help If you say yes to this option, support will be included for the AMD Sensor Fusion Hub. diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_common.h b/drivers/hid/amd-sfh-hid/amd_sfh_common.h index 0ca3254151ac..f8c6b7fc34fb 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_common.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_common.h @@ -10,6 +10,7 @@ #ifndef AMD_SFH_COMMON_H #define AMD_SFH_COMMON_H +#include <linux/auxiliary_bus.h> #include <linux/mutex.h> #include <linux/pci.h> #include "amd_sfh_hid.h" @@ -70,6 +71,7 @@ struct amd_mp2_dev { u8 init_done; u8 rver; u8 mp2_ver; + struct auxiliary_device *tm_auxdev; }; struct amd_mp2_ops { diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c index 4b1cd260410d..f6f016c8c678 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c @@ -8,11 +8,13 @@ * Basavaraj Natikar <[email protected]> */ +#include <linux/auxiliary_bus.h> #include <linux/bitops.h> #include <linux/delay.h> #include <linux/devm-helpers.h> #include <linux/dma-mapping.h> #include <linux/dmi.h> +#include <linux/idr.h> #include <linux/interrupt.h> #include <linux/io-64-nonatomic-lo-hi.h> #include <linux/iopoll.h> @@ -389,6 +391,50 @@ static const struct attribute_group *amd_sfh_groups[] = { NULL, }; +static DEFINE_IDA(sfh_tm_ida); + +static void amd_sfh_tm_cleanup(void *data) +{ + struct amd_mp2_dev *mp2 = data; + int id = mp2->tm_auxdev->id; + + auxiliary_device_destroy(mp2->tm_auxdev); + ida_free(&sfh_tm_ida, id); + mp2->tm_auxdev = NULL; +} + +static void amd_sfh_maybe_register_tm(struct amd_mp2_dev *mp2) +{ + struct auxiliary_device *adev; + bool present; + int id; + + if (mp2->tm_auxdev) + return; + + present = mp2->sfh1_1_ops ? mp2->dev_en.is_sra_present + : (mp2->mp2_ver == MP2_VER_V2 && + amd_sfh_op_idx_enabled(mp2)); + if (!present) + return; + + id = ida_alloc(&sfh_tm_ida, GFP_KERNEL); + if (id < 0) + return; + + adev = auxiliary_device_create(&mp2->pdev->dev, KBUILD_MODNAME, + "tabletmode", NULL, id); + if (!adev) { + ida_free(&sfh_tm_ida, id); + dev_warn(&mp2->pdev->dev, "tabletmode auxdev create failed\n"); + return; + } + + mp2->tm_auxdev = adev; + if (devm_add_action_or_reset(&mp2->pdev->dev, amd_sfh_tm_cleanup, mp2)) + dev_warn(&mp2->pdev->dev, "tabletmode cleanup registration failed\n"); +} + static void sfh1_1_init_work(struct work_struct *work) { struct amd_mp2_dev *mp2 = container_of(work, struct amd_mp2_dev, work); @@ -405,6 +451,7 @@ static void sfh1_1_init_work(struct work_struct *work) if (rc) dev_warn(&mp2->pdev->dev, "failed to update sysfs group\n"); + amd_sfh_maybe_register_tm(mp2); } static void sfh_init_work(struct work_struct *work) @@ -424,6 +471,7 @@ static void sfh_init_work(struct work_struct *work) sfh_set_emp2(mp2); amd_sfh_clear_intr(mp2); mp2->init_done = 1; + amd_sfh_maybe_register_tm(mp2); } static void amd_sfh_remove(struct pci_dev *pdev) -- 2.34.1