From nobody Sun Feb 8 02:56:07 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 04633232395; Fri, 31 Oct 2025 16:36:57 +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=1761928622; cv=none; b=Z74kSeNLigh/f6SYl4494DVtmAn/nFzKMOcD16kAyzq8SDni5YPttqhbRaRGZxkk+VupJxBt4KALUfgFS7Gi6uR8R9kaMKiu//gsszE5LDtPMyouFccJ7yVV1PvCkMbJi4wkSDei1vmQrLBkJzAR5azUH9zkVWcILmQc9HCz6i4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761928622; c=relaxed/simple; bh=TK78dgmBHPfa2+zhWQMNxJ0NT173ZzSSI39b1zX1ZEc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=b6ig9dErGwKpRTO9/ZH/ksLxvPBniUBLb0SPbG7yhwRMU/Gq/YZ9U8wml+PswjAeEBr4P8aN231fyCi5hcC6hCmk8ENgPsp6eTt/KwjSRIpOLCMV95nbM8OY5C0p62s/4ngqlrPBJPHBW32GN1Apg2uF1P8hL7INQLxzjPMg+YA= 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=GaE4hFsG; 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="GaE4hFsG" Received: from relay11 (localhost.localdomain [127.0.0.1]) by relay11.grserver.gr (Proxmox) with ESMTP id 069D6C61CC; Fri, 31 Oct 2025 18:36: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 relay11.grserver.gr (Proxmox) with ESMTPS id 2EE18C6187; Fri, 31 Oct 2025 18:36: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 2AB05200C57; Fri, 31 Oct 2025 18:36:54 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1761928614; bh=9xbmwqw86szpYNRWeyB2pOlJShw5/Q14Vdztv1tqfZU=; h=From:To:Subject; b=GaE4hFsG+blfKOYRios2athEmGsJWpzhWFE8GteyAKCDphZP/ZyJAXw5ERoGbYoQG 8KjaOaZjh8ssCah/BkHxnxwGduaATjJe6bMbOiLXC+VaGSZXQaztKLhG7l3kL1SEGy tnmg5v7axkfhwpTIwzy6R/Z/gxSCoyYrhbYNxEVw3iWTXZNZIOdvBBjHSPVpw7VW/g p56EDl4GQ8b6QLigJ99Vawy4W3o71GOzV7in2/SUGAm6tXTxXMeHLHm4LVFueca482 cKaa6mO57q1xQgYj5DCbNgq4A0ft7HSRp4pHE+T/Lj/s2UuX3cC+cYkqBNDk2rFbjL F+gno3EZnAgXA== 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 v3 1/6] platform/x86: ayaneo-ec: Add Ayaneo Embedded Controller platform driver Date: Fri, 31 Oct 2025 17:36:46 +0100 Message-ID: <20251031163651.1465981-2-lkml@antheas.dev> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251031163651.1465981-1-lkml@antheas.dev> References: <20251031163651.1465981-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: <176192861479.3949040.16198203735017726164@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 545a4776795e..da9498d8cc89 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4187,6 +4187,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 46e62feeda3c..ebe7d2ab8758 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.1 From nobody Sun Feb 8 02:56:07 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 BC1F524466D; Fri, 31 Oct 2025 16:36:58 +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=1761928623; cv=none; b=JFaS17pOJ9ZM+MD8JbgAZono2C1zBZAwhWd505f2OPxi7Jarpe66fu5rFQjI0XAskI8Up15nd4GsWUsIvV1OhugzrFWCxauFs+zyeFWJfJnEjXVaq5wIAgHU4E6KpROv1ABX25iwdkPvSeoO4kEg6uI0eOTn/b/NWm1RNevmZXE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761928623; c=relaxed/simple; bh=HMGMWuUZeC2e4pxi+oMCvQXVGGyvKI6byzeROI8M74A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pqgP1adX3AZwuTB4YEbvWLJE//RpQ5Kl2c0SUjmYwwCmPYuAPg878YR793QzoUaJPIuHyDnWmlBO3rK7EEVotvoqOJ2kcfNuyoKXVsnBtoTpjZR6ddzUrZvU/+UgeA/S4MuJYuLfq5XT9JQ1AWjsY6RL9K9n9DIsiLw/btRXjwI= 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=JF29CZUJ; 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="JF29CZUJ" Received: from relay10 (localhost.localdomain [127.0.0.1]) by relay10.grserver.gr (Proxmox) with ESMTP id BCB0B4648B; Fri, 31 Oct 2025 18:36: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 relay10.grserver.gr (Proxmox) with ESMTPS id 34FD045B48; Fri, 31 Oct 2025 18:36:56 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 32847200C43; Fri, 31 Oct 2025 18:36:55 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1761928615; bh=koXR5UmcruJr+5CDe+8nlbkmyDvna7CeJOVt2ByjF+8=; h=From:To:Subject; b=JF29CZUJdtcRXSVsAPqubmufBWNYWZPYwEwF1Ejm9XcZvhcNxf0krB+d5cH4L7LOq FIr1+pzW7o1UD/6IjEyrUKwjY2Jms8vMkVQStQfTv/BbdRkQKoqRHQMiqX2EHlZdJj OBMEJkV8jMrPHTAmQrjjXS6/J3HqNzJvTrNTriq5SfKZndrCQ+zZ17k4KRwSQTz0m3 j6OUUD6IfjjZDUxJnyygsMX/lufXI75Ye/OnVMnlu9JNTUqhCPLsB9nSi4fm0ZwDpr Z8Kv0qLLH9TuV+7ESjKy8w/b+22Ybd5JetMIis1EWSX/Km8OzyW3eXYwAjcwrt1Wqz 0ZtcSMUq3jQ9w== 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 v3 2/6] platform/x86: ayaneo-ec: Add hwmon support Date: Fri, 31 Oct 2025 17:36:47 +0100 Message-ID: <20251031163651.1465981-3-lkml@antheas.dev> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251031163651.1465981-1-lkml@antheas.dev> References: <20251031163651.1465981-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: <176192861573.3949085.15149187584555663153@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. Signed-off-by: Antheas Kapenekakis Reviewed-by: Armin-Wolf --- 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 ebe7d2ab8758..b3beaff4b03a 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.1 From nobody Sun Feb 8 02:56:07 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 8E1E92BEC52; Fri, 31 Oct 2025 16:37:05 +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=1761928629; cv=none; b=SXwUi2RG+5OLhFp9+S3Sr3bJx25SlF8iUY3N9IEqsVhbo4/lT/hAi8Mjq4m/J5jJngiUztPAbtTraNfM8SPR0Ex+ZllHyJOSN9mii/GeO5JUSoAbw+3Ks4e9yLA+em6X4M7ifcsUJ9QbttNSy24ol9bqlgpyNekltWMQVAMr6H8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761928629; c=relaxed/simple; bh=bqMMOXmrP6uw3H7Bwv7/NxVVe3fH/sA/ndd5CNBuZpA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Whgm3p0ipj0Ra1haz8j0VzJ6nY/LNI1rBb1CfW4w77jThcPJLx+qk3KwVKiDo9U3ff63+Rl2EB9Zm8+wI7aZZabJSePILMZb+uNYbvtVVwukyAYWSn0slfNI9AAHvy3X4I384S4NowGVkTDs2azmubJ6Lk1F9TJWT+WboF2FMqM= 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=HJeNEIue; 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="HJeNEIue" Received: from relay13 (localhost [127.0.0.1]) by relay13.grserver.gr (Proxmox) with ESMTP id 8BFEE5E570; Fri, 31 Oct 2025 18:36:59 +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 849C95E58F; Fri, 31 Oct 2025 18:36:57 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 14414200C57; Fri, 31 Oct 2025 18:36:55 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1761928616; bh=ixQIUvCQ1yl5bg3IC8Mc7sxYdE18wX74fvM8zpBiMjc=; h=From:To:Subject; b=HJeNEIueoIZ0nLM+dd+L4OhixmrA95F4RJTrJFMyX6pyTZ7SwS3lskA1hbCIBi+/6 50SBGDRssYZRJE+BDc8tC+ngRDklX3Kpkk15NIJjk1/2WUngsLlcEFwTwxWjt/tnaa xqKpgqpK9DLQivhXQ0kTSEc3ZpQW/RKl/mjnvZqbBQrGZvdOo6sSS3vZDXTHIQv8yF abb/kxVcqZ/0uRcSsqh71S63hpOuiwDBtV6gAqzPSLNzMcPnD3u0Ud/c8vXEVe5N3Q HSU3naSDB2uQhbHgArIqVdJJycCtstcau5E2+5X07Kths7Gdp/lFxSB94IZyWD1T/m qiyq+X6+Odrbw== 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 v3 3/6] platform/x86: ayaneo-ec: Add charge control support Date: Fri, 31 Oct 2025 17:36:48 +0100 Message-ID: <20251031163651.1465981-4-lkml@antheas.dev> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251031163651.1465981-1-lkml@antheas.dev> References: <20251031163651.1465981-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: <176192861661.3949147.132334295208550071@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 b3beaff4b03a..a45449ae83f8 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.1 From nobody Sun Feb 8 02:56:07 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 A79B32EC571; Fri, 31 Oct 2025 16:37:06 +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=1761928630; cv=none; b=lGolVXgAL8AL25D9rYVGTcyb2D3BBmJ9Pw2gAY0EUXXBSr+x+cIdG4ykqlF/3JF3jQmB7tEz5EyWxfxBWhENvauyTSMZRj/YElOGl+Nlup2MpFio7vg4ViDnP6ADhQHRjcHqHpMUmrukGN8CjydMnD5q1j25IP8k95Fk5TRZ8D0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761928630; c=relaxed/simple; bh=NkMQqM6g8Z26yyC688U6scWFlt4xbGcpQ3OW0MO8lh8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SnZb+GfwC8/iH/4/OiPG0YYxAWUYzrYgKvylbEeaO2mBs16csVWskD1djKAE8ThpX7zRy+cKywChB9MQhCMZJp6TumGss5NqZB5jdxacWysnF9DPNW2PcoLnlYRrgM8+xv8Km6q9ZTmVG4wBHdxlmEHRGEQNY+tRPV5ADJvEspk= 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=NKP3xKc1; 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="NKP3xKc1" Received: from relay12 (localhost [127.0.0.1]) by relay12.grserver.gr (Proxmox) with ESMTP id C20A8BDD28; Fri, 31 Oct 2025 18:36:58 +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 E54A8BDCD8; Fri, 31 Oct 2025 18:36:57 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 0A8A2200CBD; Fri, 31 Oct 2025 18:36:57 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1761928617; bh=oa44aZAO9DdfSe5ySrnFHWgZ/hRclz1+svHrWdk6014=; h=From:To:Subject; b=NKP3xKc1NnykuwHrVbFr2WdWPdTOGorPGgDmZxGATuKbYky8xQziSLtTnIHfkTAwY 9c06oUQMi7hhdHpaBPRBSnHoNpDRWZ7mv8JFHPUckeywjzfIOESZ8IJ016XQPSnKVq 8v4uv0CgHDmUvzHTuKJtEB4aecDOGpNpbDnWgoC5OTRUrJjV71okd7b+jTrl4P9lA5 J3uaqX3+r160hLaqr2CZwHoW3sxm2sXGrPHcGoJxerHxf/Lo/fB30AhAsDTV4xxif7 nwsmKYqBWy6kIs42QdcXDwdG9dPwXwsuoCsV+ZcEjaDvZiHg1V8eP4riMwlC2Ky0FU bxVKKMkZC8ViQ== 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 v3 4/6] platform/x86: ayaneo-ec: Add controller power and modules attributes Date: Fri, 31 Oct 2025 17:36:49 +0100 Message-ID: <20251031163651.1465981-5-lkml@antheas.dev> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251031163651.1465981-1-lkml@antheas.dev> References: <20251031163651.1465981-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: <176192861758.3949204.7723636090175618120@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..3c9c3580c685 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-ayaneo-ec @@ -0,0 +1,19 @@ +What: /sys/devices/platform/ayaneo-ec/controller_power +Date: Oct 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: Oct 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 da9498d8cc89..b4d62ea9a926 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4191,6 +4191,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.1 From nobody Sun Feb 8 02:56:07 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 4B8821E520A; Fri, 31 Oct 2025 16:37:06 +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=1761928630; cv=none; b=GsmVASFdEBI+hxpC+beqasQ8E4UFErR23zYTb2cn1OspSFVO6sXncy/IN2POCE3pZpT6rSZri3kmbWwrGbiYp9pWXp1ynw8cXyxq/YbjpJGiCof46mpsckyoFNUdiubrVGtDgkv1mbKg7nHHTjWxvy2aBJzoP6ueLoEgW7/srN8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761928630; c=relaxed/simple; bh=aclceXh3FOFrVf756t7t6HjUEkNBAmtcCInfN1P5BiI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ooCST24qG56W5Y++hvvKZD0ZLV4PT2VkyITi5MqZzhEWJt8X/I5bo40k9sNvjyC73eXgEZUcNx+t+X6soIqR1ORbOAZpYGednCFAyTL46SmT7eXW6wEpR8UvBJIAx4A0ikZSriuAEScL/EPzn4Tikrg+NQ0UNnR+kDUhfrW2+FI= 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=AJo9WbSa; 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="AJo9WbSa" Received: from relay13 (localhost [127.0.0.1]) by relay13.grserver.gr (Proxmox) with ESMTP id 9CEBF5E51F; Fri, 31 Oct 2025 18:37:00 +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 612E15E58E; Fri, 31 Oct 2025 18:36:59 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id ED96F200C57; Fri, 31 Oct 2025 18:36:57 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1761928618; bh=NoOd8aRPg5p392Veb8G8OrEZBQDVz/Tq1sBEu9fmk0E=; h=From:To:Subject; b=AJo9WbSaHiMn/MwdqAHU/vPeeuAHRVnm+jm4OhwUpnMxVVJ5XdzTlAs8zIQEurrFQ vxlfuP7l0W2ycP8cRlJ4c0Wt+DevmzCsGLiFxXnzQPiU33bM02piHs1oh8W8NbPwJZ BVTiC1Idbz1hQtd4HbWTMRhDm4BP9l78sDW7L5cPrxnClugUQ7MUe/yu41jyY+EBY0 leRs71QRcvWqHBC2DsbqJ4+NqD0iYwEsr1bOZHEfV0woPRMZRkYgaE8WFqwWzYCsUO 6AEduL14iwZZdG8+QaiInk+xU3u1VPIEXxUewBVMkXLTtxtisA8LYzMMBuh7sk5iqG hKE76AqrhLGxw== 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 v3 5/6] platform/x86: ayaneo-ec: Move Ayaneo devices from oxpec to ayaneo-ec Date: Fri, 31 Oct 2025 17:36:50 +0100 Message-ID: <20251031163651.1465981-6-lkml@antheas.dev> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251031163651.1465981-1-lkml@antheas.dev> References: <20251031163651.1465981-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: <176192861853.3949264.12911444964400847176@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 a45449ae83f8..b603f8a3bd52 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.1 From nobody Sun Feb 8 02:56:07 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 19E9A296159; Fri, 31 Oct 2025 16:37:01 +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=1761928625; cv=none; b=n2D3lIU8eEtTnUYkyyHvmFwRCDiB3pq5JRPm0pGTqdXXxaVlZzzPRmWqh6MDSNz5ULzOijIKGdLfiQicDPzt7bTTwKtjnfXb16ywYUYJGOjMdkJttsJkK7rC+SmBEsRT8GA8EH5dum30qvvqZjxOQaPf4D4dB2IZuV9EsqoegBI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761928625; c=relaxed/simple; bh=5/MkzF4b0enGlcC8P6GU9B36DychBhk89uhfjulbGpA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OLpRW76oAATTLOBZTnOxBJhfwFs7nX4vBCIOFWemPmYCEVJ0JkAY9Tt+9f5dk/905h8nPlkJhz2yy6TYOT2e4g54sQtyY/wSGNA7SzF3MVLUEX63hz7SOn1HS9rLYlhC7gjpdW0o5Av1WyRI74QGycYX4gBcdg3UgQ2jSqm3ngU= 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=YHOLOb8C; 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="YHOLOb8C" Received: from relay10 (localhost.localdomain [127.0.0.1]) by relay10.grserver.gr (Proxmox) with ESMTP id 58E6D464D1; Fri, 31 Oct 2025 18:37:00 +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 D6A6E45F00; Fri, 31 Oct 2025 18:36:59 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a05:f6c2:511b:0:8d8a:5967:d692:ea4e]) by linux3247.grserver.gr (Postfix) with ESMTPSA id D801E200C43; Fri, 31 Oct 2025 18:36:58 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1761928619; bh=eaCcJl1/Nu0H6MYEFWCb5trAxgrURxKusB7XqUtYWpw=; h=From:To:Subject; b=YHOLOb8C5iZo7FcEwOLHEQnbtpDuP6hUOLS3cg6FUQWvmUcj8MMY82W6iHORlcADt SMUcCwb1GUerLPgo6C0l4UQq5m29hX6fUaCC5QNC5eD0zVzPSLLgSfU7/lEL3gWHCN HPv4eKFLZlU2qR9LA9LJHbiapFb4ruZ8hKQ76VYlRWO6d4Q5JkUTtYrLvQ2zr22TTC prpZAXnmAnZKEFvauF48wTmgYxMZQyp6CmEu1hr0HRsnoNrjRByvff6PusXcp+qQZU EhY9gjtPwGN8g0SJEiBPFJEcmrXNVb5SsJwwrzwTZUMH6fkhACVmAZ1NJr2zBneNv4 MsxfpHRVm4m7A== 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 v3 6/6] platform/x86: ayaneo-ec: Add suspend hook Date: Fri, 31 Oct 2025 17:36:51 +0100 Message-ID: <20251031163651.1465981-7-lkml@antheas.dev> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251031163651.1465981-1-lkml@antheas.dev> References: <20251031163651.1465981-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: <176192861939.3949331.11112013268147092094@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 | 73 ++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/drivers/platform/x86/ayaneo-ec.c b/drivers/platform/x86/ayaneo= -ec.c index 9548e3d22093..e1ad5968d3b4 100644 --- a/drivers/platform/x86/ayaneo-ec.c +++ b/drivers/platform/x86/ayaneo-ec.c @@ -41,6 +41,8 @@ #define AYANEO_MODULE_LEFT BIT(0) #define AYANEO_MODULE_RIGHT BIT(1) =20 +#define AYANEO_CACHE_LEN 1 + struct ayaneo_ec_quirk { bool has_fan_control; bool has_charge_control; @@ -51,6 +53,9 @@ struct ayaneo_ec_platform_data { struct platform_device *pdev; struct ayaneo_ec_quirk *quirks; struct acpi_battery_hook battery_hook; + + bool restore_charge_limit; + bool restore_pwm; }; =20 static const struct ayaneo_ec_quirk quirk_fan =3D { @@ -207,10 +212,14 @@ 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 platform_get_drvdata( + to_platform_device(dev)); + int ret; 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 +233,15 @@ 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; @@ -474,10 +492,65 @@ 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.1