From nobody Tue Dec 2 02:20:00 2025 Received: from relay12.grserver.gr (relay12.grserver.gr [88.99.38.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B72E3081B7; Wed, 19 Nov 2025 17:45:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=88.99.38.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574326; cv=none; b=aQ9a/42aZQxOGqShB5USzdWjiDg/wfuiQEeJoNm5qTPX4KHyjWpkVAWSkF31p+GEtOEHkUdfpTEvK710fdBUVF9LMdcAF6bS4CfNri/0QWaXGImNw6/i4NJLkkcmUDMd+UJcWzuyTwNlqHqCcpvxdximrDxleZcZo9rbwzQILvA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574326; c=relaxed/simple; bh=Ay+Bk5333/wnOJCMASY5azKcNmPliNf0Hf4I9bvByXs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VeENUXiumB0tNgUIkVbeLrlN9XY2cXFJurt7gA9YNXbjGUaLIkr1/Fysae15Yq6Fgiz1qt2yxzSb7kVRDV2qmF9MpTSEGXMuKI1tG3sBvzYzUzp1D7usE52dS+qyWSI1CYBdLN2wMlskj+oTVDX8fHUP4AhdgvAQtpCtKBYmUvU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=Wg5RrOI+; arc=none smtp.client-ip=88.99.38.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="Wg5RrOI+" Received: from relay12 (localhost [127.0.0.1]) by relay12.grserver.gr (Proxmox) with ESMTP id 0E4D2BDCB3; Wed, 19 Nov 2025 19:45:20 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay12.grserver.gr (Proxmox) with ESMTPS id EFB4ABDAB8; Wed, 19 Nov 2025 19:45:18 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 03620200E79; Wed, 19 Nov 2025 19:45:15 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1763574318; bh=rvDibI5s4IqA3qafuQ0RH/WEPKGEm+5Qz63JfgXIdyk=; h=From:To:Subject; b=Wg5RrOI+ZYGm7U9jwp5AmirTloNvpS6d1kCjFcy4VnLUzEI2RdDyYG1CgTYcSB3xS xTSjSRwU8HbWTDDaVmaw1xjPUTURfwy4OJqqN4cY3F2vKZ21SIQfijBWFPWo88/P5B HbufnqfbVNjkUxVvMnnp/QjWfZHBFQPfmSY+OE7p7+sKqJSWjB9BwxjoS8z6rO6Xmk mkwPm5Dv52KxtSi5Oc3FiCGe34mdVVWZkeTbNsu9o1KqomP2FOxqOKMxhrs3OIPiMQ zZjPvbH/qM7wvMa+SN308FlYmYjtGXhrtCdUKTjrNus+9+VyUxs5fKZiI+LB7a6T3E smJNKmfogOUuA== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:8d8a:5967:d692:ea4e) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: platform-driver-x86@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Hans de Goede , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Derek John Clark , =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?= , Jean Delvare , Guenter Roeck , Antheas Kapenekakis , Armin Wolf Subject: [PATCH v6 1/6] platform/x86: ayaneo-ec: Add Ayaneo Embedded Controller platform driver Date: Wed, 19 Nov 2025 18:45:00 +0100 Message-ID: <20251119174505.597218-2-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251119174505.597218-1-lkml@antheas.dev> References: <20251119174505.597218-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176357431750.2086347.18128690878226637540@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" Recent Ayaneo devices feature an ACPI mapped Embedded Controller (EC) with standard addresses across models that provides access to fan speed, fan control, battery charge limits, and controller power controls. Introduce a new driver stub that will handle these driver features. Reviewed-by: Armin Wolf Signed-off-by: Antheas Kapenekakis --- MAINTAINERS | 6 +++ drivers/platform/x86/Kconfig | 10 ++++ drivers/platform/x86/Makefile | 3 ++ drivers/platform/x86/ayaneo-ec.c | 90 ++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 drivers/platform/x86/ayaneo-ec.c diff --git a/MAINTAINERS b/MAINTAINERS index e64b94e6b5a9..3912f8afe5f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4193,6 +4193,12 @@ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/pwm/adi,axi-pwmgen.yaml F: drivers/pwm/pwm-axi-pwmgen.c =20 +AYANEO PLATFORM EC DRIVER +M: Antheas Kapenekakis +L: platform-driver-x86@vger.kernel.org +S: Maintained +F: drivers/platform/x86/ayaneo-ec.c + AZ6007 DVB DRIVER M: Mauro Carvalho Chehab L: linux-media@vger.kernel.org diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index c122016d82f1..8ca95536f8d9 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -316,6 +316,16 @@ config ASUS_TF103C_DOCK If you have an Asus TF103C tablet say Y or M here, for a generic x86 distro config say M here. =20 +config AYANEO_EC + tristate "Ayaneo EC platform control" + depends on DMI + help + Enables support for the platform EC of Ayaneo devices. This + includes fan control, fan speed, charge limit, magic + module detection, and controller power control. + + If you have an Ayaneo device, say Y or M here. + config MERAKI_MX100 tristate "Cisco Meraki MX100 Platform Driver" depends on GPIOLIB diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index c7db2a88c11a..274a685eb92d 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -39,6 +39,9 @@ obj-$(CONFIG_ASUS_TF103C_DOCK) +=3D asus-tf103c-dock.o obj-$(CONFIG_EEEPC_LAPTOP) +=3D eeepc-laptop.o obj-$(CONFIG_EEEPC_WMI) +=3D eeepc-wmi.o =20 +# Ayaneo +obj-$(CONFIG_AYANEO_EC) +=3D ayaneo-ec.o + # Cisco/Meraki obj-$(CONFIG_MERAKI_MX100) +=3D meraki-mx100.o =20 diff --git a/drivers/platform/x86/ayaneo-ec.c b/drivers/platform/x86/ayaneo= -ec.c new file mode 100644 index 000000000000..2fe66c8a89f4 --- /dev/null +++ b/drivers/platform/x86/ayaneo-ec.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Platform driver for the Embedded Controller (EC) of Ayaneo devices. Han= dles + * hwmon (fan speed, fan control), battery charge limits, and magic module + * control (connected modules, controller disconnection). + * + * Copyright (C) 2025 Antheas Kapenekakis + */ + +#include +#include +#include +#include +#include +#include + +struct ayaneo_ec_quirk { +}; + +struct ayaneo_ec_platform_data { + struct platform_device *pdev; + struct ayaneo_ec_quirk *quirks; +}; + +static const struct ayaneo_ec_quirk quirk_ayaneo3 =3D { +}; + +static const struct dmi_system_id dmi_table[] =3D { + { + .matches =3D { + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "AYANEO 3"), + }, + .driver_data =3D (void *)&quirk_ayaneo3, + }, + {}, +}; + +static int ayaneo_ec_probe(struct platform_device *pdev) +{ + const struct dmi_system_id *dmi_entry; + struct ayaneo_ec_platform_data *data; + + dmi_entry =3D dmi_first_match(dmi_table); + if (!dmi_entry) + return -ENODEV; + + data =3D devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->pdev =3D pdev; + data->quirks =3D dmi_entry->driver_data; + platform_set_drvdata(pdev, data); + + return 0; +} + +static struct platform_driver ayaneo_platform_driver =3D { + .driver =3D { + .name =3D "ayaneo-ec", + }, + .probe =3D ayaneo_ec_probe, +}; + +static struct platform_device *ayaneo_platform_device; + +static int __init ayaneo_ec_init(void) +{ + ayaneo_platform_device =3D + platform_create_bundle(&ayaneo_platform_driver, + ayaneo_ec_probe, NULL, 0, NULL, 0); + + return PTR_ERR_OR_ZERO(ayaneo_platform_device); +} + +static void __exit ayaneo_ec_exit(void) +{ + platform_device_unregister(ayaneo_platform_device); + platform_driver_unregister(&ayaneo_platform_driver); +} + +MODULE_DEVICE_TABLE(dmi, dmi_table); + +module_init(ayaneo_ec_init); +module_exit(ayaneo_ec_exit); + +MODULE_AUTHOR("Antheas Kapenekakis "); +MODULE_DESCRIPTION("Ayaneo Embedded Controller (EC) platform features"); +MODULE_LICENSE("GPL"); --=20 2.52.0 From nobody Tue Dec 2 02:20:00 2025 Received: from relay13.grserver.gr (relay13.grserver.gr [178.156.171.147]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D6F998821; Wed, 19 Nov 2025 17:45:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.156.171.147 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574334; cv=none; b=rx1S3jVZ48cP4VYL317jo881aittGglQlmtle6o0UgdtRuCEen2GdXrv7Fltlvnlsr5uDk+TmqRrczcDlz5jXngHahekGLbsQPnnWZ+Q/b9f1BfZjgKqWxG/ZsMITGwt30B8oasZgv7TZhmq3RJkLwgxRvVowH2PPJvCh8foDxQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574334; c=relaxed/simple; bh=dg2PWnJWHw2TMx+htIzckKTnrAvFPsfwrO0MKQSihr4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fK0wi8T3jxO4Hf5Y9CFy3W4UpFSH2NQE3KEN1Cm7yYljXjqc94Qwfdo8z7cplVNaNXNPSwieYjETFhy8tD5+C6WVuC11yYVgkj0Nridaor7XEDGTKoylpEr/SmcGRYZwxaunJeQjdpvUZLF7kuFEGvyHAGDos4m/p28gem5PePo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=SI1RdoVs; arc=none smtp.client-ip=178.156.171.147 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="SI1RdoVs" Received: from relay13 (localhost [127.0.0.1]) by relay13.grserver.gr (Proxmox) with ESMTP id C93015E56A; Wed, 19 Nov 2025 19:45:22 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay13.grserver.gr (Proxmox) with ESMTPS id CDC085E57D; Wed, 19 Nov 2025 19:45:21 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id CF7CE200E7D; Wed, 19 Nov 2025 19:45:18 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1763574320; bh=7Z2g4VwJyUUCI2hqKgqo/X5lORYPMvx7C5VUT20FoK8=; h=From:To:Subject; b=SI1RdoVs+9DwKEg4w/nVTzj7MVGCKNT9u53QKI0aDnDZjd2q2PriyvGyGar53NKbE nAvYyb3fGaW6VvQnTblmGIR97mx+Z0fvelGcnnOn/Lo4j2J/KsaGu9LanbnY8kjqab ZEjNP50/ES3euHBu58RWTT1/b9CilIICqQCYTJa4sDJE0f53s770uabw36ScWUACGF 6qlmZCaJloKZ70HdOd8Fbcv5hfZT2bX3areHRLVQYSzgF58N4BRvDCrI9fdbSMQO0t Ao8j+ydNb2is3UqaWi3Zm4AtQj/u50Td/cW6q57nM4su/uy4v6z3IUFDDIKOOSGyDL Y05R2Ggw9JS6A== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:8d8a:5967:d692:ea4e) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: platform-driver-x86@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Hans de Goede , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Derek John Clark , =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?= , Jean Delvare , Guenter Roeck , Antheas Kapenekakis , Armin-Wolf Subject: [PATCH v6 2/6] platform/x86: ayaneo-ec: Add hwmon support Date: Wed, 19 Nov 2025 18:45:01 +0100 Message-ID: <20251119174505.597218-3-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251119174505.597218-1-lkml@antheas.dev> References: <20251119174505.597218-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176357431973.2086411.9254263283028849340@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" Add hwmon single fan sensor reads and control for Ayaneo devices. The register and method of access is the same for all devices. Reviewed-by: Armin-Wolf Signed-off-by: Antheas Kapenekakis --- drivers/platform/x86/Kconfig | 2 + drivers/platform/x86/ayaneo-ec.c | 136 +++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 8ca95536f8d9..e19850bd2609 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -319,6 +319,8 @@ config ASUS_TF103C_DOCK config AYANEO_EC tristate "Ayaneo EC platform control" depends on DMI + depends on ACPI_EC + depends on HWMON help Enables support for the platform EC of Ayaneo devices. This includes fan control, fan speed, charge limit, magic diff --git a/drivers/platform/x86/ayaneo-ec.c b/drivers/platform/x86/ayaneo= -ec.c index 2fe66c8a89f4..86d4eed49f42 100644 --- a/drivers/platform/x86/ayaneo-ec.c +++ b/drivers/platform/x86/ayaneo-ec.c @@ -7,14 +7,24 @@ * Copyright (C) 2025 Antheas Kapenekakis */ =20 +#include #include #include +#include #include #include #include #include =20 +#define AYANEO_PWM_ENABLE_REG 0x4A +#define AYANEO_PWM_REG 0x4B +#define AYANEO_PWM_MODE_AUTO 0x00 +#define AYANEO_PWM_MODE_MANUAL 0x01 + +#define AYANEO_FAN_REG 0x76 + struct ayaneo_ec_quirk { + bool has_fan_control; }; =20 struct ayaneo_ec_platform_data { @@ -23,6 +33,7 @@ struct ayaneo_ec_platform_data { }; =20 static const struct ayaneo_ec_quirk quirk_ayaneo3 =3D { + .has_fan_control =3D true, }; =20 static const struct dmi_system_id dmi_table[] =3D { @@ -36,10 +47,128 @@ static const struct dmi_system_id dmi_table[] =3D { {}, }; =20 +/* Callbacks for hwmon interface */ +static umode_t ayaneo_ec_hwmon_is_visible(const void *drvdata, + enum hwmon_sensor_types type, u32 attr, + int channel) +{ + switch (type) { + case hwmon_fan: + return 0444; + case hwmon_pwm: + return 0644; + default: + return 0; + } +} + +static int ayaneo_ec_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + u8 tmp; + int ret; + + switch (type) { + case hwmon_fan: + switch (attr) { + case hwmon_fan_input: + ret =3D ec_read(AYANEO_FAN_REG, &tmp); + if (ret) + return ret; + *val =3D tmp << 8; + ret =3D ec_read(AYANEO_FAN_REG + 1, &tmp); + if (ret) + return ret; + *val |=3D tmp; + return 0; + default: + break; + } + break; + case hwmon_pwm: + switch (attr) { + case hwmon_pwm_input: + ret =3D ec_read(AYANEO_PWM_REG, &tmp); + if (ret) + return ret; + if (tmp > 100) + return -EIO; + *val =3D (255 * tmp) / 100; + return 0; + case hwmon_pwm_enable: + ret =3D ec_read(AYANEO_PWM_ENABLE_REG, &tmp); + if (ret) + return ret; + if (tmp =3D=3D AYANEO_PWM_MODE_MANUAL) + *val =3D 1; + else if (tmp =3D=3D AYANEO_PWM_MODE_AUTO) + *val =3D 2; + else + return -EIO; + return 0; + default: + break; + } + break; + default: + break; + } + return -EOPNOTSUPP; +} + +static int ayaneo_ec_write(struct device *dev, enum hwmon_sensor_types typ= e, + u32 attr, int channel, long val) +{ + switch (type) { + case hwmon_pwm: + switch (attr) { + case hwmon_pwm_enable: + switch (val) { + case 1: + return ec_write(AYANEO_PWM_ENABLE_REG, + AYANEO_PWM_MODE_MANUAL); + case 2: + return ec_write(AYANEO_PWM_ENABLE_REG, + AYANEO_PWM_MODE_AUTO); + default: + return -EINVAL; + } + case hwmon_pwm_input: + if (val < 0 || val > 255) + return -EINVAL; + return ec_write(AYANEO_PWM_REG, (val * 100) / 255); + default: + break; + } + break; + default: + break; + } + return -EOPNOTSUPP; +} + +static const struct hwmon_ops ayaneo_ec_hwmon_ops =3D { + .is_visible =3D ayaneo_ec_hwmon_is_visible, + .read =3D ayaneo_ec_read, + .write =3D ayaneo_ec_write, +}; + +static const struct hwmon_channel_info *const ayaneo_ec_sensors[] =3D { + HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT), + HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT | HWMON_PWM_ENABLE), + NULL, +}; + +static const struct hwmon_chip_info ayaneo_ec_chip_info =3D { + .ops =3D &ayaneo_ec_hwmon_ops, + .info =3D ayaneo_ec_sensors, +}; + static int ayaneo_ec_probe(struct platform_device *pdev) { const struct dmi_system_id *dmi_entry; struct ayaneo_ec_platform_data *data; + struct device *hwdev; =20 dmi_entry =3D dmi_first_match(dmi_table); if (!dmi_entry) @@ -53,6 +182,13 @@ static int ayaneo_ec_probe(struct platform_device *pdev) data->quirks =3D dmi_entry->driver_data; platform_set_drvdata(pdev, data); =20 + if (data->quirks->has_fan_control) { + hwdev =3D devm_hwmon_device_register_with_info(&pdev->dev, + "ayaneo_ec", NULL, &ayaneo_ec_chip_info, NULL); + if (IS_ERR(hwdev)) + return PTR_ERR(hwdev); + } + return 0; } =20 --=20 2.52.0 From nobody Tue Dec 2 02:20:00 2025 Received: from relay11.grserver.gr (relay11.grserver.gr [78.46.171.57]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79A063093BA; Wed, 19 Nov 2025 17:45:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=78.46.171.57 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574330; cv=none; b=pYO7yA7gZnpnJDT0ctxtcFsRVOsaMF+6iOU8iosxuTJrV3dItYJrXvTmzXGRx02BPfzLW6/jP5IlES7ackKtEqb409FHQIp0cTKqGq1e8JhI01xG47r4ENRj7ak5GdbhOXWosleD8PpILsEcISEAkdlQlSpheBOpeM1y6sTYBfk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574330; c=relaxed/simple; bh=oveUdTlU06E6CfvUlT4/eBuZDkg69NYh/+i2jLkxuzI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JYEV2gSCoftb/VTrH006knifvnoWPq4mi/ZEJ/f0gJqVI02ex9JeaLHwyx4by7kpLvhCAz8+vkNrb8zArHM/KObBL/FRNNdY4d0vOkW33ngjNdB39f2HvR2sJbEaumpXopjGuvlkU/hgO/XdknlUqrECmaX1tP/DDylLsZwEqW4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=kR+gpE1z; arc=none smtp.client-ip=78.46.171.57 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="kR+gpE1z" Received: from relay11 (localhost.localdomain [127.0.0.1]) by relay11.grserver.gr (Proxmox) with ESMTP id C41DDC48D5; Wed, 19 Nov 2025 19:45:22 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay11.grserver.gr (Proxmox) with ESMTPS id 2FE5EBC90C; Wed, 19 Nov 2025 19:45:22 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 3CD6C200E79; Wed, 19 Nov 2025 19:45:21 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1763574321; bh=ayJ9MI5xF2/3yfcpAUOzsna2Ew6U+Ri/vAfa5QrLIHE=; h=From:To:Subject; b=kR+gpE1z1gNrrc1LwQxN0VdrapQiu4Gn3zIv/4H90oTNzKproAGlH+Y03O48c6w4L KW3XfK2pzpI03lp5tMEp8/DdUmLaAMenadUymJzTos0MBsG9cHFLNHF3EbI1Vn6R6O Q3eF67kXtI5QeJ3k63HIIL84HYgE8SlY2tRHElUQZ695Bjw/1f7yV5dy81NiG49fd2 eek2R0qOWcvzNthtpzFTOu1OfZtgNT3v3nw7I3ZErmya5TLW1/xpEa9x7Q1AGbiJHW B1bsTtVWxvyuvuCIW64LozW1q3HvynBHcIPMvwgHWTPHwC1KIKUW9PG4eCXSa7iBAR TiEVwxnx0GbEQ== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:8d8a:5967:d692:ea4e) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: platform-driver-x86@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Hans de Goede , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Derek John Clark , =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?= , Jean Delvare , Guenter Roeck , Antheas Kapenekakis , Armin Wolf Subject: [PATCH v6 3/6] platform/x86: ayaneo-ec: Add charge control support Date: Wed, 19 Nov 2025 18:45:02 +0100 Message-ID: <20251119174505.597218-4-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251119174505.597218-1-lkml@antheas.dev> References: <20251119174505.597218-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176357432178.2086468.16958912960422603405@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" Ayaneo devices support charge inhibition via the EC. This inhibition only works while the device is powered on, and resets between restarts. However, it is maintained across suspend/resume cycles. The EC does not support charge threshold control. Instead, userspace software on Windows manually toggles charge inhibition depending on battery level. Reviewed-by: Armin Wolf Signed-off-by: Antheas Kapenekakis --- drivers/platform/x86/Kconfig | 1 + drivers/platform/x86/ayaneo-ec.c | 112 +++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index e19850bd2609..b049c55057b7 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -320,6 +320,7 @@ config AYANEO_EC tristate "Ayaneo EC platform control" depends on DMI depends on ACPI_EC + depends on ACPI_BATTERY depends on HWMON help Enables support for the platform EC of Ayaneo devices. This diff --git a/drivers/platform/x86/ayaneo-ec.c b/drivers/platform/x86/ayaneo= -ec.c index 86d4eed49f42..69901ac335eb 100644 --- a/drivers/platform/x86/ayaneo-ec.c +++ b/drivers/platform/x86/ayaneo-ec.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include =20 #define AYANEO_PWM_ENABLE_REG 0x4A #define AYANEO_PWM_REG 0x4B @@ -23,17 +25,27 @@ =20 #define AYANEO_FAN_REG 0x76 =20 +#define EC_CHARGE_CONTROL_BEHAVIOURS \ + (BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) | \ + BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE)) +#define AYANEO_CHARGE_REG 0x1e +#define AYANEO_CHARGE_VAL_AUTO 0xaa +#define AYANEO_CHARGE_VAL_INHIBIT 0x55 + struct ayaneo_ec_quirk { bool has_fan_control; + bool has_charge_control; }; =20 struct ayaneo_ec_platform_data { struct platform_device *pdev; struct ayaneo_ec_quirk *quirks; + struct acpi_battery_hook battery_hook; }; =20 static const struct ayaneo_ec_quirk quirk_ayaneo3 =3D { .has_fan_control =3D true, + .has_charge_control =3D true, }; =20 static const struct dmi_system_id dmi_table[] =3D { @@ -164,11 +176,102 @@ static const struct hwmon_chip_info ayaneo_ec_chip_i= nfo =3D { .info =3D ayaneo_ec_sensors, }; =20 +static int ayaneo_psy_ext_get_prop(struct power_supply *psy, + const struct power_supply_ext *ext, + void *data, + enum power_supply_property psp, + union power_supply_propval *val) +{ + int ret; + u8 tmp; + + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: + ret =3D ec_read(AYANEO_CHARGE_REG, &tmp); + if (ret) + return ret; + + if (tmp =3D=3D AYANEO_CHARGE_VAL_INHIBIT) + val->intval =3D POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE; + else + val->intval =3D POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO; + return 0; + default: + return -EINVAL; + } +} + +static int ayaneo_psy_ext_set_prop(struct power_supply *psy, + const struct power_supply_ext *ext, + void *data, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + u8 raw_val; + + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: + switch (val->intval) { + case POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO: + raw_val =3D AYANEO_CHARGE_VAL_AUTO; + break; + case POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE: + raw_val =3D AYANEO_CHARGE_VAL_INHIBIT; + break; + default: + return -EINVAL; + } + return ec_write(AYANEO_CHARGE_REG, raw_val); + default: + return -EINVAL; + } +} + +static int ayaneo_psy_prop_is_writeable(struct power_supply *psy, + const struct power_supply_ext *ext, + void *data, + enum power_supply_property psp) +{ + return true; +} + +static const enum power_supply_property ayaneo_psy_ext_props[] =3D { + POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR, +}; + +static const struct power_supply_ext ayaneo_psy_ext =3D { + .name =3D "ayaneo-charge-control", + .properties =3D ayaneo_psy_ext_props, + .num_properties =3D ARRAY_SIZE(ayaneo_psy_ext_props), + .charge_behaviours =3D EC_CHARGE_CONTROL_BEHAVIOURS, + .get_property =3D ayaneo_psy_ext_get_prop, + .set_property =3D ayaneo_psy_ext_set_prop, + .property_is_writeable =3D ayaneo_psy_prop_is_writeable, +}; + +static int ayaneo_add_battery(struct power_supply *battery, + struct acpi_battery_hook *hook) +{ + struct ayaneo_ec_platform_data *data =3D + container_of(hook, struct ayaneo_ec_platform_data, battery_hook); + + return power_supply_register_extension(battery, &ayaneo_psy_ext, + &data->pdev->dev, NULL); +} + +static int ayaneo_remove_battery(struct power_supply *battery, + struct acpi_battery_hook *hook) +{ + power_supply_unregister_extension(battery, &ayaneo_psy_ext); + return 0; +} + static int ayaneo_ec_probe(struct platform_device *pdev) { const struct dmi_system_id *dmi_entry; struct ayaneo_ec_platform_data *data; struct device *hwdev; + int ret; =20 dmi_entry =3D dmi_first_match(dmi_table); if (!dmi_entry) @@ -189,6 +292,15 @@ static int ayaneo_ec_probe(struct platform_device *pde= v) return PTR_ERR(hwdev); } =20 + if (data->quirks->has_charge_control) { + data->battery_hook.add_battery =3D ayaneo_add_battery; + data->battery_hook.remove_battery =3D ayaneo_remove_battery; + data->battery_hook.name =3D "Ayaneo Battery"; + ret =3D devm_battery_hook_register(&pdev->dev, &data->battery_hook); + if (ret) + return ret; + } + return 0; } =20 --=20 2.52.0 From nobody Tue Dec 2 02:20:00 2025 Received: from relay11.grserver.gr (relay11.grserver.gr [78.46.171.57]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD0093254B4; Wed, 19 Nov 2025 17:45:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=78.46.171.57 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574329; cv=none; b=maD/aK4fVi8eDRvLgj/amSBceH2Xqb5Nv9ntnjc7HXMpwzjbEv+C049H6lGBs6V573Gz+PYEK9ECaUE4VW88MLk8m9ABFqfhweSfX/U/UGUNoTz2Uq/kbeLljLGXxb1fqpehBwA7djRKn+rahLYlNaUO8hX93/lq7eSb2FHHkqU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574329; c=relaxed/simple; bh=WNF0qIi3+3Lqlyc95+l6050UuIzEX0AKgmdHwh9L650=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DWfvyp3XPsB1XkANcYTg7cH5j/YH5Zld5gG1WdLg+LUGPhTced1yzUnctfrFG3KDKBFTCQ5VSpOvGlLuB6QP8tkdxaRjWz6X3qBr81iw66XN0pfwpRjh0GYekWz4Sa78LDuz5olj1A2Radrw5KyZLnKXGYuMZ4Bq4B8fvMIkKJI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=mJGjOLwl; arc=none smtp.client-ip=78.46.171.57 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="mJGjOLwl" Received: from relay11 (localhost.localdomain [127.0.0.1]) by relay11.grserver.gr (Proxmox) with ESMTP id C45FCBC90C; Wed, 19 Nov 2025 19:45:23 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay11.grserver.gr (Proxmox) with ESMTPS id 14B03C4C67; Wed, 19 Nov 2025 19:45:23 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 1DB5F200E78; Wed, 19 Nov 2025 19:45:22 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1763574322; bh=Et5I7W4hO+kHCq9UacGOPLm8w/6me6CSr5ImldsVhZg=; h=From:To:Subject; b=mJGjOLwl4BFgxrhCrga/m2wmJtHz6ved3wae+l8d/+ERt1+2CqkPeRy/lD6EEsT/h K4abqy2KqwlH18XSusA/AuN+54WW8bAsnj69X+0EX2b55ag7jcgED/KJf3GiAxwyDk 0Nq7RqvkUAXZS3yzngWoXrgup0g/MyHwj8enaqQuxG8rDYWaUZbp1bUIKb6W0DU6Qr ICG/R9YInJrXooPzhN5OYqBASvhjoSJjzdQwbI+7LgpAcpbnX4F5tCeFjdBT0HAO4V EA9GseK/PAv/UFwelkx7HwIRQfgZd61U1qJfoUNWgvyA1oRARilDAJwYsWgehFP0HD qtKmh1Mj7HoEg== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:8d8a:5967:d692:ea4e) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: platform-driver-x86@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Hans de Goede , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Derek John Clark , =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?= , Jean Delvare , Guenter Roeck , Antheas Kapenekakis , Armin Wolf Subject: [PATCH v6 4/6] platform/x86: ayaneo-ec: Add controller power and modules attributes Date: Wed, 19 Nov 2025 18:45:03 +0100 Message-ID: <20251119174505.597218-5-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251119174505.597218-1-lkml@antheas.dev> References: <20251119174505.597218-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176357432270.2086512.9444322772080322428@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" The Ayaneo 3 features hot-swappable controller modules. The ejection and management is done through HID. However, after ejecting the modules, the controller needs to be power cycled via the EC to re-initialize. For this, the EC provides a variable that holds whether the left or right modules are connected, and a power control register to turn the controller on or off. After ejecting the modules, the controller should be turned off. Then, after both modules are reinserted, the controller may be powered on again to re-initialize. This patch introduces two new sysfs attributes: - `controller_modules`: a read-only attribute that indicates whether the left and right modules are connected (none, left, right, both). - `controller_power`: a read-write attribute that allows the user to turn the controller on or off (with '1'/'0'). Therefore, after ejection is complete, userspace can power off the controller, then wait until both modules have been reinserted (`controller_modules` will return 'both') to turn on the controller. Reviewed-by: Armin Wolf Signed-off-by: Antheas Kapenekakis --- .../ABI/testing/sysfs-platform-ayaneo-ec | 19 ++++ MAINTAINERS | 1 + drivers/platform/x86/ayaneo-ec.c | 107 ++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-platform-ayaneo-ec diff --git a/Documentation/ABI/testing/sysfs-platform-ayaneo-ec b/Documenta= tion/ABI/testing/sysfs-platform-ayaneo-ec new file mode 100644 index 000000000000..4cffbf5fc7ca --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-ayaneo-ec @@ -0,0 +1,19 @@ +What: /sys/devices/platform/ayaneo-ec/controller_power +Date: Nov 2025 +KernelVersion: 6.19 +Contact: "Antheas Kapenekakis" +Description: + Current controller power state. Allows turning on and off + the controller power (e.g. for power savings). Write 1 to + turn on, 0 to turn off. File is readable and writable. + +What: /sys/devices/platform/ayaneo-ec/controller_modules +Date: Nov 2025 +KernelVersion: 6.19 +Contact: "Antheas Kapenekakis" +Description: + Shows which controller modules are currently connected to + the device. Possible values are "left", "right" and "both". + File is read-only. The Windows software for this device + will only set controller power to 1 if both module sides + are connected (i.e. this file returns "both"). diff --git a/MAINTAINERS b/MAINTAINERS index 3912f8afe5f4..5c8ec8eb90b4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4197,6 +4197,7 @@ AYANEO PLATFORM EC DRIVER M: Antheas Kapenekakis L: platform-driver-x86@vger.kernel.org S: Maintained +F: Documentation/ABI/testing/sysfs-platform-ayaneo F: drivers/platform/x86/ayaneo-ec.c =20 AZ6007 DVB DRIVER diff --git a/drivers/platform/x86/ayaneo-ec.c b/drivers/platform/x86/ayaneo= -ec.c index 69901ac335eb..87ebbb594f8f 100644 --- a/drivers/platform/x86/ayaneo-ec.c +++ b/drivers/platform/x86/ayaneo-ec.c @@ -8,6 +8,7 @@ */ =20 #include +#include #include #include #include @@ -16,6 +17,7 @@ #include #include #include +#include #include =20 #define AYANEO_PWM_ENABLE_REG 0x4A @@ -32,9 +34,18 @@ #define AYANEO_CHARGE_VAL_AUTO 0xaa #define AYANEO_CHARGE_VAL_INHIBIT 0x55 =20 +#define AYANEO_POWER_REG 0x2d +#define AYANEO_POWER_OFF 0xfe +#define AYANEO_POWER_ON 0xff +#define AYANEO_MODULE_REG 0x2f +#define AYANEO_MODULE_LEFT BIT(0) +#define AYANEO_MODULE_RIGHT BIT(1) +#define AYANEO_MODULE_MASK (AYANEO_MODULE_LEFT | AYANEO_MODULE_RIGHT) + struct ayaneo_ec_quirk { bool has_fan_control; bool has_charge_control; + bool has_magic_modules; }; =20 struct ayaneo_ec_platform_data { @@ -46,6 +57,7 @@ struct ayaneo_ec_platform_data { static const struct ayaneo_ec_quirk quirk_ayaneo3 =3D { .has_fan_control =3D true, .has_charge_control =3D true, + .has_magic_modules =3D true, }; =20 static const struct dmi_system_id dmi_table[] =3D { @@ -266,6 +278,100 @@ static int ayaneo_remove_battery(struct power_supply = *battery, return 0; } =20 +static ssize_t controller_power_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + bool value; + int ret; + + ret =3D kstrtobool(buf, &value); + if (ret) + return ret; + + ret =3D ec_write(AYANEO_POWER_REG, value ? AYANEO_POWER_ON : AYANEO_POWER= _OFF); + if (ret) + return ret; + + return count; +} + +static ssize_t controller_power_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 val; + + ret =3D ec_read(AYANEO_POWER_REG, &val); + if (ret) + return ret; + + return sysfs_emit(buf, "%d\n", val =3D=3D AYANEO_POWER_ON); +} + +static DEVICE_ATTR_RW(controller_power); + +static ssize_t controller_modules_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 unconnected_modules; + char *out; + int ret; + + ret =3D ec_read(AYANEO_MODULE_REG, &unconnected_modules); + if (ret) + return ret; + + switch (~unconnected_modules & AYANEO_MODULE_MASK) { + case AYANEO_MODULE_LEFT | AYANEO_MODULE_RIGHT: + out =3D "both"; + break; + case AYANEO_MODULE_LEFT: + out =3D "left"; + break; + case AYANEO_MODULE_RIGHT: + out =3D "right"; + break; + default: + out =3D "none"; + break; + } + + return sysfs_emit(buf, "%s\n", out); +} + +static DEVICE_ATTR_RO(controller_modules); + +static struct attribute *aya_mm_attrs[] =3D { + &dev_attr_controller_power.attr, + &dev_attr_controller_modules.attr, + NULL +}; + +static umode_t aya_mm_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev =3D kobj_to_dev(kobj); + struct platform_device *pdev =3D to_platform_device(dev); + struct ayaneo_ec_platform_data *data =3D platform_get_drvdata(pdev); + + if (data->quirks->has_magic_modules) + return attr->mode; + return 0; +} + +static const struct attribute_group aya_mm_attribute_group =3D { + .is_visible =3D aya_mm_is_visible, + .attrs =3D aya_mm_attrs, +}; + +static const struct attribute_group *ayaneo_ec_groups[] =3D { + &aya_mm_attribute_group, + NULL +}; + static int ayaneo_ec_probe(struct platform_device *pdev) { const struct dmi_system_id *dmi_entry; @@ -307,6 +413,7 @@ static int ayaneo_ec_probe(struct platform_device *pdev) static struct platform_driver ayaneo_platform_driver =3D { .driver =3D { .name =3D "ayaneo-ec", + .dev_groups =3D ayaneo_ec_groups, }, .probe =3D ayaneo_ec_probe, }; --=20 2.52.0 From nobody Tue Dec 2 02:20:00 2025 Received: from relay13.grserver.gr (relay13.grserver.gr [178.156.171.147]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7BB6A30F938; Wed, 19 Nov 2025 17:45:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.156.171.147 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574339; cv=none; b=q+bfM85uw/DrcmKXDOBnGi0P0/PctBxe5cryOLXuC6Gnhmcfzf9MTka4Kjy3EI3yAKl9WauG65uddkfA5aHDNnq64YFq8TQxoYDGNo0tmIkqBYvh+js3FZfTY9TXEXSDc3HBdPHJk07EHTRAy6OgwcciqfVBI6G+VaADRW2pws0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574339; c=relaxed/simple; bh=7X1BQA1mUMdDK0it0rXA7wa5Rtylx7WgcIt2g3SZU5U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=j5jNse3xLolSQU/cJWqrImsV2bRwnyEBhiXAR++bjpc5iN9fdJd3cWFdoWoIxrjFe/KI6wi4VJ/HeREuizQ7ZTKhnUmnm1Hy0pDpQZLHyQ38bMTaoDpCQ1Sfv+qrKk8dvW4DBwHGbhSXxEYsS2gzo3+OwDxDXbKd4VtbAV24W9A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=POX3ly0C; arc=none smtp.client-ip=178.156.171.147 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="POX3ly0C" Received: from relay13 (localhost [127.0.0.1]) by relay13.grserver.gr (Proxmox) with ESMTP id 7CBF65E57D; Wed, 19 Nov 2025 19:45:25 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay13.grserver.gr (Proxmox) with ESMTPS id 83BAE5E547; Wed, 19 Nov 2025 19:45:24 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 04B94200E79; Wed, 19 Nov 2025 19:45:22 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1763574323; bh=KVPT/Des+65BKE1pzttG2+SbL/78yO7mCWF7rk9Sm3s=; h=From:To:Subject; b=POX3ly0CfpmP9Ikybc7kkF+Qg9JYFg1CYPC435Zub+Ae19ua3wzo2CP8VY+ySi4q/ XM2rwgvifChZK5ZAOeyBmRjL8qqs42sBvXTt7ip5bSijxgonQoCfPmBgU2qxpp8di7 jnLDuHosJxMYfkAZ4T9Du5fzuNQ+RTmmXNejv9BPlttv7drqLq+8hsf+Pl06T6zUZk egN8aquz/Y7kWlwXEO4HiwSre6EXaGhVX05nKtlbeJybc8hfb+NnRz1bH2gdk15a4o NvPxg69qGkLqZGg40O1LxITVjpu1qHNrRzi/VL8MjWNbd9ajOEX3Df9wO3U+B6U6qm VC2GHQjXbLtKQ== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:8d8a:5967:d692:ea4e) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: platform-driver-x86@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Hans de Goede , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Derek John Clark , =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?= , Jean Delvare , Guenter Roeck , Antheas Kapenekakis , Armin Wolf Subject: [PATCH v6 5/6] platform/x86: ayaneo-ec: Move Ayaneo devices from oxpec to ayaneo-ec Date: Wed, 19 Nov 2025 18:45:04 +0100 Message-ID: <20251119174505.597218-6-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251119174505.597218-1-lkml@antheas.dev> References: <20251119174505.597218-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176357432362.2086555.9068946600012345904@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Currently, the oxpec driver contains Ayaneo devices. Move them to the new ayaneo-ec driver, which is dedicated to them. As this driver supports charge inhibition for Ayaneo, add support for it for the AIR, AIR 1S, AB05-Medoncino, AIR Pro, and Kun, referenced from the out-of-tree ayaneo-platform driver. In addition, update the readmes of oxpec to reflect this change. Link: https://github.com/ShadowBlip/ayaneo-platform Tested-by: Derek J. Clark Reviewed-by: Armin Wolf Reviewed-by: Ilpo J=C3=A4rvinen Signed-off-by: Antheas Kapenekakis --- drivers/platform/x86/Kconfig | 4 +- drivers/platform/x86/ayaneo-ec.c | 65 +++++++++++++++++ drivers/platform/x86/oxpec.c | 115 +------------------------------ 3 files changed, 67 insertions(+), 117 deletions(-) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index b049c55057b7..40f81aef33b8 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1043,9 +1043,7 @@ config OXP_EC help Enables support for the platform EC of OneXPlayer and AOKZOE handheld devices. This includes fan speed, fan controls, and - disabling the default TDP behavior of the device. Due to legacy - reasons, this driver also provides hwmon functionality to Ayaneo - devices and the OrangePi Neo. + disabling the default TDP behavior of the device. =20 source "drivers/platform/x86/tuxedo/Kconfig" =20 diff --git a/drivers/platform/x86/ayaneo-ec.c b/drivers/platform/x86/ayaneo= -ec.c index 87ebbb594f8f..a6fe141f07be 100644 --- a/drivers/platform/x86/ayaneo-ec.c +++ b/drivers/platform/x86/ayaneo-ec.c @@ -54,6 +54,15 @@ struct ayaneo_ec_platform_data { struct acpi_battery_hook battery_hook; }; =20 +static const struct ayaneo_ec_quirk quirk_fan =3D { + .has_fan_control =3D true, +}; + +static const struct ayaneo_ec_quirk quirk_charge_limit =3D { + .has_fan_control =3D true, + .has_charge_control =3D true, +}; + static const struct ayaneo_ec_quirk quirk_ayaneo3 =3D { .has_fan_control =3D true, .has_charge_control =3D true, @@ -61,6 +70,62 @@ static const struct ayaneo_ec_quirk quirk_ayaneo3 =3D { }; =20 static const struct dmi_system_id dmi_table[] =3D { + { + .matches =3D { + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), + DMI_MATCH(DMI_BOARD_NAME, "AYANEO 2"), + }, + .driver_data =3D (void *)&quirk_fan, + }, + { + .matches =3D { + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), + DMI_MATCH(DMI_BOARD_NAME, "FLIP"), + }, + .driver_data =3D (void *)&quirk_fan, + }, + { + .matches =3D { + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), + DMI_MATCH(DMI_BOARD_NAME, "GEEK"), + }, + .driver_data =3D (void *)&quirk_fan, + }, + { + .matches =3D { + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR"), + }, + .driver_data =3D (void *)&quirk_charge_limit, + }, + { + .matches =3D { + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR 1S"), + }, + .driver_data =3D (void *)&quirk_charge_limit, + }, + { + .matches =3D { + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "AB05-Mendocino"), + }, + .driver_data =3D (void *)&quirk_charge_limit, + }, + { + .matches =3D { + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR Pro"), + }, + .driver_data =3D (void *)&quirk_charge_limit, + }, + { + .matches =3D { + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "KUN"), + }, + .driver_data =3D (void *)&quirk_charge_limit, + }, { .matches =3D { DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c index 54377b282ff8..144a454103b9 100644 --- a/drivers/platform/x86/oxpec.c +++ b/drivers/platform/x86/oxpec.c @@ -1,8 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Platform driver for OneXPlayer and AOKZOE devices. For the time being, - * it also exposes fan controls for AYANEO, and OrangePi Handhelds via - * hwmon sysfs. + * Platform driver for OneXPlayer and AOKZOE devices. * * Fan control is provided via pwm interface in the range [0-255]. * Old AMD boards use [0-100] as range in the EC, the written value is @@ -43,14 +41,6 @@ static bool unlock_global_acpi_lock(void) =20 enum oxp_board { aok_zoe_a1 =3D 1, - aya_neo_2, - aya_neo_air, - aya_neo_air_1s, - aya_neo_air_plus_mendo, - aya_neo_air_pro, - aya_neo_flip, - aya_neo_geek, - aya_neo_kun, orange_pi_neo, oxp_2, oxp_fly, @@ -131,62 +121,6 @@ static const struct dmi_system_id dmi_table[] =3D { }, .driver_data =3D (void *)oxp_fly, }, - { - .matches =3D { - DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), - DMI_MATCH(DMI_BOARD_NAME, "AYANEO 2"), - }, - .driver_data =3D (void *)aya_neo_2, - }, - { - .matches =3D { - DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), - DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR"), - }, - .driver_data =3D (void *)aya_neo_air, - }, - { - .matches =3D { - DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), - DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR 1S"), - }, - .driver_data =3D (void *)aya_neo_air_1s, - }, - { - .matches =3D { - DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), - DMI_EXACT_MATCH(DMI_BOARD_NAME, "AB05-Mendocino"), - }, - .driver_data =3D (void *)aya_neo_air_plus_mendo, - }, - { - .matches =3D { - DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), - DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR Pro"), - }, - .driver_data =3D (void *)aya_neo_air_pro, - }, - { - .matches =3D { - DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), - DMI_MATCH(DMI_BOARD_NAME, "FLIP"), - }, - .driver_data =3D (void *)aya_neo_flip, - }, - { - .matches =3D { - DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), - DMI_MATCH(DMI_BOARD_NAME, "GEEK"), - }, - .driver_data =3D (void *)aya_neo_geek, - }, - { - .matches =3D { - DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), - DMI_EXACT_MATCH(DMI_BOARD_NAME, "KUN"), - }, - .driver_data =3D (void *)aya_neo_kun, - }, { .matches =3D { DMI_MATCH(DMI_BOARD_VENDOR, "OrangePi"), @@ -672,13 +606,6 @@ static int oxp_pwm_enable(void) case orange_pi_neo: return write_to_ec(ORANGEPI_SENSOR_PWM_ENABLE_REG, PWM_MODE_MANUAL); case aok_zoe_a1: - case aya_neo_2: - case aya_neo_air: - case aya_neo_air_plus_mendo: - case aya_neo_air_pro: - case aya_neo_flip: - case aya_neo_geek: - case aya_neo_kun: case oxp_2: case oxp_fly: case oxp_mini_amd: @@ -699,14 +626,6 @@ static int oxp_pwm_disable(void) case orange_pi_neo: return write_to_ec(ORANGEPI_SENSOR_PWM_ENABLE_REG, PWM_MODE_AUTO); case aok_zoe_a1: - case aya_neo_2: - case aya_neo_air: - case aya_neo_air_1s: - case aya_neo_air_plus_mendo: - case aya_neo_air_pro: - case aya_neo_flip: - case aya_neo_geek: - case aya_neo_kun: case oxp_2: case oxp_fly: case oxp_mini_amd: @@ -727,14 +646,6 @@ static int oxp_pwm_read(long *val) case orange_pi_neo: return read_from_ec(ORANGEPI_SENSOR_PWM_ENABLE_REG, 1, val); case aok_zoe_a1: - case aya_neo_2: - case aya_neo_air: - case aya_neo_air_1s: - case aya_neo_air_plus_mendo: - case aya_neo_air_pro: - case aya_neo_flip: - case aya_neo_geek: - case aya_neo_kun: case oxp_2: case oxp_fly: case oxp_mini_amd: @@ -774,14 +685,6 @@ static int oxp_pwm_fan_speed(long *val) case oxp_g1_i: return read_from_ec(OXP_2_SENSOR_FAN_REG, 2, val); case aok_zoe_a1: - case aya_neo_2: - case aya_neo_air: - case aya_neo_air_1s: - case aya_neo_air_plus_mendo: - case aya_neo_air_pro: - case aya_neo_flip: - case aya_neo_geek: - case aya_neo_kun: case oxp_fly: case oxp_mini_amd: case oxp_mini_amd_a07: @@ -810,14 +713,6 @@ static int oxp_pwm_input_write(long val) /* scale to range [0-184] */ val =3D (val * 184) / 255; return write_to_ec(OXP_SENSOR_PWM_REG, val); - case aya_neo_2: - case aya_neo_air: - case aya_neo_air_1s: - case aya_neo_air_plus_mendo: - case aya_neo_air_pro: - case aya_neo_flip: - case aya_neo_geek: - case aya_neo_kun: case oxp_mini_amd: case oxp_mini_amd_a07: /* scale to range [0-100] */ @@ -854,14 +749,6 @@ static int oxp_pwm_input_read(long *val) /* scale from range [0-184] */ *val =3D (*val * 255) / 184; break; - case aya_neo_2: - case aya_neo_air: - case aya_neo_air_1s: - case aya_neo_air_plus_mendo: - case aya_neo_air_pro: - case aya_neo_flip: - case aya_neo_geek: - case aya_neo_kun: case oxp_mini_amd: case oxp_mini_amd_a07: ret =3D read_from_ec(OXP_SENSOR_PWM_REG, 1, val); --=20 2.52.0 From nobody Tue Dec 2 02:20:00 2025 Received: from relay11.grserver.gr (relay11.grserver.gr [78.46.171.57]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD59C30DECC; Wed, 19 Nov 2025 17:45:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=78.46.171.57 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574331; cv=none; b=SXCWXY+TYljzN/+pPmcv4aLUSYA9SN9FNaUafVuRKIrp+qcz+7yutI4w2ABK6TkT7ENf9mo9j/qrjlHp0Vc3Ryftv6lUFL6SsinhQUEhD1JcoFH/rp5haAqpGytikOjcXdV2YE14wVtj1kVhS2/3L0TXBP9d6gQ7T8N9h/c68Bo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763574331; c=relaxed/simple; bh=+z5XqbF4/QQN0A5MmMEjZ77wdwc4xaG3dSNM0lrNndk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=l66dxypjicXFgY717UDsXS14C/daWnUD9ftOtCQMH5OLyjE999wmTLXYL+AFpUAjm8xp+fvZoGWgxqJl12XaGkDLfDPbeN9fuppvKdqKddopyByMshSSSNR2vywUfE2/xUTrbMGAYU+8V0i7Vi1ojVMKIdAX6tDNxQjoIp7MjBI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=aU9yAx5e; arc=none smtp.client-ip=78.46.171.57 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="aU9yAx5e" Received: from relay11 (localhost.localdomain [127.0.0.1]) by relay11.grserver.gr (Proxmox) with ESMTP id 6EE27C50EC; Wed, 19 Nov 2025 19:45:25 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay11.grserver.gr (Proxmox) with ESMTPS id D9E3EC5023; Wed, 19 Nov 2025 19:45:24 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id E626E200E78; Wed, 19 Nov 2025 19:45:23 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1763574324; bh=6YbJcjXJAQ0dSS7I+79MAPOfy2Sg4oINOpDtwrpxxXs=; h=From:To:Subject; b=aU9yAx5e489rRkNP/r7TGIcUP7uA99bIVf7sa+Zueb/YMlSO1NPqAsDFXRgz9Ogun wvbh39v3G1Zgqu/bpyR6EFb/8UgqqhktiyWJKZDu2ervkgGiZUowIZR9lQt2HOiBHY sp4u0JrSrDC1r9kqFoS5TYwxDdyvfsKyYJmT4osrpQx8oYioIzafG7vVhlcx/zmsdw mgIz8O0FQ6a6APV5NfXyNdTnLM9ud2PH+E3AJj+XrX4WBBhFVG0MrKewGIzAfLBkU6 6EYEl+qqOmIWbqxg6dTJ7cro60/cQjQF83VQ8RKc186I2Up0j8UlSQ7WttzxwXOWvH 7ky+/EKodmwrQ== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:8d8a:5967:d692:ea4e) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: platform-driver-x86@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org, Hans de Goede , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Derek John Clark , =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?= , Jean Delvare , Guenter Roeck , Antheas Kapenekakis , Armin Wolf Subject: [PATCH v6 6/6] platform/x86: ayaneo-ec: Add suspend hook Date: Wed, 19 Nov 2025 18:45:05 +0100 Message-ID: <20251119174505.597218-7-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251119174505.597218-1-lkml@antheas.dev> References: <20251119174505.597218-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176357432448.2086598.14999151017992077673@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" The Ayaneo EC resets after hibernation, losing the charge control state. Add a small PM hook to restore this state on hibernation resume. The fan speed is also lost during hibernation, but since hibernation failures are common with this class of devices, setting a low fan speed when the userspace program controlling the fan will potentially not take over could cause the device to overheat, so it is not restored. Reviewed-by: Armin Wolf Signed-off-by: Antheas Kapenekakis --- drivers/platform/x86/ayaneo-ec.c | 85 +++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/ayaneo-ec.c b/drivers/platform/x86/ayaneo= -ec.c index a6fe141f07be..41a24e091248 100644 --- a/drivers/platform/x86/ayaneo-ec.c +++ b/drivers/platform/x86/ayaneo-ec.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,11 @@ struct ayaneo_ec_platform_data { struct platform_device *pdev; struct ayaneo_ec_quirk *quirks; struct acpi_battery_hook battery_hook; + + // Protects access to restore_pwm + struct mutex hwmon_lock; + bool restore_charge_limit; + bool restore_pwm; }; =20 static const struct ayaneo_ec_quirk quirk_fan =3D { @@ -208,10 +214,16 @@ static int ayaneo_ec_read(struct device *dev, enum hw= mon_sensor_types type, static int ayaneo_ec_write(struct device *dev, enum hwmon_sensor_types typ= e, u32 attr, int channel, long val) { + struct ayaneo_ec_platform_data *data =3D dev_get_drvdata(dev); + int ret; + + guard(mutex)(&data->hwmon_lock); + switch (type) { case hwmon_pwm: switch (attr) { case hwmon_pwm_enable: + data->restore_pwm =3D false; switch (val) { case 1: return ec_write(AYANEO_PWM_ENABLE_REG, @@ -225,6 +237,17 @@ static int ayaneo_ec_write(struct device *dev, enum hw= mon_sensor_types type, case hwmon_pwm_input: if (val < 0 || val > 255) return -EINVAL; + if (data->restore_pwm) { + /* + * Defer restoring PWM control to after + * userspace resumes successfully + */ + ret =3D ec_write(AYANEO_PWM_ENABLE_REG, + AYANEO_PWM_MODE_MANUAL); + if (ret) + return ret; + data->restore_pwm =3D false; + } return ec_write(AYANEO_PWM_REG, (val * 100) / 255); default: break; @@ -454,11 +477,14 @@ static int ayaneo_ec_probe(struct platform_device *pd= ev) =20 data->pdev =3D pdev; data->quirks =3D dmi_entry->driver_data; + ret =3D devm_mutex_init(&pdev->dev, &data->hwmon_lock); + if (ret) + return ret; platform_set_drvdata(pdev, data); =20 if (data->quirks->has_fan_control) { hwdev =3D devm_hwmon_device_register_with_info(&pdev->dev, - "ayaneo_ec", NULL, &ayaneo_ec_chip_info, NULL); + "ayaneo_ec", data, &ayaneo_ec_chip_info, NULL); if (IS_ERR(hwdev)) return PTR_ERR(hwdev); } @@ -475,10 +501,67 @@ static int ayaneo_ec_probe(struct platform_device *pd= ev) return 0; } =20 +static int ayaneo_freeze(struct device *dev) +{ + struct platform_device *pdev =3D to_platform_device(dev); + struct ayaneo_ec_platform_data *data =3D platform_get_drvdata(pdev); + int ret; + u8 tmp; + + if (data->quirks->has_charge_control) { + ret =3D ec_read(AYANEO_CHARGE_REG, &tmp); + if (ret) + return ret; + + data->restore_charge_limit =3D tmp =3D=3D AYANEO_CHARGE_VAL_INHIBIT; + } + + if (data->quirks->has_fan_control) { + ret =3D ec_read(AYANEO_PWM_ENABLE_REG, &tmp); + if (ret) + return ret; + + data->restore_pwm =3D tmp =3D=3D AYANEO_PWM_MODE_MANUAL; + + /* + * Release the fan when entering hibernation to avoid + * overheating if hibernation fails and hangs. + */ + if (data->restore_pwm) { + ret =3D ec_write(AYANEO_PWM_ENABLE_REG, AYANEO_PWM_MODE_AUTO); + if (ret) + return ret; + } + } + + return 0; +} + +static int ayaneo_restore(struct device *dev) +{ + struct platform_device *pdev =3D to_platform_device(dev); + struct ayaneo_ec_platform_data *data =3D platform_get_drvdata(pdev); + int ret; + + if (data->quirks->has_charge_control && data->restore_charge_limit) { + ret =3D ec_write(AYANEO_CHARGE_REG, AYANEO_CHARGE_VAL_INHIBIT); + if (ret) + return ret; + } + + return 0; +} + +static const struct dev_pm_ops ayaneo_pm_ops =3D { + .freeze =3D ayaneo_freeze, + .restore =3D ayaneo_restore, +}; + static struct platform_driver ayaneo_platform_driver =3D { .driver =3D { .name =3D "ayaneo-ec", .dev_groups =3D ayaneo_ec_groups, + .pm =3D pm_sleep_ptr(&ayaneo_pm_ops), }, .probe =3D ayaneo_ec_probe, }; --=20 2.52.0