* [PATCH] amd-sfh-hid: tablet mode switch and asus quirk
@ 2026-04-27 6:22 Helge Bahmann
2026-05-12 16:06 ` Jiri Kosina
0 siblings, 1 reply; 4+ messages in thread
From: Helge Bahmann @ 2026-04-27 6:22 UTC (permalink / raw)
To: Nehal Bakulchandra Shah, Sandeep Singh, Basavaraj Natikar, jikos,
bentiss
Cc: linux-hid, linux-input
Add an input driver that interprets the "operation mode" sensor offered
by the amd sfh on some laptop models.
Add a quirk to make the driver work again with the Asus VivoBook
VivoBook (turn off the "disable interrupts" flag).
Expose the intr_disable flag as a module parameter in case it turns out
to be needed on further laptop models.
Signed-off-by: Helge Bahmann <hcb@chaoticmind.net>
---
drivers/hid/amd-sfh-hid/amd_sfh_client.c | 25 ++++++++------
drivers/hid/amd-sfh-hid/amd_sfh_hid.c | 43 ++++++++++++++++++++++++
drivers/hid/amd-sfh-hid/amd_sfh_hid.h | 6 ++++
drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 9 +++++
drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 3 ++
5 files changed, 75 insertions(+), 11 deletions(-)
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
index 7017bfa59093..a24757c5a203 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
@@ -128,10 +128,16 @@ void amd_sfh_work_buffer(struct work_struct *work)
guard(mutex)(&mp2->lock);
for (i = 0; i < cli_data->num_hid_devices; i++) {
if (cli_data->sensor_sts[i] == SENSOR_ENABLED) {
- report_size = mp2->mp2_ops->get_in_rep(i, cli_data->sensor_idx[i],
- cli_data->report_id[i], in_data);
- hid_input_report(cli_data->hid_sensor_hubs[i], HID_INPUT_REPORT,
- in_data->input_report[i], report_size, 0);
+ if (cli_data->hid_sensor_hubs[i]) {
+ report_size = mp2->mp2_ops->get_in_rep(i, cli_data->sensor_idx[i],
+ cli_data->report_id[i],
+ in_data);
+ hid_input_report(cli_data->hid_sensor_hubs[i], HID_INPUT_REPORT,
+ in_data->input_report[i], report_size, 0);
+ } else if (cli_data->sensor_idx[i] == op_idx &&
+ cli_data->modeswitch_input) {
+ amdtp_modeswitch_report(i, cli_data->modeswitch_input, in_data);
+ }
}
}
schedule_delayed_work(&cli_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
@@ -327,15 +333,12 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
for (i = 0; i < cl_data->num_hid_devices; i++) {
cl_data->cur_hid_dev = i;
- if (cl_data->sensor_idx[i] == op_idx) {
- 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]);
- continue;
- }
if (cl_data->sensor_sts[i] == SENSOR_ENABLED) {
- rc = amdtp_hid_probe(i, cl_data);
+ if (cl_data->sensor_idx[i] != op_idx)
+ rc = amdtp_hid_probe(i, cl_data);
+ else
+ rc = amdtp_modeswitch_probe(i, cl_data);
if (rc)
goto cleanup;
} else {
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
index 81f3024b7b1b..44008c02b63c 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
@@ -181,4 +181,47 @@ void amdtp_hid_remove(struct amdtp_cl_data *cli_data)
cli_data->hid_sensor_hubs[i] = NULL;
}
}
+
+ /* note: cli_data->modeswitch_input implicitly cleaned by devres */
+}
+
+int amdtp_modeswitch_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 input_dev *input;
+ int rc;
+
+ input = devm_input_allocate_device(dev);
+ if (IS_ERR(input))
+ return PTR_ERR(input);
+
+ input->name = "AMD SFH tablet mode switch sensor";
+ input->id.bustype = BUS_PCI;
+
+ input_set_capability(input, EV_SW, SW_TABLET_MODE);
+
+ rc = input_register_device(input);
+ if (rc)
+ goto cleanup;
+
+ cli_data->modeswitch_input = input;
+
+ return 0;
+
+cleanup:
+ return rc;
+}
+
+void amdtp_modeswitch_report(u32 index, struct input_dev *input, struct amd_input_data *in_data)
+{
+ u32 *sensor_virt_addr = in_data->sensor_virt_addr[index];
+ u32 value = sensor_virt_addr[0];
+
+ if (value == AMD_SFH_OP_IDX_MODE_TABLET)
+ input_report_switch(input, SW_TABLET_MODE, 1);
+ else
+ input_report_switch(input, SW_TABLET_MODE, 0);
+
+ input_sync(input);
}
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h
index 7452b0302953..20aff7b75fbd 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h
@@ -11,6 +11,8 @@
#ifndef AMDSFH_HID_H
#define AMDSFH_HID_H
+#include <linux/input.h>
+
#define MAX_HID_DEVICES 7
#define AMD_SFH_HID_VENDOR 0x1022
#define AMD_SFH_HID_PRODUCT 0x0001
@@ -50,6 +52,7 @@ struct amdtp_cl_data {
u8 sensor_idx[MAX_HID_DEVICES];
u8 *feature_report[MAX_HID_DEVICES];
u8 request_done[MAX_HID_DEVICES];
+ struct input_dev *modeswitch_input;
struct amd_input_data *in_data;
struct delayed_work work;
struct delayed_work work_buffer;
@@ -78,4 +81,7 @@ void amdtp_hid_remove(struct amdtp_cl_data *cli_data);
int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type);
void amd_sfh_set_report(struct hid_device *hid, int report_id, int report_type);
void amdtp_hid_wakeup(struct hid_device *hid);
+int amdtp_modeswitch_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data);
+void amdtp_modeswitch_report(u32 index, struct input_dev *input, struct amd_input_data *in_data);
+
#endif
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
index 1d9f955573aa..cd9cff75f114 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
@@ -39,6 +39,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)
{
@@ -317,6 +319,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"),
+ }
+ },
{}
};
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
index 2eb61f4e8434..5e968894ebe4 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
@@ -83,6 +83,9 @@ enum sensor_idx {
als_idx = 19
};
+#define AMD_SFH_OP_IDX_MODE_LAPTOP 1
+#define AMD_SFH_OP_IDX_MODE_TABLET 3
+
enum mem_use_type {
USE_DRAM,
USE_C2P_REG,
--
2.47.3
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] amd-sfh-hid: tablet mode switch and asus quirk
2026-04-27 6:22 [PATCH] amd-sfh-hid: tablet mode switch and asus quirk Helge Bahmann
@ 2026-05-12 16:06 ` Jiri Kosina
2026-05-12 17:09 ` Basavaraj Natikar
2026-05-14 7:59 ` Helge Bahmann
0 siblings, 2 replies; 4+ messages in thread
From: Jiri Kosina @ 2026-05-12 16:06 UTC (permalink / raw)
To: Helge Bahmann
Cc: Nehal Bakulchandra Shah, Sandeep Singh, Basavaraj Natikar,
bentiss, linux-hid, linux-input
On Mon, 27 Apr 2026, Helge Bahmann wrote:
> Add an input driver that interprets the "operation mode" sensor offered
> by the amd sfh on some laptop models.
>
> Add a quirk to make the driver work again with the Asus VivoBook
> VivoBook (turn off the "disable interrupts" flag).
>
> Expose the intr_disable flag as a module parameter in case it turns out
> to be needed on further laptop models.
>
> Signed-off-by: Helge Bahmann <hcb@chaoticmind.net>
Basavaraj, can you please review this one?
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] amd-sfh-hid: tablet mode switch and asus quirk
2026-05-12 16:06 ` Jiri Kosina
@ 2026-05-12 17:09 ` Basavaraj Natikar
2026-05-14 7:59 ` Helge Bahmann
1 sibling, 0 replies; 4+ messages in thread
From: Basavaraj Natikar @ 2026-05-12 17:09 UTC (permalink / raw)
To: Jiri Kosina, Helge Bahmann
Cc: Nehal Bakulchandra Shah, Sandeep Singh, Basavaraj Natikar,
bentiss, linux-hid, linux-input
On 5/12/2026 9:36 PM, Jiri Kosina wrote:
> On Mon, 27 Apr 2026, Helge Bahmann wrote:
>
>> Add an input driver that interprets the "operation mode" sensor offered
>> by the amd sfh on some laptop models.
>>
>> Add a quirk to make the driver work again with the Asus VivoBook
>> VivoBook (turn off the "disable interrupts" flag).
>>
>> Expose the intr_disable flag as a module parameter in case it turns out
>> to be needed on further laptop models.
>>
>> Signed-off-by: Helge Bahmann <hcb@chaoticmind.net>
> Basavaraj, can you please review this one?
Hi Jiri,
Sure, will review. The patch has some changes that deviate from how
other sensors are exposed in this driver, so it will take some time to
review properly. I'll respond with detailed feedback once done.
Thanks,
--
Basavaraj
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] amd-sfh-hid: tablet mode switch and asus quirk
2026-05-12 16:06 ` Jiri Kosina
2026-05-12 17:09 ` Basavaraj Natikar
@ 2026-05-14 7:59 ` Helge Bahmann
1 sibling, 0 replies; 4+ messages in thread
From: Helge Bahmann @ 2026-05-14 7:59 UTC (permalink / raw)
To: Jiri Kosina, linux-input
Cc: Nehal Bakulchandra Shah, Sandeep Singh, Basavaraj Natikar,
bentiss
On Tue, 12 May 2026, Jiri Kosina wrote:
> On Mon, 27 Apr 2026, Helge Bahmann wrote:
>
> > Add an input driver that interprets the "operation mode" sensor offered
> > by the amd sfh on some laptop models.
> >
> > Add a quirk to make the driver work again with the Asus VivoBook
> > VivoBook (turn off the "disable interrupts" flag).
> >
> > Expose the intr_disable flag as a module parameter in case it turns out
> > to be needed on further laptop models.
> >
> > Signed-off-by: Helge Bahmann <hcb@chaoticmind.net>
>
> Basavaraj, can you please review this one?
Some additional context, maybe helpful for review:
1. The numbers and behavior were extracted from the ACPI tables
(WMI driver of sorts) of the notebook; I don't have access to any
official AMD / ASUS docs or similar.
2. I have an alternate version of this change that is more indirect:
- create a HID driver providing an "abstract table mode" message
- have an input driver attaching to this newly defined HID driver
While that is keeping "more in line" with the current driver
architecture, I am not sure this indirection really helps. Particularly,
there is no "canonical" HID tablet mode switch message defined,
so it all remains completely bespoke. I am happy to change it if
you prefer, but would need your input.
3. Since this is based on Asus VivoBook and its ACPI tables,
there is a possibility that this "op sensor / tablet mode" behavior
is not as universal as I surmise. A point could be made to make this
entire behavior model-dependent (with a mod param to override
/ activate for other models). Happy to take input / advice.
Thanks for your work!
Helge
>
> Thanks,
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-05-14 8:39 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-27 6:22 [PATCH] amd-sfh-hid: tablet mode switch and asus quirk Helge Bahmann
2026-05-12 16:06 ` Jiri Kosina
2026-05-12 17:09 ` Basavaraj Natikar
2026-05-14 7:59 ` Helge Bahmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox