On Tue, Mar 4, 2025, at 9:33 PM, Nitin Joshi wrote: > Some Thinkpad products support Human Presence Detection (HPD) features. > Add new sysfs entry so that userspace can determine if feature is > supported or not. > > Reviewed-by: Mark Pearson <mpearson-lenovo@xxxxxxxxx> Just in case we're breaking protocol - I have reviewed this off mailing list with Nitin and gave it the thumbs up. The tag is correct. Mark > Signed-off-by: Nitin Joshi <nitjoshi@xxxxxxxxx> > --- > .../admin-guide/laptops/thinkpad-acpi.rst | 20 +++++ > drivers/platform/x86/thinkpad_acpi.c | 79 +++++++++++++++++++ > 2 files changed, 99 insertions(+) > > diff --git a/Documentation/admin-guide/laptops/thinkpad-acpi.rst > b/Documentation/admin-guide/laptops/thinkpad-acpi.rst > index 4ab0fef7d440..02e6c4306f90 100644 > --- a/Documentation/admin-guide/laptops/thinkpad-acpi.rst > +++ b/Documentation/admin-guide/laptops/thinkpad-acpi.rst > @@ -1576,6 +1576,26 @@ percentage level, above which charging will stop. > The exact semantics of the attributes may be found in > Documentation/ABI/testing/sysfs-class-power. > > +User Presence Sensing Detection > +------ > + > +sysfs: hpd_bios_enabled > + > +Some Thinkpad products support Human Presence Detection (HPD) features. > +Added new sysfs entry so that userspace can determine if feature related to > +HPD should be enabled or disabled. > + > +The available commands are:: > + > + cat /sys/devices/platform/thinkpad_acpi/hpd_bios_enabled > + > +BIOS status is mentioned as below: > +- 0 = Disable > +- 1 = Enable > + > +The property is read-only. If the platform doesn't have support the sysfs > +class is not created. > + > Multiple Commands, Module Parameters > ------------------------------------ > > diff --git a/drivers/platform/x86/thinkpad_acpi.c > b/drivers/platform/x86/thinkpad_acpi.c > index 72a10ed2017c..daf31b2a4c73 100644 > --- a/drivers/platform/x86/thinkpad_acpi.c > +++ b/drivers/platform/x86/thinkpad_acpi.c > @@ -11039,6 +11039,80 @@ static const struct attribute_group > auxmac_attr_group = { > .attrs = auxmac_attributes, > }; > > +/************************************************************************* > + * CHPD subdriver, for the Lenovo Human Presence Detection feature. > + */ > +#define CHPD_GET_SENSOR_STATUS 0x00200000 > +#define CHPD_GET_BIOS_UI_STATUS 0x00100000 > + > +static bool has_user_presence_sensing; > +static int hpd_bios_status; > +static int chpd_command(int command, int *output) > +{ > + acpi_handle chpd_handle; > + > + if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "CHPD", &chpd_handle))) { > + /* Platform doesn't support CHPD */ > + return -ENODEV; > + } > + > + if (!acpi_evalf(chpd_handle, output, NULL, "dd", command)) > + return -EIO; > + > + return 0; > +} > + > +/* sysfs hpd bios status */ > +static ssize_t hpd_bios_enabled_show(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + return sysfs_emit(buf, "%d\n", hpd_bios_status); > +} > +static DEVICE_ATTR_RO(hpd_bios_enabled); > + > +static struct attribute *chpd_attributes[] = { > + &dev_attr_hpd_bios_enabled.attr, > + NULL > +}; > + > +static umode_t chpd_attr_is_visible(struct kobject *kobj, > + struct attribute *attr, int n) > +{ > + return has_user_presence_sensing ? attr->mode : 0; > +} > + > +static const struct attribute_group chpd_attr_group = { > + .is_visible = chpd_attr_is_visible, > + .attrs = chpd_attributes, > +}; > + > +static int tpacpi_chpd_init(struct ibm_init_struct *iibm) > +{ > + int err, output; > + > + err = chpd_command(CHPD_GET_SENSOR_STATUS, &output); > + if (err) > + return err; > + > + if (output == 1) > + return -ENODEV; > + > + has_user_presence_sensing = true; > + /* Get User Presence Sensing BIOS status */ > + err = chpd_command(CHPD_GET_BIOS_UI_STATUS, &output); > + if (err) > + return err; > + > + hpd_bios_status = (output >> 1) & BIT(0); > + > + return err; > +} > + > +static struct ibm_struct chpd_driver_data = { > + .name = "chpd", > +}; > + > /* --------------------------------------------------------------------- */ > > static struct attribute *tpacpi_driver_attributes[] = { > @@ -11098,6 +11172,7 @@ static const struct attribute_group *tpacpi_groups[] = { > &kbdlang_attr_group, > &dprc_attr_group, > &auxmac_attr_group, > + &chpd_attr_group, > NULL, > }; > > @@ -11694,6 +11769,10 @@ static struct ibm_init_struct ibms_init[] > __initdata = { > .init = auxmac_init, > .data = &auxmac_data, > }, > + { > + .init = tpacpi_chpd_init, > + .data = &chpd_driver_data, > + }, > }; > > static int __init set_ibm_param(const char *val, const struct kernel_param *kp) > -- > 2.43.0