lkml.org 
[lkml]   [2023]   [Jun]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH v2] hwmon: (oxp-sensors) Add tt_toggle attribute on supported boards
On 6/10/23 12:23, Joaquín Ignacio Aramendía wrote:
> OneXPlayer boards from the last generation (both for OneXPlayer and AOK
> ZOE brands) have a toggle in the EC to switch the "Turbo/Silent" button
> into a different keyboard event.
>
> Add a means to use that "Turbo button takeover" function and expose it
> to userspace in a custom sysfs `tt_toggle` attribute. It can be read to
> take the current state. Write 1|0 to activate the function. The specific
> keycode is dependent on the board but can be checked by running
> `evtest` utility.
>
> Newer BIOS on the OneXPlayer added this function aside from string changes.
> Add a board enum to differentiate it from the old OneXplayer Mini AMD BIOS.
>
> Currently known supported boards:
> - AOK ZOE A1
> - OneXPlayer Mini AMD (only newer BIOS version supported)
> - OneXPlayer Mini Pro
>
> Signed-off-by: Joaquín Ignacio Aramendía <samsagax@gmail.com>
> ---
> v2 changes:
> - Attach the attribute to the platform device as per review
> - Make the attribute return status 0|1 instead of read value
> ---
> Documentation/hwmon/oxp-sensors.rst | 16 ++++
> drivers/hwmon/oxp-sensors.c | 142 +++++++++++++++++++++++++++-
> 2 files changed, 157 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/hwmon/oxp-sensors.rst b/Documentation/hwmon/oxp-sensors.rst
> index 4ab442301415..131c89fad03a 100644
> --- a/Documentation/hwmon/oxp-sensors.rst
> +++ b/Documentation/hwmon/oxp-sensors.rst
> @@ -19,6 +19,11 @@ 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.
>
> +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
> +a flip of the `tt_toggle` attribute. See below for boards that support this
> +function.
> +
> Supported devices
> -----------------
>
> @@ -33,6 +38,11 @@ Currently the driver supports the following handhelds:
> - OneXPlayer mini AMD
> - OneXPlayer mini AMD PRO
>
> +"Turbo/Silent" button behaviour toggle is only supported on:
> + - AOK ZOE A1
> + - OneXPlayer mini AMD (only with updated alpha BIOS)
> + - OneXPlayer mini AMD PRO
> +
> Sysfs entries
> -------------
>
> @@ -49,3 +59,9 @@ 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.

Mention that this attribute is attached to the platform device.

