All of lore.kernel.org
 help / color / mirror / Atom feed
From: Denis Benato <denis.benato@linux.dev>
To: "Dariusz Figzał" <dariuszfigzal@gmail.com>,
	platform-driver-x86@vger.kernel.org
Cc: corentin.chary@gmail.com, luke@ljones.dev, hansg@kernel.org,
	ilpo.jarvinen@linux.intel.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] platform/x86: asus-wmi: add keystone dongle support
Date: Thu, 28 May 2026 21:12:14 +0200	[thread overview]
Message-ID: <28b15057-3655-4211-be75-5ccbbfcf419d@linux.dev> (raw)
In-Reply-To: <20260528185752.81563-1-dariuszfigzal@gmail.com>


On 5/28/26 20:57, Dariusz Figzał wrote:
> The ASUS Keystone is a physical NFC-like dongle that slots into supported
> ASUS laptops. The EC fires WMI notify code 0xB4 on insert/remove events.
>
> Expose the current insert state via a sysfs attribute by querying WMI
> device ID 0x00120091 (DSTS). This devid does not follow the standard DSTS
> convention: PRESENCE_BIT (0x00010000) encodes the insert state rather than
> feature presence, and STATUS_BIT is never set. Presence of a keystone slot
> is detected by a successful DSTS call.
Reviewed-by: Denis Benato <denis.benato@linux.dev>
> Signed-off-by: Dariusz Figzał <dariuszfigzal@gmail.com>
> ---
>
> Changes in v2:
> - Use .is_visible and platform_attributes[] instead of
>   device_create_file/device_remove_file (Ilpo Järvinen)
>
>  drivers/platform/x86/asus-wmi.c            | 65 ++++++++++++++++++++++
>  include/linux/platform_data/x86/asus-wmi.h |  7 +++
>  2 files changed, 72 insertions(+)
>
> diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> index 80144c412b90..3c9ef826551d 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -70,6 +70,7 @@ module_param(fnlock_default, bool, 0444);
>  #define NOTIFY_KBD_TTP			0xae
>  #define NOTIFY_LID_FLIP			0xfa
>  #define NOTIFY_LID_FLIP_ROG		0xbd
> +#define NOTIFY_KEYSTONE			0xb4
>  
>  #define ASUS_WMI_FNLOCK_BIOS_DISABLED	BIT(0)
>  
> @@ -279,6 +280,8 @@ struct asus_wmi {
>  	u32 tablet_switch_dev_id;
>  	bool tablet_switch_inverted;
>  
> +	bool keystone_available;
> +
>  	enum fan_type fan_type;
>  	enum fan_type gpu_fan_type;
>  	enum fan_type mid_fan_type;
> @@ -646,6 +649,55 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
>  	return status == 0 && (retval & ASUS_WMI_DSTS_PRESENCE_BIT);
>  }
>  
> +/* Keystone *******************************************************************/
> +
> +static int keystone_check_present(struct asus_wmi *asus)
> +{
> +	u32 retval;
> +	int err;
> +
> +	asus->keystone_available = false;
> +
> +	/*
> +	 * Use a raw devstate call rather than asus_wmi_dev_is_present().
> +	 * For this devid, PRESENCE_BIT encodes current insert state, not
> +	 * feature presence, so asus_wmi_dev_is_present() would return false
> +	 * whenever the dongle is absent at boot, even on machines that have
> +	 * a keystone slot.
> +	 * -ENODEV means the firmware doesn't know this devid at all.
> +	 * retval is not examined here, only the return code matters.
> +	 */
> +	err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_KEYSTONE, &retval);
> +	if (err == -ENODEV)
> +		return 0;
> +	if (err)
> +		return err;
> +
> +	asus->keystone_available = true;
> +	return 0;
> +}
> +
> +static ssize_t keystone_show(struct device *dev,
> +			     struct device_attribute *attr, char *buf)
> +{
> +	struct asus_wmi *asus = dev_get_drvdata(dev);
> +	u32 retval;
> +	int err;
> +
> +	err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_KEYSTONE, &retval);
> +	if (err)
> +		return err;
> +
> +	return sysfs_emit(buf, "%d\n", !!(retval & ASUS_WMI_DSTS_PRESENCE_BIT));
> +}
> +
> +static DEVICE_ATTR_RO(keystone);
> +
> +static void asus_wmi_keystone_notify(struct asus_wmi *asus)
> +{
> +	sysfs_notify(&asus->platform_device->dev.kobj, NULL, "keystone");
> +}
> +
>  /* Input **********************************************************************/
>  static void asus_wmi_tablet_sw_report(struct asus_wmi *asus, bool value)
>  {
> @@ -4575,6 +4627,12 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
>  		return;
>  	}
>  
> +	if (code == NOTIFY_KEYSTONE) {
> +		if (asus->keystone_available)
> +			asus_wmi_keystone_notify(asus);
> +		return;
> +	}
> +
>  	if (code == NOTIFY_KBD_FBM || code == NOTIFY_KBD_TTP) {
>  		if (asus->fan_boost_mode_available)
>  			fan_boost_mode_switch_next(asus);
> @@ -4698,6 +4756,7 @@ static struct attribute *platform_attributes[] = {
>  	&dev_attr_lid_resume.attr,
>  	&dev_attr_als_enable.attr,
>  	&dev_attr_fan_boost_mode.attr,
> +	&dev_attr_keystone.attr,
>  #if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
>  		&dev_attr_charge_mode.attr,
>  		&dev_attr_egpu_enable.attr,
> @@ -4741,6 +4800,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
>  		devid = ASUS_WMI_DEVID_ALS_ENABLE;
>  	else if (attr == &dev_attr_fan_boost_mode.attr)
>  		ok = asus->fan_boost_mode_available;
> +	else if (attr == &dev_attr_keystone.attr)
> +		ok = asus->keystone_available;
>  
>  #if IS_ENABLED(CONFIG_ASUS_WMI_DEPRECATED_ATTRS)
>  	if (attr == &dev_attr_charge_mode.attr)
> @@ -5081,6 +5142,10 @@ static int asus_wmi_add(struct platform_device *pdev)
>  	if (err)
>  		goto fail_platform_profile_setup;
>  
> +	err = keystone_check_present(asus);
> +	if (err)
> +		dev_warn(&pdev->dev, "Failed to check Keystone presence: %d\n", err);
> +
>  	err = asus_wmi_sysfs_init(asus->platform_device);
>  	if (err)
>  		goto fail_sysfs;
> diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
> index 554f41b827e1..c29962d5baac 100644
> --- a/include/linux/platform_data/x86/asus-wmi.h
> +++ b/include/linux/platform_data/x86/asus-wmi.h
> @@ -147,6 +147,13 @@
>  #define ASUS_WMI_DEVID_GPU_MUX		0x00090016
>  #define ASUS_WMI_DEVID_GPU_MUX_VIVO	0x00090026
>  
> +/* Keystone dongle insert/remove state.
> + * PRESENCE_BIT (0x00010000) encodes insert state:
> + * 0x00010000 = inserted, 0x00000000 = absent. STATUS_BIT is never set.
> + * 0xFFFFFFFE means no keystone slot on this machine.
> + */
> +#define ASUS_WMI_DEVID_KEYSTONE		0x00120091
> +
>  /* TUF laptop RGB modes/colours */
>  #define ASUS_WMI_DEVID_TUF_RGB_MODE	0x00100056
>  #define ASUS_WMI_DEVID_TUF_RGB_MODE2	0x0010005A

      reply	other threads:[~2026-05-28 19:13 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-28 18:57 [PATCH v2] platform/x86: asus-wmi: add keystone dongle support Dariusz Figzał
2026-05-28 19:12 ` Denis Benato [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=28b15057-3655-4211-be75-5ccbbfcf419d@linux.dev \
    --to=denis.benato@linux.dev \
    --cc=corentin.chary@gmail.com \
    --cc=dariuszfigzal@gmail.com \
    --cc=hansg@kernel.org \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luke@ljones.dev \
    --cc=platform-driver-x86@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.