[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240815031358.21027-2-derekjohn.clark@gmail.com>
Date: Wed, 14 Aug 2024 20:12:41 -0700
From: "Derek J. Clark" <derekjohn.clark@...il.com>
To: Guenter Roeck <linux@...ck-us.net>
Cc: Jean Delvare <jdelvare@...e.com>,
Jonathan Corbet <corbet@....net>,
Joaquín Ignacio Aramendía <samsagax@...il.com>,
"Derek J . Clark" <derekjohn.clark@...il.com>,
linux-hwmon@...r.kernel.org,
linux-doc@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH 1/1] hwmon: (oxp-sensors) Add support for multiple new devices.
Add support for the OrangePi NEO-01. It uses different registers for PWM
manual mode, set PWM, and read fan speed than previous devices. Valid PWM
input and duty cycle is 1-244, we scale this from 1-255 to maintain
compatibility with the existing interface.
Add OneXPlayer 2 series and OneXFly models. The 2 series uses a new
register for turbo button takeover. While at it, adjust formatting of some
constants and reorders all cases alphabetically for consistency. Rename
OXP_OLD constants to OXP_MINI for disambiguation.
Adds support for AYANEO models 2S, AIR 1S, Flip DS, Flip KB, GEEK 1S, and
KUN.
Signed-off-by: Derek J. Clark <derekjohn.clark@...il.com>
---
Documentation/hwmon/oxp-sensors.rst | 33 ++--
drivers/hwmon/oxp-sensors.c | 273 +++++++++++++++++++++++++---
2 files changed, 267 insertions(+), 39 deletions(-)
diff --git a/Documentation/hwmon/oxp-sensors.rst b/Documentation/hwmon/oxp-sensors.rst
index 50618f064379..7b2a2b5d6e80 100644
--- a/Documentation/hwmon/oxp-sensors.rst
+++ b/Documentation/hwmon/oxp-sensors.rst
@@ -10,14 +10,12 @@ Authors:
Description:
------------
-Handheld devices from One Netbook and Aya Neo provide fan readings and fan
+Handheld devices from OneNetbook and AYANEO provide fan readings and fan
control through their embedded controllers.
-Currently only supports AMD boards from One X Player, AOK ZOE, and some Aya
-Neo devices. One X Player Intel boards could be supported if we could figure
-out the EC registers and values to write to since the EC layout and model is
-different. Aya Neo devices preceding the AIR may not be supportable as the EC
-model is different and do not appear to have manual control capabilities.
+Currently supports OneXPlayer AMD devices, AOKZOE, AYANEO, and OrangePi
+handheld devices. AYANEO devices preceding the AIR are not be supportable
+as the EC model is different and do not have manual control capabilities.
Some 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
@@ -31,20 +29,33 @@ Currently the driver supports the following handhelds:
- AOK ZOE A1
- AOK ZOE A1 PRO
- - Aya Neo 2
- - Aya Neo AIR
- - Aya Neo AIR Plus (Mendocino)
- - Aya Neo AIR Pro
- - Aya Neo Geek
+ - AYANEO 2
+ - AYANEO 2S
+ - AYANEO AIR
+ - AYANEO AIR 1S
+ - AYANEO AIR Plus (Mendocino)
+ - AYANEO AIR Pro
+ - AYANEO KUN
+ - AYANEO Geek
+ - AYANEO Geek 1S
+ - AYANEO Flip DS
+ - AYANEO Flip KB
+ - OneXPlayer 2
+ - OneXPlayer 2 Pro
- OneXPlayer AMD
- OneXPlayer mini AMD
- OneXPlayer mini AMD PRO
+ - OneXPlayer OneXFly
+ - 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
Sysfs entries
-------------
diff --git a/drivers/hwmon/oxp-sensors.c b/drivers/hwmon/oxp-sensors.c
index 8d3b0f86cc57..701d46fde943 100644
--- a/drivers/hwmon/oxp-sensors.c
+++ b/drivers/hwmon/oxp-sensors.c
@@ -42,10 +42,18 @@ static bool unlock_global_acpi_lock(void)
enum oxp_board {
aok_zoe_a1 = 1,
aya_neo_2,
+ aya_neo_2s,
aya_neo_air,
+ aya_neo_air_1s,
aya_neo_air_plus_mendo,
aya_neo_air_pro,
+ aya_neo_flip,
aya_neo_geek,
+ aya_neo_geek_1s,
+ aya_neo_kun,
+ orange_pi_neo,
+ oxp_2,
+ oxp_fly,
oxp_mini_amd,
oxp_mini_amd_a07,
oxp_mini_amd_pro,
@@ -54,21 +62,29 @@ enum oxp_board {
static enum oxp_board board;
/* Fan reading and PWM */
-#define OXP_SENSOR_FAN_REG 0x76 /* Fan reading is 2 registers long */
-#define OXP_SENSOR_PWM_ENABLE_REG 0x4A /* PWM enable is 1 register long */
-#define OXP_SENSOR_PWM_REG 0x4B /* PWM reading is 1 register long */
+#define OXP_SENSOR_FAN_REG 0x76 /* Fan reading is 2 registers long */
+#define OXP_SENSOR_PWM_ENABLE_REG 0x4A /* PWM enable is 1 register long */
+#define OXP_SENSOR_PWM_REG 0x4B /* PWM reading is 1 register long */
+#define PWM_MODE_AUTO 0x00
+#define PWM_MODE_MANUAL 0x01
+
+/* OrangePi fan eding and PWM */
+#define ORANGEPI_SENSOR_FAN_REG 0x78 /* Fan reading is 2 registers long */
+#define ORANGEPI_SENSOR_PWM_ENABLE_REG 0x40 /* PWM enable is 1 register long */
+#define ORANGEPI_SENSOR_PWM_REG 0x38 /* PWM reading is 1 register long */
/* Turbo button takeover function
- * Older boards have different values and EC registers
+ * Different boards have different values and EC registers
* for the same function
*/
-#define OXP_OLD_TURBO_SWITCH_REG 0x1E
-#define OXP_OLD_TURBO_TAKE_VAL 0x01
-#define OXP_OLD_TURBO_RETURN_VAL 0x00
+#define OXP_TURBO_SWITCH_REG 0xF1
+#define OXP_2_TURBO_SWITCH_REG 0xEB /* OXP2 and OXP2 Pro */
+#define OXP_MINI_TURBO_SWITCH_REG 0x1E /* Mini AO7 */
+
+#define OXP_TURBO_TAKE_VAL 0x40
+#define OXP_MINI_TURBO_TAKE_VAL 0x01
-#define OXP_TURBO_SWITCH_REG 0xF1
-#define OXP_TURBO_TAKE_VAL 0x40
-#define OXP_TURBO_RETURN_VAL 0x00
+#define OXP_TURBO_RETURN_VAL 0x00 /* Common return val */
static const struct dmi_system_id dmi_table[] = {
{
@@ -92,6 +108,13 @@ static const struct dmi_system_id dmi_table[] = {
},
.driver_data = (void *)aya_neo_2,
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "AYANEO 2S"),
+ },
+ .driver_data = (void *)aya_neo_2s,
+ },
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
@@ -99,6 +122,13 @@ static const struct dmi_system_id dmi_table[] = {
},
.driver_data = (void *)aya_neo_air,
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR 1S"),
+ },
+ .driver_data = (void *)aya_neo_air_1s,
+ },
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
@@ -113,6 +143,13 @@ static const struct dmi_system_id dmi_table[] = {
},
.driver_data = (void *)aya_neo_air_pro,
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
+ DMI_MATCH(DMI_BOARD_NAME, "FLIP"),
+ },
+ .driver_data = (void *)aya_neo_flip,
+ },
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
@@ -120,6 +157,27 @@ static const struct dmi_system_id dmi_table[] = {
},
.driver_data = (void *)aya_neo_geek,
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "GEEK 1S"),
+ },
+ .driver_data = (void *)aya_neo_geek_1s,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "KUN"),
+ },
+ .driver_data = (void *)aya_neo_kun,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "OrangePi"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "NEO-01"),
+ },
+ .driver_data = (void *)orange_pi_neo,
+ },
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
@@ -127,6 +185,34 @@ static const struct dmi_system_id dmi_table[] = {
},
.driver_data = (void *)oxp_mini_amd,
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER 2 ARP23"),
+ },
+ .driver_data = (void *)oxp_2,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER 2 PRO ARP23P"),
+ },
+ .driver_data = (void *)oxp_2,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER 2 PRO ARP23P EVA-01"),
+ },
+ .driver_data = (void *)oxp_2,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER F1"),
+ },
+ .driver_data = (void *)oxp_fly,
+ },
{
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
@@ -192,14 +278,19 @@ static int tt_toggle_enable(void)
switch (board) {
case oxp_mini_amd_a07:
- reg = OXP_OLD_TURBO_SWITCH_REG;
- val = OXP_OLD_TURBO_TAKE_VAL;
+ reg = OXP_MINI_TURBO_SWITCH_REG;
+ val = OXP_MINI_TURBO_TAKE_VAL;
break;
- case oxp_mini_amd_pro:
case aok_zoe_a1:
+ case oxp_fly:
+ case oxp_mini_amd_pro:
reg = OXP_TURBO_SWITCH_REG;
val = OXP_TURBO_TAKE_VAL;
break;
+ case oxp_2:
+ reg = OXP_2_TURBO_SWITCH_REG;
+ val = OXP_TURBO_TAKE_VAL;
+ break;
default:
return -EINVAL;
}
@@ -213,14 +304,19 @@ static int tt_toggle_disable(void)
switch (board) {
case oxp_mini_amd_a07:
- reg = OXP_OLD_TURBO_SWITCH_REG;
- val = OXP_OLD_TURBO_RETURN_VAL;
+ reg = OXP_MINI_TURBO_SWITCH_REG;
+ val = OXP_TURBO_RETURN_VAL;
break;
- case oxp_mini_amd_pro:
case aok_zoe_a1:
+ case oxp_fly:
+ case oxp_mini_amd_pro:
reg = OXP_TURBO_SWITCH_REG;
val = OXP_TURBO_RETURN_VAL;
break;
+ case oxp_2:
+ reg = OXP_2_TURBO_SWITCH_REG;
+ val = OXP_TURBO_RETURN_VAL;
+ break;
default:
return -EINVAL;
}
@@ -233,6 +329,8 @@ static umode_t tt_toggle_is_visible(struct kobject *kobj,
{
switch (board) {
case aok_zoe_a1:
+ case oxp_2:
+ case oxp_fly:
case oxp_mini_amd_a07:
case oxp_mini_amd_pro:
return attr->mode;
@@ -273,12 +371,16 @@ static ssize_t tt_toggle_show(struct device *dev,
switch (board) {
case oxp_mini_amd_a07:
- reg = OXP_OLD_TURBO_SWITCH_REG;
+ reg = OXP_MINI_TURBO_SWITCH_REG;
break;
- case oxp_mini_amd_pro:
case aok_zoe_a1:
+ case oxp_fly:
+ case oxp_mini_amd_pro:
reg = OXP_TURBO_SWITCH_REG;
break;
+ case oxp_2:
+ reg = OXP_2_TURBO_SWITCH_REG;
+ break;
default:
return -EINVAL;
}
@@ -295,12 +397,55 @@ static DEVICE_ATTR_RW(tt_toggle);
/* PWM enable/disable functions */
static int oxp_pwm_enable(void)
{
- return write_to_ec(OXP_SENSOR_PWM_ENABLE_REG, 0x01);
+ switch (board) {
+ case orange_pi_neo:
+ return write_to_ec(ORANGEPI_SENSOR_PWM_ENABLE_REG, PWM_MODE_MANUAL);
+ case aok_zoe_a1:
+ case aya_neo_2:
+ case aya_neo_2s:
+ case aya_neo_air:
+ case aya_neo_air_plus_mendo:
+ case aya_neo_air_pro:
+ case aya_neo_flip:
+ case aya_neo_geek:
+ case aya_neo_geek_1s:
+ case aya_neo_kun:
+ case oxp_mini_amd:
+ case oxp_mini_amd_a07:
+ case oxp_2:
+ case oxp_fly:
+ case oxp_mini_amd_pro:
+ return write_to_ec(OXP_SENSOR_PWM_ENABLE_REG, PWM_MODE_MANUAL);
+ default:
+ return -EINVAL;
+ }
}
static int oxp_pwm_disable(void)
{
- return write_to_ec(OXP_SENSOR_PWM_ENABLE_REG, 0x00);
+ switch (board) {
+ case orange_pi_neo:
+ return write_to_ec(ORANGEPI_SENSOR_PWM_ENABLE_REG, PWM_MODE_AUTO);
+ case aok_zoe_a1:
+ case aya_neo_2:
+ case aya_neo_2s:
+ 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_geek_1s:
+ case aya_neo_kun:
+ case oxp_mini_amd:
+ case oxp_mini_amd_a07:
+ case oxp_2:
+ case oxp_fly:
+ case oxp_mini_amd_pro:
+ return write_to_ec(OXP_SENSOR_PWM_ENABLE_REG, PWM_MODE_AUTO);
+ default:
+ return -EINVAL;
+ }
}
/* Callbacks for hwmon interface */
@@ -326,7 +471,29 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
case hwmon_fan:
switch (attr) {
case hwmon_fan_input:
- return read_from_ec(OXP_SENSOR_FAN_REG, 2, val);
+ switch (board) {
+ case orange_pi_neo:
+ return read_from_ec(ORANGEPI_SENSOR_FAN_REG, 2, val);
+ case aok_zoe_a1:
+ case aya_neo_2:
+ case aya_neo_2s:
+ 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_geek_1s:
+ case aya_neo_kun:
+ case oxp_mini_amd:
+ case oxp_mini_amd_a07:
+ case oxp_2:
+ case oxp_fly:
+ case oxp_mini_amd_pro:
+ return read_from_ec(OXP_SENSOR_FAN_REG, 2, val);
+ default:
+ break;
+ }
default:
break;
}
@@ -334,27 +501,66 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
case hwmon_pwm:
switch (attr) {
case hwmon_pwm_input:
- ret = read_from_ec(OXP_SENSOR_PWM_REG, 1, val);
- if (ret)
- return 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 aya_neo_2:
+ case aya_neo_2s:
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_geek_1s:
+ 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;
*val = (*val * 255) / 100;
break;
- case oxp_mini_amd_pro:
case aok_zoe_a1:
+ case oxp_2:
+ 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;
case hwmon_pwm_enable:
- return read_from_ec(OXP_SENSOR_PWM_ENABLE_REG, 1, 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_2s:
+ 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_geek_1s:
+ case aya_neo_kun:
+ case oxp_mini_amd:
+ case oxp_mini_amd_a07:
+ case oxp_2:
+ case oxp_fly:
+ case oxp_mini_amd_pro:
+ return read_from_ec(OXP_SENSOR_PWM_ENABLE_REG, 1, val);
+ default:
+ break;
+ }
default:
break;
}
@@ -381,21 +587,32 @@ static int oxp_platform_write(struct device *dev, enum hwmon_sensor_types type,
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 aya_neo_2:
+ case aya_neo_2s:
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_geek_1s:
+ case aya_neo_kun:
case oxp_mini_amd:
case oxp_mini_amd_a07:
val = (val * 100) / 255;
- break;
+ return write_to_ec(OXP_SENSOR_PWM_REG, val);
case aok_zoe_a1:
+ case oxp_2:
+ case oxp_fly:
case oxp_mini_amd_pro:
+ return write_to_ec(OXP_SENSOR_PWM_REG, val);
default:
break;
}
- return write_to_ec(OXP_SENSOR_PWM_REG, val);
default:
break;
}
--
2.46.0
Powered by blists - more mailing lists