> diff --git a/drivers/hwmon/oxp-sensors.c b/drivers/hwmon/oxp-sensors.c
> index 0ec7588610ad..59e4e906ced5 100644
> --- a/drivers/hwmon/oxp-sensors.c
> +++ b/drivers/hwmon/oxp-sensors.c
> @@ -47,15 +47,29 @@ enum oxp_board {
> aya_neo_air_pro,
> aya_neo_geek,
> oxp_mini_amd,
> + oxp_mini_amd_a07,
> oxp_mini_amd_pro,
> };
>
> 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 */
>
> +/* Turbo button takeover function
> + * Older 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_TURBO_TAKE_VAL 0x40
> +#define OXP_TURBO_RETURN_VAL 0x00
> +
> static const struct dmi_system_id dmi_table[] = {
> {
> .matches = {
> @@ -104,7 +118,7 @@ static const struct dmi_system_id dmi_table[] = {
> DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"),
> DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER mini A07"),
> },
> - .driver_data = (void *)oxp_mini_amd,
> + .driver_data = (void *)oxp_mini_amd_a07,
> },
> {
> .matches = {
> @@ -156,6 +170,112 @@ static int write_to_ec(u8 reg, u8 value)
> return ret;
> }
>
> +/* Turbo button toggle functions */
> +static int tt_toggle_enable(void)
> +{
> + u8 reg;
> + u8 val;
> +
> + switch (board) {
> + case oxp_mini_amd_a07:
> + reg = OXP_OLD_TURBO_SWITCH_REG;
> + val = OXP_OLD_TURBO_TAKE_VAL;
> + break;
> + case oxp_mini_amd_pro:
> + case aok_zoe_a1:
> + reg = OXP_TURBO_SWITCH_REG;
> + val = OXP_TURBO_TAKE_VAL;
> + break;
> + default:
> + return -EINVAL;
> + }
> + return write_to_ec(reg, val);
> +}
> +
> +static int tt_toggle_disable(void)
> +{
> + u8 reg;
> + u8 val;
> +
> + switch (board) {
> + case oxp_mini_amd_a07:
> + reg = OXP_OLD_TURBO_SWITCH_REG;
> + val = OXP_OLD_TURBO_RETURN_VAL;
> + break;
> + case oxp_mini_amd_pro:
> + case aok_zoe_a1:
> + reg = OXP_TURBO_SWITCH_REG;
> + val = OXP_TURBO_RETURN_VAL;
> + break;
> + default:
> + return -EINVAL;
> + }
> + return write_to_ec(reg, val);
> +}
> +
> +/* Callbacks for turbo toggle attribute */
> +static ssize_t tt_toggle_store(struct device *dev,
> + struct device_attribute *attr, const char *buf,
> + size_t count)
> +{
> + int rval;
> + unsigned int value;
> +
> + rval = kstrtouint(buf, 10, &value);
> + if (rval)
> + return rval;

Please use kstrtobool().

> +
> + switch (value) {
> + case 0:
> + rval = tt_toggle_disable();
> + if (rval)
> + return rval;
> + return count;
> + case 1:
> + rval = tt_toggle_enable();
> + if (rval)
> + return rval;
> + return count;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static ssize_t tt_toggle_show(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + int retval;
> + u8 reg;
> + long val;
> + int status;
> +
> + switch (board) {
> + case oxp_mini_amd_a07:
> + reg = OXP_OLD_TURBO_SWITCH_REG;
> + break;
> + case oxp_mini_amd_pro:
> + case aok_zoe_a1:
> + reg = OXP_TURBO_SWITCH_REG;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + retval = read_from_ec(reg, 1, &val);
> + if (retval)
> + return retval;
> +
> + if (val)
> + status = 1;
> + else
> + status = 0;
> +
> + return sysfs_emit(buf, "%d\n", status);

return sysfs_emit(buf, "%d\n", !!val);

is much simpler.

> +}
> +
> +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);
> @@ -206,6 +326,7 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type,
> case aya_neo_air_pro:
> case aya_neo_geek:
> case oxp_mini_amd:
> + case oxp_mini_amd_a07:
> *val = (*val * 255) / 100;
> break;
> case oxp_mini_amd_pro:
> @@ -247,6 +368,7 @@ static int oxp_platform_write(struct device *dev, enum hwmon_sensor_types type,
> case aya_neo_air_pro:
> case aya_neo_geek:
> case oxp_mini_amd:
> + case oxp_mini_amd_a07:
> val = (val * 100) / 255;
> break;
> case aok_zoe_a1:
> @@ -274,6 +396,13 @@ static const struct hwmon_channel_info * const oxp_platform_sensors[] = {
> NULL,
> };
>
> +static struct attribute *oxp_ec_attrs[] = {
> + &dev_attr_tt_toggle.attr,
> + NULL
> +};
> +
> +ATTRIBUTE_GROUPS(oxp_ec);
> +
> static const struct hwmon_ops oxp_ec_hwmon_ops = {
> .is_visible = oxp_ec_hwmon_is_visible,
> .read = oxp_platform_read,
> @@ -291,6 +420,7 @@ static int oxp_platform_probe(struct platform_device *pdev)
> const struct dmi_system_id *dmi_entry;
> struct device *dev = &pdev->dev;
> struct device *hwdev;
> + int ret;
>
> /*
> * Have to check for AMD processor here because DMI strings are the
> @@ -305,6 +435,16 @@ static int oxp_platform_probe(struct platform_device *pdev)
>
> board = (enum oxp_board)(unsigned long)dmi_entry->driver_data;
>
> + switch (board) {
> + case aok_zoe_a1:
> + case oxp_mini_amd_a07:
> + case oxp_mini_amd_pro:
> + ret = devm_device_add_groups(dev, oxp_ec_groups);
> + if (ret)
> + return ret;
break;

> + default:

break;

> + }
> +
> hwdev = devm_hwmon_device_register_with_info(dev, "oxpec", NULL,
> &oxp_ec_chip_info, NULL);
>

\
 
 \ /
  Last update: 2023-06-10 23:09    [W:1.429 / U:0.520 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site