[PATCH v3 4/5] HID: amd_sfh: Register tablet-mode auxiliary device
Basavaraj Natikar <[email protected]> Mon, 3 Aug 2026 23:22:29 +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 | 50 ++++++++++++++++++++++++ 3 files changed, 53 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..1405167aa369 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,51 @@ static const struct attribute_group *amd_sfh_groups[] = { NULL, }; +static DEFINE_IDA(sfh_tm_ida); + +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; +} + +static void amd_sfh_unregister_tm(struct amd_mp2_dev *mp2) +{ + int id; + + if (!mp2->tm_auxdev) + return; + + id = mp2->tm_auxdev->id; + auxiliary_device_destroy(mp2->tm_auxdev); + mp2->tm_auxdev = NULL; + ida_free(&sfh_tm_ida, id); +} + 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 +452,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 +472,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) @@ -431,6 +480,7 @@ static void amd_sfh_remove(struct pci_dev *pdev) struct amd_mp2_dev *mp2 = pci_get_drvdata(pdev); flush_work(&mp2->work); + amd_sfh_unregister_tm(mp2); if (mp2->init_done) mp2->mp2_ops->remove(mp2); } -- 2.34.1