* [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86
@ 2025-03-19 17:54 Antheas Kapenekakis
2025-03-19 17:54 ` [PATCH v6 01/14] hwmon: (oxp-sensors) Distinguish the X1 variants Antheas Kapenekakis
` (14 more replies)
0 siblings, 15 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:54 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
This four part series updates the oxpsensors module to bring it in line
with its Windows OneXPlayer counterpart. First, it adds support for all
2024, 2025 OneXPlayer handhelds and their special variants. Then, it moves
the module to platform/x86 to allow for including more EC features.
Then, it adds the new charge limiting and bypass features that were first
introduced in the X1 and retrofit to older OneXFly variants and for
controlling the turbo led found in the X1 models. For Bypass, it adds a new
charge_behaviour variant called inhibit-charge-s0.
Finally, it performs a minor refactor by moving around switch statements
into their own functions, in order to allow for fixing the pwm1_enable ABI
in the final patch. Currently, pwm1_enable sets the fan to auto with the
value 0 and allows manual control with the value 1. This patch makes it
so 0 sets the fan to full speed, 1 sets the fan to manual control, and
2 sets the fan to auto. This requires both setting enable and the fan
speed when the enable sysfs is written to as 0, hence the refactor.
As this is a minor ABI break and there is userspace software relying
on this previous behavior, the last patch also changes the /name of the
hwmon endpoint to "oxp_ec" from "oxpec" (mirroring WMI module conventions)
such that userspace software that relied on the previous behavior can be
retrofit to the new kernel while enabling correct functionality on old
and new kernels. Failing that, software that is not updated will just
stop controlling the fans, ensuring no malignant behavior.
---
V5: https://lore.kernel.org/all/20250317155349.1236188-1-lkml@antheas.dev/
V4: https://lore.kernel.org/all/20250311165406.331046-1-lkml@antheas.dev/
V3: https://lore.kernel.org/all/20250309112114.1177361-1-lkml@antheas.dev/
Changes since V5:
- Separate doc entries with Fixes as by Mario
- Add sysfs file name to subject as per Thomas
- Make tt_led and tt_turbo const as per Thomas
- Align a couple of structs as per Thomas
- Remove excess battery check as per Thomas
- For Thomas: devices without a BIOS update battery control is a NOOP
OXP is a boutique manufacturer for now, so gathering information
about old devices to add BIOS checks is not practical unfortunately
Changes since V4:
- Fix nits by Hans
- change inhibit-charge-s0 to inhibit-charge-awake
- use devm_battery_hook_register and power_supply_unregister_extension
(based on cros driver)
- move charge behavior patches to the end to make the rest of the series
easier to merge
- CC platform-x86 and power maintainers
Changes since V3:
- Fix nits by Derek
- Remove the hwmon documentation as it is not required for platform
drivers (suggested by Guenter)
- Add ACPI_BATTERY and HWMON depends to Kconfig
(reported by kernel robot)
- Homogenize driver into following reverse xmas convention
Changes since V2:
- Add ack by Guenter, move platform move patch to be third (not first
to allow for device support backport to lts kernels)
- Rework patch text, especially in the refactor patches as per Derek
- Change bypass to use charge_behaviour instead of charge_type, as that
ABI supports capability detection and is more appropriate
- Move battery attach to probe instead of init
- Fix bug where reading tt_led would instead use the turbo register
Changes since V1:
- Add X1 Pro, F1 Pro variants
- Fix minor typo in initial patches
- Convert oxp-sensors into a platform driver, as it is no longer
considered a hwmon driver.
- Add sysfs documentation and myself to the MAINTAINERS file
- Update documentation to state that this is the OneXPlayer/AOKZOE
platform driver, and that support for Ayaneo/OPI is provided until
they gain their own platform driver.
Antheas Kapenekakis (14):
hwmon: (oxp-sensors) Distinguish the X1 variants
hwmon: (oxp-sensors) Add all OneXFly variants
platform/x86: oxpec: Move hwmon/oxp-sensors to platform/x86
ABI: testing: sysfs-class-oxp: add missing documentation
ABI: testing: sysfs-class-oxp: add tt_led attribute documentation
platform/x86: oxpec: Rename ec group to tt_toggle
platform/x86: oxpec: Add turbo led support to X1 devices
platform/x86: oxpec: Move pwm_enable read to its own function
platform/x86: oxpec: Move pwm value read/write to separate functions
platform/x86: oxpec: Move fan speed read to separate function
platform/x86: oxpec: Adhere to sysfs-class-hwmon and enable pwm on 2
platform/x86: oxpec: Follow reverse xmas convention for tt_toggle
power: supply: add inhibit-charge-awake to charge_behaviour
platform/x86: oxpec: Add charge threshold and behaviour to OneXPlayer
Documentation/ABI/testing/sysfs-class-power | 11 +-
Documentation/ABI/testing/sysfs-platform-oxp | 25 +
Documentation/hwmon/index.rst | 2 +-
Documentation/hwmon/oxp-sensors.rst | 89 ---
MAINTAINERS | 7 +-
drivers/hwmon/Kconfig | 11 -
drivers/hwmon/Makefile | 1 -
drivers/platform/x86/Kconfig | 13 +
drivers/platform/x86/Makefile | 3 +
.../oxp-sensors.c => platform/x86/oxpec.c} | 624 ++++++++++++++----
drivers/power/supply/power_supply_sysfs.c | 7 +-
drivers/power/supply/test_power.c | 1 +
include/linux/power_supply.h | 1 +
13 files changed, 540 insertions(+), 255 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-platform-oxp
delete mode 100644 Documentation/hwmon/oxp-sensors.rst
rename drivers/{hwmon/oxp-sensors.c => platform/x86/oxpec.c} (52%)
base-commit: 4701f33a10702d5fc577c32434eb62adde0a1ae1
--
2.48.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v6 01/14] hwmon: (oxp-sensors) Distinguish the X1 variants
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
@ 2025-03-19 17:54 ` Antheas Kapenekakis
2025-03-19 17:54 ` [PATCH v6 02/14] hwmon: (oxp-sensors) Add all OneXFly variants Antheas Kapenekakis
` (13 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:54 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
Currently, the oxp-sensors driver fuzzy matches the X1 variants. Luckily,
X1 and X1 mini share most hardware features so this works. However, they
are completely different product lines, and there is an expectation that
OneXPlayer will release more devices in the X1 line that may have
differences.
Therefore, distinguish the 3 devices that currently exist in the market.
These are the OneXPlayer X1 AMD and Intel variants, and the X1 mini which
only has an AMD variant. As far as registers go, all three support the
current driver functionality.
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
drivers/hwmon/oxp-sensors.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/oxp-sensors.c b/drivers/hwmon/oxp-sensors.c
index 83730d9318240..5a4230ad3757e 100644
--- a/drivers/hwmon/oxp-sensors.c
+++ b/drivers/hwmon/oxp-sensors.c
@@ -205,7 +205,28 @@ static const struct dmi_system_id dmi_table[] = {
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
- DMI_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X1"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X1 A"),
+ },
+ .driver_data = (void *)oxp_x1,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X1 i"),
+ },
+ .driver_data = (void *)oxp_x1,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X1 mini"),
+ },
+ .driver_data = (void *)oxp_x1,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X1Pro"),
},
.driver_data = (void *)oxp_x1,
},
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 02/14] hwmon: (oxp-sensors) Add all OneXFly variants
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
2025-03-19 17:54 ` [PATCH v6 01/14] hwmon: (oxp-sensors) Distinguish the X1 variants Antheas Kapenekakis
@ 2025-03-19 17:54 ` Antheas Kapenekakis
2025-03-19 17:54 ` [PATCH v6 03/14] platform/x86: oxpec: Move hwmon/oxp-sensors to platform/x86 Antheas Kapenekakis
` (12 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:54 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
Currently, the driver only has the F1 OneXFly variant, which was based
on the 7000 AMD platform. Add its special editions: F1 EVA-01, F1 OLED.
F1 OLED might have been a dev unit, but it is supported by OneXConsole
with the same features so add it. Then add the F1L variant which is
based on the 8000 AMD platform and the F1Pro and its special edition
EVA-02.
One might ask why not just fuzzy match. Well, EVA-02 is a variant of
F1Pro which is a Strix Point handheld, but does not have F1Pro in its
name. This makes it risky to fuzzy match, as special variants in the
future from different platforms might not have the same feature set
or registers.
By happenstance, all current devices use the same registers. For the
charge limitting feature on this series, only F1Pro/X1 (AMD) were
released with it, but OneXPlayer is providing bios updates for F1, F1L,
X1 Mini units that use the same register, so treat all of them the same.
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
drivers/hwmon/oxp-sensors.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/drivers/hwmon/oxp-sensors.c b/drivers/hwmon/oxp-sensors.c
index 5a4230ad3757e..f7a64fbc8f33e 100644
--- a/drivers/hwmon/oxp-sensors.c
+++ b/drivers/hwmon/oxp-sensors.c
@@ -188,6 +188,41 @@ static const struct dmi_system_id dmi_table[] = {
},
.driver_data = (void *)oxp_fly,
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER F1 EVA-01"),
+ },
+ .driver_data = (void *)oxp_fly,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER F1 OLED"),
+ },
+ .driver_data = (void *)oxp_fly,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER F1L"),
+ },
+ .driver_data = (void *)oxp_fly,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER F1Pro"),
+ },
+ .driver_data = (void *)oxp_fly,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER F1 EVA-02"),
+ },
+ .driver_data = (void *)oxp_fly,
+ },
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 03/14] platform/x86: oxpec: Move hwmon/oxp-sensors to platform/x86
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
2025-03-19 17:54 ` [PATCH v6 01/14] hwmon: (oxp-sensors) Distinguish the X1 variants Antheas Kapenekakis
2025-03-19 17:54 ` [PATCH v6 02/14] hwmon: (oxp-sensors) Add all OneXFly variants Antheas Kapenekakis
@ 2025-03-19 17:54 ` Antheas Kapenekakis
2025-03-19 17:54 ` [PATCH v6 04/14] ABI: testing: sysfs-class-oxp: add missing documentation Antheas Kapenekakis
` (11 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:54 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
The EC of OneXPlayer devices used to only control the fan.
This is no longer the case, with the EC of OneXPlayer gaining
additional functionality (turbo button, turbo led, battery controls).
As it will be beneficial from a complexity perspective
to retain this driver as a single unit, move it out
of hwmon, and into platform/x86. Also, remove the
hwmon documentation to avoid it becoming stale.
While at it, add myself to the maintainer's file.
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
Documentation/hwmon/index.rst | 2 +-
Documentation/hwmon/oxp-sensors.rst | 89 -------------------
MAINTAINERS | 7 +-
drivers/hwmon/Kconfig | 11 ---
drivers/hwmon/Makefile | 1 -
drivers/platform/x86/Kconfig | 12 +++
drivers/platform/x86/Makefile | 3 +
.../oxp-sensors.c => platform/x86/oxpec.c} | 10 +--
8 files changed, 24 insertions(+), 111 deletions(-)
delete mode 100644 Documentation/hwmon/oxp-sensors.rst
rename drivers/{hwmon/oxp-sensors.c => platform/x86/oxpec.c} (98%)
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 874f8fd263252..dd7a54d5f2816 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -186,7 +186,7 @@ Hardware Monitoring Kernel Drivers
nzxt-kraken3
nzxt-smart2
occ
- oxp-sensors
+ oxpec
pc87360
pc87427
pcf8591
diff --git a/Documentation/hwmon/oxp-sensors.rst b/Documentation/hwmon/oxp-sensors.rst
deleted file mode 100644
index 581c4dafbfa13..0000000000000
--- a/Documentation/hwmon/oxp-sensors.rst
+++ /dev/null
@@ -1,89 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0-or-later
-
-Kernel driver oxp-sensors
-=========================
-
-Authors:
- - Derek John Clark <derekjohn.clark@gmail.com>
- - Joaquín Ignacio Aramendía <samsagax@gmail.com>
-
-Description:
-------------
-
-Handheld devices from OneNetbook, AOKZOE, AYANEO, And OrangePi provide fan
-readings and fan control through their embedded controllers.
-
-Currently supports OneXPlayer devices, AOKZOE, AYANEO, and OrangePi
-handheld devices. AYANEO devices preceding the AIR and OneXPlayer devices
-preceding the Mini A07 are not supportable as the EC model is different
-and do not have manual control capabilities.
-
-Some OneXPlayer and AOKZOE models have a toggle for changing the behaviour
-of the "Turbo/Silent" button of the device. It will change the key event
-that it triggers with a flip of the `tt_toggle` attribute. See below for
-boards that support this function.
-
-Supported devices
------------------
-
-Currently the driver supports the following handhelds:
-
- - AOKZOE A1
- - AOKZOE A1 PRO
- - AYANEO 2
- - AYANEO 2S
- - AYANEO AIR
- - AYANEO AIR 1S
- - AYANEO AIR Plus (Mendocino)
- - AYANEO AIR Pro
- - AYANEO Flip DS
- - AYANEO Flip KB
- - AYANEO Geek
- - AYANEO Geek 1S
- - AYANEO KUN
- - OneXPlayer 2
- - OneXPlayer 2 Pro
- - OneXPlayer AMD
- - OneXPlayer mini AMD
- - OneXPlayer mini AMD PRO
- - OneXPlayer OneXFly
- - OneXPlayer X1 A
- - OneXPlayer X1 i
- - OneXPlayer X1 mini
- - OrangePi NEO-01
-
-"Turbo/Silent" button behaviour toggle is only supported on:
- - AOK ZOE A1
- - AOK ZOE A1 PRO
- - OneXPlayer 2
- - OneXPlayer 2 Pro
- - OneXPlayer mini AMD (only with updated alpha BIOS)
- - OneXPlayer mini AMD PRO
- - OneXPlayer OneXFly
- - OneXPlayer X1 A
- - OneXPlayer X1 i
- - OneXPlayer X1 mini
-
-Sysfs entries
--------------
-
-The following attributes are supported:
-
-fan1_input
- Read Only. Reads current fan RPM.
-
-pwm1_enable
- Read Write. Enable manual fan control. Write "1" to set to manual, write "0"
- to let the EC control de fan speed. Read this attribute to see current status.
-
-pwm1
- Read Write. Read this attribute to see current duty cycle in the range [0-255].
- When pwm1_enable is set to "1" (manual) write any value in the range [0-255]
- to set fan speed.
-
-tt_toggle
- Read Write. Read this attribute to check the status of the turbo/silent
- button behaviour function. Write "1" to activate the switch and "0" to
- deactivate it. The specific keycodes and behaviour is specific to the device
- both with this function on and off. This attribute is attached to the platform
- driver and not to the hwmon driver (/sys/devices/platform/oxp-platform/tt_toggle)
diff --git a/MAINTAINERS b/MAINTAINERS
index c9763412a5089..20720f92e4a63 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17656,12 +17656,13 @@ S: Maintained
F: drivers/mtd/nand/onenand/
F: include/linux/mtd/onenand*.h
-ONEXPLAYER FAN DRIVER
+ONEXPLAYER PLATFORM EC DRIVER
+M: Antheas Kapenekakis <lkml@antheas.dev>
M: Derek John Clark <derekjohn.clark@gmail.com>
M: Joaquín Ignacio Aramendía <samsagax@gmail.com>
-L: linux-hwmon@vger.kernel.org
+L: platform-driver-x86@vger.kernel.org
S: Maintained
-F: drivers/hwmon/oxp-sensors.c
+F: drivers/platform/x86/oxpec.c
ONIE TLV NVMEM LAYOUT DRIVER
M: Miquel Raynal <miquel.raynal@bootlin.com>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 4cbaba15d86ef..09f7aed96d15e 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1774,17 +1774,6 @@ config SENSORS_NZXT_SMART2
source "drivers/hwmon/occ/Kconfig"
-config SENSORS_OXP
- tristate "OneXPlayer EC fan control"
- depends on ACPI_EC
- depends on X86
- help
- If you say yes here you get support for fan readings and control over
- OneXPlayer handheld devices. Only OneXPlayer mini AMD handheld variant
- boards are supported.
-
- Can also be built as a module. In that case it will be called oxp-sensors.
-
config SENSORS_PCF8591
tristate "Philips PCF8591 ADC/DAC"
depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index b7ef0f0562d37..0edb08824b178 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -181,7 +181,6 @@ obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o
obj-$(CONFIG_SENSORS_NZXT_KRAKEN2) += nzxt-kraken2.o
obj-$(CONFIG_SENSORS_NZXT_KRAKEN3) += nzxt-kraken3.o
obj-$(CONFIG_SENSORS_NZXT_SMART2) += nzxt-smart2.o
-obj-$(CONFIG_SENSORS_OXP) += oxp-sensors.o
obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 0258dd879d64b..82cfc76bc5c9f 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1186,6 +1186,18 @@ config SEL3350_PLATFORM
To compile this driver as a module, choose M here: the module
will be called sel3350-platform.
+config OXP_EC
+ tristate "OneXPlayer EC platform control"
+ depends on ACPI_EC
+ depends on HWMON
+ depends on X86
+ 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.
+
endif # X86_PLATFORM_DEVICES
config P2SB
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index e1b1429470674..f64a191c1162e 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -153,3 +153,6 @@ obj-$(CONFIG_WINMATE_FM07_KEYS) += winmate-fm07-keys.o
# SEL
obj-$(CONFIG_SEL3350_PLATFORM) += sel3350-platform.o
+
+# OneXPlayer
+obj-$(CONFIG_OXP_EC) += oxpec.o
\ No newline at end of file
diff --git a/drivers/hwmon/oxp-sensors.c b/drivers/platform/x86/oxpec.c
similarity index 98%
rename from drivers/hwmon/oxp-sensors.c
rename to drivers/platform/x86/oxpec.c
index f7a64fbc8f33e..dc3a0871809cd 100644
--- a/drivers/hwmon/oxp-sensors.c
+++ b/drivers/platform/x86/oxpec.c
@@ -1,11 +1,8 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Platform driver for OneXPlayer, AOKZOE, AYANEO, and OrangePi Handhelds
- * that expose fan reading and control via hwmon sysfs.
- *
- * Old OXP boards have the same DMI strings and they are told apart by
- * the boot cpu vendor (Intel/AMD). Of these older models only AMD is
- * supported.
+ * Platform driver for OneXPlayer and AOKZOE devices. For the time being,
+ * it also exposes fan controls for AYANEO, and OrangePi Handhelds via
+ * hwmon sysfs.
*
* 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
@@ -16,6 +13,7 @@
*
* Copyright (C) 2022 Joaquín I. Aramendía <samsagax@gmail.com>
* Copyright (C) 2024 Derek J. Clark <derekjohn.clark@gmail.com>
+ * Copyright (C) 2025 Antheas Kapenekakis <lkml@antheas.dev>
*/
#include <linux/acpi.h>
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 04/14] ABI: testing: sysfs-class-oxp: add missing documentation
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (2 preceding siblings ...)
2025-03-19 17:54 ` [PATCH v6 03/14] platform/x86: oxpec: Move hwmon/oxp-sensors to platform/x86 Antheas Kapenekakis
@ 2025-03-19 17:54 ` Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 05/14] ABI: testing: sysfs-class-oxp: add tt_led attribute documentation Antheas Kapenekakis
` (10 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:54 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
Add missing documentation about the tt_toggle attribute that was
added in kernel 6.5.
Fixes: be144ee491272 ("hwmon: (oxp-sensors) Add tt_toggle attribute on supported boards")
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
Documentation/ABI/testing/sysfs-platform-oxp | 13 +++++++++++++
1 file changed, 13 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-platform-oxp
diff --git a/Documentation/ABI/testing/sysfs-platform-oxp b/Documentation/ABI/testing/sysfs-platform-oxp
new file mode 100644
index 0000000000000..091269ab2c8c4
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-platform-oxp
@@ -0,0 +1,13 @@
+What: /sys/devices/platform/<platform>/tt_toggle
+Date: Jun 2023
+KernelVersion: 6.5
+Contact: "Antheas Kapenekakis" <lkml@antheas.dev>
+Description:
+ Takeover TDP controls from the device. OneXPlayer devices have a
+ turbo button that can be used to switch between two TDP modes
+ (usually 15W and 25W). By setting this attribute to 1, this
+ functionality is disabled, handing TDP control over to (Windows)
+ userspace software and the Turbo button turns into a keyboard
+ shortcut over the AT keyboard of the device. In addition,
+ using this setting is a prerequisite for PWM control for most
+ newer models (otherwise it NOOPs).
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 05/14] ABI: testing: sysfs-class-oxp: add tt_led attribute documentation
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (3 preceding siblings ...)
2025-03-19 17:54 ` [PATCH v6 04/14] ABI: testing: sysfs-class-oxp: add missing documentation Antheas Kapenekakis
@ 2025-03-19 17:55 ` Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 06/14] platform/x86: oxpec: Rename ec group to tt_toggle Antheas Kapenekakis
` (9 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:55 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
Adds documentation about the tt_led attribute of OneXPlayer devices
to the sysfs-class-oxp ABI documentation.
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
Documentation/ABI/testing/sysfs-platform-oxp | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-platform-oxp b/Documentation/ABI/testing/sysfs-platform-oxp
index 091269ab2c8c4..ccf8e5902cf86 100644
--- a/Documentation/ABI/testing/sysfs-platform-oxp
+++ b/Documentation/ABI/testing/sysfs-platform-oxp
@@ -11,3 +11,15 @@ Description:
shortcut over the AT keyboard of the device. In addition,
using this setting is a prerequisite for PWM control for most
newer models (otherwise it NOOPs).
+
+What: /sys/devices/platform/<platform>/tt_led
+Date: Feb 2025
+KernelVersion: 6.15
+Contact: "Antheas Kapenekakis" <lkml@antheas.dev>
+Description:
+ Some OneXPlayer devices (e.g., X1 series) feature a little LED
+ nested in the Turbo button. This LED is illuminated when the
+ device is in the higher TDP mode (e.g., 25W). Once tt_toggle
+ is engaged, this LED is left dangling to its last state. This
+ attribute allows userspace to control the LED state manually
+ (either with 1 or 0). Only a subset of devices contain this LED.
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 06/14] platform/x86: oxpec: Rename ec group to tt_toggle
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (4 preceding siblings ...)
2025-03-19 17:55 ` [PATCH v6 05/14] ABI: testing: sysfs-class-oxp: add tt_led attribute documentation Antheas Kapenekakis
@ 2025-03-19 17:55 ` Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 07/14] platform/x86: oxpec: Add turbo led support to X1 devices Antheas Kapenekakis
` (8 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:55 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
Currently, the EC group is used for the turbo button. However, the next
patch in the series adds support for the LED button in X1 devices, which
is only applicable for X1 devices. Therefore, rename it to prepare for
adding the second group. And make it const while at it.
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
drivers/platform/x86/oxpec.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c
index dc3a0871809cd..78ab87be3dbf7 100644
--- a/drivers/platform/x86/oxpec.c
+++ b/drivers/platform/x86/oxpec.c
@@ -681,18 +681,18 @@ static const struct hwmon_channel_info * const oxp_platform_sensors[] = {
NULL,
};
-static struct attribute *oxp_ec_attrs[] = {
+static const struct attribute *oxp_tt_toggle_attrs[] = {
&dev_attr_tt_toggle.attr,
NULL
};
-static struct attribute_group oxp_ec_attribute_group = {
+static const struct attribute_group oxp_tt_toggle_attribute_group = {
.is_visible = tt_toggle_is_visible,
- .attrs = oxp_ec_attrs,
+ .attrs = oxp_tt_toggle_attrs,
};
static const struct attribute_group *oxp_ec_groups[] = {
- &oxp_ec_attribute_group,
+ &oxp_tt_toggle_attribute_group,
NULL
};
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 07/14] platform/x86: oxpec: Add turbo led support to X1 devices
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (5 preceding siblings ...)
2025-03-19 17:55 ` [PATCH v6 06/14] platform/x86: oxpec: Rename ec group to tt_toggle Antheas Kapenekakis
@ 2025-03-19 17:55 ` Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 08/14] platform/x86: oxpec: Move pwm_enable read to its own function Antheas Kapenekakis
` (7 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:55 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
The X1 and X1 mini lineups feature an LED nested within their turbo
button. When turbo takeover is not enabled, the turbo button allows
the device to switch from 18W to 25W TDP. When the device is in the
25W TDP mode, the LED is turned on.
However, when we engage turbo takeover, the turbo led remains on its
last state, which might be illuminated and cannot be currently
controlled. Therefore, add the register that controls it under sysfs,
to allow userspace to turn it off once engaging turbo takeover and
then control it as they wish.
2024 OneXPlayer devices, other than the X1s, do not have a turbo LED.
However, earlier models do, so this can be extended to them as well
when the register for it is found.
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
drivers/platform/x86/oxpec.c | 84 ++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c
index 78ab87be3dbf7..1fbf733f98ec6 100644
--- a/drivers/platform/x86/oxpec.c
+++ b/drivers/platform/x86/oxpec.c
@@ -87,6 +87,12 @@ static enum oxp_board board;
#define OXP_TURBO_RETURN_VAL 0x00 /* Common return val */
+/* X1 Turbo LED */
+#define OXP_X1_TURBO_LED_REG 0x57
+
+#define OXP_X1_TURBO_LED_OFF 0x01
+#define OXP_X1_TURBO_LED_ON 0x02
+
static const struct dmi_system_id dmi_table[] = {
{
.matches = {
@@ -434,6 +440,73 @@ static ssize_t tt_toggle_show(struct device *dev,
static DEVICE_ATTR_RW(tt_toggle);
+/* Callbacks for turbo LED attribute */
+static umode_t tt_led_is_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+{
+ switch (board) {
+ case oxp_x1:
+ return attr->mode;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static ssize_t tt_led_store(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ u8 reg, val;
+ bool value;
+ int rval;
+
+ rval = kstrtobool(buf, &value);
+ if (rval)
+ return rval;
+
+ switch (board) {
+ case oxp_x1:
+ reg = OXP_X1_TURBO_LED_REG;
+ val = value ? OXP_X1_TURBO_LED_ON : OXP_X1_TURBO_LED_OFF;
+ break;
+ default:
+ return -EINVAL;
+ }
+ rval = write_to_ec(reg, val);
+
+ if (rval)
+ return rval;
+
+ return count;
+}
+
+static ssize_t tt_led_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int retval;
+ long enval;
+ long val;
+ u8 reg;
+
+ switch (board) {
+ case oxp_x1:
+ reg = OXP_X1_TURBO_LED_REG;
+ enval = OXP_X1_TURBO_LED_ON;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ retval = read_from_ec(reg, 1, &val);
+ if (retval)
+ return retval;
+
+ return sysfs_emit(buf, "%d\n", val == enval);
+}
+
+static DEVICE_ATTR_RW(tt_led);
+
/* PWM enable/disable functions */
static int oxp_pwm_enable(void)
{
@@ -691,8 +764,19 @@ static const struct attribute_group oxp_tt_toggle_attribute_group = {
.attrs = oxp_tt_toggle_attrs,
};
+static const struct attribute *oxp_tt_led_attrs[] = {
+ &dev_attr_tt_led.attr,
+ NULL
+};
+
+static const struct attribute_group oxp_tt_led_attribute_group = {
+ .is_visible = tt_led_is_visible,
+ .attrs = oxp_tt_led_attrs,
+};
+
static const struct attribute_group *oxp_ec_groups[] = {
&oxp_tt_toggle_attribute_group,
+ &oxp_tt_led_attribute_group,
NULL
};
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 08/14] platform/x86: oxpec: Move pwm_enable read to its own function
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (6 preceding siblings ...)
2025-03-19 17:55 ` [PATCH v6 07/14] platform/x86: oxpec: Add turbo led support to X1 devices Antheas Kapenekakis
@ 2025-03-19 17:55 ` Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 09/14] platform/x86: oxpec: Move pwm value read/write to separate functions Antheas Kapenekakis
` (6 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:55 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
Currently, this driver breaks ABI by using auto as 0 and manual as 1.
However, for pwm_enable, 0 is full speed, 1 is manual, and 2 is auto.
For the correction to be possible, this means that the pwm_enable
endpoint will need access to both pwm enable and value (as for
the 0th value, the fan needs to be set to full power).
Therefore, begin by moving the current pwm_enable read to its own
function, oxp_pwm_enable.
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
drivers/platform/x86/oxpec.c | 50 +++++++++++++++++++-----------------
1 file changed, 27 insertions(+), 23 deletions(-)
diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c
index 1fbf733f98ec6..b0668f3db4e10 100644
--- a/drivers/platform/x86/oxpec.c
+++ b/drivers/platform/x86/oxpec.c
@@ -559,6 +559,32 @@ static int oxp_pwm_disable(void)
}
}
+static int oxp_pwm_read(long *val)
+{
+ switch (board) {
+ 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:
+ case oxp_mini_amd_a07:
+ case oxp_mini_amd_pro:
+ case oxp_x1:
+ return read_from_ec(OXP_SENSOR_PWM_ENABLE_REG, 1, val);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
/* Callbacks for hwmon interface */
static umode_t oxp_ec_hwmon_is_visible(const void *drvdata,
enum hwmon_sensor_types type, u32 attr, int channel)
@@ -656,29 +682,7 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
}
return 0;
case hwmon_pwm_enable:
- switch (board) {
- 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:
- case oxp_mini_amd_a07:
- case oxp_mini_amd_pro:
- case oxp_x1:
- return read_from_ec(OXP_SENSOR_PWM_ENABLE_REG, 1, val);
- default:
- break;
- }
- break;
+ return oxp_pwm_read(val);
default:
break;
}
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 09/14] platform/x86: oxpec: Move pwm value read/write to separate functions
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (7 preceding siblings ...)
2025-03-19 17:55 ` [PATCH v6 08/14] platform/x86: oxpec: Move pwm_enable read to its own function Antheas Kapenekakis
@ 2025-03-19 17:55 ` Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 10/14] platform/x86: oxpec: Move fan speed read to separate function Antheas Kapenekakis
` (5 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:55 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
Currently, this driver breaks hwmon ABI by using auto as 0 and manual
as 1. However, for pwm_enable, 0 is full speed, 1 is manual, and 2 is
auto. For the correction to be possible, this means that the pwm_enable
endpoint will need access to both pwm enable and value (as for
the 0th value, the fan needs to be set to full power).
Therefore, move the pwm value read/write to separate functions.
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
drivers/platform/x86/oxpec.c | 162 +++++++++++++++++++----------------
1 file changed, 87 insertions(+), 75 deletions(-)
diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c
index b0668f3db4e10..aaa60b68babfa 100644
--- a/drivers/platform/x86/oxpec.c
+++ b/drivers/platform/x86/oxpec.c
@@ -599,6 +599,91 @@ static umode_t oxp_ec_hwmon_is_visible(const void *drvdata,
}
}
+/* PWM input read/write functions */
+static int oxp_pwm_input_write(long val)
+{
+ if (val < 0 || val > 255)
+ return -EINVAL;
+ switch (board) {
+ case orange_pi_neo:
+ /* scale to range [1-244] */
+ val = ((val - 1) * 243 / 254) + 1;
+ return write_to_ec(ORANGEPI_SENSOR_PWM_REG, val);
+ case oxp_2:
+ case oxp_x1:
+ /* scale to range [0-184] */
+ val = (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] */
+ val = (val * 100) / 255;
+ return write_to_ec(OXP_SENSOR_PWM_REG, val);
+ case aok_zoe_a1:
+ case oxp_fly:
+ case oxp_mini_amd_pro:
+ return write_to_ec(OXP_SENSOR_PWM_REG, val);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int oxp_pwm_input_read(long *val)
+{
+ int ret;
+
+ switch (board) {
+ case orange_pi_neo:
+ ret = read_from_ec(ORANGEPI_SENSOR_PWM_REG, 1, val);
+ if (ret)
+ return ret;
+ /* scale from range [1-244] */
+ *val = ((*val - 1) * 254 / 243) + 1;
+ break;
+ case oxp_2:
+ case oxp_x1:
+ ret = read_from_ec(OXP_SENSOR_PWM_REG, 1, val);
+ if (ret)
+ return ret;
+ /* scale from range [0-184] */
+ *val = (*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 = read_from_ec(OXP_SENSOR_PWM_REG, 1, val);
+ if (ret)
+ return ret;
+ /* scale from range [0-100] */
+ *val = (*val * 255) / 100;
+ break;
+ case aok_zoe_a1:
+ case oxp_fly:
+ case oxp_mini_amd_pro:
+ default:
+ ret = read_from_ec(OXP_SENSOR_PWM_REG, 1, val);
+ if (ret)
+ return ret;
+ break;
+ }
+ return 0;
+}
+
static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
{
@@ -639,48 +724,7 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
case hwmon_pwm:
switch (attr) {
case hwmon_pwm_input:
- switch (board) {
- case orange_pi_neo:
- ret = read_from_ec(ORANGEPI_SENSOR_PWM_REG, 1, val);
- if (ret)
- return ret;
- /* scale from range [1-244] */
- *val = ((*val - 1) * 254 / 243) + 1;
- break;
- case oxp_2:
- case oxp_x1:
- ret = read_from_ec(OXP_SENSOR_PWM_REG, 1, val);
- if (ret)
- return ret;
- /* scale from range [0-184] */
- *val = (*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 = read_from_ec(OXP_SENSOR_PWM_REG, 1, val);
- if (ret)
- return ret;
- /* scale from range [0-100] */
- *val = (*val * 255) / 100;
- break;
- case aok_zoe_a1:
- case oxp_fly:
- case oxp_mini_amd_pro:
- default:
- ret = read_from_ec(OXP_SENSOR_PWM_REG, 1, val);
- if (ret)
- return ret;
- break;
- }
- return 0;
+ return oxp_pwm_input_read(val);
case hwmon_pwm_enable:
return oxp_pwm_read(val);
default:
@@ -706,39 +750,7 @@ static int oxp_platform_write(struct device *dev, enum hwmon_sensor_types type,
return oxp_pwm_disable();
return -EINVAL;
case hwmon_pwm_input:
- if (val < 0 || val > 255)
- return -EINVAL;
- switch (board) {
- case orange_pi_neo:
- /* scale to range [1-244] */
- val = ((val - 1) * 243 / 254) + 1;
- return write_to_ec(ORANGEPI_SENSOR_PWM_REG, val);
- case oxp_2:
- case oxp_x1:
- /* scale to range [0-184] */
- val = (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] */
- val = (val * 100) / 255;
- return write_to_ec(OXP_SENSOR_PWM_REG, val);
- case aok_zoe_a1:
- case oxp_fly:
- case oxp_mini_amd_pro:
- return write_to_ec(OXP_SENSOR_PWM_REG, val);
- default:
- break;
- }
- break;
+ return oxp_pwm_input_write(val);
default:
break;
}
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 10/14] platform/x86: oxpec: Move fan speed read to separate function
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (8 preceding siblings ...)
2025-03-19 17:55 ` [PATCH v6 09/14] platform/x86: oxpec: Move pwm value read/write to separate functions Antheas Kapenekakis
@ 2025-03-19 17:55 ` Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 11/14] platform/x86: oxpec: Adhere to sysfs-class-hwmon and enable pwm on 2 Antheas Kapenekakis
` (4 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:55 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
While not necessary for fixing the ABI hwmon issue, fan speed will be
the only remaining value without a function. Therefore, finish the
refactor by moving it to a separate function.
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
drivers/platform/x86/oxpec.c | 53 ++++++++++++++++++++----------------
1 file changed, 29 insertions(+), 24 deletions(-)
diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c
index aaa60b68babfa..e84afc5f53379 100644
--- a/drivers/platform/x86/oxpec.c
+++ b/drivers/platform/x86/oxpec.c
@@ -599,6 +599,34 @@ static umode_t oxp_ec_hwmon_is_visible(const void *drvdata,
}
}
+/* Fan speed read function */
+static int oxp_pwm_fan_speed(long *val)
+{
+ switch (board) {
+ case orange_pi_neo:
+ return read_from_ec(ORANGEPI_SENSOR_FAN_REG, 2, val);
+ case oxp_2:
+ case oxp_x1:
+ 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:
+ case oxp_mini_amd_pro:
+ return read_from_ec(OXP_SENSOR_FAN_REG, 2, val);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
/* PWM input read/write functions */
static int oxp_pwm_input_write(long val)
{
@@ -693,30 +721,7 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
case hwmon_fan:
switch (attr) {
case hwmon_fan_input:
- switch (board) {
- case orange_pi_neo:
- return read_from_ec(ORANGEPI_SENSOR_FAN_REG, 2, val);
- case oxp_2:
- case oxp_x1:
- 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:
- case oxp_mini_amd_pro:
- return read_from_ec(OXP_SENSOR_FAN_REG, 2, val);
- default:
- break;
- }
- break;
+ return oxp_pwm_fan_speed(val);
default:
break;
}
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 11/14] platform/x86: oxpec: Adhere to sysfs-class-hwmon and enable pwm on 2
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (9 preceding siblings ...)
2025-03-19 17:55 ` [PATCH v6 10/14] platform/x86: oxpec: Move fan speed read to separate function Antheas Kapenekakis
@ 2025-03-19 17:55 ` Antheas Kapenekakis
2025-03-22 8:23 ` Thomas Weißschuh
2025-03-19 17:55 ` [PATCH v6 12/14] platform/x86: oxpec: Follow reverse xmas convention for tt_toggle Antheas Kapenekakis
` (3 subsequent siblings)
14 siblings, 1 reply; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:55 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
Currently, the driver does not adhere to the sysfs-class-hwmon
specification: 0 is used for auto fan control and 1 is used for manual
control. However, it is expected that 0 sets the fan to full speed,
1 sets the fan to manual, and then 2 is used for automatic control.
Therefore, change the sysfs API to reflect this and enable pwm on 2.
As we are breaking the ABI for this driver, rename oxpec to oxp_ec,
reflecting the naming convention used by other drivers, to allow for
a smooth migration in current userspace programs.
Closes: https://lore.kernel.org/linux-hwmon/20241027174836.8588-1-derekjohn.clark@gmail.com/
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
drivers/platform/x86/oxpec.c | 35 ++++++++++++++++++++++++++++++++---
1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c
index e84afc5f53379..680fa537babf6 100644
--- a/drivers/platform/x86/oxpec.c
+++ b/drivers/platform/x86/oxpec.c
@@ -731,7 +731,27 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
case hwmon_pwm_input:
return oxp_pwm_input_read(val);
case hwmon_pwm_enable:
- return oxp_pwm_read(val);
+ ret = oxp_pwm_read(val);
+ if (ret)
+ return ret;
+
+ /* Check for auto and return 2 */
+ if (!*val) {
+ *val = 2;
+ return 0;
+ }
+
+ /* Return 0 if at full fan speed, 1 otherwise */
+ ret = oxp_pwm_fan_speed(val);
+ if (ret)
+ return ret;
+
+ if (*val == 255)
+ *val = 0;
+ else
+ *val = 1;
+
+ return 0;
default:
break;
}
@@ -745,15 +765,24 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
static int oxp_platform_write(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
{
+ int ret;
+
switch (type) {
case hwmon_pwm:
switch (attr) {
case hwmon_pwm_enable:
if (val == 1)
return oxp_pwm_enable();
- else if (val == 0)
+ else if (val == 2)
return oxp_pwm_disable();
- return -EINVAL;
+ else if (val != 0)
+ return -EINVAL;
+
+ /* Enable PWM and set to max speed */
+ ret = oxp_pwm_enable();
+ if (ret)
+ return ret;
+ return oxp_pwm_input_write(255);
case hwmon_pwm_input:
return oxp_pwm_input_write(val);
default:
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 12/14] platform/x86: oxpec: Follow reverse xmas convention for tt_toggle
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (10 preceding siblings ...)
2025-03-19 17:55 ` [PATCH v6 11/14] platform/x86: oxpec: Adhere to sysfs-class-hwmon and enable pwm on 2 Antheas Kapenekakis
@ 2025-03-19 17:55 ` Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 13/14] power: supply: add inhibit-charge-awake to charge_behaviour Antheas Kapenekakis
` (2 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:55 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
Since the rest of the driver follows this convention, apply it to the
tt_toggle attribute as well.
Suggested-by: Derek J. Clark <derekjohn.clark@gmail.com>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
drivers/platform/x86/oxpec.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c
index 680fa537babf6..fe76973fa0c2c 100644
--- a/drivers/platform/x86/oxpec.c
+++ b/drivers/platform/x86/oxpec.c
@@ -275,9 +275,9 @@ static const struct dmi_system_id dmi_table[] = {
/* Helper functions to handle EC read/write */
static int read_from_ec(u8 reg, int size, long *val)
{
- int i;
- int ret;
u8 buffer;
+ int ret;
+ int i;
if (!lock_global_acpi_lock())
return -EBUSY;
@@ -389,8 +389,8 @@ static ssize_t tt_toggle_store(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
- int rval;
bool value;
+ int rval;
rval = kstrtobool(buf, &value);
if (rval)
@@ -411,8 +411,8 @@ static ssize_t tt_toggle_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int retval;
- u8 reg;
long val;
+ u8 reg;
switch (board) {
case oxp_mini_amd_a07:
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 13/14] power: supply: add inhibit-charge-awake to charge_behaviour
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (11 preceding siblings ...)
2025-03-19 17:55 ` [PATCH v6 12/14] platform/x86: oxpec: Follow reverse xmas convention for tt_toggle Antheas Kapenekakis
@ 2025-03-19 17:55 ` Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 14/14] platform/x86: oxpec: Add charge threshold and behaviour to OneXPlayer Antheas Kapenekakis
2025-03-20 17:33 ` [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Derek J. Clark
14 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:55 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
OneXPlayer devices have a charge inhibit feature
that allows the user to select between it being
active always or only when the device is on.
Therefore, add attribute inhibit-charge-awake to
charge_behaviour to allow the user to select
that charge should be paused only when the device
is awake.
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
Documentation/ABI/testing/sysfs-class-power | 11 ++++++-----
drivers/power/supply/power_supply_sysfs.c | 7 ++++---
drivers/power/supply/test_power.c | 1 +
include/linux/power_supply.h | 1 +
4 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-class-power b/Documentation/ABI/testing/sysfs-class-power
index 2a5c1a09a28f9..78afb2422fc5a 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -508,11 +508,12 @@ Description:
Access: Read, Write
Valid values:
- ================ ====================================
- auto: Charge normally, respect thresholds
- inhibit-charge: Do not charge while AC is attached
- force-discharge: Force discharge while AC is attached
- ================ ====================================
+ ===================== ========================================
+ auto: Charge normally, respect thresholds
+ inhibit-charge: Do not charge while AC is attached
+ inhibit-charge-awake: inhibit-charge only when device is awake
+ force-discharge: Force discharge while AC is attached
+ ===================== ========================================
What: /sys/class/power_supply/<supply_name>/technology
Date: May 2007
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index edb058c19c9c4..f769d5941d0d3 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -138,9 +138,10 @@ static const char * const POWER_SUPPLY_SCOPE_TEXT[] = {
};
static const char * const POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[] = {
- [POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO] = "auto",
- [POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE] = "inhibit-charge",
- [POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE] = "force-discharge",
+ [POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO] = "auto",
+ [POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE] = "inhibit-charge",
+ [POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE_AWAKE] = "inhibit-charge-awake",
+ [POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE] = "force-discharge",
};
static struct power_supply_attr power_supply_attrs[] __ro_after_init = {
diff --git a/drivers/power/supply/test_power.c b/drivers/power/supply/test_power.c
index 2a975a110f485..958e0c0cf2876 100644
--- a/drivers/power/supply/test_power.c
+++ b/drivers/power/supply/test_power.c
@@ -214,6 +214,7 @@ static const struct power_supply_desc test_power_desc[] = {
.property_is_writeable = test_power_battery_property_is_writeable,
.charge_behaviours = BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO)
| BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE)
+ | BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE_AWAKE)
| BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE),
},
[TEST_USB] = {
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 6ed53b2921624..bb8e9e62ce834 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -212,6 +212,7 @@ enum power_supply_usb_type {
enum power_supply_charge_behaviour {
POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO = 0,
POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE,
+ POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE_AWAKE,
POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE,
};
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 14/14] platform/x86: oxpec: Add charge threshold and behaviour to OneXPlayer
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (12 preceding siblings ...)
2025-03-19 17:55 ` [PATCH v6 13/14] power: supply: add inhibit-charge-awake to charge_behaviour Antheas Kapenekakis
@ 2025-03-19 17:55 ` Antheas Kapenekakis
2025-03-22 8:27 ` Thomas Weißschuh
2025-03-20 17:33 ` [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Derek J. Clark
14 siblings, 1 reply; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-19 17:55 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Derek J Clark,
Kevin Greenberg, Joshua Tam, Parth Menon, Eileen, linux-kernel,
sre, linux, ilpo.jarvinen, hdegoede, mario.limonciello,
Antheas Kapenekakis
With the X1 (AMD), OneXPlayer added a charge limit and charge inhibit
feature to their devices. Charge limit allows for choosing an arbitrary
battery charge setpoint in percentages. Charge ihibit allows to instruct
the device to stop charging either when it is awake or always.
This feature was then extended for the F1Pro as well. OneXPlayer also
released BIOS updates for the X1 Mini, X1 (Intel), and F1 devices that
add support for this feature. Therefore, enable it for all F1 and
X1 devices.
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
drivers/platform/x86/Kconfig | 1 +
drivers/platform/x86/oxpec.c | 160 ++++++++++++++++++++++++++++++++++-
2 files changed, 157 insertions(+), 4 deletions(-)
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 82cfc76bc5c9f..f4d993658c01f 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1189,6 +1189,7 @@ config SEL3350_PLATFORM
config OXP_EC
tristate "OneXPlayer EC platform control"
depends on ACPI_EC
+ depends on ACPI_BATTERY
depends on HWMON
depends on X86
help
diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c
index fe76973fa0c2c..2e9a1f17fef96 100644
--- a/drivers/platform/x86/oxpec.c
+++ b/drivers/platform/x86/oxpec.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/processor.h>
+#include <acpi/battery.h>
/* Handle ACPI lock mechanism */
static u32 oxp_mutex;
@@ -60,6 +61,7 @@ enum oxp_board {
};
static enum oxp_board board;
+static struct device *oxp_dev;
/* Fan reading and PWM */
#define OXP_SENSOR_FAN_REG 0x76 /* Fan reading is 2 registers long */
@@ -93,6 +95,23 @@ static enum oxp_board board;
#define OXP_X1_TURBO_LED_OFF 0x01
#define OXP_X1_TURBO_LED_ON 0x02
+/* Battery extension settings */
+#define EC_CHARGE_CONTROL_BEHAVIOURS (BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) | \
+ BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE) | \
+ BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE_AWAKE))
+
+#define OXP_X1_CHARGE_LIMIT_REG 0xA3 /* X1 charge limit (%) */
+#define OXP_X1_CHARGE_INHIBIT_REG 0xA4 /* X1 bypass charging */
+
+#define OXP_X1_CHARGE_INHIBIT_MASK_AWAKE 0x01
+/*
+ * X1 Mask is 0x0A, OneXFly F1Pro is just 0x02
+ * but the extra bit on the X1 does nothing.
+ */
+#define OXP_X1_CHARGE_INHIBIT_MASK_OFF 0x02
+#define OXP_X1_CHARGE_INHIBIT_MASK_ALWAYS (OXP_X1_CHARGE_INHIBIT_MASK_AWAKE | \
+ OXP_X1_CHARGE_INHIBIT_MASK_OFF)
+
static const struct dmi_system_id dmi_table[] = {
{
.matches = {
@@ -507,6 +526,129 @@ static ssize_t tt_led_show(struct device *dev,
static DEVICE_ATTR_RW(tt_led);
+/* Callbacks for charge behaviour attributes */
+static bool oxp_psy_ext_supported(void)
+{
+ switch (board) {
+ case oxp_x1:
+ case oxp_fly:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+static int oxp_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)
+{
+ long raw_val;
+ int ret;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD:
+ ret = read_from_ec(OXP_X1_CHARGE_LIMIT_REG, 1, &raw_val);
+ if (ret)
+ return ret;
+ if (raw_val > 100)
+ return -EINVAL;
+ val->intval = raw_val;
+ return 0;
+ case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
+ ret = read_from_ec(OXP_X1_CHARGE_INHIBIT_REG, 1, &raw_val);
+ if (ret)
+ return ret;
+ if ((raw_val & OXP_X1_CHARGE_INHIBIT_MASK_ALWAYS) ==
+ OXP_X1_CHARGE_INHIBIT_MASK_ALWAYS)
+ val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE;
+ else if ((raw_val & OXP_X1_CHARGE_INHIBIT_MASK_AWAKE) ==
+ OXP_X1_CHARGE_INHIBIT_MASK_AWAKE)
+ val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE_AWAKE;
+ else
+ val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int oxp_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)
+{
+ long raw_val;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD:
+ if (val->intval > 100)
+ return -EINVAL;
+ return write_to_ec(OXP_X1_CHARGE_LIMIT_REG, val->intval);
+ case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
+ switch (val->intval) {
+ case POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO:
+ raw_val = 0;
+ break;
+ case POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE_AWAKE:
+ raw_val = OXP_X1_CHARGE_INHIBIT_MASK_AWAKE;
+ break;
+ case POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE:
+ raw_val = OXP_X1_CHARGE_INHIBIT_MASK_ALWAYS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return write_to_ec(OXP_X1_CHARGE_INHIBIT_REG, raw_val);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int oxp_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 oxp_psy_ext_props[] = {
+ POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
+ POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD,
+};
+
+struct power_supply_ext oxp_psy_ext = {
+ .name = "oxp-charge-control",
+ .properties = oxp_psy_ext_props,
+ .num_properties = ARRAY_SIZE(oxp_psy_ext_props),
+ .charge_behaviours = EC_CHARGE_CONTROL_BEHAVIOURS,
+ .get_property = oxp_psy_ext_get_prop,
+ .set_property = oxp_psy_ext_set_prop,
+ .property_is_writeable = oxp_psy_prop_is_writeable,
+};
+
+static int oxp_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
+{
+ return power_supply_register_extension(battery, &oxp_psy_ext, oxp_dev, NULL);
+}
+
+static int oxp_remove_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
+{
+ power_supply_unregister_extension(battery, &oxp_psy_ext);
+ return 0;
+}
+
+static struct acpi_battery_hook battery_hook = {
+ .add_battery = oxp_add_battery,
+ .remove_battery = oxp_remove_battery,
+ .name = "OneXPlayer Battery",
+};
+
/* PWM enable/disable functions */
static int oxp_pwm_enable(void)
{
@@ -845,12 +987,22 @@ static const struct hwmon_chip_info oxp_ec_chip_info = {
static int oxp_platform_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct device *hwdev;
+ int ret;
+
+ oxp_dev = dev;
+ ret = PTR_ERR_OR_ZERO(devm_hwmon_device_register_with_info(
+ dev, "oxp_ec", NULL, &oxp_ec_chip_info, NULL));
- hwdev = devm_hwmon_device_register_with_info(dev, "oxpec", NULL,
- &oxp_ec_chip_info, NULL);
+ if (ret)
+ return ret;
- return PTR_ERR_OR_ZERO(hwdev);
+ if (oxp_psy_ext_supported()) {
+ ret = devm_battery_hook_register(dev, &battery_hook);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static struct platform_driver oxp_platform_driver = {
--
2.48.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
` (13 preceding siblings ...)
2025-03-19 17:55 ` [PATCH v6 14/14] platform/x86: oxpec: Add charge threshold and behaviour to OneXPlayer Antheas Kapenekakis
@ 2025-03-20 17:33 ` Derek J. Clark
2025-03-20 18:01 ` Antheas Kapenekakis
14 siblings, 1 reply; 20+ messages in thread
From: Derek J. Clark @ 2025-03-20 17:33 UTC (permalink / raw)
To: Antheas Kapenekakis, platform-driver-x86
Cc: linux-hwmon, linux-doc, linux-pm, Guenter Roeck, Jean Delvare,
Jonathan Corbet, Joaquin Ignacio Aramendia, Kevin Greenberg,
Joshua Tam, Parth Menon, Eileen, linux-kernel, sre, linux,
ilpo.jarvinen, hdegoede, mario.limonciello
On March 19, 2025 7:54:55 AM HST, Antheas Kapenekakis <lkml@antheas.dev> wrote:
>This four part series updates the oxpsensors module to bring it in line
>with its Windows OneXPlayer counterpart. First, it adds support for all
>2024, 2025 OneXPlayer handhelds and their special variants. Then, it moves
>the module to platform/x86 to allow for including more EC features.
>
>Then, it adds the new charge limiting and bypass features that were first
>introduced in the X1 and retrofit to older OneXFly variants and for
>controlling the turbo led found in the X1 models. For Bypass, it adds a new
>charge_behaviour variant called inhibit-charge-s0.
>
>Finally, it performs a minor refactor by moving around switch statements
>into their own functions, in order to allow for fixing the pwm1_enable ABI
>in the final patch. Currently, pwm1_enable sets the fan to auto with the
>value 0 and allows manual control with the value 1. This patch makes it
>so 0 sets the fan to full speed, 1 sets the fan to manual control, and
>2 sets the fan to auto. This requires both setting enable and the fan
>speed when the enable sysfs is written to as 0, hence the refactor.
>
>As this is a minor ABI break and there is userspace software relying
>on this previous behavior, the last patch also changes the /name of the
>hwmon endpoint to "oxp_ec" from "oxpec" (mirroring WMI module conventions)
>such that userspace software that relied on the previous behavior can be
>retrofit to the new kernel while enabling correct functionality on old
>and new kernels. Failing that, software that is not updated will just
>stop controlling the fans, ensuring no malignant behavior.
>
>---
>V5: https://lore.kernel.org/all/20250317155349.1236188-1-lkml@antheas.dev/
>V4: https://lore.kernel.org/all/20250311165406.331046-1-lkml@antheas.dev/
>V3: https://lore.kernel.org/all/20250309112114.1177361-1-lkml@antheas.dev/
>
>Changes since V5:
> - Separate doc entries with Fixes as by Mario
> - Add sysfs file name to subject as per Thomas
> - Make tt_led and tt_turbo const as per Thomas
> - Align a couple of structs as per Thomas
> - Remove excess battery check as per Thomas
> - For Thomas: devices without a BIOS update battery control is a NOOP
> OXP is a boutique manufacturer for now, so gathering information
> about old devices to add BIOS checks is not practical unfortunately
Antheas,
This sort of begs the question on how this feature was tested on those devices? That question includes whether or not it is really a no-op in unsupported BIOS. My old contacts at OXP are no longer employed there, are you in contact with anyone at OXP currently that can potentially provide the data?
I'm still of the opinion that the attribute should be explicitly enabled only on a known supported BIOS. IMO there is a general assumption that a driver exposed attribute fd will work and having a no-op will confuse users and lead to spurious bug reports. We shouldn't be exposing a no-op in the sysfs for a driver if we can avoid it. If we add the BIOS checks we can also print to dmesg if a BIOS is too low a version so they will know why it isn't there.
That being said, it does seem likely low risk, so I'm not nacking the feature as is if the subsystem maintainers are okay with it.
- Derek
>Changes since V4:
> - Fix nits by Hans
> - change inhibit-charge-s0 to inhibit-charge-awake
> - use devm_battery_hook_register and power_supply_unregister_extension
> (based on cros driver)
> - move charge behavior patches to the end to make the rest of the series
> easier to merge
> - CC platform-x86 and power maintainers
>
>Changes since V3:
> - Fix nits by Derek
> - Remove the hwmon documentation as it is not required for platform
> drivers (suggested by Guenter)
> - Add ACPI_BATTERY and HWMON depends to Kconfig
> (reported by kernel robot)
> - Homogenize driver into following reverse xmas convention
>
>Changes since V2:
> - Add ack by Guenter, move platform move patch to be third (not first
> to allow for device support backport to lts kernels)
> - Rework patch text, especially in the refactor patches as per Derek
> - Change bypass to use charge_behaviour instead of charge_type, as that
> ABI supports capability detection and is more appropriate
> - Move battery attach to probe instead of init
> - Fix bug where reading tt_led would instead use the turbo register
>
>Changes since V1:
> - Add X1 Pro, F1 Pro variants
> - Fix minor typo in initial patches
> - Convert oxp-sensors into a platform driver, as it is no longer
> considered a hwmon driver.
> - Add sysfs documentation and myself to the MAINTAINERS file
> - Update documentation to state that this is the OneXPlayer/AOKZOE
> platform driver, and that support for Ayaneo/OPI is provided until
> they gain their own platform driver.
>
>Antheas Kapenekakis (14):
> hwmon: (oxp-sensors) Distinguish the X1 variants
> hwmon: (oxp-sensors) Add all OneXFly variants
> platform/x86: oxpec: Move hwmon/oxp-sensors to platform/x86
> ABI: testing: sysfs-class-oxp: add missing documentation
> ABI: testing: sysfs-class-oxp: add tt_led attribute documentation
> platform/x86: oxpec: Rename ec group to tt_toggle
> platform/x86: oxpec: Add turbo led support to X1 devices
> platform/x86: oxpec: Move pwm_enable read to its own function
> platform/x86: oxpec: Move pwm value read/write to separate functions
> platform/x86: oxpec: Move fan speed read to separate function
> platform/x86: oxpec: Adhere to sysfs-class-hwmon and enable pwm on 2
> platform/x86: oxpec: Follow reverse xmas convention for tt_toggle
> power: supply: add inhibit-charge-awake to charge_behaviour
> platform/x86: oxpec: Add charge threshold and behaviour to OneXPlayer
>
> Documentation/ABI/testing/sysfs-class-power | 11 +-
> Documentation/ABI/testing/sysfs-platform-oxp | 25 +
> Documentation/hwmon/index.rst | 2 +-
> Documentation/hwmon/oxp-sensors.rst | 89 ---
> MAINTAINERS | 7 +-
> drivers/hwmon/Kconfig | 11 -
> drivers/hwmon/Makefile | 1 -
> drivers/platform/x86/Kconfig | 13 +
> drivers/platform/x86/Makefile | 3 +
> .../oxp-sensors.c => platform/x86/oxpec.c} | 624 ++++++++++++++----
> drivers/power/supply/power_supply_sysfs.c | 7 +-
> drivers/power/supply/test_power.c | 1 +
> include/linux/power_supply.h | 1 +
> 13 files changed, 540 insertions(+), 255 deletions(-)
> create mode 100644 Documentation/ABI/testing/sysfs-platform-oxp
> delete mode 100644 Documentation/hwmon/oxp-sensors.rst
> rename drivers/{hwmon/oxp-sensors.c => platform/x86/oxpec.c} (52%)
>
>
>base-commit: 4701f33a10702d5fc577c32434eb62adde0a1ae1
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86
2025-03-20 17:33 ` [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Derek J. Clark
@ 2025-03-20 18:01 ` Antheas Kapenekakis
0 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-20 18:01 UTC (permalink / raw)
To: Derek J. Clark
Cc: platform-driver-x86, linux-hwmon, linux-doc, linux-pm,
Guenter Roeck, Jean Delvare, Jonathan Corbet,
Joaquin Ignacio Aramendia, Kevin Greenberg, Joshua Tam,
Parth Menon, Eileen, linux-kernel, sre, linux, ilpo.jarvinen,
hdegoede, mario.limonciello
On Thu, 20 Mar 2025 at 18:33, Derek J. Clark <derekjohn.clark@gmail.com> wrote:
>
>
>
> On March 19, 2025 7:54:55 AM HST, Antheas Kapenekakis <lkml@antheas.dev> wrote:
> >This four part series updates the oxpsensors module to bring it in line
> >with its Windows OneXPlayer counterpart. First, it adds support for all
> >2024, 2025 OneXPlayer handhelds and their special variants. Then, it moves
> >the module to platform/x86 to allow for including more EC features.
> >
> >Then, it adds the new charge limiting and bypass features that were first
> >introduced in the X1 and retrofit to older OneXFly variants and for
> >controlling the turbo led found in the X1 models. For Bypass, it adds a new
> >charge_behaviour variant called inhibit-charge-s0.
> >
> >Finally, it performs a minor refactor by moving around switch statements
> >into their own functions, in order to allow for fixing the pwm1_enable ABI
> >in the final patch. Currently, pwm1_enable sets the fan to auto with the
> >value 0 and allows manual control with the value 1. This patch makes it
> >so 0 sets the fan to full speed, 1 sets the fan to manual control, and
> >2 sets the fan to auto. This requires both setting enable and the fan
> >speed when the enable sysfs is written to as 0, hence the refactor.
> >
> >As this is a minor ABI break and there is userspace software relying
> >on this previous behavior, the last patch also changes the /name of the
> >hwmon endpoint to "oxp_ec" from "oxpec" (mirroring WMI module conventions)
> >such that userspace software that relied on the previous behavior can be
> >retrofit to the new kernel while enabling correct functionality on old
> >and new kernels. Failing that, software that is not updated will just
> >stop controlling the fans, ensuring no malignant behavior.
> >
> >---
> >V5: https://lore.kernel.org/all/20250317155349.1236188-1-lkml@antheas.dev/
> >V4: https://lore.kernel.org/all/20250311165406.331046-1-lkml@antheas.dev/
> >V3: https://lore.kernel.org/all/20250309112114.1177361-1-lkml@antheas.dev/
> >
> >Changes since V5:
> > - Separate doc entries with Fixes as by Mario
> > - Add sysfs file name to subject as per Thomas
> > - Make tt_led and tt_turbo const as per Thomas
> > - Align a couple of structs as per Thomas
> > - Remove excess battery check as per Thomas
> > - For Thomas: devices without a BIOS update battery control is a NOOP
> > OXP is a boutique manufacturer for now, so gathering information
> > about old devices to add BIOS checks is not practical unfortunately
>
> Antheas,
> This sort of begs the question on how this feature was tested on those devices? That question includes whether or not it is really a no-op in unsupported BIOS. My old contacts at OXP are no longer employed there, are you in contact with anyone at OXP currently that can potentially provide the data?
>
> I'm still of the opinion that the attribute should be explicitly enabled only on a known supported BIOS. IMO there is a general assumption that a driver exposed attribute fd will work and having a no-op will confuse users and lead to spurious bug reports. We shouldn't be exposing a no-op in the sysfs for a driver if we can avoid it. If we add the BIOS checks we can also print to dmesg if a BIOS is too low a version so they will know why it isn't there.
>
> That being said, it does seem likely low risk, so I'm not nacking the feature as is if the subsystem maintainers are okay with it.
>
> - Derek
Hi Derek,
I have tested this patch series on an X1 (AMD) personally. I also have
multiple people that have tested it on an F1 Pro, X1 Intel, and an X1
Mini. And I am pretty sure that at least 1 or 2 people have tested on
an older BIOS too without an ill effect.
The older F1s are a bit of a question mark. The BIOS update for those
came out around Xmas and I do not have that many users with them.
However, they act identically to the new ones when it comes to the EC
and the controller, so I do not think that is that big of an issue.
Also, no one has asked yet about it not working on those devices. And
they ask about a lot of things. Yanking charging support from those
will just hurt those users unnecessarily as they will get it later.
Eileen is from OneXPlayer and is cc'd in this series.
Antheas
> >Changes since V4:
> > - Fix nits by Hans
> > - change inhibit-charge-s0 to inhibit-charge-awake
> > - use devm_battery_hook_register and power_supply_unregister_extension
> > (based on cros driver)
> > - move charge behavior patches to the end to make the rest of the series
> > easier to merge
> > - CC platform-x86 and power maintainers
> >
> >Changes since V3:
> > - Fix nits by Derek
> > - Remove the hwmon documentation as it is not required for platform
> > drivers (suggested by Guenter)
> > - Add ACPI_BATTERY and HWMON depends to Kconfig
> > (reported by kernel robot)
> > - Homogenize driver into following reverse xmas convention
> >
> >Changes since V2:
> > - Add ack by Guenter, move platform move patch to be third (not first
> > to allow for device support backport to lts kernels)
> > - Rework patch text, especially in the refactor patches as per Derek
> > - Change bypass to use charge_behaviour instead of charge_type, as that
> > ABI supports capability detection and is more appropriate
> > - Move battery attach to probe instead of init
> > - Fix bug where reading tt_led would instead use the turbo register
> >
> >Changes since V1:
> > - Add X1 Pro, F1 Pro variants
> > - Fix minor typo in initial patches
> > - Convert oxp-sensors into a platform driver, as it is no longer
> > considered a hwmon driver.
> > - Add sysfs documentation and myself to the MAINTAINERS file
> > - Update documentation to state that this is the OneXPlayer/AOKZOE
> > platform driver, and that support for Ayaneo/OPI is provided until
> > they gain their own platform driver.
> >
> >Antheas Kapenekakis (14):
> > hwmon: (oxp-sensors) Distinguish the X1 variants
> > hwmon: (oxp-sensors) Add all OneXFly variants
> > platform/x86: oxpec: Move hwmon/oxp-sensors to platform/x86
> > ABI: testing: sysfs-class-oxp: add missing documentation
> > ABI: testing: sysfs-class-oxp: add tt_led attribute documentation
> > platform/x86: oxpec: Rename ec group to tt_toggle
> > platform/x86: oxpec: Add turbo led support to X1 devices
> > platform/x86: oxpec: Move pwm_enable read to its own function
> > platform/x86: oxpec: Move pwm value read/write to separate functions
> > platform/x86: oxpec: Move fan speed read to separate function
> > platform/x86: oxpec: Adhere to sysfs-class-hwmon and enable pwm on 2
> > platform/x86: oxpec: Follow reverse xmas convention for tt_toggle
> > power: supply: add inhibit-charge-awake to charge_behaviour
> > platform/x86: oxpec: Add charge threshold and behaviour to OneXPlayer
> >
> > Documentation/ABI/testing/sysfs-class-power | 11 +-
> > Documentation/ABI/testing/sysfs-platform-oxp | 25 +
> > Documentation/hwmon/index.rst | 2 +-
> > Documentation/hwmon/oxp-sensors.rst | 89 ---
> > MAINTAINERS | 7 +-
> > drivers/hwmon/Kconfig | 11 -
> > drivers/hwmon/Makefile | 1 -
> > drivers/platform/x86/Kconfig | 13 +
> > drivers/platform/x86/Makefile | 3 +
> > .../oxp-sensors.c => platform/x86/oxpec.c} | 624 ++++++++++++++----
> > drivers/power/supply/power_supply_sysfs.c | 7 +-
> > drivers/power/supply/test_power.c | 1 +
> > include/linux/power_supply.h | 1 +
> > 13 files changed, 540 insertions(+), 255 deletions(-)
> > create mode 100644 Documentation/ABI/testing/sysfs-platform-oxp
> > delete mode 100644 Documentation/hwmon/oxp-sensors.rst
> > rename drivers/{hwmon/oxp-sensors.c => platform/x86/oxpec.c} (52%)
> >
> >
> >base-commit: 4701f33a10702d5fc577c32434eb62adde0a1ae1
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v6 11/14] platform/x86: oxpec: Adhere to sysfs-class-hwmon and enable pwm on 2
2025-03-19 17:55 ` [PATCH v6 11/14] platform/x86: oxpec: Adhere to sysfs-class-hwmon and enable pwm on 2 Antheas Kapenekakis
@ 2025-03-22 8:23 ` Thomas Weißschuh
2025-03-22 8:31 ` Antheas Kapenekakis
0 siblings, 1 reply; 20+ messages in thread
From: Thomas Weißschuh @ 2025-03-22 8:23 UTC (permalink / raw)
To: Antheas Kapenekakis
Cc: platform-driver-x86, linux-hwmon, linux-doc, linux-pm,
Guenter Roeck, Jean Delvare, Jonathan Corbet,
Joaquin Ignacio Aramendia, Derek J Clark, Kevin Greenberg,
Joshua Tam, Parth Menon, Eileen, linux-kernel, sre, ilpo.jarvinen,
hdegoede, mario.limonciello
On 2025-03-19 18:55:06+0100, Antheas Kapenekakis wrote:
> Currently, the driver does not adhere to the sysfs-class-hwmon
> specification: 0 is used for auto fan control and 1 is used for manual
> control. However, it is expected that 0 sets the fan to full speed,
> 1 sets the fan to manual, and then 2 is used for automatic control.
>
> Therefore, change the sysfs API to reflect this and enable pwm on 2.
>
> As we are breaking the ABI for this driver, rename oxpec to oxp_ec,
> reflecting the naming convention used by other drivers, to allow for
> a smooth migration in current userspace programs.
Where is the renaming being done?
> Closes: https://lore.kernel.org/linux-hwmon/20241027174836.8588-1-derekjohn.clark@gmail.com/
> Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
> Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
> ---
> drivers/platform/x86/oxpec.c | 35 ++++++++++++++++++++++++++++++++---
> 1 file changed, 32 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c
> index e84afc5f53379..680fa537babf6 100644
> --- a/drivers/platform/x86/oxpec.c
> +++ b/drivers/platform/x86/oxpec.c
> @@ -731,7 +731,27 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
> case hwmon_pwm_input:
> return oxp_pwm_input_read(val);
> case hwmon_pwm_enable:
> - return oxp_pwm_read(val);
> + ret = oxp_pwm_read(val);
> + if (ret)
> + return ret;
> +
> + /* Check for auto and return 2 */
> + if (!*val) {
> + *val = 2;
> + return 0;
> + }
> +
> + /* Return 0 if at full fan speed, 1 otherwise */
> + ret = oxp_pwm_fan_speed(val);
> + if (ret)
> + return ret;
> +
> + if (*val == 255)
> + *val = 0;
> + else
> + *val = 1;
> +
> + return 0;
> default:
> break;
> }
> @@ -745,15 +765,24 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
> static int oxp_platform_write(struct device *dev, enum hwmon_sensor_types type,
> u32 attr, int channel, long val)
> {
> + int ret;
> +
> switch (type) {
> case hwmon_pwm:
> switch (attr) {
> case hwmon_pwm_enable:
> if (val == 1)
> return oxp_pwm_enable();
> - else if (val == 0)
> + else if (val == 2)
> return oxp_pwm_disable();
> - return -EINVAL;
> + else if (val != 0)
> + return -EINVAL;
> +
> + /* Enable PWM and set to max speed */
> + ret = oxp_pwm_enable();
> + if (ret)
> + return ret;
> + return oxp_pwm_input_write(255);
> case hwmon_pwm_input:
> return oxp_pwm_input_write(val);
> default:
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v6 14/14] platform/x86: oxpec: Add charge threshold and behaviour to OneXPlayer
2025-03-19 17:55 ` [PATCH v6 14/14] platform/x86: oxpec: Add charge threshold and behaviour to OneXPlayer Antheas Kapenekakis
@ 2025-03-22 8:27 ` Thomas Weißschuh
0 siblings, 0 replies; 20+ messages in thread
From: Thomas Weißschuh @ 2025-03-22 8:27 UTC (permalink / raw)
To: Antheas Kapenekakis
Cc: platform-driver-x86, linux-hwmon, linux-doc, linux-pm,
Guenter Roeck, Jean Delvare, Jonathan Corbet,
Joaquin Ignacio Aramendia, Derek J Clark, Kevin Greenberg,
Joshua Tam, Parth Menon, Eileen, linux-kernel, sre, ilpo.jarvinen,
hdegoede, mario.limonciello
On 2025-03-19 18:55:09+0100, Antheas Kapenekakis wrote:
> With the X1 (AMD), OneXPlayer added a charge limit and charge inhibit
> feature to their devices. Charge limit allows for choosing an arbitrary
> battery charge setpoint in percentages. Charge ihibit allows to instruct
> the device to stop charging either when it is awake or always.
>
> This feature was then extended for the F1Pro as well. OneXPlayer also
> released BIOS updates for the X1 Mini, X1 (Intel), and F1 devices that
> add support for this feature. Therefore, enable it for all F1 and
> X1 devices.
>
> Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
> ---
> drivers/platform/x86/Kconfig | 1 +
> drivers/platform/x86/oxpec.c | 160 ++++++++++++++++++++++++++++++++++-
> 2 files changed, 157 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index 82cfc76bc5c9f..f4d993658c01f 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -1189,6 +1189,7 @@ config SEL3350_PLATFORM
> config OXP_EC
> tristate "OneXPlayer EC platform control"
> depends on ACPI_EC
> + depends on ACPI_BATTERY
> depends on HWMON
> depends on X86
> help
> diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c
> index fe76973fa0c2c..2e9a1f17fef96 100644
> --- a/drivers/platform/x86/oxpec.c
> +++ b/drivers/platform/x86/oxpec.c
> @@ -24,6 +24,7 @@
> #include <linux/module.h>
> #include <linux/platform_device.h>
> #include <linux/processor.h>
> +#include <acpi/battery.h>
>
> /* Handle ACPI lock mechanism */
> static u32 oxp_mutex;
> @@ -60,6 +61,7 @@ enum oxp_board {
> };
>
> static enum oxp_board board;
> +static struct device *oxp_dev;
>
> /* Fan reading and PWM */
> #define OXP_SENSOR_FAN_REG 0x76 /* Fan reading is 2 registers long */
> @@ -93,6 +95,23 @@ static enum oxp_board board;
> #define OXP_X1_TURBO_LED_OFF 0x01
> #define OXP_X1_TURBO_LED_ON 0x02
>
> +/* Battery extension settings */
> +#define EC_CHARGE_CONTROL_BEHAVIOURS (BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) | \
> + BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE) | \
> + BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE_AWAKE))
> +
> +#define OXP_X1_CHARGE_LIMIT_REG 0xA3 /* X1 charge limit (%) */
> +#define OXP_X1_CHARGE_INHIBIT_REG 0xA4 /* X1 bypass charging */
> +
> +#define OXP_X1_CHARGE_INHIBIT_MASK_AWAKE 0x01
> +/*
> + * X1 Mask is 0x0A, OneXFly F1Pro is just 0x02
> + * but the extra bit on the X1 does nothing.
> + */
> +#define OXP_X1_CHARGE_INHIBIT_MASK_OFF 0x02
> +#define OXP_X1_CHARGE_INHIBIT_MASK_ALWAYS (OXP_X1_CHARGE_INHIBIT_MASK_AWAKE | \
> + OXP_X1_CHARGE_INHIBIT_MASK_OFF)
> +
> static const struct dmi_system_id dmi_table[] = {
> {
> .matches = {
> @@ -507,6 +526,129 @@ static ssize_t tt_led_show(struct device *dev,
>
> static DEVICE_ATTR_RW(tt_led);
>
> +/* Callbacks for charge behaviour attributes */
> +static bool oxp_psy_ext_supported(void)
> +{
> + switch (board) {
> + case oxp_x1:
> + case oxp_fly:
> + return true;
> + default:
> + break;
> + }
> + return false;
> +}
> +
> +static int oxp_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)
> +{
> + long raw_val;
> + int ret;
> +
> + switch (psp) {
> + case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD:
> + ret = read_from_ec(OXP_X1_CHARGE_LIMIT_REG, 1, &raw_val);
> + if (ret)
> + return ret;
> + if (raw_val > 100)
> + return -EINVAL;
Theoretically raw_val could be < 0.
> + val->intval = raw_val;
> + return 0;
> + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
> + ret = read_from_ec(OXP_X1_CHARGE_INHIBIT_REG, 1, &raw_val);
> + if (ret)
> + return ret;
> + if ((raw_val & OXP_X1_CHARGE_INHIBIT_MASK_ALWAYS) ==
> + OXP_X1_CHARGE_INHIBIT_MASK_ALWAYS)
> + val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE;
> + else if ((raw_val & OXP_X1_CHARGE_INHIBIT_MASK_AWAKE) ==
> + OXP_X1_CHARGE_INHIBIT_MASK_AWAKE)
> + val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE_AWAKE;
> + else
> + val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO;
> + return 0;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int oxp_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)
> +{
> + long raw_val;
> +
> + switch (psp) {
> + case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD:
> + if (val->intval > 100)
> + return -EINVAL;
> + return write_to_ec(OXP_X1_CHARGE_LIMIT_REG, val->intval);
> + case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
> + switch (val->intval) {
> + case POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO:
> + raw_val = 0;
> + break;
> + case POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE_AWAKE:
> + raw_val = OXP_X1_CHARGE_INHIBIT_MASK_AWAKE;
> + break;
> + case POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE:
> + raw_val = OXP_X1_CHARGE_INHIBIT_MASK_ALWAYS;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + return write_to_ec(OXP_X1_CHARGE_INHIBIT_REG, raw_val);
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int oxp_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 oxp_psy_ext_props[] = {
> + POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
> + POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD,
> +};
> +
> +struct power_supply_ext oxp_psy_ext = {
static const
> + .name = "oxp-charge-control",
> + .properties = oxp_psy_ext_props,
> + .num_properties = ARRAY_SIZE(oxp_psy_ext_props),
> + .charge_behaviours = EC_CHARGE_CONTROL_BEHAVIOURS,
> + .get_property = oxp_psy_ext_get_prop,
> + .set_property = oxp_psy_ext_set_prop,
> + .property_is_writeable = oxp_psy_prop_is_writeable,
> +};
> +
> +static int oxp_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
> +{
> + return power_supply_register_extension(battery, &oxp_psy_ext, oxp_dev, NULL);
> +}
> +
> +static int oxp_remove_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
> +{
> + power_supply_unregister_extension(battery, &oxp_psy_ext);
> + return 0;
> +}
> +
> +static struct acpi_battery_hook battery_hook = {
> + .add_battery = oxp_add_battery,
> + .remove_battery = oxp_remove_battery,
> + .name = "OneXPlayer Battery",
> +};
> +
> /* PWM enable/disable functions */
> static int oxp_pwm_enable(void)
> {
> @@ -845,12 +987,22 @@ static const struct hwmon_chip_info oxp_ec_chip_info = {
> static int oxp_platform_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> - struct device *hwdev;
> + int ret;
> +
> + oxp_dev = dev;
> + ret = PTR_ERR_OR_ZERO(devm_hwmon_device_register_with_info(
> + dev, "oxp_ec", NULL, &oxp_ec_chip_info, NULL));
>
> - hwdev = devm_hwmon_device_register_with_info(dev, "oxpec", NULL,
> - &oxp_ec_chip_info, NULL);
> + if (ret)
> + return ret;
>
> - return PTR_ERR_OR_ZERO(hwdev);
> + if (oxp_psy_ext_supported()) {
> + ret = devm_battery_hook_register(dev, &battery_hook);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> }
>
> static struct platform_driver oxp_platform_driver = {
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v6 11/14] platform/x86: oxpec: Adhere to sysfs-class-hwmon and enable pwm on 2
2025-03-22 8:23 ` Thomas Weißschuh
@ 2025-03-22 8:31 ` Antheas Kapenekakis
0 siblings, 0 replies; 20+ messages in thread
From: Antheas Kapenekakis @ 2025-03-22 8:31 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: platform-driver-x86, linux-hwmon, linux-doc, linux-pm,
Guenter Roeck, Jean Delvare, Jonathan Corbet,
Joaquin Ignacio Aramendia, Derek J Clark, Kevin Greenberg,
Joshua Tam, Parth Menon, Eileen, linux-kernel, sre, ilpo.jarvinen,
hdegoede, mario.limonciello
On Sat, 22 Mar 2025 at 09:24, Thomas Weißschuh <linux@weissschuh.net> wrote:
>
> On 2025-03-19 18:55:06+0100, Antheas Kapenekakis wrote:
> > Currently, the driver does not adhere to the sysfs-class-hwmon
> > specification: 0 is used for auto fan control and 1 is used for manual
> > control. However, it is expected that 0 sets the fan to full speed,
> > 1 sets the fan to manual, and then 2 is used for automatic control.
> >
> > Therefore, change the sysfs API to reflect this and enable pwm on 2.
> >
> > As we are breaking the ABI for this driver, rename oxpec to oxp_ec,
> > reflecting the naming convention used by other drivers, to allow for
> > a smooth migration in current userspace programs.
>
> Where is the renaming being done?
Good catch thomas. When I did the battery rebase after v4 [1], it
seems to have moved from this patch to the battery patch [2]
Antheas
[1] https://lore.kernel.org/all/20250311165406.331046-13-lkml@antheas.dev/
[2] https://lore.kernel.org/all/20250319181044.392235-15-lkml@antheas.dev/
> > Closes: https://lore.kernel.org/linux-hwmon/20241027174836.8588-1-derekjohn.clark@gmail.com/
> > Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
> > Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
> > ---
> > drivers/platform/x86/oxpec.c | 35 ++++++++++++++++++++++++++++++++---
> > 1 file changed, 32 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c
> > index e84afc5f53379..680fa537babf6 100644
> > --- a/drivers/platform/x86/oxpec.c
> > +++ b/drivers/platform/x86/oxpec.c
> > @@ -731,7 +731,27 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
> > case hwmon_pwm_input:
> > return oxp_pwm_input_read(val);
> > case hwmon_pwm_enable:
> > - return oxp_pwm_read(val);
> > + ret = oxp_pwm_read(val);
> > + if (ret)
> > + return ret;
> > +
> > + /* Check for auto and return 2 */
> > + if (!*val) {
> > + *val = 2;
> > + return 0;
> > + }
> > +
> > + /* Return 0 if at full fan speed, 1 otherwise */
> > + ret = oxp_pwm_fan_speed(val);
> > + if (ret)
> > + return ret;
> > +
> > + if (*val == 255)
> > + *val = 0;
> > + else
> > + *val = 1;
> > +
> > + return 0;
> > default:
> > break;
> > }
> > @@ -745,15 +765,24 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
> > static int oxp_platform_write(struct device *dev, enum hwmon_sensor_types type,
> > u32 attr, int channel, long val)
> > {
> > + int ret;
> > +
> > switch (type) {
> > case hwmon_pwm:
> > switch (attr) {
> > case hwmon_pwm_enable:
> > if (val == 1)
> > return oxp_pwm_enable();
> > - else if (val == 0)
> > + else if (val == 2)
> > return oxp_pwm_disable();
> > - return -EINVAL;
> > + else if (val != 0)
> > + return -EINVAL;
> > +
> > + /* Enable PWM and set to max speed */
> > + ret = oxp_pwm_enable();
> > + if (ret)
> > + return ret;
> > + return oxp_pwm_input_write(255);
> > case hwmon_pwm_input:
> > return oxp_pwm_input_write(val);
> > default:
> > --
> > 2.48.1
> >
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2025-03-22 8:31 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-19 17:54 [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Antheas Kapenekakis
2025-03-19 17:54 ` [PATCH v6 01/14] hwmon: (oxp-sensors) Distinguish the X1 variants Antheas Kapenekakis
2025-03-19 17:54 ` [PATCH v6 02/14] hwmon: (oxp-sensors) Add all OneXFly variants Antheas Kapenekakis
2025-03-19 17:54 ` [PATCH v6 03/14] platform/x86: oxpec: Move hwmon/oxp-sensors to platform/x86 Antheas Kapenekakis
2025-03-19 17:54 ` [PATCH v6 04/14] ABI: testing: sysfs-class-oxp: add missing documentation Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 05/14] ABI: testing: sysfs-class-oxp: add tt_led attribute documentation Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 06/14] platform/x86: oxpec: Rename ec group to tt_toggle Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 07/14] platform/x86: oxpec: Add turbo led support to X1 devices Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 08/14] platform/x86: oxpec: Move pwm_enable read to its own function Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 09/14] platform/x86: oxpec: Move pwm value read/write to separate functions Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 10/14] platform/x86: oxpec: Move fan speed read to separate function Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 11/14] platform/x86: oxpec: Adhere to sysfs-class-hwmon and enable pwm on 2 Antheas Kapenekakis
2025-03-22 8:23 ` Thomas Weißschuh
2025-03-22 8:31 ` Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 12/14] platform/x86: oxpec: Follow reverse xmas convention for tt_toggle Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 13/14] power: supply: add inhibit-charge-awake to charge_behaviour Antheas Kapenekakis
2025-03-19 17:55 ` [PATCH v6 14/14] platform/x86: oxpec: Add charge threshold and behaviour to OneXPlayer Antheas Kapenekakis
2025-03-22 8:27 ` Thomas Weißschuh
2025-03-20 17:33 ` [PATCH v6 00/14] hwmon: (oxpsensors) Add devices, features, fix ABI and move to platform/x86 Derek J. Clark
2025-03-20 18:01 ` Antheas Kapenekakis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).