From nobody Sat Feb 7 18:21:23 2026 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 2FD8E2A1AA; Mon, 10 Nov 2025 18:08:54 +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=1762798137; cv=none; b=hceNdVaSnyimHY44oXjmDn3/z1fN2eCd0jlDYuAIdlOXSeihMoQflIB9Hz8bW/F868QF+yqnYiMXgRioxxf3Vx4w+iSy5eCZ7WT23msD6ZPtlfIXACrfGhk/9xafY9CwtqbN7Pto/Rv00rMoE/F7TcHK5XMszkWenVcbQb4ncmU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762798137; c=relaxed/simple; bh=VaAfZMx61BCwKqY6I0ACj+D+Kdvy/IECYIb/uSDrztw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DjztWEX8OgFKj9TmEFBF5+pyH4TU3TSXbjOLHxaOYazXySxaYF4DzSGOMcz7netIp4x/xXcUlBUnpYT81jpIanzP6vtFvKUpfigz2eLilpAkWsp4AO93UDfuXIVh6wLas3DtAm14LOzAKfJNRPzhF4i/tYL7NnBbWujlwi7jR/8= 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=YV96e0Cq; 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="YV96e0Cq" Received: from relay12 (localhost [127.0.0.1]) by relay12.grserver.gr (Proxmox) with ESMTP id 4D9B9BDB5A; Mon, 10 Nov 2025 20:08:52 +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 50985BDA22; Mon, 10 Nov 2025 20:08:51 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 78C81200823; Mon, 10 Nov 2025 20:08:50 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1762798131; bh=bz85/sWxuhkVZLuJnSMI3WyTgjUd1yk3z+GP78j4EIE=; h=From:To:Subject; b=YV96e0CqcefdK8SCRbwfPK4n50TsPNwBZc5Nyuzl4hbVaCYuD25SRA6ZdC9bSc/9K 2kBbZkZO6pHMHk/FxF4NlgYGW2w1fyfayJnHmwdnfkhwLws8SIpy1B5pyVkQ3tpwpQ SKm41LbsVfdpHEKZS20Cs0VdU3wyBmnhyfHUUMs6QM/lqWxHI5DLoVHpLZxwafe9Hf /CaznqMjpt6g7jv/788U3sLgMM3P38otVA99scSCcr6aFyCQnrNVvIGvrsWtwdwvOd E4h2yqLrE7be63E9kngYfRSWF+TivhFZR5EgMqAIVxk0Od3+cA9dpdVmuF4hmvn1XP Hpar3Q61zueaw== 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 Subject: [PATCH v4 1/6] platform/x86: ayaneo-ec: Add Ayaneo Embedded Controller platform driver Date: Mon, 10 Nov 2025 19:08:41 +0100 Message-ID: <20251110180846.1490726-2-lkml@antheas.dev> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20251110180846.1490726-1-lkml@antheas.dev> References: <20251110180846.1490726-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: <176279813097.3664500.16665288900178778636@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. Signed-off-by: Antheas Kapenekakis --- MAINTAINERS | 6 +++ drivers/platform/x86/Kconfig | 9 ++++ drivers/platform/x86/Makefile | 3 ++ drivers/platform/x86/ayaneo-ec.c | 90 ++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 drivers/platform/x86/ayaneo-ec.c diff --git a/MAINTAINERS b/MAINTAINERS index ddecf1ef3bed..c5bf7207c45f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4192,6 +4192,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..1a7f8ae793ba 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -316,6 +316,15 @@ 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" + 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.51.2 From nobody Sat Feb 7 18:21:23 2026 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 36C96314D05; Mon, 10 Nov 2025 18:09:00 +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=1762798142; cv=none; b=duXHqyrcH4xFl3ip1YFq9sYqIxnH4MKed6/elu97UZEkiLm6QBzvU2OtRmH0EkZP9STHlAZ/I7plKmNsNCg3EREK4Vs/J8c+WJXI1Kw9GSwD2Ly7XjLsLBIA+tXckOrRKcT2HHqGfsoHnRvQJ5CbEWHUe1wnlXAzOeErVmNck9c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762798142; c=relaxed/simple; bh=jT2+rAJec85m4Pksligs+QJYHF/0GzOUbBikFjoA2h4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RUTOZs5F2C1ez3p5U7dSA1JFxOZful4MNQhZHdGdZg4/7ICr4MI9HG8GYmbKKhLNq5Mp6N8/gCFBRp4OQaFkKF71x/YSGdrQ3/PptlRESf8+o04fow5IxVnbi71KHYH7Rh+sVZjAhfXGOTTj3RsDoJItzSCa0MQo/Uumap49XeY= 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=k0ePDSxe; 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="k0ePDSxe" Received: from relay11 (localhost.localdomain [127.0.0.1]) by relay11.grserver.gr (Proxmox) with ESMTP id BE07CC3014; Mon, 10 Nov 2025 20:08:52 +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 29CC3C2CBB; Mon, 10 Nov 2025 20:08:52 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 4E155200B90; Mon, 10 Nov 2025 20:08:51 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1762798131; bh=UE/BF9u0dcsC8aROs93IpCxBrcSjUBhKEdO3njtxFWI=; h=From:To:Subject; b=k0ePDSxevjT8hWjcBMmjUIkgvhjQo3KOutOlr4mUizIXvy9mXK6kr6u5JPiGCSsH3 +I8UamPP8xyDBeE/fCJkQZZHXi259Z1Y1xHXVxejQITj+fDcSlOtnuZp9utxaTizfS 9r3GmnDiFdwmsrZBgSDsLF6GNFXXNFI7puM+rnM/MzKU2BlVMfePKAHOq4ymlQuqzm WXfsTV8EBoVc30ZO1uQnChez6dsSStSSFT3IRJjZa/379YCQ23yZRdShKWeGx4UDaE ELdbsB2oB2SAdjD8dl3oGLvHSavYzR93o8buzwR1MhkZas/bADcMYHEUBYr84M3rLL vNS77GMogzGJA== 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 v4 2/6] platform/x86: ayaneo-ec: Add hwmon support Date: Mon, 10 Nov 2025 19:08:42 +0100 Message-ID: <20251110180846.1490726-3-lkml@antheas.dev> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20251110180846.1490726-1-lkml@antheas.dev> References: <20251110180846.1490726-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: <176279813184.3664543.15707535675207559485@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 1a7f8ae793ba..974c174b1a7e 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -318,6 +318,8 @@ config ASUS_TF103C_DOCK =20 config AYANEO_EC tristate "Ayaneo EC platform control" + 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..108a23458a4f 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.51.2 From nobody Sat Feb 7 18:21:23 2026 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 250E42D877E; Mon, 10 Nov 2025 18:08:55 +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=1762798138; cv=none; b=GF4nil5wn13oCVf2Phx1S8hI3rl1gEiIE97fgBiwCswwsJ1cCcP57khIm4LNvaYfyY5IDSSzNHvmRGEL3P34FUiIenOtJ9aMDXQmT4YhaIx1LpfahHi+9n7NPbFXUlqcLGhr6imbKPhREGGrf7hqF7oEyomz1MjoVCFtxbNoO20= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762798138; c=relaxed/simple; bh=T20ZLj8rbn6D9p6SAB4g1X2yJzPnHfq8QCetficHHEM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GCJDdjeNnoAPjnzUcdpSqu5QrE9dR1Vn8Q/30TYMR80J7TCQh0mnMtGAQxoF0j8vewr8boQTIIXrto7GglBYvvAiCB4N7KQ5YCnNIs4bsDFwkREQ5pzg71SI8jIj1i/1d9pPxujZOAm05d3fnLoUnM54GRIugaG0OrDKaddcd8Y= 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=KLpoyqO/; 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="KLpoyqO/" Received: from relay13 (localhost [127.0.0.1]) by relay13.grserver.gr (Proxmox) with ESMTP id DF7A55E626; Mon, 10 Nov 2025 20:08:54 +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 773795E5D8; Mon, 10 Nov 2025 20:08:53 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 1BBA9200EB5; Mon, 10 Nov 2025 20:08:52 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1762798132; bh=W5mPzm3hhsH6AA9r0EdTUQ2Fb9JIfAPSyw8+ZAhiIso=; h=From:To:Subject; b=KLpoyqO/PjUuU8woaECJJ/ZST8gBFuQDIehBQsKISSHWVDan49KMS53jEtm41IUlh Kpqb2ObMFpSOkaa+3mvxLBfiXgquS8n6zqZf72kNeFawy9S87OPBRPBVkeN+xR59Sw ZIKTwWL+316I7+oWat0tnq1taBK6iJWX4elr+tIqcn/U3pWSPV0I4ST5+jniU24Ngu 5bZ7sTqH5F4V1qMh+nF7L1I5OP2dWyTDj8LJKlFFEAdUzm1gOzCcdb26QJt/CC7WQk e0A8KBxj4xutSK9lFmAzkN+s1vrZRO+weOaXBbX8cxayv1+kCH/PdciyBStKiAAdxh iW3FgwY49ZojA== 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 v4 3/6] platform/x86: ayaneo-ec: Add charge control support Date: Mon, 10 Nov 2025 19:08:43 +0100 Message-ID: <20251110180846.1490726-4-lkml@antheas.dev> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20251110180846.1490726-1-lkml@antheas.dev> References: <20251110180846.1490726-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: <176279813261.3664594.9576537115405679421@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 974c174b1a7e..d5be37db997c 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -319,6 +319,7 @@ config ASUS_TF103C_DOCK config AYANEO_EC tristate "Ayaneo EC platform control" 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 108a23458a4f..697bb053a7d6 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.51.2 From nobody Sat Feb 7 18:21:23 2026 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 3B0C93161A3; Mon, 10 Nov 2025 18:09:01 +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=1762798143; cv=none; b=Tx5wg5vgncxCkdUcLjVj+unl7o0ayeZVWiE9ElA52hLEzE8QsxJTXVa1WvlQ6aRgh3lWa8yLGLkcck6z5254Si2IIxgcM6E3r3fp9gbreTMtDuXqv4rmEmhXT1x87wGnFHbVRHxP1HG2l5goicBS949LJK2FKGEp4YDUgqKfzaU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762798143; c=relaxed/simple; bh=zO8HKTJa5YLhqXw893Ymdi8oQkOKbsC897WeL5ASTBA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IMfey58nxKdU4rYFm4iOpWqUeNLzdQutF2QSpTG33MWyjjGVDudQvJej5EqK+A5V6IScBH5+NkJdCEmWw0u5ul96yEu1rqwVthmslJNPxGbMMZ3M8C2VSCpYXzDRCpYU4NmauWB+cI0JnpVv6sEs47hlo507BJBHYyUnFDjAcbA= 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=ViHO/tYb; 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="ViHO/tYb" Received: from relay11 (localhost.localdomain [127.0.0.1]) by relay11.grserver.gr (Proxmox) with ESMTP id A536FC3000; Mon, 10 Nov 2025 20:08:54 +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 CC1D5C3015; Mon, 10 Nov 2025 20:08:53 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id EA0881FCFC4; Mon, 10 Nov 2025 20:08:52 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1762798133; bh=1s3DNmISMr0wFSFsbV18zzeA4NM6RDsEGpEVBAm3Y4E=; h=From:To:Subject; b=ViHO/tYbNCYxIy7XU/O0g3Lc0d7nUgIMod/iCdpvk5r5xKTEGz0Ttgi0b0gSMLmqM j6J6wIUZLtAYEB3bLhqKSAAh3tFWYkREtgeFL63n4qXFtdV5ayrY0bnTAKAN+ixUza ZHItNWYhay8Po8uZAv90lZXM2NTvahov2Aqp06tYdXKbqusVJwdpHv3uwwaB/JeXmO uVjeuVjAHYgqbdL0oF4Y83axH68D3LMlJirXpFeENxkiYsOB5xpwsAzmT4kzEt5yjQ g4iS/gZvU+3ovGTc7b3Rj1vvHasTkJd69glMQUr4MKua6v7UAzrC7wYCvrME3db+tO LKvteKNm0UjSA== 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 v4 4/6] platform/x86: ayaneo-ec: Add controller power and modules attributes Date: Mon, 10 Nov 2025 19:08:44 +0100 Message-ID: <20251110180846.1490726-5-lkml@antheas.dev> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20251110180846.1490726-1-lkml@antheas.dev> References: <20251110180846.1490726-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: <176279813348.3664677.12145099863403819751@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 | 106 ++++++++++++++++++ 3 files changed, 126 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 c5bf7207c45f..f8ab009b6224 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4196,6 +4196,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 697bb053a7d6..0652c044ad76 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,17 @@ #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) + struct ayaneo_ec_quirk { bool has_fan_control; bool has_charge_control; + bool has_magic_modules; }; =20 struct ayaneo_ec_platform_data { @@ -46,6 +56,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 +277,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) +{ + char *out; + int ret; + u8 val; + + ret =3D ec_read(AYANEO_MODULE_REG, &val); + if (ret) + return ret; + + switch (~val & (AYANEO_MODULE_LEFT | AYANEO_MODULE_RIGHT)) { + 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 +412,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.51.2 From nobody Sat Feb 7 18:21:23 2026 Received: from relay10.grserver.gr (relay10.grserver.gr [37.27.248.198]) (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 484C52E7BB4; Mon, 10 Nov 2025 18:08:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=37.27.248.198 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762798139; cv=none; b=DivZ7jWW6EI1NMu9Aw3rVHz6Q8N2HhEx0JBUPeyRkb2hmDWIcYnUE4c8O9VAKJ05fcRwMNPDQC0QA+vWjvqWzsWhvlgmMnFOVDNxUzWKudAJTeX+B9qkmpYRmZtPb1Y/6urjUT5wDrzGlJ087+DvLw+Hg9Ma7ysF9VV2qYsgRYQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762798139; c=relaxed/simple; bh=0LWFDGOlrOvcq8RR748x03+hkEwCE8cRvLQw6UA7bcs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GjHzfRH0uRXWgP84INetwdaEW6MkYeBCcuqpKGJ2wIT4mgXn9v3cjvGmP5hZRBnXK3MueBKxojIxpN4iNBxtUvKriclZgQvU1ye2zeTmw8ffOe0A3rQiHR7E0ul0oQZokLdzDyz9oS0h08YIhgyCiLz0fYfCnulsIB5blCy+6xc= 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=ZPxYQusU; arc=none smtp.client-ip=37.27.248.198 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="ZPxYQusU" Received: from relay10 (localhost.localdomain [127.0.0.1]) by relay10.grserver.gr (Proxmox) with ESMTP id 8C7D93FBE2; Mon, 10 Nov 2025 20:08:55 +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 relay10.grserver.gr (Proxmox) with ESMTPS id C4FE73FB99; Mon, 10 Nov 2025 20:08:54 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id BF2A2200823; Mon, 10 Nov 2025 20:08:53 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1762798134; bh=/JwoClgzoA34amseRDO6s/Zm+XvPWhscfAGReI1ZuO0=; h=From:To:Subject; b=ZPxYQusU8A4vjZVa0U6O0ZJNFLVqHRsSzHxjZPiZB2YC/Zy0LIkYUWt7OkTAB8p9M RMIfKcCKQ/ruVwaMyTes3vhgx5ezZfZW/JxPggh6GXIcCc/t2fLt6zTaF+6RTCt79s buKs0t8tFHBE/8O7k5x6MFzvn444JvyJX2EvweE01iu379gmUZ6sYEE6lfvKEVOpdi pPnjXUExTXGaJW29YLrOoizDoqAxOX3Boc+nj4JLuDsckMQAGVf5VzwofeJc1CoHeW R8tBdu5KEbkFOyUk7QFdF3+lK8OEciSXAhxytCJkDqA3356MQM5tG7Xt6VhNTPWWyS XkrH373++TvCw== 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 v4 5/6] platform/x86: ayaneo-ec: Move Ayaneo devices from oxpec to ayaneo-ec Date: Mon, 10 Nov 2025 19:08:45 +0100 Message-ID: <20251110180846.1490726-6-lkml@antheas.dev> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20251110180846.1490726-1-lkml@antheas.dev> References: <20251110180846.1490726-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: <176279813430.3664756.11609094080758744442@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 d5be37db997c..1927fe229085 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1042,9 +1042,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 0652c044ad76..9548e3d22093 100644 --- a/drivers/platform/x86/ayaneo-ec.c +++ b/drivers/platform/x86/ayaneo-ec.c @@ -53,6 +53,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, @@ -60,6 +69,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.51.2 From nobody Sat Feb 7 18:21:23 2026 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 549B52E92BA; Mon, 10 Nov 2025 18:08:57 +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=1762798139; cv=none; b=tZ9qWKTV/9Lj3RT+UtUhAIn2RIKU6WJiCgDXlGampgDZZrqVaOUD05oTeGYaPhyOAwJtXKtTmuh6d9ZdluI4TbQwlQxGkqMzTWiUOg2IPXQViTyeKt3BDGhSYpWM600uT9RlmWjw46/sbKCsYGLSNR7Vfk93Ncd4i6XMH9RlrWo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762798139; c=relaxed/simple; bh=ZQuJNwIZQjYCB2Ur2PhZH1//YriBqukPRRd0WBh99gc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CZ49HVcB2vgib7WD0AfxsZkXu6lMQLd6N2P6E+H1UQvlOnRfOXbrXQ5BVVhO83E5Q/dDnatc4rsaZAe0M//u2xNXw5wKDHUgAI5nUGIIQq/Tyji2GgJvydI6usDhvEgZuuJYir1xLjbxDgXA02NdNe65pQgN6p5Jc/KNj//fzG4= 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=Jn/T6OQK; 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=temperror (0-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="Jn/T6OQK" Received: from relay13 (localhost [127.0.0.1]) by relay13.grserver.gr (Proxmox) with ESMTP id 99E385E620; Mon, 10 Nov 2025 20:08:56 +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 E2B5D5E612; Mon, 10 Nov 2025 20:08:55 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 932D61FE461; Mon, 10 Nov 2025 20:08:54 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1762798135; bh=r5vFPIuIqw2Ozjx2rDjoRsAOF4F3nnf121dTH3jiqOk=; h=From:To:Subject; b=Jn/T6OQKO86JxAmfufGVkQpEnV6fWJxiVtniEn8FhDAAx4GPsMumFhzSHSkSFFgLy 7rYLc/6tm56cUywBA2lFX969u3EPhSWq95UzXDY9TaGm16bCiae4P76tnSkfDsPV3+ 5Z6ZSqCEaQLJZ22nRo69F160c4+L+b4j5WE20YZi2efONj0QgJx0n1MEoy7DJXMPLh ri8+WEASGT5MzQDiyC37b4fiuXW9u0S4yF5YY07kR1VhXLWk+boDoK1SKMWyTE3g4Y AUEPNUGvK8irmF8gy17IWw7yRCNj3Bpa5TA1+Qtwp8g8BUTp1aTKOdsKwLCAL+pNML fsjXuTNiDnCrA== 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 Subject: [PATCH v4 6/6] platform/x86: ayaneo-ec: Add suspend hook Date: Mon, 10 Nov 2025 19:08:46 +0100 Message-ID: <20251110180846.1490726-7-lkml@antheas.dev> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20251110180846.1490726-1-lkml@antheas.dev> References: <20251110180846.1490726-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: <176279813508.3664791.15761385760381332320@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. Signed-off-by: Antheas Kapenekakis --- drivers/platform/x86/ayaneo-ec.c | 84 +++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/ayaneo-ec.c b/drivers/platform/x86/ayaneo= -ec.c index 9548e3d22093..ee97c326c429 100644 --- a/drivers/platform/x86/ayaneo-ec.c +++ b/drivers/platform/x86/ayaneo-ec.c @@ -51,6 +51,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 { @@ -207,10 +212,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, @@ -224,6 +235,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; @@ -453,11 +475,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); } @@ -474,10 +499,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 &ayaneo_pm_ops, }, .probe =3D ayaneo_ec_probe, }; --=20 2.51.2