From 4b9e65325f18184e9da262a3415f6398935e8255 Mon Sep 17 00:00:00 2001 From: fewtarius Date: Mon, 19 Dec 2022 17:14:32 -0500 Subject: [PATCH] * Update kernel and OS to support AyaNeo Air / Air Pro fan control. * Bump WIFI drivers. * Add WIFI module quirk and WIFI not waking from sleep on Air. * Fix splash screen on rotated displays. * Move autostart to its own package. --- packages/jelos/package.mk | 16 +- .../quirks/AYANEO AIR/002-wifi_module | 19 - packages/jelos/sources/scripts/jelos-info | 2 +- packages/jelos/sources/scripts/show_splash | 23 +- .../kernel/linux-drivers/RTL8812AU/package.mk | 2 +- .../kernel/linux-drivers/RTL8814AU/package.mk | 2 +- .../kernel/linux-drivers/RTL8821AU/package.mk | 2 +- .../kernel/linux-drivers/RTL8821CU/package.mk | 2 +- .../kernel/linux-drivers/RTL88x2BU/package.mk | 2 +- .../linux/patches/X86_64/001-hwsensors.patch | 4845 +++++++++++++++++ .../patches/X86_64/002-ayaneo-sensors.patch | 246 + ...-rt5.patch => 003-patch-6.1-rc7-rt5.patch} | 0 ....patch => 004-steam-deck-controller.patch} | 0 packages/sysutils/autostart/package.mk | 26 + .../autostart/sources}/autostart | 0 .../autostart/sources}/common/001-setup | 0 .../autostart/sources}/common/002-kernel | 0 .../autostart/sources}/common/003-logging | 0 .../autostart/sources}/common/004-upgrade | 0 .../autostart/sources}/common/005-alsa | 0 .../autostart/sources}/common/006-brightness | 0 .../autostart/sources}/common/007-rootpw | 0 .../autostart/sources}/common/008-network | 0 .../autostart/sources}/common/009-bluetooth | 0 .../autostart/sources}/common/010-uimode | 0 .../autostart/sources}/common/098-wireguard | 0 .../sources}/common/099-networkservices | 0 .../autostart/sources}/daemons/001-ssh | 0 .../autostart/sources}/daemons/002-samba | 0 .../sources}/daemons/003-wait-time-sync | 0 .../autostart/sources}/daemons/004-tailscaled | 0 .../autostart/sources}/daemons/005-fstrim | 0 .../quirks/ATARI VCS 800 Onyx/001-audio | 0 .../autostart/sources}/quirks/AYANEO AIR Pro | 0 .../sources}/quirks/AYANEO AIR/001-audio | 5 + .../sources/quirks/AYANEO AIR/002-fancontrol | 18 + .../sources}/quirks/Anbernic RG351MP | 0 .../quirks/Anbernic RG351P/001-hardwareinit | 0 .../autostart/sources}/quirks/Anbernic RG351V | 0 .../quirks/Anbernic RG353P-M/001-hardwareinit | 0 .../autostart/sources}/quirks/Anbernic RG353V | 0 .../autostart/sources}/quirks/Anbernic RG503 | 0 .../quirks/Anbernic RG552/001-hardwareinit | 0 .../quirks/Anbernic RG552/002-audiomixer | 0 .../quirks/PowKiddy RGB20S/001-hardwareinit | 0 packages/sysutils/busybox/scripts/init | 29 +- packages/sysutils/sleep/package.mk | 14 +- packages/sysutils/sleep/sources/modules.bad | 2 + packages/sysutils/sleep/sources/sleep.sh | 27 +- .../system-utils/sources/scripts/fancontrol | 8 +- .../system-utils/system.d/fancontrol.service | 1 - packages/ui/emulationstation/package.mk | 2 +- packages/ui/splash/package.mk | 4 +- .../devices/handheld/linux/linux.x86_64.conf | 1 + projects/Rockchip/devices/RG552/device.config | 1 + 55 files changed, 5229 insertions(+), 70 deletions(-) delete mode 100644 packages/jelos/sources/autostart/quirks/AYANEO AIR/002-wifi_module create mode 100644 packages/kernel/linux/patches/X86_64/001-hwsensors.patch create mode 100644 packages/kernel/linux/patches/X86_64/002-ayaneo-sensors.patch rename packages/kernel/linux/patches/X86_64/{patch-6.1-rc7-rt5.patch => 003-patch-6.1-rc7-rt5.patch} (100%) rename packages/kernel/linux/patches/X86_64/{steam-deck-controller.patch => 004-steam-deck-controller.patch} (100%) create mode 100644 packages/sysutils/autostart/package.mk rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/autostart (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/001-setup (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/002-kernel (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/003-logging (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/004-upgrade (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/005-alsa (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/006-brightness (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/007-rootpw (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/008-network (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/009-bluetooth (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/010-uimode (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/098-wireguard (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/common/099-networkservices (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/daemons/001-ssh (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/daemons/002-samba (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/daemons/003-wait-time-sync (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/daemons/004-tailscaled (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/daemons/005-fstrim (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/ATARI VCS 800 Onyx/001-audio (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/AYANEO AIR Pro (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/AYANEO AIR/001-audio (66%) create mode 100644 packages/sysutils/autostart/sources/quirks/AYANEO AIR/002-fancontrol rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/Anbernic RG351MP (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/Anbernic RG351P/001-hardwareinit (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/Anbernic RG351V (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/Anbernic RG353P-M/001-hardwareinit (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/Anbernic RG353V (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/Anbernic RG503 (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/Anbernic RG552/001-hardwareinit (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/Anbernic RG552/002-audiomixer (100%) rename packages/{jelos/sources/autostart => sysutils/autostart/sources}/quirks/PowKiddy RGB20S/001-hardwareinit (100%) create mode 100644 packages/sysutils/sleep/sources/modules.bad diff --git a/packages/jelos/package.mk b/packages/jelos/package.mk index a8a783428..33a83b5ef 100644 --- a/packages/jelos/package.mk +++ b/packages/jelos/package.mk @@ -24,7 +24,7 @@ fi PKG_BASEOS="plymouth-lite grep wget libjpeg-turbo util-linux xmlstarlet bluetool gnupg gzip patchelf \ imagemagick terminus-font vim bash pyudev dialog six git dbus-python coreutils miniupnpc \ - nss-mdns avahi alsa-ucm-conf MC fbgrab modules system-utils" + nss-mdns avahi alsa-ucm-conf MC fbgrab modules system-utils autostart" PKG_UI="emulationstation es-themes" @@ -113,17 +113,6 @@ post_install() { mkdir -p ${INSTALL}/etc/profile.d cp ${PROJECT_DIR}/${PROJECT}/devices/${DEVICE}/device.config ${INSTALL}/etc/profile.d/01-deviceconfig - # Split this up into other packages - cp ${PKG_DIR}/sources/autostart/autostart ${INSTALL}/usr/bin - mkdir -p ${INSTALL}/usr/lib/autostart/common - mkdir -p ${INSTALL}/usr/lib/autostart/daemons - cp ${PKG_DIR}/sources/autostart/common/* ${INSTALL}/usr/lib/autostart/common - cp ${PKG_DIR}/sources/autostart/daemons/* ${INSTALL}/usr/lib/autostart/daemons - mkdir -p ${INSTALL}/usr/lib/autostart/quirks - cp -r ${PKG_DIR}/sources/autostart/quirks/* ${INSTALL}/usr/lib/autostart/quirks - chmod -R 0755 ${INSTALL}/usr/lib/autostart ${INSTALL}/usr/bin/autostart - enable_service jelos-autostart.service - if [ ! -d "${INSTALL}/usr/share" ] then mkdir "${INSTALL}/usr/share" @@ -144,6 +133,9 @@ EOF chmod 0755 ${INSTALL}/usr/bin/* ||: enable_service jelos-automount.service + ### Fix and migrate to autostart package + enable_service jelos-autostart.service + if [ -d "${PKG_DIR}/sources/asound/${DEVICE}" ] then cp ${PKG_DIR}/sources/asound/${DEVICE}/* ${INSTALL}/usr/config/ diff --git a/packages/jelos/sources/autostart/quirks/AYANEO AIR/002-wifi_module b/packages/jelos/sources/autostart/quirks/AYANEO AIR/002-wifi_module deleted file mode 100644 index 7b1e51ef0..000000000 --- a/packages/jelos/sources/autostart/quirks/AYANEO AIR/002-wifi_module +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: Apache-2.0 -# Copyright (C) 2021-present Fewtarius (https://github.com/fewtarius) - -. /etc/profile - -if [ ! -d "/storage/.config/profile.d/" ] -then - mkdir -p /storage/.config/profile.d -fi -if [ ! -e "/storage/.config/profile.d/001-wifi_module" ] -then - cat </storage/.config/profile.d/001-wifi_module -DEVICE_INTERNAL_WIFI=true -DEVICE_WIFI_MODULE="mt7921e" -DEVICE_WIFI_MODULE_SLEEPS=false -EOF - chmod 0755 /storage/.config/profile.d/001-wifi_module -fi diff --git a/packages/jelos/sources/scripts/jelos-info b/packages/jelos/sources/scripts/jelos-info index 2e8de4ee0..b1e4e2bd3 100755 --- a/packages/jelos/sources/scripts/jelos-info +++ b/packages/jelos/sources/scripts/jelos-info @@ -70,7 +70,7 @@ done # temperature # Unit: millidegree Celsius -TEMPE=$(cat /sys/devices/virtual/thermal/thermal_zone*/temp 2>/dev/null | sort -rn | head -1 | sed -e s+"[0-9][0-9][0-9]$"++) +TEMPE=$(cat ${DEVICE_TEMP_SENSOR} 2>/dev/null | sort -rn | head -1 | sed -e s+"[0-9][0-9][0-9]$"++) echo "SYSTEM INFORMATION:" echo "OPERATING SYSTEM: ${OS_NAME}" echo "VERSION: ${OS_VERSION}" diff --git a/packages/jelos/sources/scripts/show_splash b/packages/jelos/sources/scripts/show_splash index ad82883c0..477331802 100755 --- a/packages/jelos/sources/scripts/show_splash +++ b/packages/jelos/sources/scripts/show_splash @@ -11,13 +11,34 @@ SPLASH_TYPE="$1" hres="$(fbset 2>/dev/null | awk '/geometry/ { print $2 }')" vres="$(fbset 2>/dev/null | awk '/geometry/ { print $3 }')" +rotation="$(cat /sys/devices/virtual/graphics/fbcon/rotate)" if [ "${SPLASH_TYPE}" == "intro" ] || [ "${SPLASH_TYPE}" == "exit" ] then - if [ ${vres} -gt ${hres} ] + if [ ${vres} -gt ${hres} ] && \ + [ -e "/usr/config/splash/splashl.png" ] then + ### When we have a device specific splash SPLASH="/usr/config/splash/splashl.png" + elif [ ! -e "/usr/config/splash/splashl.png" ] + then + ### When we don't define a splash + case ${rotation} in + 0) + SPLASH="/usr/config/splash/splash.png" + ;; + 1) + SPLASH="/usr/config/splash/splash_90.png" + ;; + 2) + SPLASH="/usr/config/splash/splash_180.png" + ;; + 3) + SPLASH="/usr/config/splash/splash_270.png" + ;; + esac else + ### When we don't know what to do. SPLASH="/usr/config/splash/splash.png" fi else diff --git a/packages/kernel/linux-drivers/RTL8812AU/package.mk b/packages/kernel/linux-drivers/RTL8812AU/package.mk index 05e2c04ea..ebe432860 100644 --- a/packages/kernel/linux-drivers/RTL8812AU/package.mk +++ b/packages/kernel/linux-drivers/RTL8812AU/package.mk @@ -4,7 +4,7 @@ # Copyright (C) 2021-present Fewtarius PKG_NAME="RTL8812AU" -PKG_VERSION="b7c68a25d41cf14da9f7176ccc260d6efba5c5db" +PKG_VERSION="65949c530359ece8f28c84516f4d17fe7ab7d897" PKG_LICENSE="GPL" PKG_SITE="https://github.com/morrownr/8812au-20210629" PKG_URL="${PKG_SITE}.git" diff --git a/packages/kernel/linux-drivers/RTL8814AU/package.mk b/packages/kernel/linux-drivers/RTL8814AU/package.mk index ff236292c..5af56ae19 100644 --- a/packages/kernel/linux-drivers/RTL8814AU/package.mk +++ b/packages/kernel/linux-drivers/RTL8814AU/package.mk @@ -4,7 +4,7 @@ # Copyright (C) 2021-present Fewtarius PKG_NAME="RTL8814AU" -PKG_VERSION="3f2f6805617bcfef66f2fd2129acbc87b181fd36" +PKG_VERSION="932df6f7da6c3a384cf91f33eb195097eb0cb6c5" PKG_LICENSE="GPL" PKG_SITE="https://github.com/morrownr/8814au" PKG_URL="${PKG_SITE}.git" diff --git a/packages/kernel/linux-drivers/RTL8821AU/package.mk b/packages/kernel/linux-drivers/RTL8821AU/package.mk index d08fb4317..3beaddf1c 100644 --- a/packages/kernel/linux-drivers/RTL8821AU/package.mk +++ b/packages/kernel/linux-drivers/RTL8821AU/package.mk @@ -4,7 +4,7 @@ # Copyright (C) 2021-present Fewtarius PKG_NAME="RTL8821AU" -PKG_VERSION="b46c98dec45ae413add32b04a96253979b858bc6" +PKG_VERSION="663dc8fe1fbc100be9ed532f003c6eb90dab3d33" PKG_LICENSE="GPL" PKG_SITE="https://github.com/morrownr/8821au-20210708" PKG_URL="${PKG_SITE}.git" diff --git a/packages/kernel/linux-drivers/RTL8821CU/package.mk b/packages/kernel/linux-drivers/RTL8821CU/package.mk index 8b87d4379..8de5d6957 100644 --- a/packages/kernel/linux-drivers/RTL8821CU/package.mk +++ b/packages/kernel/linux-drivers/RTL8821CU/package.mk @@ -4,7 +4,7 @@ # Copyright (C) 2021-present Fewtarius PKG_NAME="RTL8821CU" -PKG_VERSION="122ef09302885dfe2cb9ec9cf16a7df699d1cadb" +PKG_VERSION="86cc5ceb7c28b9b997838e1c796847f6c395c382" PKG_LICENSE="GPL" PKG_SITE="https://github.com/morrownr/8821cu-20210118" PKG_URL="${PKG_SITE}.git" diff --git a/packages/kernel/linux-drivers/RTL88x2BU/package.mk b/packages/kernel/linux-drivers/RTL88x2BU/package.mk index 3c952eb38..b06a56f50 100644 --- a/packages/kernel/linux-drivers/RTL88x2BU/package.mk +++ b/packages/kernel/linux-drivers/RTL88x2BU/package.mk @@ -4,7 +4,7 @@ # Copyright (C) 2021-present Fewtarius PKG_NAME="RTL88x2BU" -PKG_VERSION="6a2916db1a01625b9f2fc77d466f07e498735c44" +PKG_VERSION="9a04d2bb9d882c7f2708560774d7b96a70d83f4b" PKG_LICENSE="GPL" PKG_SITE="https://github.com/morrownr/88x2bu-20210702" PKG_URL="${PKG_SITE}.git" diff --git a/packages/kernel/linux/patches/X86_64/001-hwsensors.patch b/packages/kernel/linux/patches/X86_64/001-hwsensors.patch new file mode 100644 index 000000000..46ec6da73 --- /dev/null +++ b/packages/kernel/linux/patches/X86_64/001-hwsensors.patch @@ -0,0 +1,4845 @@ +From 415519ad6966ce35f2535fc3ff95549414beb032 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Wed, 5 Oct 2022 16:27:52 +0100 +Subject: hwmon: (fschmd) Make const arrays static const + +Don't populate the read-only const arrays names and watchdog_minors +on the stack but instead make them static const. Also makes the +object code a little smaller. + +Signed-off-by: Colin Ian King +Link: https://lore.kernel.org/r/20221005152752.318493-1-colin.i.king@gmail.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/fschmd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c +index 0a77d61619288..e1f426e86f36c 100644 +--- a/drivers/hwmon/fschmd.c ++++ b/drivers/hwmon/fschmd.c +@@ -1083,9 +1083,9 @@ static int fschmd_detect(struct i2c_client *client, + static int fschmd_probe(struct i2c_client *client) + { + struct fschmd_data *data; +- const char * const names[7] = { "Poseidon", "Hermes", "Scylla", ++ static const char * const names[7] = { "Poseidon", "Hermes", "Scylla", + "Heracles", "Heimdall", "Hades", "Syleus" }; +- const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 }; ++ static const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 }; + int i, err; + enum chips kind = i2c_match_id(fschmd_id, client)->driver_data; + +-- +cgit + + +From 12c44ab8b401c29d8d3569aaea34da662b8ece1d Mon Sep 17 00:00:00 2001 +From: Ahmad Khalifa +Date: Tue, 4 Oct 2022 22:01:01 +0100 +Subject: hwmon: (it87) Add param to ignore ACPI resource conflicts + +Add parameter to ignore ACPI resource conflicts as an alternate to using +'acpi_enforce_resources=lax'. + +Some BIOSes reserve resources and don't use them and the system wide +parameter may result in failures to certain drivers. + +Signed-off-by: Ahmad Khalifa +Link: https://lore.kernel.org/r/20221004210100.540120-2-ahmad@khalifa.ws +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/it87.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c +index 7bd154ba351b9..e920dd26225ff 100644 +--- a/drivers/hwmon/it87.c ++++ b/drivers/hwmon/it87.c +@@ -69,6 +69,10 @@ static unsigned short force_id; + module_param(force_id, ushort, 0); + MODULE_PARM_DESC(force_id, "Override the detected device ID"); + ++static bool ignore_resource_conflict; ++module_param(ignore_resource_conflict, bool, 0); ++MODULE_PARM_DESC(ignore_resource_conflict, "Ignore ACPI resource conflict"); ++ + static struct platform_device *it87_pdev[2]; + + #define REG_2E 0x2e /* The register to read/write */ +@@ -3261,8 +3265,10 @@ static int __init it87_device_add(int index, unsigned short address, + int err; + + err = acpi_check_resource_conflict(&res); +- if (err) +- return err; ++ if (err) { ++ if (!ignore_resource_conflict) ++ return err; ++ } + + pdev = platform_device_alloc(DRVNAME, address); + if (!pdev) +-- +cgit + + +From b3b19931a5c22f5a09f846e037b23f8a74455d0a Mon Sep 17 00:00:00 2001 +From: Ahmad Khalifa +Date: Tue, 4 Oct 2022 22:01:03 +0100 +Subject: hwmon: (it87) Check for a valid chip before using force_id + +Check there is a chip before using force_id parameter as there +is no value in registering a non-existent chip + +Signed-off-by: Ahmad Khalifa +Link: https://lore.kernel.org/r/20221004210100.540120-3-ahmad@khalifa.ws +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/it87.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c +index e920dd26225ff..73ed21ab325ba 100644 +--- a/drivers/hwmon/it87.c ++++ b/drivers/hwmon/it87.c +@@ -2401,7 +2401,13 @@ static int __init it87_find(int sioaddr, unsigned short *address, + return err; + + err = -ENODEV; +- chip_type = force_id ? force_id : superio_inw(sioaddr, DEVID); ++ chip_type = superio_inw(sioaddr, DEVID); ++ /* check first for a valid chip before forcing chip id */ ++ if (chip_type == 0xffff) ++ goto exit; ++ ++ if (force_id) ++ chip_type = force_id; + + switch (chip_type) { + case IT8705F_DEVID: +-- +cgit + + +From deeab9ea40dbaabdf0e2828b5c3da3418ae7dd39 Mon Sep 17 00:00:00 2001 +From: Stephen Kitt +Date: Tue, 11 Oct 2022 16:33:08 +0200 +Subject: hwmon: use simple i2c probe + +All these drivers have an i2c probe function which doesn't use the +"struct i2c_device_id *id" parameter, so they can trivially be +converted to the "probe_new" style of probe with a single argument. + +This is part of an ongoing transition to single-argument i2c probe +functions. Old-style probe functions involve a call to i2c_match_id: +in drivers/i2c/i2c-core-base.c, + + /* + * When there are no more users of probe(), + * rename probe_new to probe. + */ + if (driver->probe_new) + status = driver->probe_new(client); + else if (driver->probe) + status = driver->probe(client, + i2c_match_id(driver->id_table, client)); + else + status = -EINVAL; + +Drivers which don't need the second parameter can be declared using +probe_new instead, avoiding the call to i2c_match_id. Drivers which do +can still be converted to probe_new-style, calling i2c_match_id +themselves (as is done currently for of_match_id). + +This change was done using the following Coccinelle script, and fixed +up for whitespace changes: + +@ rule1 @ +identifier fn; +identifier client, id; +@@ + +- static int fn(struct i2c_client *client, const struct i2c_device_id *id) ++ static int fn(struct i2c_client *client) +{ +...when != id +} + +@ rule2 depends on rule1 @ +identifier rule1.fn; +identifier driver; +@@ + +struct i2c_driver driver = { +- .probe ++ .probe_new + = +( + fn +| +- &fn ++ fn +) + , +}; + +Signed-off-by: Stephen Kitt +Link: https://lore.kernel.org/r/20221011143309.3141267-1-steve@sk2.org +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/aht10.c | 5 ++--- + drivers/hwmon/emc2305.c | 4 ++-- + drivers/hwmon/ltc2992.c | 4 ++-- + drivers/hwmon/max127.c | 5 ++--- + drivers/hwmon/sbrmi.c | 5 ++--- + drivers/hwmon/sbtsi_temp.c | 5 ++--- + drivers/hwmon/sht4x.c | 5 ++--- + 7 files changed, 14 insertions(+), 19 deletions(-) + +diff --git a/drivers/hwmon/aht10.c b/drivers/hwmon/aht10.c +index 2d9770cb4401b..d76f3441ecf1a 100644 +--- a/drivers/hwmon/aht10.c ++++ b/drivers/hwmon/aht10.c +@@ -289,8 +289,7 @@ static const struct hwmon_chip_info aht10_chip_info = { + .info = aht10_info, + }; + +-static int aht10_probe(struct i2c_client *client, +- const struct i2c_device_id *aht10_id) ++static int aht10_probe(struct i2c_client *client) + { + struct device *device = &client->dev; + struct device *hwmon_dev; +@@ -336,7 +335,7 @@ static struct i2c_driver aht10_driver = { + .driver = { + .name = "aht10", + }, +- .probe = aht10_probe, ++ .probe_new = aht10_probe, + .id_table = aht10_id, + }; + +diff --git a/drivers/hwmon/emc2305.c b/drivers/hwmon/emc2305.c +index aa1f25add0b6b..f222fcf3b6aa1 100644 +--- a/drivers/hwmon/emc2305.c ++++ b/drivers/hwmon/emc2305.c +@@ -518,7 +518,7 @@ static int emc2305_identify(struct device *dev) + return 0; + } + +-static int emc2305_probe(struct i2c_client *client, const struct i2c_device_id *id) ++static int emc2305_probe(struct i2c_client *client) + { + struct i2c_adapter *adapter = client->adapter; + struct device *dev = &client->dev; +@@ -607,7 +607,7 @@ static struct i2c_driver emc2305_driver = { + .driver = { + .name = "emc2305", + }, +- .probe = emc2305_probe, ++ .probe_new = emc2305_probe, + .remove = emc2305_remove, + .id_table = emc2305_ids, + .address_list = emc2305_normal_i2c, +diff --git a/drivers/hwmon/ltc2992.c b/drivers/hwmon/ltc2992.c +index 72489d5d7eaf9..88514152d9306 100644 +--- a/drivers/hwmon/ltc2992.c ++++ b/drivers/hwmon/ltc2992.c +@@ -881,7 +881,7 @@ static int ltc2992_parse_dt(struct ltc2992_state *st) + return 0; + } + +-static int ltc2992_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) ++static int ltc2992_i2c_probe(struct i2c_client *client) + { + struct device *hwmon_dev; + struct ltc2992_state *st; +@@ -927,7 +927,7 @@ static struct i2c_driver ltc2992_i2c_driver = { + .name = "ltc2992", + .of_match_table = ltc2992_of_match, + }, +- .probe = ltc2992_i2c_probe, ++ .probe_new = ltc2992_i2c_probe, + .id_table = ltc2992_i2c_id, + }; + +diff --git a/drivers/hwmon/max127.c b/drivers/hwmon/max127.c +index 402ffdc2f425b..0e21e7e6bbd2e 100644 +--- a/drivers/hwmon/max127.c ++++ b/drivers/hwmon/max127.c +@@ -303,8 +303,7 @@ static const struct hwmon_chip_info max127_chip_info = { + .info = max127_info, + }; + +-static int max127_probe(struct i2c_client *client, +- const struct i2c_device_id *id) ++static int max127_probe(struct i2c_client *client) + { + int i; + struct device *hwmon_dev; +@@ -340,7 +339,7 @@ static struct i2c_driver max127_driver = { + .driver = { + .name = "max127", + }, +- .probe = max127_probe, ++ .probe_new = max127_probe, + .id_table = max127_id, + }; + +diff --git a/drivers/hwmon/sbrmi.c b/drivers/hwmon/sbrmi.c +index 7bf0c3fba75fe..8ea5a4d3219ff 100644 +--- a/drivers/hwmon/sbrmi.c ++++ b/drivers/hwmon/sbrmi.c +@@ -297,8 +297,7 @@ static int sbrmi_get_max_pwr_limit(struct sbrmi_data *data) + return ret; + } + +-static int sbrmi_probe(struct i2c_client *client, +- const struct i2c_device_id *id) ++static int sbrmi_probe(struct i2c_client *client) + { + struct device *dev = &client->dev; + struct device *hwmon_dev; +@@ -348,7 +347,7 @@ static struct i2c_driver sbrmi_driver = { + .name = "sbrmi", + .of_match_table = of_match_ptr(sbrmi_of_match), + }, +- .probe = sbrmi_probe, ++ .probe_new = sbrmi_probe, + .id_table = sbrmi_id, + }; + +diff --git a/drivers/hwmon/sbtsi_temp.c b/drivers/hwmon/sbtsi_temp.c +index e35357c48b8e6..4c37de846f93b 100644 +--- a/drivers/hwmon/sbtsi_temp.c ++++ b/drivers/hwmon/sbtsi_temp.c +@@ -199,8 +199,7 @@ static const struct hwmon_chip_info sbtsi_chip_info = { + .info = sbtsi_info, + }; + +-static int sbtsi_probe(struct i2c_client *client, +- const struct i2c_device_id *id) ++static int sbtsi_probe(struct i2c_client *client) + { + struct device *dev = &client->dev; + struct device *hwmon_dev; +@@ -239,7 +238,7 @@ static struct i2c_driver sbtsi_driver = { + .name = "sbtsi", + .of_match_table = of_match_ptr(sbtsi_of_match), + }, +- .probe = sbtsi_probe, ++ .probe_new = sbtsi_probe, + .id_table = sbtsi_id, + }; + +diff --git a/drivers/hwmon/sht4x.c b/drivers/hwmon/sht4x.c +index 13ac2d8f22c79..13e042927bf89 100644 +--- a/drivers/hwmon/sht4x.c ++++ b/drivers/hwmon/sht4x.c +@@ -232,8 +232,7 @@ static const struct hwmon_chip_info sht4x_chip_info = { + .info = sht4x_info, + }; + +-static int sht4x_probe(struct i2c_client *client, +- const struct i2c_device_id *sht4x_id) ++static int sht4x_probe(struct i2c_client *client) + { + struct device *device = &client->dev; + struct device *hwmon_dev; +@@ -292,7 +291,7 @@ static struct i2c_driver sht4x_driver = { + .name = "sht4x", + .of_match_table = sht4x_of_match, + }, +- .probe = sht4x_probe, ++ .probe_new = sht4x_probe, + .id_table = sht4x_id, + }; + +-- +cgit + + +From ad804a4d82fc7ececb457c06c8ba8b3a9d0e3bfd Mon Sep 17 00:00:00 2001 +From: Matti Vaittinen +Date: Fri, 21 Oct 2022 16:18:43 +0300 +Subject: hwmon: (lm90) simplify using devm_regulator_get_enable() + +Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), +add_action_or_reset(regulator_disable)' and use the +devm_regulator_get_enable(). + +Signed-off-by: Matti Vaittinen +Link: https://lore.kernel.org/r/a1fa4364cbb775de25478117dd22dda0742089e3.1666357434.git.mazziesaccount@gmail.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/lm90.c | 20 ++------------------ + 1 file changed, 2 insertions(+), 18 deletions(-) + +diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c +index db595f7d01f8a..a3f95ba00dbff 100644 +--- a/drivers/hwmon/lm90.c ++++ b/drivers/hwmon/lm90.c +@@ -2663,11 +2663,6 @@ static void lm90_remove_pec(void *dev) + device_remove_file(dev, &dev_attr_pec); + } + +-static void lm90_regulator_disable(void *regulator) +-{ +- regulator_disable(regulator); +-} +- + static int lm90_probe_channel_from_dt(struct i2c_client *client, + struct device_node *child, + struct lm90_data *data) +@@ -2749,24 +2744,13 @@ static int lm90_probe(struct i2c_client *client) + struct device *dev = &client->dev; + struct i2c_adapter *adapter = client->adapter; + struct hwmon_channel_info *info; +- struct regulator *regulator; + struct device *hwmon_dev; + struct lm90_data *data; + int err; + +- regulator = devm_regulator_get(dev, "vcc"); +- if (IS_ERR(regulator)) +- return PTR_ERR(regulator); +- +- err = regulator_enable(regulator); +- if (err < 0) { +- dev_err(dev, "Failed to enable regulator: %d\n", err); +- return err; +- } +- +- err = devm_add_action_or_reset(dev, lm90_regulator_disable, regulator); ++ err = devm_regulator_get_enable(dev, "vcc"); + if (err) +- return err; ++ return dev_err_probe(dev, err, "Failed to enable regulator\n"); + + data = devm_kzalloc(dev, sizeof(struct lm90_data), GFP_KERNEL); + if (!data) +-- +cgit + + +From bba63de0c7a7e69584266872cb278cf12fe9ae83 Mon Sep 17 00:00:00 2001 +From: Matti Vaittinen +Date: Fri, 21 Oct 2022 16:19:04 +0300 +Subject: hwmon: (adm1177) simplify using devm_regulator_get_enable() + +Drop open-coded pattern: 'devm_regulator_get(), regulator_enable(), +add_action_or_reset(regulator_disable)' and use the +devm_regulator_get_enable() and drop the pointer to the regulator. +This simplifies code and makes it less tempting to add manual control +for the regulator which is also controlled by devm. + +Signed-off-by: Matti Vaittinen +Link: https://lore.kernel.org/r/7773541795f280db31dd981ffc21df8a630b794a.1666357434.git.mazziesaccount@gmail.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/adm1177.c | 27 +++------------------------ + 1 file changed, 3 insertions(+), 24 deletions(-) + +diff --git a/drivers/hwmon/adm1177.c b/drivers/hwmon/adm1177.c +index 0c5dbc5e33b46..be17a26a84f19 100644 +--- a/drivers/hwmon/adm1177.c ++++ b/drivers/hwmon/adm1177.c +@@ -26,14 +26,12 @@ + /** + * struct adm1177_state - driver instance specific data + * @client: pointer to i2c client +- * @reg: regulator info for the power supply of the device + * @r_sense_uohm: current sense resistor value + * @alert_threshold_ua: current limit for shutdown + * @vrange_high: internal voltage divider + */ + struct adm1177_state { + struct i2c_client *client; +- struct regulator *reg; + u32 r_sense_uohm; + u32 alert_threshold_ua; + bool vrange_high; +@@ -189,13 +187,6 @@ static const struct hwmon_chip_info adm1177_chip_info = { + .info = adm1177_info, + }; + +-static void adm1177_remove(void *data) +-{ +- struct adm1177_state *st = data; +- +- regulator_disable(st->reg); +-} +- + static int adm1177_probe(struct i2c_client *client) + { + struct device *dev = &client->dev; +@@ -210,21 +201,9 @@ static int adm1177_probe(struct i2c_client *client) + + st->client = client; + +- st->reg = devm_regulator_get_optional(&client->dev, "vref"); +- if (IS_ERR(st->reg)) { +- if (PTR_ERR(st->reg) == -EPROBE_DEFER) +- return -EPROBE_DEFER; +- +- st->reg = NULL; +- } else { +- ret = regulator_enable(st->reg); +- if (ret) +- return ret; +- ret = devm_add_action_or_reset(&client->dev, adm1177_remove, +- st); +- if (ret) +- return ret; +- } ++ ret = devm_regulator_get_enable_optional(&client->dev, "vref"); ++ if (ret == -EPROBE_DEFER) ++ return -EPROBE_DEFER; + + if (device_property_read_u32(dev, "shunt-resistor-micro-ohms", + &st->r_sense_uohm)) +-- +cgit + + +From 7bce898147000718084c842e150519319dc202c6 Mon Sep 17 00:00:00 2001 +From: Quan Nguyen +Date: Thu, 29 Sep 2022 16:43:13 +0700 +Subject: hwmon: Add Ampere's Altra smpro-hwmon driver + +This commit adds support for Ampere SMpro hwmon driver. This driver +supports accessing various CPU sensors provided by the SMpro co-processor +including temperature, power, voltages, and current. + +Signed-off-by: Quan Nguyen +Link: https://lore.kernel.org/r/20220929094321.770125-2-quan@os.amperecomputing.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/Kconfig | 8 + + drivers/hwmon/Makefile | 1 + + drivers/hwmon/smpro-hwmon.c | 463 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 472 insertions(+) + create mode 100644 drivers/hwmon/smpro-hwmon.c + +diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +index 7ac3daaf59ce0..e7ec6af309c79 100644 +--- a/drivers/hwmon/Kconfig ++++ b/drivers/hwmon/Kconfig +@@ -67,6 +67,14 @@ config SENSORS_ABITUGURU3 + This driver can also be built as a module. If so, the module + will be called abituguru3. + ++config SENSORS_SMPRO ++ tristate "Ampere's Altra SMpro hardware monitoring driver" ++ depends on MFD_SMPRO ++ help ++ If you say yes here you get support for the thermal, voltage, ++ current and power sensors of Ampere's Altra processor family SoC ++ with SMpro co-processor. ++ + config SENSORS_AD7314 + tristate "Analog Devices AD7314 and compatibles" + depends on SPI +diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile +index 11d076cad8a2d..c5cd7e3a67ffd 100644 +--- a/drivers/hwmon/Makefile ++++ b/drivers/hwmon/Makefile +@@ -187,6 +187,7 @@ obj-$(CONFIG_SENSORS_SHT4x) += sht4x.o + obj-$(CONFIG_SENSORS_SHTC1) += shtc1.o + obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o + obj-$(CONFIG_SENSORS_SMM665) += smm665.o ++obj-$(CONFIG_SENSORS_SMPRO) += smpro-hwmon.o + obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o + obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o + obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o +diff --git a/drivers/hwmon/smpro-hwmon.c b/drivers/hwmon/smpro-hwmon.c +new file mode 100644 +index 0000000000000..ee54e21c2c123 +--- /dev/null ++++ b/drivers/hwmon/smpro-hwmon.c +@@ -0,0 +1,463 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Ampere Computing SoC's SMPro Hardware Monitoring Driver ++ * ++ * Copyright (c) 2022, Ampere Computing LLC ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Logical Power Sensor Registers */ ++#define SOC_TEMP 0x10 ++#define SOC_VRD_TEMP 0x11 ++#define DIMM_VRD_TEMP 0x12 ++#define CORE_VRD_TEMP 0x13 ++#define CH0_DIMM_TEMP 0x14 ++#define CH1_DIMM_TEMP 0x15 ++#define CH2_DIMM_TEMP 0x16 ++#define CH3_DIMM_TEMP 0x17 ++#define CH4_DIMM_TEMP 0x18 ++#define CH5_DIMM_TEMP 0x19 ++#define CH6_DIMM_TEMP 0x1A ++#define CH7_DIMM_TEMP 0x1B ++#define RCA_VRD_TEMP 0x1C ++ ++#define CORE_VRD_PWR 0x20 ++#define SOC_PWR 0x21 ++#define DIMM_VRD1_PWR 0x22 ++#define DIMM_VRD2_PWR 0x23 ++#define CORE_VRD_PWR_MW 0x26 ++#define SOC_PWR_MW 0x27 ++#define DIMM_VRD1_PWR_MW 0x28 ++#define DIMM_VRD2_PWR_MW 0x29 ++#define RCA_VRD_PWR 0x2A ++#define RCA_VRD_PWR_MW 0x2B ++ ++#define MEM_HOT_THRESHOLD 0x32 ++#define SOC_VR_HOT_THRESHOLD 0x33 ++#define CORE_VRD_VOLT 0x34 ++#define SOC_VRD_VOLT 0x35 ++#define DIMM_VRD1_VOLT 0x36 ++#define DIMM_VRD2_VOLT 0x37 ++#define RCA_VRD_VOLT 0x38 ++ ++#define CORE_VRD_CURR 0x39 ++#define SOC_VRD_CURR 0x3A ++#define DIMM_VRD1_CURR 0x3B ++#define DIMM_VRD2_CURR 0x3C ++#define RCA_VRD_CURR 0x3D ++ ++struct smpro_hwmon { ++ struct regmap *regmap; ++}; ++ ++struct smpro_sensor { ++ const u8 reg; ++ const u8 reg_ext; ++ const char *label; ++}; ++ ++static const struct smpro_sensor temperature[] = { ++ { ++ .reg = SOC_TEMP, ++ .label = "temp1 SoC" ++ }, ++ { ++ .reg = SOC_VRD_TEMP, ++ .reg_ext = SOC_VR_HOT_THRESHOLD, ++ .label = "temp2 SoC VRD" ++ }, ++ { ++ .reg = DIMM_VRD_TEMP, ++ .label = "temp3 DIMM VRD" ++ }, ++ { ++ .reg = CORE_VRD_TEMP, ++ .label = "temp4 CORE VRD" ++ }, ++ { ++ .reg = CH0_DIMM_TEMP, ++ .reg_ext = MEM_HOT_THRESHOLD, ++ .label = "temp5 CH0 DIMM" ++ }, ++ { ++ .reg = CH1_DIMM_TEMP, ++ .reg_ext = MEM_HOT_THRESHOLD, ++ .label = "temp6 CH1 DIMM" ++ }, ++ { ++ .reg = CH2_DIMM_TEMP, ++ .reg_ext = MEM_HOT_THRESHOLD, ++ .label = "temp7 CH2 DIMM" ++ }, ++ { ++ .reg = CH3_DIMM_TEMP, ++ .reg_ext = MEM_HOT_THRESHOLD, ++ .label = "temp8 CH3 DIMM" ++ }, ++ { ++ .reg = CH4_DIMM_TEMP, ++ .reg_ext = MEM_HOT_THRESHOLD, ++ .label = "temp9 CH4 DIMM" ++ }, ++ { ++ .reg = CH5_DIMM_TEMP, ++ .reg_ext = MEM_HOT_THRESHOLD, ++ .label = "temp10 CH5 DIMM" ++ }, ++ { ++ .reg = CH6_DIMM_TEMP, ++ .reg_ext = MEM_HOT_THRESHOLD, ++ .label = "temp11 CH6 DIMM" ++ }, ++ { ++ .reg = CH7_DIMM_TEMP, ++ .reg_ext = MEM_HOT_THRESHOLD, ++ .label = "temp12 CH7 DIMM" ++ }, ++ { ++ .reg = RCA_VRD_TEMP, ++ .label = "temp13 RCA VRD" ++ }, ++}; ++ ++static const struct smpro_sensor voltage[] = { ++ { ++ .reg = CORE_VRD_VOLT, ++ .label = "vout0 CORE VRD" ++ }, ++ { ++ .reg = SOC_VRD_VOLT, ++ .label = "vout1 SoC VRD" ++ }, ++ { ++ .reg = DIMM_VRD1_VOLT, ++ .label = "vout2 DIMM VRD1" ++ }, ++ { ++ .reg = DIMM_VRD2_VOLT, ++ .label = "vout3 DIMM VRD2" ++ }, ++ { ++ .reg = RCA_VRD_VOLT, ++ .label = "vout4 RCA VRD" ++ }, ++}; ++ ++static const struct smpro_sensor curr_sensor[] = { ++ { ++ .reg = CORE_VRD_CURR, ++ .label = "iout1 CORE VRD" ++ }, ++ { ++ .reg = SOC_VRD_CURR, ++ .label = "iout2 SoC VRD" ++ }, ++ { ++ .reg = DIMM_VRD1_CURR, ++ .label = "iout3 DIMM VRD1" ++ }, ++ { ++ .reg = DIMM_VRD2_CURR, ++ .label = "iout4 DIMM VRD2" ++ }, ++ { ++ .reg = RCA_VRD_CURR, ++ .label = "iout5 RCA VRD" ++ }, ++}; ++ ++static const struct smpro_sensor power[] = { ++ { ++ .reg = CORE_VRD_PWR, ++ .reg_ext = CORE_VRD_PWR_MW, ++ .label = "power1 CORE VRD" ++ }, ++ { ++ .reg = SOC_PWR, ++ .reg_ext = SOC_PWR_MW, ++ .label = "power2 SoC" ++ }, ++ { ++ .reg = DIMM_VRD1_PWR, ++ .reg_ext = DIMM_VRD1_PWR_MW, ++ .label = "power3 DIMM VRD1" ++ }, ++ { ++ .reg = DIMM_VRD2_PWR, ++ .reg_ext = DIMM_VRD2_PWR_MW, ++ .label = "power4 DIMM VRD2" ++ }, ++ { ++ .reg = RCA_VRD_PWR, ++ .reg_ext = RCA_VRD_PWR_MW, ++ .label = "power5 RCA VRD" ++ }, ++}; ++ ++static int smpro_read_temp(struct device *dev, u32 attr, int channel, long *val) ++{ ++ struct smpro_hwmon *hwmon = dev_get_drvdata(dev); ++ unsigned int value; ++ int ret; ++ ++ switch (attr) { ++ case hwmon_temp_input: ++ ret = regmap_read(hwmon->regmap, temperature[channel].reg, &value); ++ if (ret) ++ return ret; ++ break; ++ case hwmon_temp_crit: ++ ret = regmap_read(hwmon->regmap, temperature[channel].reg_ext, &value); ++ if (ret) ++ return ret; ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ *val = sign_extend32(value, 8) * 1000; ++ return 0; ++} ++ ++static int smpro_read_in(struct device *dev, u32 attr, int channel, long *val) ++{ ++ struct smpro_hwmon *hwmon = dev_get_drvdata(dev); ++ unsigned int value; ++ int ret; ++ ++ switch (attr) { ++ case hwmon_in_input: ++ ret = regmap_read(hwmon->regmap, voltage[channel].reg, &value); ++ if (ret < 0) ++ return ret; ++ /* 15-bit value in 1mV */ ++ *val = value & 0x7fff; ++ return 0; ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static int smpro_read_curr(struct device *dev, u32 attr, int channel, long *val) ++{ ++ struct smpro_hwmon *hwmon = dev_get_drvdata(dev); ++ unsigned int value; ++ int ret; ++ ++ switch (attr) { ++ case hwmon_curr_input: ++ ret = regmap_read(hwmon->regmap, curr_sensor[channel].reg, &value); ++ if (ret < 0) ++ return ret; ++ /* Scale reported by the hardware is 1mA */ ++ *val = value & 0x7fff; ++ return 0; ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static int smpro_read_power(struct device *dev, u32 attr, int channel, long *val_pwr) ++{ ++ struct smpro_hwmon *hwmon = dev_get_drvdata(dev); ++ unsigned int val = 0, val_mw = 0; ++ int ret; ++ ++ switch (attr) { ++ case hwmon_power_input: ++ ret = regmap_read(hwmon->regmap, power[channel].reg, &val); ++ if (ret) ++ return ret; ++ ++ ret = regmap_read(hwmon->regmap, power[channel].reg_ext, &val_mw); ++ if (ret) ++ return ret; ++ /* 10-bit value */ ++ *val_pwr = (val & 0x3ff) * 1000000 + (val_mw & 0x3ff) * 1000; ++ return 0; ++ ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static int smpro_read(struct device *dev, enum hwmon_sensor_types type, ++ u32 attr, int channel, long *val) ++{ ++ switch (type) { ++ case hwmon_temp: ++ return smpro_read_temp(dev, attr, channel, val); ++ case hwmon_in: ++ return smpro_read_in(dev, attr, channel, val); ++ case hwmon_power: ++ return smpro_read_power(dev, attr, channel, val); ++ case hwmon_curr: ++ return smpro_read_curr(dev, attr, channel, val); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static int smpro_read_string(struct device *dev, enum hwmon_sensor_types type, ++ u32 attr, int channel, const char **str) ++{ ++ switch (type) { ++ case hwmon_temp: ++ switch (attr) { ++ case hwmon_temp_label: ++ *str = temperature[channel].label; ++ return 0; ++ default: ++ break; ++ } ++ break; ++ ++ case hwmon_in: ++ switch (attr) { ++ case hwmon_in_label: ++ *str = voltage[channel].label; ++ return 0; ++ default: ++ break; ++ } ++ break; ++ ++ case hwmon_curr: ++ switch (attr) { ++ case hwmon_curr_label: ++ *str = curr_sensor[channel].label; ++ return 0; ++ default: ++ break; ++ } ++ break; ++ ++ case hwmon_power: ++ switch (attr) { ++ case hwmon_power_label: ++ *str = power[channel].label; ++ return 0; ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ return -EOPNOTSUPP; ++} ++ ++static umode_t smpro_is_visible(const void *data, enum hwmon_sensor_types type, ++ u32 attr, int channel) ++{ ++ const struct smpro_hwmon *hwmon = data; ++ unsigned int value; ++ int ret; ++ ++ switch (type) { ++ case hwmon_temp: ++ switch (attr) { ++ case hwmon_temp_input: ++ case hwmon_temp_label: ++ case hwmon_temp_crit: ++ ret = regmap_read(hwmon->regmap, temperature[channel].reg, &value); ++ if (ret || value == 0xFFFF) ++ return 0; ++ break; ++ } ++ default: ++ break; ++ } ++ ++ return 0444; ++} ++ ++static const struct hwmon_channel_info *smpro_info[] = { ++ HWMON_CHANNEL_INFO(temp, ++ HWMON_T_INPUT | HWMON_T_LABEL, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, ++ HWMON_T_INPUT | HWMON_T_LABEL, ++ HWMON_T_INPUT | HWMON_T_LABEL, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, ++ HWMON_T_INPUT | HWMON_T_LABEL), ++ HWMON_CHANNEL_INFO(in, ++ HWMON_I_INPUT | HWMON_I_LABEL, ++ HWMON_I_INPUT | HWMON_I_LABEL, ++ HWMON_I_INPUT | HWMON_I_LABEL, ++ HWMON_I_INPUT | HWMON_I_LABEL, ++ HWMON_I_INPUT | HWMON_I_LABEL), ++ HWMON_CHANNEL_INFO(power, ++ HWMON_P_INPUT | HWMON_P_LABEL, ++ HWMON_P_INPUT | HWMON_P_LABEL, ++ HWMON_P_INPUT | HWMON_P_LABEL, ++ HWMON_P_INPUT | HWMON_P_LABEL, ++ HWMON_P_INPUT | HWMON_P_LABEL), ++ HWMON_CHANNEL_INFO(curr, ++ HWMON_C_INPUT | HWMON_C_LABEL, ++ HWMON_C_INPUT | HWMON_C_LABEL, ++ HWMON_C_INPUT | HWMON_C_LABEL, ++ HWMON_C_INPUT | HWMON_C_LABEL, ++ HWMON_C_INPUT | HWMON_C_LABEL), ++ NULL ++}; ++ ++static const struct hwmon_ops smpro_hwmon_ops = { ++ .is_visible = smpro_is_visible, ++ .read = smpro_read, ++ .read_string = smpro_read_string, ++}; ++ ++static const struct hwmon_chip_info smpro_chip_info = { ++ .ops = &smpro_hwmon_ops, ++ .info = smpro_info, ++}; ++ ++static int smpro_hwmon_probe(struct platform_device *pdev) ++{ ++ struct smpro_hwmon *hwmon; ++ struct device *hwmon_dev; ++ ++ hwmon = devm_kzalloc(&pdev->dev, sizeof(struct smpro_hwmon), GFP_KERNEL); ++ if (!hwmon) ++ return -ENOMEM; ++ ++ hwmon->regmap = dev_get_regmap(pdev->dev.parent, NULL); ++ if (!hwmon->regmap) ++ return -ENODEV; ++ ++ hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, "smpro_hwmon", ++ hwmon, &smpro_chip_info, NULL); ++ ++ return PTR_ERR_OR_ZERO(hwmon_dev); ++} ++ ++static struct platform_driver smpro_hwmon_driver = { ++ .probe = smpro_hwmon_probe, ++ .driver = { ++ .name = "smpro-hwmon", ++ }, ++}; ++ ++module_platform_driver(smpro_hwmon_driver); ++ ++MODULE_AUTHOR("Thu Nguyen "); ++MODULE_AUTHOR("Quan Nguyen "); ++MODULE_DESCRIPTION("Ampere Altra SMPro hwmon driver"); ++MODULE_LICENSE("GPL"); +-- +cgit + + +From 694144b215fc077087d68dfc3d1ef7dae9fec387 Mon Sep 17 00:00:00 2001 +From: Quan Nguyen +Date: Thu, 29 Sep 2022 16:43:14 +0700 +Subject: docs: hwmon: (smpro-hwmon) Add documentation + +Add documentation for the Ampere(R)'s Altra(R) SMpro hwmon driver. + +Signed-off-by: Thu Nguyen +Signed-off-by: Quan Nguyen +Link: https://lore.kernel.org/r/20220929094321.770125-3-quan@os.amperecomputing.com +Signed-off-by: Guenter Roeck +--- + Documentation/hwmon/index.rst | 1 + + Documentation/hwmon/smpro-hwmon.rst | 101 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 102 insertions(+) + create mode 100644 Documentation/hwmon/smpro-hwmon.rst + +diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst +index c1d11cf13eef1..ddff3c5713d74 100644 +--- a/Documentation/hwmon/index.rst ++++ b/Documentation/hwmon/index.rst +@@ -187,6 +187,7 @@ Hardware Monitoring Kernel Drivers + sis5595 + sl28cpld + smm665 ++ smpro-hwmon + smsc47b397 + smsc47m192 + smsc47m1 +diff --git a/Documentation/hwmon/smpro-hwmon.rst b/Documentation/hwmon/smpro-hwmon.rst +new file mode 100644 +index 0000000000000..3a9b14dacf897 +--- /dev/null ++++ b/Documentation/hwmon/smpro-hwmon.rst +@@ -0,0 +1,101 @@ ++.. SPDX-License-Identifier: GPL-2.0-only ++ ++Kernel driver Ampere(R)'s Altra(R) SMpro hwmon ++============================================== ++ ++Supported chips: ++ ++ * Ampere(R) Altra(R) ++ ++ Prefix: 'smpro' ++ ++ Reference: Altra SoC BMC Interface Specification ++ ++Author: Thu Nguyen ++ ++Description ++----------- ++This driver supports hardware monitoring for Ampere(R) Altra(R) SoC's based on the ++SMpro co-processor (SMpro). ++The following sensor types are supported by the driver: ++ ++ * temperature ++ * voltage ++ * current ++ * power ++ ++The SMpro interface provides the registers to query the various sensors and ++their values which are then exported to userspace by this driver. ++ ++Usage Notes ++----------- ++ ++SMpro hwmon driver creates at least two sysfs files for each sensor. ++ ++* File ``_label`` reports the sensor label. ++* File ``_input`` returns the sensor value. ++ ++The sysfs files are allocated in the SMpro root fs folder. ++There is one root folder for each SMpro instance. ++ ++When the SoC is turned off, the driver will fail to read registers ++and return -ENXIO. ++ ++Sysfs entries ++------------- ++ ++The following sysfs files are supported: ++ ++* Ampere(R) Altra(R): ++ ++============ ============= ====== =============================================== ++Name Unit Perm Description ++temp1_input milli Celsius RO SoC temperature ++temp2_input milli Celsius RO Max temperature reported among SoC VRDs ++temp2_crit milli Celsius RO SoC VRD HOT Threshold temperature ++temp3_input milli Celsius RO Max temperature reported among DIMM VRDs ++temp4_input milli Celsius RO Max temperature reported among Core VRDs ++temp5_input milli Celsius RO Temperature of DIMM0 on CH0 ++temp5_crit milli Celsius RO MEM HOT Threshold for all DIMMs ++temp6_input milli Celsius RO Temperature of DIMM0 on CH1 ++temp6_crit milli Celsius RO MEM HOT Threshold for all DIMMs ++temp7_input milli Celsius RO Temperature of DIMM0 on CH2 ++temp7_crit milli Celsius RO MEM HOT Threshold for all DIMMs ++temp8_input milli Celsius RO Temperature of DIMM0 on CH3 ++temp8_crit milli Celsius RO MEM HOT Threshold for all DIMMs ++temp9_input milli Celsius RO Temperature of DIMM0 on CH4 ++temp9_crit milli Celsius RO MEM HOT Threshold for all DIMMs ++temp10_input milli Celsius RO Temperature of DIMM0 on CH5 ++temp10_crit milli Celsius RO MEM HOT Threshold for all DIMMs ++temp11_input milli Celsius RO Temperature of DIMM0 on CH6 ++temp11_crit milli Celsius RO MEM HOT Threshold for all DIMMs ++temp12_input milli Celsius RO Temperature of DIMM0 on CH7 ++temp12_crit milli Celsius RO MEM HOT Threshold for all DIMMs ++temp13_input milli Celsius RO Max temperature reported among RCA VRDs ++in0_input milli Volts RO Core voltage ++in1_input milli Volts RO SoC voltage ++in2_input milli Volts RO DIMM VRD1 voltage ++in3_input milli Volts RO DIMM VRD2 voltage ++in4_input milli Volts RO RCA VRD voltage ++cur1_input milli Amperes RO Core VRD current ++cur2_input milli Amperes RO SoC VRD current ++cur3_input milli Amperes RO DIMM VRD1 current ++cur4_input milli Amperes RO DIMM VRD2 current ++cur5_input milli Amperes RO RCA VRD current ++power1_input micro Watts RO Core VRD power ++power2_input micro Watts RO SoC VRD power ++power3_input micro Watts RO DIMM VRD1 power ++power4_input micro Watts RO DIMM VRD2 power ++power5_input micro Watts RO RCA VRD power ++============ ============= ====== =============================================== ++ ++Example:: ++ ++ # cat in0_input ++ 830 ++ # cat temp1_input ++ 37000 ++ # cat curr1_input ++ 9000 ++ # cat power5_input ++ 19500000 +-- +cgit + + +From 6d270868cd529c39ac746e9ae3522c43f2764aca Mon Sep 17 00:00:00 2001 +From: Jeremy Kerr +Date: Mon, 24 Oct 2022 16:15:27 +0800 +Subject: hwmon: (occ) OCC sensors aren't arch-specific + +Commit c112d75840fb ("hwmon: OCC drivers are ARM-only") made the OCC +sensor drivers not selectable on powerpc64: + + These drivers are for a BMC inside PowerPC servers. The BMC runs on + ARM hardware, so only propose the drivers on this architecture, unless + build-testing. + +... but we now have a powerpc64 BMC (still for a powerpc64 host), so +drop the `depends on` that excludes building for this platform. + +Signed-off-by: Jeremy Kerr +Acked-by: Joel Stanley +Link: https://lore.kernel.org/r/20221024081527.3842565-1-jk@codeconstruct.com.au +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/occ/Kconfig | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/hwmon/occ/Kconfig b/drivers/hwmon/occ/Kconfig +index 35a7070db8277..348c21100a372 100644 +--- a/drivers/hwmon/occ/Kconfig ++++ b/drivers/hwmon/occ/Kconfig +@@ -6,7 +6,6 @@ + config SENSORS_OCC_P8_I2C + tristate "POWER8 OCC through I2C" + depends on I2C +- depends on ARM || ARM64 || COMPILE_TEST + select SENSORS_OCC + help + This option enables support for monitoring sensors provided by the +@@ -21,7 +20,6 @@ config SENSORS_OCC_P8_I2C + config SENSORS_OCC_P9_SBE + tristate "POWER9 OCC through SBE" + depends on FSI_OCC +- depends on ARM || ARM64 || COMPILE_TEST + select SENSORS_OCC + help + This option enables support for monitoring sensors provided by the +-- +cgit + + +From 662d20b3a5afee888e805c5326ccdb7ebbd23012 Mon Sep 17 00:00:00 2001 +From: Aleksa Savic +Date: Mon, 24 Oct 2022 17:10:39 +0200 +Subject: hwmon: (aquacomputer_d5next) Add support for temperature sensor + offsets + +Add support for reading and writing temperature sensor offsets +on the Aquacomputer D5 Next, Farbwerk 360, Octo and Quadro, +for which the needed offsets are known. Implemented by +Leonard Anderweit [1]. + +[1] https://github.com/aleksamagicka/aquacomputer_d5next-hwmon/pull/22 + +Originally-from: Leonard Anderweit +Signed-off-by: Aleksa Savic +Link: https://lore.kernel.org/r/20221024151039.7222-1-savicaleksa83@gmail.com +Signed-off-by: Guenter Roeck +--- + Documentation/hwmon/aquacomputer_d5next.rst | 1 + + drivers/hwmon/aquacomputer_d5next.c | 88 ++++++++++++++++++++++++----- + 2 files changed, 75 insertions(+), 14 deletions(-) + +diff --git a/Documentation/hwmon/aquacomputer_d5next.rst b/Documentation/hwmon/aquacomputer_d5next.rst +index e238533b5fe01..15226346434dd 100644 +--- a/Documentation/hwmon/aquacomputer_d5next.rst ++++ b/Documentation/hwmon/aquacomputer_d5next.rst +@@ -62,6 +62,7 @@ Sysfs entries + + ================ ============================================================== + temp[1-20]_input Physical/virtual temperature sensors (in millidegrees Celsius) ++temp[1-4]_offset Temperature sensor correction offset (in millidegrees Celsius) + fan[1-8]_input Pump/fan speed (in RPM) / Flow speed (in dL/h) + power[1-8]_input Pump/fan power (in micro Watts) + in[0-7]_input Pump/fan voltage (in milli Volts) +diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c +index c51a2678f0eb5..608f57f59cf94 100644 +--- a/drivers/hwmon/aquacomputer_d5next.c ++++ b/drivers/hwmon/aquacomputer_d5next.c +@@ -80,6 +80,7 @@ static u8 secondary_ctrl_report[] = { + #define D5NEXT_5V_VOLTAGE 0x39 + #define D5NEXT_12V_VOLTAGE 0x37 + #define D5NEXT_CTRL_REPORT_SIZE 0x329 ++#define D5NEXT_TEMP_CTRL_OFFSET 0x2D + static u8 d5next_sensor_fan_offsets[] = { D5NEXT_PUMP_OFFSET, D5NEXT_FAN_OFFSET }; + + /* Pump and fan speed registers in D5 Next control report (from 0-100%) */ +@@ -94,6 +95,8 @@ static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 }; + #define FARBWERK360_SENSOR_START 0x32 + #define FARBWERK360_NUM_VIRTUAL_SENSORS 16 + #define FARBWERK360_VIRTUAL_SENSORS_START 0x3a ++#define FARBWERK360_CTRL_REPORT_SIZE 0x682 ++#define FARBWERK360_TEMP_CTRL_OFFSET 0x8 + + /* Register offsets for the Octo fan controller */ + #define OCTO_POWER_CYCLES 0x18 +@@ -103,6 +106,7 @@ static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 }; + #define OCTO_NUM_VIRTUAL_SENSORS 16 + #define OCTO_VIRTUAL_SENSORS_START 0x45 + #define OCTO_CTRL_REPORT_SIZE 0x65F ++#define OCTO_TEMP_CTRL_OFFSET 0xA + static u8 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB, 0xD8 }; + + /* Fan speed registers in Octo control report (from 0-100%) */ +@@ -117,6 +121,7 @@ static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0 + #define QUADRO_VIRTUAL_SENSORS_START 0x3c + #define QUADRO_CTRL_REPORT_SIZE 0x3c1 + #define QUADRO_FLOW_SENSOR_OFFSET 0x6e ++#define QUADRO_TEMP_CTRL_OFFSET 0xA + static u8 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 }; + + /* Fan speed registers in Quadro control report (from 0-100%) */ +@@ -282,6 +287,7 @@ struct aqc_data { + int temp_sensor_start_offset; + int num_virtual_temp_sensors; + int virtual_temp_sensor_start_offset; ++ u16 temp_ctrl_offset; + u16 power_cycle_count_offset; + u8 flow_sensor_offset; + +@@ -365,8 +371,8 @@ static int aqc_send_ctrl_data(struct aqc_data *priv) + return ret; + } + +-/* Refreshes the control buffer and returns value at offset */ +-static int aqc_get_ctrl_val(struct aqc_data *priv, int offset) ++/* Refreshes the control buffer and stores value at offset in val */ ++static int aqc_get_ctrl_val(struct aqc_data *priv, int offset, long *val) + { + int ret; + +@@ -376,7 +382,7 @@ static int aqc_get_ctrl_val(struct aqc_data *priv, int offset) + if (ret < 0) + goto unlock_and_return; + +- ret = get_unaligned_be16(priv->buffer + offset); ++ *val = (s16)get_unaligned_be16(priv->buffer + offset); + + unlock_and_return: + mutex_unlock(&priv->mutex); +@@ -393,7 +399,7 @@ static int aqc_set_ctrl_val(struct aqc_data *priv, int offset, long val) + if (ret < 0) + goto unlock_and_return; + +- put_unaligned_be16((u16)val, priv->buffer + offset); ++ put_unaligned_be16((s16)val, priv->buffer + offset); + + ret = aqc_send_ctrl_data(priv); + +@@ -408,8 +414,28 @@ static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u3 + + switch (type) { + case hwmon_temp: ++ if (channel < priv->num_temp_sensors) { ++ switch (attr) { ++ case hwmon_temp_label: ++ case hwmon_temp_input: ++ return 0444; ++ case hwmon_temp_offset: ++ if (priv->temp_ctrl_offset != 0) ++ return 0644; ++ break; ++ default: ++ break; ++ } ++ } ++ + if (channel < priv->num_temp_sensors + priv->num_virtual_temp_sensors) +- return 0444; ++ switch (attr) { ++ case hwmon_temp_label: ++ case hwmon_temp_input: ++ return 0444; ++ default: ++ break; ++ } + break; + case hwmon_pwm: + if (priv->fan_ctrl_offsets && channel < priv->num_fans) { +@@ -492,10 +518,25 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, + + switch (type) { + case hwmon_temp: +- if (priv->temp_input[channel] == -ENODATA) +- return -ENODATA; ++ switch (attr) { ++ case hwmon_temp_input: ++ if (priv->temp_input[channel] == -ENODATA) ++ return -ENODATA; ++ ++ *val = priv->temp_input[channel]; ++ break; ++ case hwmon_temp_offset: ++ ret = ++ aqc_get_ctrl_val(priv, priv->temp_ctrl_offset + ++ channel * AQC_TEMP_SENSOR_SIZE, val); ++ if (ret < 0) ++ return ret; + +- *val = priv->temp_input[channel]; ++ *val *= 10; ++ break; ++ default: ++ break; ++ } + break; + case hwmon_fan: + *val = priv->speed_input[channel]; +@@ -505,7 +546,7 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, + break; + case hwmon_pwm: + if (priv->fan_ctrl_offsets) { +- ret = aqc_get_ctrl_val(priv, priv->fan_ctrl_offsets[channel]); ++ ret = aqc_get_ctrl_val(priv, priv->fan_ctrl_offsets[channel], val); + if (ret < 0) + return ret; + +@@ -563,6 +604,21 @@ static int aqc_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, + struct aqc_data *priv = dev_get_drvdata(dev); + + switch (type) { ++ case hwmon_temp: ++ switch (attr) { ++ case hwmon_temp_offset: ++ /* Limit temp offset to +/- 15K as in the official software */ ++ val = clamp_val(val, -15000, 15000) / 10; ++ ret = ++ aqc_set_ctrl_val(priv, priv->temp_ctrl_offset + ++ channel * AQC_TEMP_SENSOR_SIZE, val); ++ if (ret < 0) ++ return ret; ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ break; + case hwmon_pwm: + switch (attr) { + case hwmon_pwm_input: +@@ -597,10 +653,10 @@ static const struct hwmon_ops aqc_hwmon_ops = { + + static const struct hwmon_channel_info *aqc_info[] = { + HWMON_CHANNEL_INFO(temp, +- HWMON_T_INPUT | HWMON_T_LABEL, +- HWMON_T_INPUT | HWMON_T_LABEL, +- HWMON_T_INPUT | HWMON_T_LABEL, +- HWMON_T_INPUT | HWMON_T_LABEL, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET, ++ HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET, + HWMON_T_INPUT | HWMON_T_LABEL, + HWMON_T_INPUT | HWMON_T_LABEL, + HWMON_T_INPUT | HWMON_T_LABEL, +@@ -853,6 +909,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) + priv->virtual_temp_sensor_start_offset = D5NEXT_VIRTUAL_SENSORS_START; + priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES; + priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE; ++ priv->temp_ctrl_offset = D5NEXT_TEMP_CTRL_OFFSET; + + priv->temp_label = label_d5next_temp; + priv->virtual_temp_label = label_virtual_temp_sensors; +@@ -877,7 +934,8 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) + priv->temp_sensor_start_offset = FARBWERK360_SENSOR_START; + priv->num_virtual_temp_sensors = FARBWERK360_NUM_VIRTUAL_SENSORS; + priv->virtual_temp_sensor_start_offset = FARBWERK360_VIRTUAL_SENSORS_START; +- ++ priv->buffer_size = FARBWERK360_CTRL_REPORT_SIZE; ++ priv->temp_ctrl_offset = FARBWERK360_TEMP_CTRL_OFFSET; + priv->temp_label = label_temp_sensors; + priv->virtual_temp_label = label_virtual_temp_sensors; + break; +@@ -893,6 +951,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) + priv->virtual_temp_sensor_start_offset = OCTO_VIRTUAL_SENSORS_START; + priv->power_cycle_count_offset = OCTO_POWER_CYCLES; + priv->buffer_size = OCTO_CTRL_REPORT_SIZE; ++ priv->temp_ctrl_offset = OCTO_TEMP_CTRL_OFFSET; + + priv->temp_label = label_temp_sensors; + priv->virtual_temp_label = label_virtual_temp_sensors; +@@ -914,6 +973,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) + priv->power_cycle_count_offset = QUADRO_POWER_CYCLES; + priv->buffer_size = QUADRO_CTRL_REPORT_SIZE; + priv->flow_sensor_offset = QUADRO_FLOW_SENSOR_OFFSET; ++ priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET; + + priv->temp_label = label_temp_sensors; + priv->virtual_temp_label = label_virtual_temp_sensors; +-- +cgit + + +From 8f2fa4726faf01094d7a5be7bd0c120c565f54d9 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sun, 23 Oct 2022 23:31:56 +0200 +Subject: hwmon: (jc42) Convert register access and caching to regmap/regcache + +Switch the jc42 driver to use an I2C regmap to access the registers. +Also move over to regmap's built-in caching instead of adding a +custom caching implementation. This works for JC42_REG_TEMP_UPPER, +JC42_REG_TEMP_LOWER and JC42_REG_TEMP_CRITICAL as these values never +change except when explicitly written. The cache For JC42_REG_TEMP is +dropped (regmap can't cache it because it's volatile, meaning it can +change at any time) as well for simplicity and consistency with other +drivers. + +Signed-off-by: Martin Blumenstingl +Link: https://lore.kernel.org/r/20221023213157.11078-2-martin.blumenstingl@googlemail.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/Kconfig | 1 + + drivers/hwmon/jc42.c | 233 ++++++++++++++++++++++++++++---------------------- + 2 files changed, 132 insertions(+), 102 deletions(-) + +diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +index e7ec6af309c79..a5253abb7ea72 100644 +--- a/drivers/hwmon/Kconfig ++++ b/drivers/hwmon/Kconfig +@@ -807,6 +807,7 @@ config SENSORS_IT87 + config SENSORS_JC42 + tristate "JEDEC JC42.4 compliant memory module temperature sensors" + depends on I2C ++ select REGMAP_I2C + help + If you say yes here, you get support for JEDEC JC42.4 compliant + temperature sensors, which are used on many DDR3 memory modules for +diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c +index 30888feaf589b..355639d208d04 100644 +--- a/drivers/hwmon/jc42.c ++++ b/drivers/hwmon/jc42.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + /* Addresses to scan */ + static const unsigned short normal_i2c[] = { +@@ -199,31 +200,14 @@ static struct jc42_chips jc42_chips[] = { + { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK }, + }; + +-enum temp_index { +- t_input = 0, +- t_crit, +- t_min, +- t_max, +- t_num_temp +-}; +- +-static const u8 temp_regs[t_num_temp] = { +- [t_input] = JC42_REG_TEMP, +- [t_crit] = JC42_REG_TEMP_CRITICAL, +- [t_min] = JC42_REG_TEMP_LOWER, +- [t_max] = JC42_REG_TEMP_UPPER, +-}; +- + /* Each client has this additional data */ + struct jc42_data { +- struct i2c_client *client; + struct mutex update_lock; /* protect register access */ ++ struct regmap *regmap; + bool extended; /* true if extended range supported */ + bool valid; +- unsigned long last_updated; /* In jiffies */ + u16 orig_config; /* original configuration */ + u16 config; /* current configuration */ +- u16 temp[t_num_temp];/* Temperatures */ + }; + + #define JC42_TEMP_MIN_EXTENDED (-40000) +@@ -248,85 +232,102 @@ static int jc42_temp_from_reg(s16 reg) + return reg * 125 / 2; + } + +-static struct jc42_data *jc42_update_device(struct device *dev) +-{ +- struct jc42_data *data = dev_get_drvdata(dev); +- struct i2c_client *client = data->client; +- struct jc42_data *ret = data; +- int i, val; +- +- mutex_lock(&data->update_lock); +- +- if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { +- for (i = 0; i < t_num_temp; i++) { +- val = i2c_smbus_read_word_swapped(client, temp_regs[i]); +- if (val < 0) { +- ret = ERR_PTR(val); +- goto abort; +- } +- data->temp[i] = val; +- } +- data->last_updated = jiffies; +- data->valid = true; +- } +-abort: +- mutex_unlock(&data->update_lock); +- return ret; +-} +- + static int jc42_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) + { +- struct jc42_data *data = jc42_update_device(dev); +- int temp, hyst; ++ struct jc42_data *data = dev_get_drvdata(dev); ++ unsigned int regval; ++ int ret, temp, hyst; + +- if (IS_ERR(data)) +- return PTR_ERR(data); ++ mutex_lock(&data->update_lock); + + switch (attr) { + case hwmon_temp_input: +- *val = jc42_temp_from_reg(data->temp[t_input]); +- return 0; ++ ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); ++ if (ret) ++ break; ++ ++ *val = jc42_temp_from_reg(regval); ++ break; + case hwmon_temp_min: +- *val = jc42_temp_from_reg(data->temp[t_min]); +- return 0; ++ ret = regmap_read(data->regmap, JC42_REG_TEMP_LOWER, ®val); ++ if (ret) ++ break; ++ ++ *val = jc42_temp_from_reg(regval); ++ break; + case hwmon_temp_max: +- *val = jc42_temp_from_reg(data->temp[t_max]); +- return 0; ++ ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val); ++ if (ret) ++ break; ++ ++ *val = jc42_temp_from_reg(regval); ++ break; + case hwmon_temp_crit: +- *val = jc42_temp_from_reg(data->temp[t_crit]); +- return 0; ++ ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, ++ ®val); ++ if (ret) ++ break; ++ ++ *val = jc42_temp_from_reg(regval); ++ break; + case hwmon_temp_max_hyst: +- temp = jc42_temp_from_reg(data->temp[t_max]); ++ ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, ®val); ++ if (ret) ++ break; ++ ++ temp = jc42_temp_from_reg(regval); + hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) + >> JC42_CFG_HYST_SHIFT]; + *val = temp - hyst; +- return 0; ++ break; + case hwmon_temp_crit_hyst: +- temp = jc42_temp_from_reg(data->temp[t_crit]); ++ ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, ++ ®val); ++ if (ret) ++ break; ++ ++ temp = jc42_temp_from_reg(regval); + hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) + >> JC42_CFG_HYST_SHIFT]; + *val = temp - hyst; +- return 0; ++ break; + case hwmon_temp_min_alarm: +- *val = (data->temp[t_input] >> JC42_ALARM_MIN_BIT) & 1; +- return 0; ++ ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); ++ if (ret) ++ break; ++ ++ *val = (regval >> JC42_ALARM_MIN_BIT) & 1; ++ break; + case hwmon_temp_max_alarm: +- *val = (data->temp[t_input] >> JC42_ALARM_MAX_BIT) & 1; +- return 0; ++ ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); ++ if (ret) ++ break; ++ ++ *val = (regval >> JC42_ALARM_MAX_BIT) & 1; ++ break; + case hwmon_temp_crit_alarm: +- *val = (data->temp[t_input] >> JC42_ALARM_CRIT_BIT) & 1; +- return 0; ++ ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); ++ if (ret) ++ break; ++ ++ *val = (regval >> JC42_ALARM_CRIT_BIT) & 1; ++ break; + default: +- return -EOPNOTSUPP; ++ ret = -EOPNOTSUPP; ++ break; + } ++ ++ mutex_unlock(&data->update_lock); ++ ++ return ret; + } + + static int jc42_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) + { + struct jc42_data *data = dev_get_drvdata(dev); +- struct i2c_client *client = data->client; ++ unsigned int regval; + int diff, hyst; + int ret; + +@@ -334,21 +335,23 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, + + switch (attr) { + case hwmon_temp_min: +- data->temp[t_min] = jc42_temp_to_reg(val, data->extended); +- ret = i2c_smbus_write_word_swapped(client, temp_regs[t_min], +- data->temp[t_min]); ++ ret = regmap_write(data->regmap, JC42_REG_TEMP_LOWER, ++ jc42_temp_to_reg(val, data->extended)); + break; + case hwmon_temp_max: +- data->temp[t_max] = jc42_temp_to_reg(val, data->extended); +- ret = i2c_smbus_write_word_swapped(client, temp_regs[t_max], +- data->temp[t_max]); ++ ret = regmap_write(data->regmap, JC42_REG_TEMP_UPPER, ++ jc42_temp_to_reg(val, data->extended)); + break; + case hwmon_temp_crit: +- data->temp[t_crit] = jc42_temp_to_reg(val, data->extended); +- ret = i2c_smbus_write_word_swapped(client, temp_regs[t_crit], +- data->temp[t_crit]); ++ ret = regmap_write(data->regmap, JC42_REG_TEMP_CRITICAL, ++ jc42_temp_to_reg(val, data->extended)); + break; + case hwmon_temp_crit_hyst: ++ ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, ++ ®val); ++ if (ret) ++ return ret; ++ + /* + * JC42.4 compliant chips only support four hysteresis values. + * Pick best choice and go from there. +@@ -356,7 +359,7 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, + val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED + : JC42_TEMP_MIN) - 6000, + JC42_TEMP_MAX); +- diff = jc42_temp_from_reg(data->temp[t_crit]) - val; ++ diff = jc42_temp_from_reg(regval) - val; + hyst = 0; + if (diff > 0) { + if (diff < 2250) +@@ -368,9 +371,8 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, + } + data->config = (data->config & ~JC42_CFG_HYST_MASK) | + (hyst << JC42_CFG_HYST_SHIFT); +- ret = i2c_smbus_write_word_swapped(data->client, +- JC42_REG_CONFIG, +- data->config); ++ ret = regmap_write(data->regmap, JC42_REG_CONFIG, ++ data->config); + break; + default: + ret = -EOPNOTSUPP; +@@ -470,51 +472,80 @@ static const struct hwmon_chip_info jc42_chip_info = { + .info = jc42_info, + }; + ++static bool jc42_readable_reg(struct device *dev, unsigned int reg) ++{ ++ return (reg >= JC42_REG_CAP && reg <= JC42_REG_DEVICEID) || ++ reg == JC42_REG_SMBUS; ++} ++ ++static bool jc42_writable_reg(struct device *dev, unsigned int reg) ++{ ++ return (reg >= JC42_REG_CONFIG && reg <= JC42_REG_TEMP_CRITICAL) || ++ reg == JC42_REG_SMBUS; ++} ++ ++static bool jc42_volatile_reg(struct device *dev, unsigned int reg) ++{ ++ return reg == JC42_REG_CONFIG || reg == JC42_REG_TEMP; ++} ++ ++static const struct regmap_config jc42_regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 16, ++ .val_format_endian = REGMAP_ENDIAN_BIG, ++ .max_register = JC42_REG_SMBUS, ++ .writeable_reg = jc42_writable_reg, ++ .readable_reg = jc42_readable_reg, ++ .volatile_reg = jc42_volatile_reg, ++ .cache_type = REGCACHE_RBTREE, ++}; ++ + static int jc42_probe(struct i2c_client *client) + { + struct device *dev = &client->dev; + struct device *hwmon_dev; ++ unsigned int config, cap; + struct jc42_data *data; +- int config, cap; ++ int ret; + + data = devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + +- data->client = client; ++ data->regmap = devm_regmap_init_i2c(client, &jc42_regmap_config); ++ if (IS_ERR(data->regmap)) ++ return PTR_ERR(data->regmap); ++ + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + +- cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP); +- if (cap < 0) +- return cap; ++ ret = regmap_read(data->regmap, JC42_REG_CAP, &cap); ++ if (ret) ++ return ret; + + data->extended = !!(cap & JC42_CAP_RANGE); + + if (device_property_read_bool(dev, "smbus-timeout-disable")) { +- int smbus; +- + /* + * Not all chips support this register, but from a + * quick read of various datasheets no chip appears + * incompatible with the below attempt to disable + * the timeout. And the whole thing is opt-in... + */ +- smbus = i2c_smbus_read_word_swapped(client, JC42_REG_SMBUS); +- if (smbus < 0) +- return smbus; +- i2c_smbus_write_word_swapped(client, JC42_REG_SMBUS, +- smbus | SMBUS_STMOUT); ++ ret = regmap_set_bits(data->regmap, JC42_REG_SMBUS, ++ SMBUS_STMOUT); ++ if (ret) ++ return ret; + } + +- config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG); +- if (config < 0) +- return config; ++ ret = regmap_read(data->regmap, JC42_REG_CONFIG, &config); ++ if (ret) ++ return ret; + + data->orig_config = config; + if (config & JC42_CFG_SHUTDOWN) { + config &= ~JC42_CFG_SHUTDOWN; +- i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config); ++ regmap_write(data->regmap, JC42_REG_CONFIG, config); + } + data->config = config; + +@@ -535,7 +566,7 @@ static void jc42_remove(struct i2c_client *client) + + config = (data->orig_config & ~JC42_CFG_HYST_MASK) + | (data->config & JC42_CFG_HYST_MASK); +- i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config); ++ regmap_write(data->regmap, JC42_REG_CONFIG, config); + } + } + +@@ -546,8 +577,7 @@ static int jc42_suspend(struct device *dev) + struct jc42_data *data = dev_get_drvdata(dev); + + data->config |= JC42_CFG_SHUTDOWN; +- i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, +- data->config); ++ regmap_write(data->regmap, JC42_REG_CONFIG, data->config); + return 0; + } + +@@ -556,8 +586,7 @@ static int jc42_resume(struct device *dev) + struct jc42_data *data = dev_get_drvdata(dev); + + data->config &= ~JC42_CFG_SHUTDOWN; +- i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG, +- data->config); ++ regmap_write(data->regmap, JC42_REG_CONFIG, data->config); + return 0; + } + +-- +cgit + + +From 084ed144c448fd5bc8ed5a58247153fbbfd115c3 Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Sun, 23 Oct 2022 23:31:57 +0200 +Subject: hwmon: (jc42) Restore the min/max/critical temperatures on resume +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The JC42 compatible thermal sensor on Kingston KSM32ES8/16ME DIMMs +(using Micron E-Die) is an ST Microelectronics STTS2004 (manufacturer +0x104a, device 0x2201). It does not keep the previously programmed +minimum, maximum and critical temperatures after system suspend and +resume (which is a shutdown / startup cycle for the JC42 temperature +sensor). This results in an alarm on system resume because the hardware +default for these values is 0°C (so any environment temperature greater +than 0°C will trigger the alarm). + +Example before system suspend: + jc42-i2c-0-1a + Adapter: SMBus PIIX4 adapter port 0 at 0b00 + temp1: +34.8°C (low = +0.0°C) + (high = +85.0°C, hyst = +85.0°C) + (crit = +95.0°C, hyst = +95.0°C) + +Example after system resume (without this change): + jc42-i2c-0-1a + Adapter: SMBus PIIX4 adapter port 0 at 0b00 + temp1: +34.8°C (low = +0.0°C) ALARM (HIGH, CRIT) + (high = +0.0°C, hyst = +0.0°C) + (crit = +0.0°C, hyst = +0.0°C) + +Apply the cached values from the JC42_REG_TEMP_UPPER, +JC42_REG_TEMP_LOWER, JC42_REG_TEMP_CRITICAL and JC42_REG_SMBUS (where +the SMBUS register is not related to this issue but a side-effect of +using regcache_sync() during system resume with the previously +cached/programmed values. This fixes the alarm due to the hardware +defaults of 0°C because the previously applied limits (set by userspace) +are re-applied on system resume. + +Fixes: 175c490c9e7f ("hwmon: (jc42) Add support for STTS2004 and AT30TSE004") +Reviewed-by: Guenter Roeck +Signed-off-by: Martin Blumenstingl +Link: https://lore.kernel.org/r/20221023213157.11078-3-martin.blumenstingl@googlemail.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/jc42.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c +index 355639d208d04..0554b41c32bc7 100644 +--- a/drivers/hwmon/jc42.c ++++ b/drivers/hwmon/jc42.c +@@ -578,6 +578,10 @@ static int jc42_suspend(struct device *dev) + + data->config |= JC42_CFG_SHUTDOWN; + regmap_write(data->regmap, JC42_REG_CONFIG, data->config); ++ ++ regcache_cache_only(data->regmap, true); ++ regcache_mark_dirty(data->regmap); ++ + return 0; + } + +@@ -585,9 +589,13 @@ static int jc42_resume(struct device *dev) + { + struct jc42_data *data = dev_get_drvdata(dev); + ++ regcache_cache_only(data->regmap, false); ++ + data->config &= ~JC42_CFG_SHUTDOWN; + regmap_write(data->regmap, JC42_REG_CONFIG, data->config); +- return 0; ++ ++ /* Restore cached register values to hardware */ ++ return regcache_sync(data->regmap); + } + + static const struct dev_pm_ops jc42_dev_pm_ops = { +-- +cgit + + +From b744db17abf6a2efc2bfa80870cc88e9799a8ccc Mon Sep 17 00:00:00 2001 +From: Yang Yingliang +Date: Thu, 27 Oct 2022 14:29:31 +0800 +Subject: hwmon: (jc42) Fix missing unlock on error in jc42_write() + +Add the missing unlock before return from function jc42_write() +in the error handling case. + +Fixes: 37dedaee8bc6 ("hwmon: (jc42) Convert register access and caching to regmap/regcache") +Signed-off-by: Yang Yingliang +Reviewed-by: Martin Blumenstingl +Link: https://lore.kernel.org/r/20221027062931.598247-1-yangyingliang@huawei.com +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/jc42.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c +index 0554b41c32bc7..6593d81cb901b 100644 +--- a/drivers/hwmon/jc42.c ++++ b/drivers/hwmon/jc42.c +@@ -350,7 +350,7 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, + ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL, + ®val); + if (ret) +- return ret; ++ break; + + /* + * JC42.4 compliant chips only support four hysteresis values. +-- +cgit + + +From 9e913888647be447c3d114042428f02d24676390 Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Thu, 27 Oct 2022 16:16:12 -0700 +Subject: hwmon: (smpro-hwmon) Improve switch statments in smpro_is_visible() + +Clang warns: + + drivers/hwmon/smpro-hwmon.c:378:2: error: unannotated fall-through between switch labels [-Werror,-Wimplicit-fallthrough] + default: + ^ + drivers/hwmon/smpro-hwmon.c:378:2: note: insert 'break;' to avoid fall-through + default: + ^ + break; + 1 error generated. + +Clang is a little more pedantic than GCC, which does not warn when +falling through to a case that is just break or return. Clang's version +is more in line with the kernel's own stance in deprecated.rst, which +states that all switch/case blocks must end in either break, +fallthrough, continue, goto, or return. + +Add the missing break to silence the warning. Additionally, adjust the +indentation of a break and add a default case to the inner switch +statement. + +Fixes: a87456864cbb ("hwmon: Add Ampere's Altra smpro-hwmon driver") +Link: https://github.com/ClangBuiltLinux/linux/issues/1751 +Signed-off-by: Nathan Chancellor +Link: https://lore.kernel.org/r/20221027231611.3824800-1-nathan@kernel.org +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/smpro-hwmon.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/hwmon/smpro-hwmon.c b/drivers/hwmon/smpro-hwmon.c +index ee54e21c2c123..a76c49dd8438d 100644 +--- a/drivers/hwmon/smpro-hwmon.c ++++ b/drivers/hwmon/smpro-hwmon.c +@@ -373,8 +373,11 @@ static umode_t smpro_is_visible(const void *data, enum hwmon_sensor_types type, + ret = regmap_read(hwmon->regmap, temperature[channel].reg, &value); + if (ret || value == 0xFFFF) + return 0; +- break; ++ break; ++ default: ++ break; + } ++ break; + default: + break; + } +-- +cgit + + +From daec55ce62ad0bb6948c8edf84e7ec3b95720177 Mon Sep 17 00:00:00 2001 +From: Felix Nieuwenhuizen +Date: Thu, 27 Oct 2022 16:51:35 +0200 +Subject: hwmon: (pmbus/ltc2978) add support for LTC7132 + +Add support for LTC7132. +The relevant registers in the LTC7132 are identical to the LTC7880. +So it's just a matter of adding the chip id. + +Signed-off-by: Felix Nieuwenhuizen +Link: https://lore.kernel.org/r/20221027145135.31802-1-Felix.Nieuwenhuizen@etas.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/pmbus/ltc2978.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c +index 6d2592731ba3d..79f480b4425d2 100644 +--- a/drivers/hwmon/pmbus/ltc2978.c ++++ b/drivers/hwmon/pmbus/ltc2978.c +@@ -23,7 +23,7 @@ enum chips { + /* Managers */ + ltc2972, ltc2974, ltc2975, ltc2977, ltc2978, ltc2979, ltc2980, + /* Controllers */ +- ltc3880, ltc3882, ltc3883, ltc3884, ltc3886, ltc3887, ltc3889, ltc7880, ++ ltc3880, ltc3882, ltc3883, ltc3884, ltc3886, ltc3887, ltc3889, ltc7132, ltc7880, + /* Modules */ + ltm2987, ltm4664, ltm4675, ltm4676, ltm4677, ltm4678, ltm4680, ltm4686, + ltm4700, +@@ -45,15 +45,14 @@ enum chips { + #define LTC2974_MFR_IOUT_PEAK 0xd7 + #define LTC2974_MFR_IOUT_MIN 0xd8 + +-/* LTC3880, LTC3882, LTC3883, LTC3887, LTM4675, and LTM4676 */ ++/* LTC3880, LTC3882, LTC3883, LTC3887, LTM4675, LTM4676, LTC7132 */ + #define LTC3880_MFR_IOUT_PEAK 0xd7 + #define LTC3880_MFR_CLEAR_PEAKS 0xe3 + #define LTC3880_MFR_TEMPERATURE2_PEAK 0xf4 + +-/* LTC3883, LTC3884, LTC3886, LTC3889 and LTC7880 only */ ++/* LTC3883, LTC3884, LTC3886, LTC3889, LTC7132, LTC7880 */ + #define LTC3883_MFR_IIN_PEAK 0xe1 + +- + /* LTC2975 only */ + #define LTC2975_MFR_IIN_PEAK 0xc4 + #define LTC2975_MFR_IIN_MIN 0xc5 +@@ -79,10 +78,11 @@ enum chips { + #define LTC3884_ID 0x4C00 + #define LTC3886_ID 0x4600 + #define LTC3887_ID 0x4700 +-#define LTM2987_ID_A 0x8010 /* A/B for two die IDs */ +-#define LTM2987_ID_B 0x8020 + #define LTC3889_ID 0x4900 ++#define LTC7132_ID 0x4CE0 + #define LTC7880_ID 0x49E0 ++#define LTM2987_ID_A 0x8010 /* A/B for two die IDs */ ++#define LTM2987_ID_B 0x8020 + #define LTM4664_ID 0x4120 + #define LTM4675_ID 0x47a0 + #define LTM4676_ID_REV1 0x4400 +@@ -547,6 +547,7 @@ static const struct i2c_device_id ltc2978_id[] = { + {"ltc3886", ltc3886}, + {"ltc3887", ltc3887}, + {"ltc3889", ltc3889}, ++ {"ltc7132", ltc7132}, + {"ltc7880", ltc7880}, + {"ltm2987", ltm2987}, + {"ltm4664", ltm4664}, +@@ -651,6 +652,8 @@ static int ltc2978_get_id(struct i2c_client *client) + return ltc3887; + else if (chip_id == LTC3889_ID) + return ltc3889; ++ else if (chip_id == LTC7132_ID) ++ return ltc7132; + else if (chip_id == LTC7880_ID) + return ltc7880; + else if (chip_id == LTM2987_ID_A || chip_id == LTM2987_ID_B) +@@ -831,6 +834,7 @@ static int ltc2978_probe(struct i2c_client *client) + case ltc3884: + case ltc3886: + case ltc3889: ++ case ltc7132: + case ltc7880: + case ltm4664: + case ltm4678: +@@ -902,6 +906,7 @@ static const struct of_device_id ltc2978_of_match[] = { + { .compatible = "lltc,ltc3886" }, + { .compatible = "lltc,ltc3887" }, + { .compatible = "lltc,ltc3889" }, ++ { .compatible = "lltc,ltc7132" }, + { .compatible = "lltc,ltc7880" }, + { .compatible = "lltc,ltm2987" }, + { .compatible = "lltc,ltm4664" }, +-- +cgit + + +From 78d448a3725584b7c46d3d881035943f759135fd Mon Sep 17 00:00:00 2001 +From: Martin Blumenstingl +Date: Mon, 31 Oct 2022 22:51:40 +0100 +Subject: hwmon: (jc42) Consistently use bit and bitfield macros in the driver + +Use BIT() and GENMASK() macros for defining the bitfields inside the +registers. Also use FIELD_GET() and FIELD_PREP() where appropriate. This +makes the coding style within the driver consistent. No functional +changes intended. + +Signed-off-by: Martin Blumenstingl +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/jc42.c | 36 ++++++++++++++++++------------------ + 1 file changed, 18 insertions(+), 18 deletions(-) + +diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c +index 6593d81cb901b..8523bf974310b 100644 +--- a/drivers/hwmon/jc42.c ++++ b/drivers/hwmon/jc42.c +@@ -10,6 +10,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -37,20 +38,19 @@ static const unsigned short normal_i2c[] = { + #define JC42_REG_SMBUS 0x22 /* NXP and Atmel, possibly others? */ + + /* Status bits in temperature register */ +-#define JC42_ALARM_CRIT_BIT 15 +-#define JC42_ALARM_MAX_BIT 14 +-#define JC42_ALARM_MIN_BIT 13 ++#define JC42_ALARM_CRIT BIT(15) ++#define JC42_ALARM_MAX BIT(14) ++#define JC42_ALARM_MIN BIT(13) + + /* Configuration register defines */ +-#define JC42_CFG_CRIT_ONLY (1 << 2) +-#define JC42_CFG_TCRIT_LOCK (1 << 6) +-#define JC42_CFG_EVENT_LOCK (1 << 7) +-#define JC42_CFG_SHUTDOWN (1 << 8) +-#define JC42_CFG_HYST_SHIFT 9 +-#define JC42_CFG_HYST_MASK (0x03 << 9) ++#define JC42_CFG_CRIT_ONLY BIT(2) ++#define JC42_CFG_TCRIT_LOCK BIT(6) ++#define JC42_CFG_EVENT_LOCK BIT(7) ++#define JC42_CFG_SHUTDOWN BIT(8) ++#define JC42_CFG_HYST_MASK GENMASK(10, 9) + + /* Capabilities */ +-#define JC42_CAP_RANGE (1 << 2) ++#define JC42_CAP_RANGE BIT(2) + + /* Manufacturer IDs */ + #define ADT_MANID 0x11d4 /* Analog Devices */ +@@ -277,8 +277,8 @@ static int jc42_read(struct device *dev, enum hwmon_sensor_types type, + break; + + temp = jc42_temp_from_reg(regval); +- hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) +- >> JC42_CFG_HYST_SHIFT]; ++ hyst = jc42_hysteresis[FIELD_GET(JC42_CFG_HYST_MASK, ++ data->config)]; + *val = temp - hyst; + break; + case hwmon_temp_crit_hyst: +@@ -288,8 +288,8 @@ static int jc42_read(struct device *dev, enum hwmon_sensor_types type, + break; + + temp = jc42_temp_from_reg(regval); +- hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) +- >> JC42_CFG_HYST_SHIFT]; ++ hyst = jc42_hysteresis[FIELD_GET(JC42_CFG_HYST_MASK, ++ data->config)]; + *val = temp - hyst; + break; + case hwmon_temp_min_alarm: +@@ -297,21 +297,21 @@ static int jc42_read(struct device *dev, enum hwmon_sensor_types type, + if (ret) + break; + +- *val = (regval >> JC42_ALARM_MIN_BIT) & 1; ++ *val = FIELD_GET(JC42_ALARM_MIN, regval); + break; + case hwmon_temp_max_alarm: + ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); + if (ret) + break; + +- *val = (regval >> JC42_ALARM_MAX_BIT) & 1; ++ *val = FIELD_GET(JC42_ALARM_MAX, regval); + break; + case hwmon_temp_crit_alarm: + ret = regmap_read(data->regmap, JC42_REG_TEMP, ®val); + if (ret) + break; + +- *val = (regval >> JC42_ALARM_CRIT_BIT) & 1; ++ *val = FIELD_GET(JC42_ALARM_CRIT, regval); + break; + default: + ret = -EOPNOTSUPP; +@@ -370,7 +370,7 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type, + hyst = 3; /* 6.0 degrees C */ + } + data->config = (data->config & ~JC42_CFG_HYST_MASK) | +- (hyst << JC42_CFG_HYST_SHIFT); ++ FIELD_PREP(JC42_CFG_HYST_MASK, hyst); + ret = regmap_write(data->regmap, JC42_REG_CONFIG, + data->config); + break; +-- +cgit + + +From c1cb98c55f470447479298aaec7f92219562613e Mon Sep 17 00:00:00 2001 +From: Quan Nguyen +Date: Wed, 2 Nov 2022 13:21:03 +0700 +Subject: docs: hwmon: (smpro-hwmon) Improve grammar and formatting + +Improve documentation grammar and formatting for the +Ampere(R)'s Altra(R) SMpro hwmon driver. + +Thanks Bagas for the changes in the link below. + +Link: https://lore.kernel.org/lkml/Y1aHiaZ1OpHZIzS9@google.com/T/#mfea2167b99384486a1b75d9304536015116c1821 +Signed-off-by: Quan Nguyen +Reviewed-by: Bagas Sanjaya +Link: https://lore.kernel.org/r/20221102062103.3135417-1-quan@os.amperecomputing.com +Signed-off-by: Guenter Roeck +--- + Documentation/hwmon/smpro-hwmon.rst | 111 ++++++++++++++++++------------------ + 1 file changed, 56 insertions(+), 55 deletions(-) + +diff --git a/Documentation/hwmon/smpro-hwmon.rst b/Documentation/hwmon/smpro-hwmon.rst +index 3a9b14dacf897..fb7b3665735bb 100644 +--- a/Documentation/hwmon/smpro-hwmon.rst ++++ b/Documentation/hwmon/smpro-hwmon.rst +@@ -7,39 +7,39 @@ Supported chips: + + * Ampere(R) Altra(R) + +- Prefix: 'smpro' ++ Prefix: ``smpro`` + +- Reference: Altra SoC BMC Interface Specification ++ Reference: `Altra SoC BMC Interface Specification` + + Author: Thu Nguyen + + Description + ----------- +-This driver supports hardware monitoring for Ampere(R) Altra(R) SoC's based on the +-SMpro co-processor (SMpro). +-The following sensor types are supported by the driver: ++The smpro-hwmon driver supports hardware monitoring for Ampere(R) Altra(R) ++SoCs based on the SMpro co-processor (SMpro). The following sensor metrics ++are supported by the driver: + + * temperature + * voltage + * current + * power + +-The SMpro interface provides the registers to query the various sensors and ++The interface provides the registers to query the various sensors and + their values which are then exported to userspace by this driver. + + Usage Notes + ----------- + +-SMpro hwmon driver creates at least two sysfs files for each sensor. ++The driver creates at least two sysfs files for each sensor. + +-* File ``_label`` reports the sensor label. +-* File ``_input`` returns the sensor value. ++* ``_label`` reports the sensor label. ++* ``_input`` returns the sensor value. + +-The sysfs files are allocated in the SMpro root fs folder. +-There is one root folder for each SMpro instance. ++The sysfs files are allocated in the SMpro rootfs folder, with one root ++directory for each instance. + +-When the SoC is turned off, the driver will fail to read registers +-and return -ENXIO. ++When the SoC is turned off, the driver will fail to read registers and ++return ``-ENXIO``. + + Sysfs entries + ------------- +@@ -48,48 +48,49 @@ The following sysfs files are supported: + + * Ampere(R) Altra(R): + +-============ ============= ====== =============================================== +-Name Unit Perm Description +-temp1_input milli Celsius RO SoC temperature +-temp2_input milli Celsius RO Max temperature reported among SoC VRDs +-temp2_crit milli Celsius RO SoC VRD HOT Threshold temperature +-temp3_input milli Celsius RO Max temperature reported among DIMM VRDs +-temp4_input milli Celsius RO Max temperature reported among Core VRDs +-temp5_input milli Celsius RO Temperature of DIMM0 on CH0 +-temp5_crit milli Celsius RO MEM HOT Threshold for all DIMMs +-temp6_input milli Celsius RO Temperature of DIMM0 on CH1 +-temp6_crit milli Celsius RO MEM HOT Threshold for all DIMMs +-temp7_input milli Celsius RO Temperature of DIMM0 on CH2 +-temp7_crit milli Celsius RO MEM HOT Threshold for all DIMMs +-temp8_input milli Celsius RO Temperature of DIMM0 on CH3 +-temp8_crit milli Celsius RO MEM HOT Threshold for all DIMMs +-temp9_input milli Celsius RO Temperature of DIMM0 on CH4 +-temp9_crit milli Celsius RO MEM HOT Threshold for all DIMMs +-temp10_input milli Celsius RO Temperature of DIMM0 on CH5 +-temp10_crit milli Celsius RO MEM HOT Threshold for all DIMMs +-temp11_input milli Celsius RO Temperature of DIMM0 on CH6 +-temp11_crit milli Celsius RO MEM HOT Threshold for all DIMMs +-temp12_input milli Celsius RO Temperature of DIMM0 on CH7 +-temp12_crit milli Celsius RO MEM HOT Threshold for all DIMMs +-temp13_input milli Celsius RO Max temperature reported among RCA VRDs +-in0_input milli Volts RO Core voltage +-in1_input milli Volts RO SoC voltage +-in2_input milli Volts RO DIMM VRD1 voltage +-in3_input milli Volts RO DIMM VRD2 voltage +-in4_input milli Volts RO RCA VRD voltage +-cur1_input milli Amperes RO Core VRD current +-cur2_input milli Amperes RO SoC VRD current +-cur3_input milli Amperes RO DIMM VRD1 current +-cur4_input milli Amperes RO DIMM VRD2 current +-cur5_input milli Amperes RO RCA VRD current +-power1_input micro Watts RO Core VRD power +-power2_input micro Watts RO SoC VRD power +-power3_input micro Watts RO DIMM VRD1 power +-power4_input micro Watts RO DIMM VRD2 power +-power5_input micro Watts RO RCA VRD power +-============ ============= ====== =============================================== +- +-Example:: ++ ============ ============= ====== =============================================== ++ Name Unit Perm Description ++ ============ ============= ====== =============================================== ++ temp1_input millicelsius RO SoC temperature ++ temp2_input millicelsius RO Max temperature reported among SoC VRDs ++ temp2_crit millicelsius RO SoC VRD HOT Threshold temperature ++ temp3_input millicelsius RO Max temperature reported among DIMM VRDs ++ temp4_input millicelsius RO Max temperature reported among Core VRDs ++ temp5_input millicelsius RO Temperature of DIMM0 on CH0 ++ temp5_crit millicelsius RO MEM HOT Threshold for all DIMMs ++ temp6_input millicelsius RO Temperature of DIMM0 on CH1 ++ temp6_crit millicelsius RO MEM HOT Threshold for all DIMMs ++ temp7_input millicelsius RO Temperature of DIMM0 on CH2 ++ temp7_crit millicelsius RO MEM HOT Threshold for all DIMMs ++ temp8_input millicelsius RO Temperature of DIMM0 on CH3 ++ temp8_crit millicelsius RO MEM HOT Threshold for all DIMMs ++ temp9_input millicelsius RO Temperature of DIMM0 on CH4 ++ temp9_crit millicelsius RO MEM HOT Threshold for all DIMMs ++ temp10_input millicelsius RO Temperature of DIMM0 on CH5 ++ temp10_crit millicelsius RO MEM HOT Threshold for all DIMMs ++ temp11_input millicelsius RO Temperature of DIMM0 on CH6 ++ temp11_crit millicelsius RO MEM HOT Threshold for all DIMMs ++ temp12_input millicelsius RO Temperature of DIMM0 on CH7 ++ temp12_crit millicelsius RO MEM HOT Threshold for all DIMMs ++ temp13_input millicelsius RO Max temperature reported among RCA VRDs ++ in0_input millivolts RO Core voltage ++ in1_input millivolts RO SoC voltage ++ in2_input millivolts RO DIMM VRD1 voltage ++ in3_input millivolts RO DIMM VRD2 voltage ++ in4_input millivolts RO RCA VRD voltage ++ cur1_input milliamperes RO Core VRD current ++ cur2_input milliamperes RO SoC VRD current ++ cur3_input milliamperes RO DIMM VRD1 current ++ cur4_input milliamperes RO DIMM VRD2 current ++ cur5_input milliamperes RO RCA VRD current ++ power1_input microwatts RO Core VRD power ++ power2_input microwatts RO SoC VRD power ++ power3_input microwatts RO DIMM VRD1 power ++ power4_input microwatts RO DIMM VRD2 power ++ power5_input microwatts RO RCA VRD power ++ ============ ============= ====== =============================================== ++ ++ Example:: + + # cat in0_input + 830 +-- +cgit + + +From 25f986887dd54a93edcc5cb499b2e42f4d9c359c Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sun, 6 Nov 2022 20:34:16 +0100 +Subject: hwmon: Include when appropriate + +The kstrto() functions have been moved from kernel.h to +kstrtox.h. + +So, include the latter directly in the appropriate files. + +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/51688cf50bda44e2731381a31287c62319388783.1667763218.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/atxp1.c | 1 + + drivers/hwmon/gpio-fan.c | 1 + + drivers/hwmon/hwmon.c | 1 + + drivers/hwmon/lm90.c | 1 + + drivers/hwmon/mr75203.c | 1 + + drivers/hwmon/pcf8591.c | 1 + + drivers/hwmon/pmbus/q54sj108a2.c | 1 + + include/linux/hwmon-sysfs.h | 1 + + 8 files changed, 8 insertions(+) + +diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c +index 4fd8de8022bc7..118297ea1dcfa 100644 +--- a/drivers/hwmon/atxp1.c ++++ b/drivers/hwmon/atxp1.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + #include +diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c +index ba408942dbe73..e75db6f64e8ce 100644 +--- a/drivers/hwmon/gpio-fan.c ++++ b/drivers/hwmon/gpio-fan.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c +index 4218750d5a66b..33edb5c02f7d7 100644 +--- a/drivers/hwmon/hwmon.c ++++ b/drivers/hwmon/hwmon.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c +index a3f95ba00dbff..6498d5acf7055 100644 +--- a/drivers/hwmon/lm90.c ++++ b/drivers/hwmon/lm90.c +@@ -103,6 +103,7 @@ + #include + #include + #include ++#include + #include + #include + #include +diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c +index 394a4c7e46abc..50a8b9c3f94d6 100644 +--- a/drivers/hwmon/mr75203.c ++++ b/drivers/hwmon/mr75203.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +diff --git a/drivers/hwmon/pcf8591.c b/drivers/hwmon/pcf8591.c +index af9614e918a45..1dbe209ae13f5 100644 +--- a/drivers/hwmon/pcf8591.c ++++ b/drivers/hwmon/pcf8591.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + /* Insmod parameters */ + +diff --git a/drivers/hwmon/pmbus/q54sj108a2.c b/drivers/hwmon/pmbus/q54sj108a2.c +index fa298b4265a1c..d3ba129513240 100644 +--- a/drivers/hwmon/pmbus/q54sj108a2.c ++++ b/drivers/hwmon/pmbus/q54sj108a2.c +@@ -8,6 +8,7 @@ + + #include + #include ++#include + #include + #include + #include "pmbus.h" +diff --git a/include/linux/hwmon-sysfs.h b/include/linux/hwmon-sysfs.h +index cb26d02f52f37..d896713359cdc 100644 +--- a/include/linux/hwmon-sysfs.h ++++ b/include/linux/hwmon-sysfs.h +@@ -8,6 +8,7 @@ + #define _LINUX_HWMON_SYSFS_H + + #include ++#include + + struct sensor_device_attribute{ + struct device_attribute dev_attr; +-- +cgit + + +From a1bedbcc1cf7c3d2b6b75156a6f90cadcb5e4809 Mon Sep 17 00:00:00 2001 +From: Frank Crawford +Date: Sun, 6 Nov 2022 10:25:32 +1100 +Subject: hwmon: (it87) Add DMI table for future extensions + +Add in DMI matching table to match various board quirks and settings. +This will be useful for future extentions, but will start with the +existing definition of the Shuttle SN68PT. + +Signed-off-by: Frank Crawford +Link: https://lore.kernel.org/r/20221105232531.1619387-1-frank@crawford.emu.id.au +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/it87.c | 72 ++++++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 53 insertions(+), 19 deletions(-) + +diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c +index 73ed21ab325ba..9997f76b1f4aa 100644 +--- a/drivers/hwmon/it87.c ++++ b/drivers/hwmon/it87.c +@@ -567,6 +567,14 @@ struct it87_data { + s8 auto_temp[NUM_AUTO_PWM][5]; /* [nr][0] is point1_temp_hyst */ + }; + ++/* Board specific settings from DMI matching */ ++struct it87_dmi_data { ++ u8 skip_pwm; /* pwm channels to skip for this board */ ++}; ++ ++/* Global for results from DMI matching, if needed */ ++static struct it87_dmi_data *dmi_data; ++ + static int adc_lsb(const struct it87_data *data, int nr) + { + int lsb; +@@ -2393,7 +2401,6 @@ static int __init it87_find(int sioaddr, unsigned short *address, + { + int err; + u16 chip_type; +- const char *board_vendor, *board_name; + const struct it87_devices *config; + + err = superio_enter(sioaddr); +@@ -2812,24 +2819,9 @@ static int __init it87_find(int sioaddr, unsigned short *address, + if (sio_data->beep_pin) + pr_info("Beeping is supported\n"); + +- /* Disable specific features based on DMI strings */ +- board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); +- board_name = dmi_get_system_info(DMI_BOARD_NAME); +- if (board_vendor && board_name) { +- if (strcmp(board_vendor, "nVIDIA") == 0 && +- strcmp(board_name, "FN68PT") == 0) { +- /* +- * On the Shuttle SN68PT, FAN_CTL2 is apparently not +- * connected to a fan, but to something else. One user +- * has reported instant system power-off when changing +- * the PWM2 duty cycle, so we disable it. +- * I use the board name string as the trigger in case +- * the same board is ever used in other systems. +- */ +- pr_info("Disabling pwm2 due to hardware constraints\n"); +- sio_data->skip_pwm = BIT(1); +- } +- } ++ /* Set values based on DMI matches */ ++ if (dmi_data) ++ sio_data->skip_pwm |= dmi_data->skip_pwm; + + exit: + superio_exit(sioaddr); +@@ -3307,6 +3299,46 @@ exit_device_put: + return err; + } + ++/* callback function for DMI */ ++static int it87_dmi_cb(const struct dmi_system_id *dmi_entry) ++{ ++ dmi_data = dmi_entry->driver_data; ++ ++ if (dmi_data && dmi_data->skip_pwm) ++ pr_info("Disabling pwm2 due to hardware constraints\n"); ++ ++ return 1; ++} ++ ++/* ++ * On the Shuttle SN68PT, FAN_CTL2 is apparently not ++ * connected to a fan, but to something else. One user ++ * has reported instant system power-off when changing ++ * the PWM2 duty cycle, so we disable it. ++ * I use the board name string as the trigger in case ++ * the same board is ever used in other systems. ++ */ ++static struct it87_dmi_data nvidia_fn68pt = { ++ .skip_pwm = BIT(1), ++}; ++ ++#define IT87_DMI_MATCH_VND(vendor, name, cb, data) \ ++ { \ ++ .callback = cb, \ ++ .matches = { \ ++ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, vendor), \ ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, name), \ ++ }, \ ++ .driver_data = data, \ ++ } ++ ++static const struct dmi_system_id it87_dmi_table[] __initconst = { ++ IT87_DMI_MATCH_VND("nVIDIA", "FN68PT", it87_dmi_cb, &nvidia_fn68pt), ++ { } ++ ++}; ++MODULE_DEVICE_TABLE(dmi, it87_dmi_table); ++ + static int __init sm_it87_init(void) + { + int sioaddr[2] = { REG_2E, REG_4E }; +@@ -3319,6 +3351,8 @@ static int __init sm_it87_init(void) + if (err) + return err; + ++ dmi_check_system(it87_dmi_table); ++ + for (i = 0; i < ARRAY_SIZE(sioaddr); i++) { + memset(&sio_data, 0, sizeof(struct it87_sio_data)); + isa_address[i] = 0; +-- +cgit + + +From d5d896b838222fcd037c91c9e0e8f6ab719db05f Mon Sep 17 00:00:00 2001 +From: Aleksa Savic +Date: Mon, 7 Nov 2022 15:24:55 +0100 +Subject: hwmon: (aquacomputer_d5next) Clear up macros and comments + +Reorganize macro definitions into sections for each supported +device, with additional comments on their purpose. This should +make it easier to follow what report each offset is coming +from. Also, reformat per-device initializations in +aqc_probe() to organize them into sections (fan info, +temp sensors, other parameters and lastly labels). + +No functional changes. + +Signed-off-by: Aleksa Savic +Link: https://lore.kernel.org/r/20221107142455.655998-1-savicaleksa83@gmail.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/aquacomputer_d5next.c | 97 ++++++++++++++++++++++++------------- + 1 file changed, 63 insertions(+), 34 deletions(-) + +diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c +index 608f57f59cf94..49d3f9876fe80 100644 +--- a/drivers/hwmon/aquacomputer_d5next.c ++++ b/drivers/hwmon/aquacomputer_d5next.c +@@ -59,7 +59,7 @@ static u8 secondary_ctrl_report[] = { + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x34, 0xC6 + }; + +-/* Register offsets for all Aquacomputer devices */ ++/* Sensor sizes and offsets for all Aquacomputer devices */ + #define AQC_TEMP_SENSOR_SIZE 0x02 + #define AQC_TEMP_SENSOR_DISCONNECTED 0x7FFF + #define AQC_FAN_PERCENT_OFFSET 0x00 +@@ -68,67 +68,80 @@ static u8 secondary_ctrl_report[] = { + #define AQC_FAN_POWER_OFFSET 0x06 + #define AQC_FAN_SPEED_OFFSET 0x08 + +-/* Register offsets for the D5 Next pump */ +-#define D5NEXT_POWER_CYCLES 0x18 +-#define D5NEXT_COOLANT_TEMP 0x57 ++/* Specs of the D5 Next pump */ + #define D5NEXT_NUM_FANS 2 + #define D5NEXT_NUM_SENSORS 1 + #define D5NEXT_NUM_VIRTUAL_SENSORS 8 +-#define D5NEXT_VIRTUAL_SENSORS_START 0x3f ++#define D5NEXT_CTRL_REPORT_SIZE 0x329 ++ ++/* Sensor report offsets for the D5 Next pump */ ++#define D5NEXT_POWER_CYCLES 0x18 ++#define D5NEXT_COOLANT_TEMP 0x57 + #define D5NEXT_PUMP_OFFSET 0x6c + #define D5NEXT_FAN_OFFSET 0x5f + #define D5NEXT_5V_VOLTAGE 0x39 + #define D5NEXT_12V_VOLTAGE 0x37 +-#define D5NEXT_CTRL_REPORT_SIZE 0x329 +-#define D5NEXT_TEMP_CTRL_OFFSET 0x2D ++#define D5NEXT_VIRTUAL_SENSORS_START 0x3f + static u8 d5next_sensor_fan_offsets[] = { D5NEXT_PUMP_OFFSET, D5NEXT_FAN_OFFSET }; + +-/* Pump and fan speed registers in D5 Next control report (from 0-100%) */ +-static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 }; ++/* Control report offsets for the D5 Next pump */ ++#define D5NEXT_TEMP_CTRL_OFFSET 0x2D /* Temperature sensor offsets location */ ++static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 }; /* Pump and fan speed (from 0-100%) */ + +-/* Register offsets for the Farbwerk RGB controller */ ++/* Spec and sensor report offset for the Farbwerk RGB controller */ + #define FARBWERK_NUM_SENSORS 4 + #define FARBWERK_SENSOR_START 0x2f + +-/* Register offsets for the Farbwerk 360 RGB controller */ ++/* Specs of the Farbwerk 360 RGB controller */ + #define FARBWERK360_NUM_SENSORS 4 +-#define FARBWERK360_SENSOR_START 0x32 + #define FARBWERK360_NUM_VIRTUAL_SENSORS 16 +-#define FARBWERK360_VIRTUAL_SENSORS_START 0x3a + #define FARBWERK360_CTRL_REPORT_SIZE 0x682 ++ ++/* Sensor report offsets for the Farbwerk 360 */ ++#define FARBWERK360_SENSOR_START 0x32 ++#define FARBWERK360_VIRTUAL_SENSORS_START 0x3a ++ ++/* Control report offsets for the Farbwerk 360 */ + #define FARBWERK360_TEMP_CTRL_OFFSET 0x8 + +-/* Register offsets for the Octo fan controller */ +-#define OCTO_POWER_CYCLES 0x18 ++/* Specs of the Octo fan controller */ + #define OCTO_NUM_FANS 8 + #define OCTO_NUM_SENSORS 4 +-#define OCTO_SENSOR_START 0x3D + #define OCTO_NUM_VIRTUAL_SENSORS 16 +-#define OCTO_VIRTUAL_SENSORS_START 0x45 + #define OCTO_CTRL_REPORT_SIZE 0x65F +-#define OCTO_TEMP_CTRL_OFFSET 0xA ++ ++/* Sensor report offsets for the Octo */ ++#define OCTO_POWER_CYCLES 0x18 ++#define OCTO_SENSOR_START 0x3D ++#define OCTO_VIRTUAL_SENSORS_START 0x45 + static u8 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB, 0xD8 }; + +-/* Fan speed registers in Octo control report (from 0-100%) */ ++/* Control report offsets for the Octo */ ++#define OCTO_TEMP_CTRL_OFFSET 0xA ++/* Fan speed offsets (0-100%) */ + static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0x259, 0x2AE }; + +-/* Register offsets for the Quadro fan controller */ +-#define QUADRO_POWER_CYCLES 0x18 ++/* Specs of Quadro fan controller */ + #define QUADRO_NUM_FANS 4 + #define QUADRO_NUM_SENSORS 4 +-#define QUADRO_SENSOR_START 0x34 + #define QUADRO_NUM_VIRTUAL_SENSORS 16 +-#define QUADRO_VIRTUAL_SENSORS_START 0x3c + #define QUADRO_CTRL_REPORT_SIZE 0x3c1 ++ ++/* Sensor report offsets for the Quadro */ ++#define QUADRO_POWER_CYCLES 0x18 ++#define QUADRO_SENSOR_START 0x34 ++#define QUADRO_VIRTUAL_SENSORS_START 0x3c + #define QUADRO_FLOW_SENSOR_OFFSET 0x6e +-#define QUADRO_TEMP_CTRL_OFFSET 0xA + static u8 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 }; + +-/* Fan speed registers in Quadro control report (from 0-100%) */ +-static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 }; ++/* Control report offsets for the Quadro */ ++#define QUADRO_TEMP_CTRL_OFFSET 0xA ++static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 }; /* Fan speed offsets (0-100%) */ + +-/* Register offsets for the High Flow Next */ ++/* Specs of High Flow Next flow sensor */ + #define HIGHFLOWNEXT_NUM_SENSORS 2 ++ ++/* Sensor report offsets for the High Flow Next */ + #define HIGHFLOWNEXT_SENSOR_START 85 + #define HIGHFLOWNEXT_FLOW 81 + #define HIGHFLOWNEXT_WATER_QUALITY 89 +@@ -903,14 +916,17 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) + priv->num_fans = D5NEXT_NUM_FANS; + priv->fan_sensor_offsets = d5next_sensor_fan_offsets; + priv->fan_ctrl_offsets = d5next_ctrl_fan_offsets; ++ + priv->num_temp_sensors = D5NEXT_NUM_SENSORS; + priv->temp_sensor_start_offset = D5NEXT_COOLANT_TEMP; + priv->num_virtual_temp_sensors = D5NEXT_NUM_VIRTUAL_SENSORS; + priv->virtual_temp_sensor_start_offset = D5NEXT_VIRTUAL_SENSORS_START; +- priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES; +- priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE; + priv->temp_ctrl_offset = D5NEXT_TEMP_CTRL_OFFSET; + ++ priv->buffer_size = D5NEXT_CTRL_REPORT_SIZE; ++ ++ priv->power_cycle_count_offset = D5NEXT_POWER_CYCLES; ++ + priv->temp_label = label_d5next_temp; + priv->virtual_temp_label = label_virtual_temp_sensors; + priv->speed_label = label_d5next_speeds; +@@ -922,20 +938,25 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) + priv->kind = farbwerk; + + priv->num_fans = 0; ++ + priv->num_temp_sensors = FARBWERK_NUM_SENSORS; + priv->temp_sensor_start_offset = FARBWERK_SENSOR_START; ++ + priv->temp_label = label_temp_sensors; + break; + case USB_PRODUCT_ID_FARBWERK360: + priv->kind = farbwerk360; + + priv->num_fans = 0; ++ + priv->num_temp_sensors = FARBWERK360_NUM_SENSORS; + priv->temp_sensor_start_offset = FARBWERK360_SENSOR_START; + priv->num_virtual_temp_sensors = FARBWERK360_NUM_VIRTUAL_SENSORS; + priv->virtual_temp_sensor_start_offset = FARBWERK360_VIRTUAL_SENSORS_START; +- priv->buffer_size = FARBWERK360_CTRL_REPORT_SIZE; + priv->temp_ctrl_offset = FARBWERK360_TEMP_CTRL_OFFSET; ++ ++ priv->buffer_size = FARBWERK360_CTRL_REPORT_SIZE; ++ + priv->temp_label = label_temp_sensors; + priv->virtual_temp_label = label_virtual_temp_sensors; + break; +@@ -945,14 +966,17 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) + priv->num_fans = OCTO_NUM_FANS; + priv->fan_sensor_offsets = octo_sensor_fan_offsets; + priv->fan_ctrl_offsets = octo_ctrl_fan_offsets; ++ + priv->num_temp_sensors = OCTO_NUM_SENSORS; + priv->temp_sensor_start_offset = OCTO_SENSOR_START; + priv->num_virtual_temp_sensors = OCTO_NUM_VIRTUAL_SENSORS; + priv->virtual_temp_sensor_start_offset = OCTO_VIRTUAL_SENSORS_START; +- priv->power_cycle_count_offset = OCTO_POWER_CYCLES; +- priv->buffer_size = OCTO_CTRL_REPORT_SIZE; + priv->temp_ctrl_offset = OCTO_TEMP_CTRL_OFFSET; + ++ priv->buffer_size = OCTO_CTRL_REPORT_SIZE; ++ ++ priv->power_cycle_count_offset = OCTO_POWER_CYCLES; ++ + priv->temp_label = label_temp_sensors; + priv->virtual_temp_label = label_virtual_temp_sensors; + priv->speed_label = label_fan_speed; +@@ -966,14 +990,17 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) + priv->num_fans = QUADRO_NUM_FANS; + priv->fan_sensor_offsets = quadro_sensor_fan_offsets; + priv->fan_ctrl_offsets = quadro_ctrl_fan_offsets; ++ + priv->num_temp_sensors = QUADRO_NUM_SENSORS; + priv->temp_sensor_start_offset = QUADRO_SENSOR_START; + priv->num_virtual_temp_sensors = QUADRO_NUM_VIRTUAL_SENSORS; + priv->virtual_temp_sensor_start_offset = QUADRO_VIRTUAL_SENSORS_START; +- priv->power_cycle_count_offset = QUADRO_POWER_CYCLES; ++ priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET; ++ + priv->buffer_size = QUADRO_CTRL_REPORT_SIZE; ++ + priv->flow_sensor_offset = QUADRO_FLOW_SENSOR_OFFSET; +- priv->temp_ctrl_offset = QUADRO_TEMP_CTRL_OFFSET; ++ priv->power_cycle_count_offset = QUADRO_POWER_CYCLES; + + priv->temp_label = label_temp_sensors; + priv->virtual_temp_label = label_virtual_temp_sensors; +@@ -986,8 +1013,10 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) + priv->kind = highflownext; + + priv->num_fans = 0; ++ + priv->num_temp_sensors = HIGHFLOWNEXT_NUM_SENSORS; + priv->temp_sensor_start_offset = HIGHFLOWNEXT_SENSOR_START; ++ + priv->power_cycle_count_offset = QUADRO_POWER_CYCLES; + + priv->temp_label = label_highflownext_temp_sensors; +-- +cgit + + +From ed264e8a7d18c5fec2587ed750c87b75d5348210 Mon Sep 17 00:00:00 2001 +From: Joaquín Ignacio Aramendía +Date: Fri, 4 Nov 2022 11:07:00 -0300 +Subject: hwmon: add OneXPlayer mini AMD sensors driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Sensors driver for OXP Handhelds from One-Netbook that expose fan reading +and control via hwmon sysfs. + +As far as I could gather all OXP boards have the same DMI strings and +they can be told appart only by the boot cpu vendor (Intel/AMD). +Currently only AMD boards are supported since Intel have different EC +registers and values to read/write. + +Fan control is provided via pwm interface in the range [0-255]. AMD +boards have [0-100] as range in the EC, the written value is scaled to +accommodate for that. + +Signed-off-by: Joaquín Ignacio Aramendía +Link: https://lore.kernel.org/r/20221104140659.593608-1-samsagax@gmail.com +[groeck: Removed misleading comment about module_platform_driver()] +Signed-off-by: Guenter Roeck +--- + Documentation/hwmon/index.rst | 1 + + Documentation/hwmon/oxp-sensors.rst | 34 +++++ + MAINTAINERS | 6 + + drivers/hwmon/Kconfig | 11 ++ + drivers/hwmon/Makefile | 1 + + drivers/hwmon/oxp-sensors.c | 256 ++++++++++++++++++++++++++++++++++++ + 6 files changed, 309 insertions(+) + create mode 100644 Documentation/hwmon/oxp-sensors.rst + create mode 100644 drivers/hwmon/oxp-sensors.c + +diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst +index ddff3c5713d74..fe2cc6b73634c 100644 +--- a/Documentation/hwmon/index.rst ++++ b/Documentation/hwmon/index.rst +@@ -160,6 +160,7 @@ Hardware Monitoring Kernel Drivers + nzxt-kraken2 + nzxt-smart2 + occ ++ oxp-sensors + pc87360 + pc87427 + pcf8591 +diff --git a/Documentation/hwmon/oxp-sensors.rst b/Documentation/hwmon/oxp-sensors.rst +new file mode 100644 +index 0000000000000..f612dddc964ae +--- /dev/null ++++ b/Documentation/hwmon/oxp-sensors.rst +@@ -0,0 +1,34 @@ ++.. SPDX-License-Identifier: GPL-2.0-or-later ++ ++Kernel driver oxp-sensors ++========================= ++ ++Author: ++ - Joaquín Ignacio Aramendía ++ ++Description: ++------------ ++ ++One X Player devices from One Netbook provide fan readings and fan control ++through its Embedded Controller. ++ ++Currently only supports AMD boards from the One X Player lineup. 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. ++ ++Sysfs entries ++------------- ++ ++The following attributes are supported: ++ ++fan1_input ++ Read Only. Reads current fan RMP. ++ ++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. +diff --git a/MAINTAINERS b/MAINTAINERS +index 1daadaa4d48be..90220659206cb 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -15345,6 +15345,12 @@ S: Maintained + F: drivers/mtd/nand/onenand/ + F: include/linux/mtd/onenand*.h + ++ONEXPLAYER FAN DRIVER ++M: Joaquín Ignacio Aramendía ++L: linux-hwmon@vger.kernel.org ++S: Maintained ++F: drivers/hwmon/oxp-sensors.c ++ + ONION OMEGA2+ BOARD + M: Harvey Hunt + L: linux-mips@vger.kernel.org +diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +index a5253abb7ea72..3176c33af6c69 100644 +--- a/drivers/hwmon/Kconfig ++++ b/drivers/hwmon/Kconfig +@@ -1616,6 +1616,17 @@ config SENSORS_NZXT_SMART2 + + source "drivers/hwmon/occ/Kconfig" + ++config SENSORS_OXP ++ tristate "OneXPlayer EC fan control" ++ depends on ACPI ++ 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 c5cd7e3a67ffd..e2e4e87b282f5 100644 +--- a/drivers/hwmon/Makefile ++++ b/drivers/hwmon/Makefile +@@ -167,6 +167,7 @@ obj-$(CONFIG_SENSORS_NSA320) += nsa320-hwmon.o + obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o + obj-$(CONFIG_SENSORS_NZXT_KRAKEN2) += nzxt-kraken2.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/hwmon/oxp-sensors.c b/drivers/hwmon/oxp-sensors.c +new file mode 100644 +index 0000000000000..b1653eb5e6707 +--- /dev/null ++++ b/drivers/hwmon/oxp-sensors.c +@@ -0,0 +1,256 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Platform driver for OXP Handhelds that expose fan reading and control ++ * via hwmon sysfs. ++ * ++ * All boards have the same DMI strings and they are told appart by the ++ * boot cpu vendor (Intel/AMD). Currently only AMD boards are supported ++ * but the code is made to be simple to add other handheld boards in the ++ * future. ++ * Fan control is provided via pwm interface in the range [0-255]. AMD ++ * boards use [0-100] as range in the EC, the written value is scaled to ++ * accommodate for that. ++ * ++ * Copyright (C) 2022 Joaquín I. Aramendía ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Handle ACPI lock mechanism */ ++static u32 oxp_mutex; ++ ++#define ACPI_LOCK_DELAY_MS 500 ++ ++static bool lock_global_acpi_lock(void) ++{ ++ return ACPI_SUCCESS(acpi_acquire_global_lock(ACPI_LOCK_DELAY_MS, &oxp_mutex)); ++} ++ ++static bool unlock_global_acpi_lock(void) ++{ ++ return ACPI_SUCCESS(acpi_release_global_lock(oxp_mutex)); ++} ++ ++#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 */ ++ ++static const struct dmi_system_id dmi_table[] = { ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONE XPLAYER"), ++ }, ++ }, ++ {}, ++}; ++ ++/* Helper functions to handle EC read/write */ ++static int read_from_ec(u8 reg, int size, long *val) ++{ ++ int i; ++ int ret; ++ u8 buffer; ++ ++ if (!lock_global_acpi_lock()) ++ return -EBUSY; ++ ++ *val = 0; ++ for (i = 0; i < size; i++) { ++ ret = ec_read(reg + i, &buffer); ++ if (ret) ++ return ret; ++ *val <<= i * 8; ++ *val += buffer; ++ } ++ ++ if (!unlock_global_acpi_lock()) ++ return -EBUSY; ++ ++ return 0; ++} ++ ++static int write_to_ec(const struct device *dev, u8 reg, u8 value) ++{ ++ int ret; ++ ++ if (!lock_global_acpi_lock()) ++ return -EBUSY; ++ ++ ret = ec_write(reg, value); ++ ++ if (!unlock_global_acpi_lock()) ++ return -EBUSY; ++ ++ return ret; ++} ++ ++static int oxp_pwm_enable(const struct device *dev) ++{ ++ return write_to_ec(dev, OXP_SENSOR_PWM_ENABLE_REG, 0x01); ++} ++ ++static int oxp_pwm_disable(const struct device *dev) ++{ ++ return write_to_ec(dev, OXP_SENSOR_PWM_ENABLE_REG, 0x00); ++} ++ ++/* Callbacks for hwmon interface */ ++static umode_t oxp_ec_hwmon_is_visible(const void *drvdata, ++ enum hwmon_sensor_types type, u32 attr, int channel) ++{ ++ switch (type) { ++ case hwmon_fan: ++ return 0444; ++ case hwmon_pwm: ++ return 0644; ++ default: ++ return 0; ++ } ++} ++ ++static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type, ++ u32 attr, int channel, long *val) ++{ ++ int ret; ++ ++ switch (type) { ++ case hwmon_fan: ++ switch (attr) { ++ case hwmon_fan_input: ++ return read_from_ec(OXP_SENSOR_FAN_REG, 2, val); ++ default: ++ break; ++ } ++ break; ++ case hwmon_pwm: ++ switch (attr) { ++ case hwmon_pwm_input: ++ ret = read_from_ec(OXP_SENSOR_PWM_REG, 2, val); ++ if (ret) ++ return ret; ++ *val = (*val * 255) / 100; ++ return 0; ++ case hwmon_pwm_enable: ++ return read_from_ec(OXP_SENSOR_PWM_ENABLE_REG, 1, val); ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ return -EOPNOTSUPP; ++} ++ ++static int oxp_platform_write(struct device *dev, enum hwmon_sensor_types type, ++ u32 attr, int channel, long val) ++{ ++ switch (type) { ++ case hwmon_pwm: ++ switch (attr) { ++ case hwmon_pwm_enable: ++ if (val == 1) ++ return oxp_pwm_enable(dev); ++ else if (val == 0) ++ return oxp_pwm_disable(dev); ++ return -EINVAL; ++ case hwmon_pwm_input: ++ if (val < 0 || val > 255) ++ return -EINVAL; ++ val = (val * 100) / 255; ++ return write_to_ec(dev, OXP_SENSOR_PWM_REG, val); ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ return -EOPNOTSUPP; ++} ++ ++/* Known sensors in the OXP EC controllers */ ++static const struct hwmon_channel_info *oxp_platform_sensors[] = { ++ HWMON_CHANNEL_INFO(fan, ++ HWMON_F_INPUT), ++ HWMON_CHANNEL_INFO(pwm, ++ HWMON_PWM_INPUT | HWMON_PWM_ENABLE), ++ NULL, ++}; ++ ++static const struct hwmon_ops oxp_ec_hwmon_ops = { ++ .is_visible = oxp_ec_hwmon_is_visible, ++ .read = oxp_platform_read, ++ .write = oxp_platform_write, ++}; ++ ++static const struct hwmon_chip_info oxp_ec_chip_info = { ++ .ops = &oxp_ec_hwmon_ops, ++ .info = oxp_platform_sensors, ++}; ++ ++/* Initialization logic */ ++static int oxp_platform_probe(struct platform_device *pdev) ++{ ++ const struct dmi_system_id *dmi_entry; ++ struct device *dev = &pdev->dev; ++ struct device *hwdev; ++ ++ /* ++ * Have to check for AMD processor here because DMI strings are the ++ * same between Intel and AMD boards, the only way to tell them appart ++ * is the CPU. ++ * Intel boards seem to have different EC registers and values to ++ * read/write. ++ */ ++ dmi_entry = dmi_first_match(dmi_table); ++ if (!dmi_entry || boot_cpu_data.x86_vendor != X86_VENDOR_AMD) ++ return -ENODEV; ++ ++ hwdev = devm_hwmon_device_register_with_info(dev, "oxpec", NULL, ++ &oxp_ec_chip_info, NULL); ++ ++ return PTR_ERR_OR_ZERO(hwdev); ++} ++ ++static struct platform_driver oxp_platform_driver = { ++ .driver = { ++ .name = "oxp-platform", ++ }, ++ .probe = oxp_platform_probe, ++}; ++ ++static struct platform_device *oxp_platform_device; ++ ++static int __init oxp_platform_init(void) ++{ ++ oxp_platform_device = ++ platform_create_bundle(&oxp_platform_driver, ++ oxp_platform_probe, NULL, 0, NULL, 0); ++ ++ return PTR_ERR_OR_ZERO(oxp_platform_device); ++} ++ ++static void __exit oxp_platform_exit(void) ++{ ++ platform_device_unregister(oxp_platform_device); ++ platform_driver_unregister(&oxp_platform_driver); ++} ++ ++MODULE_DEVICE_TABLE(dmi, dmi_table); ++ ++module_init(oxp_platform_init); ++module_exit(oxp_platform_exit); ++ ++MODULE_AUTHOR("Joaquín Ignacio Aramendía "); ++MODULE_DESCRIPTION("Platform driver that handles EC sensors of OneXPlayer devices"); ++MODULE_LICENSE("GPL"); +-- +cgit + + +From 5c0e64dde80ffe78d930db4e38e6218598aecd85 Mon Sep 17 00:00:00 2001 +From: Zhang Rui +Date: Tue, 8 Nov 2022 15:50:49 +0800 +Subject: hwmon: (coretemp) Remove obsolete temp_data->valid + +Checking for the valid bit of IA32_THERM_STATUS is removed in commit +bf6ea084ebb5 ("hwmon: (coretemp) Do not return -EAGAIN for low +temperatures"), and temp_data->valid is set and never cleared when the +temperature has been read once. + +Remove the obsolete temp_data->valid field. + +Signed-off-by: Zhang Rui +Link: https://lore.kernel.org/r/20221108075051.5139-2-rui.zhang@intel.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/coretemp.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c +index 9bee4d33fbdf0..27d88c3a3487f 100644 +--- a/drivers/hwmon/coretemp.c ++++ b/drivers/hwmon/coretemp.c +@@ -64,7 +64,6 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); + * @attr_size: Total number of pre-core attrs displayed in the sysfs. + * @is_pkg_data: If this is 1, the temp_data holds pkgtemp data. + * Otherwise, temp_data holds coretemp data. +- * @valid: If this is 1, the current temperature is valid. + */ + struct temp_data { + int temp; +@@ -76,7 +75,6 @@ struct temp_data { + u32 status_reg; + int attr_size; + bool is_pkg_data; +- bool valid; + struct sensor_device_attribute sd_attrs[TOTAL_ATTRS]; + char attr_name[TOTAL_ATTRS][CORETEMP_NAME_LENGTH]; + struct attribute *attrs[TOTAL_ATTRS + 1]; +@@ -157,7 +155,7 @@ static ssize_t show_temp(struct device *dev, + mutex_lock(&tdata->update_lock); + + /* Check whether the time interval has elapsed */ +- if (!tdata->valid || time_after(jiffies, tdata->last_updated + HZ)) { ++ if (time_after(jiffies, tdata->last_updated + HZ)) { + rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); + /* + * Ignore the valid bit. In all observed cases the register +@@ -166,7 +164,6 @@ static ssize_t show_temp(struct device *dev, + * really help at all. + */ + tdata->temp = tdata->tjmax - ((eax >> 16) & 0x7f) * 1000; +- tdata->valid = true; + tdata->last_updated = jiffies; + } + +-- +cgit + + +From 07619140e2a12484ea262b8845fd09e099f843a8 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sun, 13 Nov 2022 10:13:16 +0100 +Subject: hwmon: Remove some useless #include + + is not needed for these drivers. Remove the +corresponding #include. + +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/41610f64a69bd0245ebc811fcff10ee54e93ac46.1668330765.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/vt8231.c | 1 - + drivers/hwmon/w83l786ng.c | 1 - + 2 files changed, 2 deletions(-) + +diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c +index 3b7f8922b0d5a..b7c6392ba6737 100644 +--- a/drivers/hwmon/vt8231.c ++++ b/drivers/hwmon/vt8231.c +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c +index 2c4646fa84260..5597e1c2d95cf 100644 +--- a/drivers/hwmon/w83l786ng.c ++++ b/drivers/hwmon/w83l786ng.c +@@ -16,7 +16,6 @@ + #include + #include + #include +-#include + #include + #include + #include +-- +cgit + + +From 2bc0e6d07ee50497043112d677fdd34327cf025c Mon Sep 17 00:00:00 2001 +From: Zhang Rui +Date: Sun, 13 Nov 2022 23:31:43 +0800 +Subject: hwmon: (coretemp) rearrange tjmax handing code + +Rearrange the tjmax handling code so that it can be used directly in +the sysfs attribute callbacks without forward declarations. + +No functional change in this patch. + +Signed-off-by: Zhang Rui +Link: https://lore.kernel.org/r/20221113153145.32696-2-rui.zhang@intel.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/coretemp.c | 156 +++++++++++++++++++++++------------------------ + 1 file changed, 78 insertions(+), 78 deletions(-) + +diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c +index 27d88c3a3487f..6b6ee563e0087 100644 +--- a/drivers/hwmon/coretemp.c ++++ b/drivers/hwmon/coretemp.c +@@ -93,84 +93,6 @@ struct platform_data { + struct device_attribute name_attr; + }; + +-/* Keep track of how many zone pointers we allocated in init() */ +-static int max_zones __read_mostly; +-/* Array of zone pointers. Serialized by cpu hotplug lock */ +-static struct platform_device **zone_devices; +- +-static ssize_t show_label(struct device *dev, +- struct device_attribute *devattr, char *buf) +-{ +- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); +- struct platform_data *pdata = dev_get_drvdata(dev); +- struct temp_data *tdata = pdata->core_data[attr->index]; +- +- if (tdata->is_pkg_data) +- return sprintf(buf, "Package id %u\n", pdata->pkg_id); +- +- return sprintf(buf, "Core %u\n", tdata->cpu_core_id); +-} +- +-static ssize_t show_crit_alarm(struct device *dev, +- struct device_attribute *devattr, char *buf) +-{ +- u32 eax, edx; +- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); +- struct platform_data *pdata = dev_get_drvdata(dev); +- struct temp_data *tdata = pdata->core_data[attr->index]; +- +- mutex_lock(&tdata->update_lock); +- rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); +- mutex_unlock(&tdata->update_lock); +- +- return sprintf(buf, "%d\n", (eax >> 5) & 1); +-} +- +-static ssize_t show_tjmax(struct device *dev, +- struct device_attribute *devattr, char *buf) +-{ +- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); +- struct platform_data *pdata = dev_get_drvdata(dev); +- +- return sprintf(buf, "%d\n", pdata->core_data[attr->index]->tjmax); +-} +- +-static ssize_t show_ttarget(struct device *dev, +- struct device_attribute *devattr, char *buf) +-{ +- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); +- struct platform_data *pdata = dev_get_drvdata(dev); +- +- return sprintf(buf, "%d\n", pdata->core_data[attr->index]->ttarget); +-} +- +-static ssize_t show_temp(struct device *dev, +- struct device_attribute *devattr, char *buf) +-{ +- u32 eax, edx; +- struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); +- struct platform_data *pdata = dev_get_drvdata(dev); +- struct temp_data *tdata = pdata->core_data[attr->index]; +- +- mutex_lock(&tdata->update_lock); +- +- /* Check whether the time interval has elapsed */ +- if (time_after(jiffies, tdata->last_updated + HZ)) { +- rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); +- /* +- * Ignore the valid bit. In all observed cases the register +- * value is either low or zero if the valid bit is 0. +- * Return it instead of reporting an error which doesn't +- * really help at all. +- */ +- tdata->temp = tdata->tjmax - ((eax >> 16) & 0x7f) * 1000; +- tdata->last_updated = jiffies; +- } +- +- mutex_unlock(&tdata->update_lock); +- return sprintf(buf, "%d\n", tdata->temp); +-} +- + struct tjmax_pci { + unsigned int device; + int tjmax; +@@ -376,6 +298,84 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) + return adjust_tjmax(c, id, dev); + } + ++/* Keep track of how many zone pointers we allocated in init() */ ++static int max_zones __read_mostly; ++/* Array of zone pointers. Serialized by cpu hotplug lock */ ++static struct platform_device **zone_devices; ++ ++static ssize_t show_label(struct device *dev, ++ struct device_attribute *devattr, char *buf) ++{ ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); ++ struct platform_data *pdata = dev_get_drvdata(dev); ++ struct temp_data *tdata = pdata->core_data[attr->index]; ++ ++ if (tdata->is_pkg_data) ++ return sprintf(buf, "Package id %u\n", pdata->pkg_id); ++ ++ return sprintf(buf, "Core %u\n", tdata->cpu_core_id); ++} ++ ++static ssize_t show_crit_alarm(struct device *dev, ++ struct device_attribute *devattr, char *buf) ++{ ++ u32 eax, edx; ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); ++ struct platform_data *pdata = dev_get_drvdata(dev); ++ struct temp_data *tdata = pdata->core_data[attr->index]; ++ ++ mutex_lock(&tdata->update_lock); ++ rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); ++ mutex_unlock(&tdata->update_lock); ++ ++ return sprintf(buf, "%d\n", (eax >> 5) & 1); ++} ++ ++static ssize_t show_tjmax(struct device *dev, ++ struct device_attribute *devattr, char *buf) ++{ ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); ++ struct platform_data *pdata = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%d\n", pdata->core_data[attr->index]->tjmax); ++} ++ ++static ssize_t show_ttarget(struct device *dev, ++ struct device_attribute *devattr, char *buf) ++{ ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); ++ struct platform_data *pdata = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%d\n", pdata->core_data[attr->index]->ttarget); ++} ++ ++static ssize_t show_temp(struct device *dev, ++ struct device_attribute *devattr, char *buf) ++{ ++ u32 eax, edx; ++ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); ++ struct platform_data *pdata = dev_get_drvdata(dev); ++ struct temp_data *tdata = pdata->core_data[attr->index]; ++ ++ mutex_lock(&tdata->update_lock); ++ ++ /* Check whether the time interval has elapsed */ ++ if (time_after(jiffies, tdata->last_updated + HZ)) { ++ rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); ++ /* ++ * Ignore the valid bit. In all observed cases the register ++ * value is either low or zero if the valid bit is 0. ++ * Return it instead of reporting an error which doesn't ++ * really help at all. ++ */ ++ tdata->temp = tdata->tjmax - ((eax >> 16) & 0x7f) * 1000; ++ tdata->last_updated = jiffies; ++ } ++ ++ mutex_unlock(&tdata->update_lock); ++ return sprintf(buf, "%d\n", tdata->temp); ++} ++ + static int create_core_attrs(struct temp_data *tdata, struct device *dev, + int attr_no) + { +-- +cgit + + +From c0c67f8761cec1fe36c21d85b1a5400ea7ac30cd Mon Sep 17 00:00:00 2001 +From: Zhang Rui +Date: Sun, 13 Nov 2022 23:31:44 +0800 +Subject: hwmon: (coretemp) Add support for dynamic tjmax + +Tjmax value retrieved from MSR_IA32_TEMPERATURE_TARGET can be changed at +runtime when the Intel SST-PP (Intel Speed Select Technology - +Performance Profile) level is changed. + +Improve the code to always use updated tjmax when it can be retrieved +from MSR_IA32_TEMPERATURE_TARGET. + +When tjmax can not be retrieved from MSR_IA32_TEMPERATURE_TARGET, still +follow the previous logic and always use a static tjmax value. + +Signed-off-by: Zhang Rui +Link: https://lore.kernel.org/r/20221113153145.32696-3-rui.zhang@intel.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/coretemp.c | 46 +++++++++++++++++++++++++++++++--------------- + 1 file changed, 31 insertions(+), 15 deletions(-) + +diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c +index 6b6ee563e0087..5e03cfbbe99b8 100644 +--- a/drivers/hwmon/coretemp.c ++++ b/drivers/hwmon/coretemp.c +@@ -55,6 +55,8 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); + + /* + * Per-Core Temperature Data ++ * @tjmax: The static tjmax value when tjmax cannot be retrieved from ++ * IA32_TEMPERATURE_TARGET MSR. + * @last_updated: The time when the current temperature value was updated + * earlier (in jiffies). + * @cpu_core_id: The CPU Core from which temperature values should be read +@@ -259,20 +261,25 @@ static bool cpu_has_tjmax(struct cpuinfo_x86 *c) + model != 0x36; + } + +-static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) ++static int get_tjmax(struct temp_data *tdata, struct device *dev) + { ++ struct cpuinfo_x86 *c = &cpu_data(tdata->cpu); + int err; + u32 eax, edx; + u32 val; + ++ /* use static tjmax once it is set */ ++ if (tdata->tjmax) ++ return tdata->tjmax; ++ + /* + * A new feature of current Intel(R) processors, the + * IA32_TEMPERATURE_TARGET contains the TjMax value + */ +- err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); ++ err = rdmsr_safe_on_cpu(tdata->cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); + if (err) { + if (cpu_has_tjmax(c)) +- dev_warn(dev, "Unable to read TjMax from CPU %u\n", id); ++ dev_warn(dev, "Unable to read TjMax from CPU %u\n", tdata->cpu); + } else { + val = (eax >> 16) & 0xff; + /* +@@ -288,14 +295,15 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) + if (force_tjmax) { + dev_notice(dev, "TjMax forced to %d degrees C by user\n", + force_tjmax); +- return force_tjmax * 1000; ++ tdata->tjmax = force_tjmax * 1000; ++ } else { ++ /* ++ * An assumption is made for early CPUs and unreadable MSR. ++ * NOTE: the calculated value may not be correct. ++ */ ++ tdata->tjmax = adjust_tjmax(c, tdata->cpu, dev); + } +- +- /* +- * An assumption is made for early CPUs and unreadable MSR. +- * NOTE: the calculated value may not be correct. +- */ +- return adjust_tjmax(c, id, dev); ++ return tdata->tjmax; + } + + /* Keep track of how many zone pointers we allocated in init() */ +@@ -336,8 +344,14 @@ static ssize_t show_tjmax(struct device *dev, + { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct platform_data *pdata = dev_get_drvdata(dev); ++ struct temp_data *tdata = pdata->core_data[attr->index]; ++ int tjmax; ++ ++ mutex_lock(&tdata->update_lock); ++ tjmax = get_tjmax(tdata, dev); ++ mutex_unlock(&tdata->update_lock); + +- return sprintf(buf, "%d\n", pdata->core_data[attr->index]->tjmax); ++ return sprintf(buf, "%d\n", tjmax); + } + + static ssize_t show_ttarget(struct device *dev, +@@ -356,9 +370,11 @@ static ssize_t show_temp(struct device *dev, + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct platform_data *pdata = dev_get_drvdata(dev); + struct temp_data *tdata = pdata->core_data[attr->index]; ++ int tjmax; + + mutex_lock(&tdata->update_lock); + ++ tjmax = get_tjmax(tdata, dev); + /* Check whether the time interval has elapsed */ + if (time_after(jiffies, tdata->last_updated + HZ)) { + rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); +@@ -368,7 +384,7 @@ static ssize_t show_temp(struct device *dev, + * Return it instead of reporting an error which doesn't + * really help at all. + */ +- tdata->temp = tdata->tjmax - ((eax >> 16) & 0x7f) * 1000; ++ tdata->temp = tjmax - ((eax >> 16) & 0x7f) * 1000; + tdata->last_updated = jiffies; + } + +@@ -453,7 +469,7 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, + struct platform_data *pdata = platform_get_drvdata(pdev); + struct cpuinfo_x86 *c = &cpu_data(cpu); + u32 eax, edx; +- int err, index, attr_no; ++ int err, index, attr_no, tjmax; + + /* + * Find attr number for sysfs: +@@ -488,7 +504,7 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, + goto exit_free; + + /* We can access status register. Get Critical Temperature */ +- tdata->tjmax = get_tjmax(c, cpu, &pdev->dev); ++ tjmax = get_tjmax(tdata, &pdev->dev); + + /* + * Read the still undocumented bits 8:15 of IA32_TEMPERATURE_TARGET. +@@ -500,7 +516,7 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, + &eax, &edx); + if (!err) { + tdata->ttarget +- = tdata->tjmax - ((eax >> 8) & 0xff) * 1000; ++ = tjmax - ((eax >> 8) & 0xff) * 1000; + tdata->attr_size++; + } + } +-- +cgit + + +From fae30e3c203e0f854d0420b50e54e31a75b6a8a4 Mon Sep 17 00:00:00 2001 +From: Zhang Rui +Date: Sun, 13 Nov 2022 23:31:45 +0800 +Subject: hwmon: (coretemp) Add support for dynamic ttarget + +Tjmax value retrieved from MSR_IA32_TEMPERATURE_TARGET can be changed at +runtime when the Intel SST-PP (Intel Speed Select Technology - +Performance Profile) level is changed. As a result, the ttarget value +also becomes dyamic. + +Improve the code to always get updated ttarget value. + +Signed-off-by: Zhang Rui +Link: https://lore.kernel.org/r/20221113153145.32696-4-rui.zhang@intel.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/coretemp.c | 57 ++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 41 insertions(+), 16 deletions(-) + +diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c +index 5e03cfbbe99b8..ca7a9b373bbd6 100644 +--- a/drivers/hwmon/coretemp.c ++++ b/drivers/hwmon/coretemp.c +@@ -69,7 +69,6 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); + */ + struct temp_data { + int temp; +- int ttarget; + int tjmax; + unsigned long last_updated; + unsigned int cpu; +@@ -306,6 +305,30 @@ static int get_tjmax(struct temp_data *tdata, struct device *dev) + return tdata->tjmax; + } + ++static int get_ttarget(struct temp_data *tdata, struct device *dev) ++{ ++ u32 eax, edx; ++ int tjmax, ttarget_offset, ret; ++ ++ /* ++ * ttarget is valid only if tjmax can be retrieved from ++ * MSR_IA32_TEMPERATURE_TARGET ++ */ ++ if (tdata->tjmax) ++ return -ENODEV; ++ ++ ret = rdmsr_safe_on_cpu(tdata->cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); ++ if (ret) ++ return ret; ++ ++ tjmax = (eax >> 16) & 0xff; ++ ++ /* Read the still undocumented bits 8:15 of IA32_TEMPERATURE_TARGET. */ ++ ttarget_offset = (eax >> 8) & 0xff; ++ ++ return (tjmax - ttarget_offset) * 1000; ++} ++ + /* Keep track of how many zone pointers we allocated in init() */ + static int max_zones __read_mostly; + /* Array of zone pointers. Serialized by cpu hotplug lock */ +@@ -359,8 +382,16 @@ static ssize_t show_ttarget(struct device *dev, + { + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct platform_data *pdata = dev_get_drvdata(dev); ++ struct temp_data *tdata = pdata->core_data[attr->index]; ++ int ttarget; + +- return sprintf(buf, "%d\n", pdata->core_data[attr->index]->ttarget); ++ mutex_lock(&tdata->update_lock); ++ ttarget = get_ttarget(tdata, dev); ++ mutex_unlock(&tdata->update_lock); ++ ++ if (ttarget < 0) ++ return ttarget; ++ return sprintf(buf, "%d\n", ttarget); + } + + static ssize_t show_temp(struct device *dev, +@@ -469,7 +500,7 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, + struct platform_data *pdata = platform_get_drvdata(pdev); + struct cpuinfo_x86 *c = &cpu_data(cpu); + u32 eax, edx; +- int err, index, attr_no, tjmax; ++ int err, index, attr_no; + + /* + * Find attr number for sysfs: +@@ -503,23 +534,17 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu, + if (err) + goto exit_free; + +- /* We can access status register. Get Critical Temperature */ +- tjmax = get_tjmax(tdata, &pdev->dev); ++ /* Make sure tdata->tjmax is a valid indicator for dynamic/static tjmax */ ++ get_tjmax(tdata, &pdev->dev); + + /* +- * Read the still undocumented bits 8:15 of IA32_TEMPERATURE_TARGET. +- * The target temperature is available on older CPUs but not in this +- * register. Atoms don't have the register at all. ++ * The target temperature is available on older CPUs but not in the ++ * MSR_IA32_TEMPERATURE_TARGET register. Atoms don't have the register ++ * at all. + */ +- if (c->x86_model > 0xe && c->x86_model != 0x1c) { +- err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, +- &eax, &edx); +- if (!err) { +- tdata->ttarget +- = tjmax - ((eax >> 8) & 0xff) * 1000; ++ if (c->x86_model > 0xe && c->x86_model != 0x1c) ++ if (get_ttarget(tdata, &pdev->dev) >= 0) + tdata->attr_size++; +- } +- } + + pdata->core_data[attr_no] = tdata; + +-- +cgit + + +From 1864069c695d475e0ce98a335c62274b81be57b4 Mon Sep 17 00:00:00 2001 +From: Denis Pauk +Date: Mon, 14 Nov 2022 23:44:56 +0200 +Subject: hwmon: (nct6775) add ASUS CROSSHAIR VIII/TUF/ProArt B550M + +Boards such as +* ProArt B550-CREATOR +* ProArt Z490-CREATOR 10G +* ROG CROSSHAIR VIII EXTREME +* ROG CROSSHAIR VIII HERO (WI-FI) +* TUF GAMING B550M-E +* TUF GAMING B550M-E (WI-FI) +* TUF GAMING B550M-PLUS WIFI II +have got a nct6775 chip, but by default there's no use of it +because of resource conflict with WMI method. + +This commit adds such boards to the WMI monitoring list. + +BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807 +Signed-off-by: Denis Pauk +Reported-by: yutesdb +Tested-by: yutesdb +Link: https://lore.kernel.org/r/20221114214456.3891-1-pauk.denis@gmail.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/nct6775-platform.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/hwmon/nct6775-platform.c b/drivers/hwmon/nct6775-platform.c +index b347837842139..bf43f73dc835f 100644 +--- a/drivers/hwmon/nct6775-platform.c ++++ b/drivers/hwmon/nct6775-platform.c +@@ -1043,7 +1043,9 @@ static struct platform_device *pdev[2]; + + static const char * const asus_wmi_boards[] = { + "PRO H410T", ++ "ProArt B550-CREATOR", + "ProArt X570-CREATOR WIFI", ++ "ProArt Z490-CREATOR 10G", + "Pro B550M-C", + "Pro WS X570-ACE", + "PRIME B360-PLUS", +@@ -1055,8 +1057,10 @@ static const char * const asus_wmi_boards[] = { + "PRIME X570-P", + "PRIME X570-PRO", + "ROG CROSSHAIR VIII DARK HERO", ++ "ROG CROSSHAIR VIII EXTREME", + "ROG CROSSHAIR VIII FORMULA", + "ROG CROSSHAIR VIII HERO", ++ "ROG CROSSHAIR VIII HERO (WI-FI)", + "ROG CROSSHAIR VIII IMPACT", + "ROG STRIX B550-A GAMING", + "ROG STRIX B550-E GAMING", +@@ -1080,8 +1084,11 @@ static const char * const asus_wmi_boards[] = { + "ROG STRIX Z490-G GAMING (WI-FI)", + "ROG STRIX Z490-H GAMING", + "ROG STRIX Z490-I GAMING", ++ "TUF GAMING B550M-E", ++ "TUF GAMING B550M-E (WI-FI)", + "TUF GAMING B550M-PLUS", + "TUF GAMING B550M-PLUS (WI-FI)", ++ "TUF GAMING B550M-PLUS WIFI II", + "TUF GAMING B550-PLUS", + "TUF GAMING B550-PLUS WIFI II", + "TUF GAMING B550-PRO", +-- +cgit + + +From ef9948dfe1056a89f699edc8eb691a8ed99eda5e Mon Sep 17 00:00:00 2001 +From: Patrick Rudolph +Date: Thu, 17 Nov 2022 19:40:22 +0100 +Subject: hwmon: (pmbus) Add power good support + +Update error flags with regulation out if regulator is on & power +good status bit is set + +Signed-off-by: Patrick Rudolph +Signed-off-by: Naresh Solanki +Link: https://lore.kernel.org/r/20221117184022.1808508-1-Naresh.Solanki@9elements.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/pmbus/pmbus_core.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c +index 7ec04934747e1..20ca26e19db75 100644 +--- a/drivers/hwmon/pmbus/pmbus_core.c ++++ b/drivers/hwmon/pmbus/pmbus_core.c +@@ -2827,9 +2827,13 @@ static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned + if (status < 0) + return status; + +- if (pmbus_regulator_is_enabled(rdev) && (status & PB_STATUS_OFF)) +- *flags |= REGULATOR_ERROR_FAIL; ++ if (pmbus_regulator_is_enabled(rdev)) { ++ if (status & PB_STATUS_OFF) ++ *flags |= REGULATOR_ERROR_FAIL; + ++ if (status & PB_STATUS_POWER_GOOD_N) ++ *flags |= REGULATOR_ERROR_REGULATION_OUT; ++ } + /* + * Unlike most other status bits, PB_STATUS_{IOUT_OC,VOUT_OV} are + * defined strictly as fault indicators (not warnings). +-- +cgit + + +From 59882c7f6714141300882af3d39ca6ffecf54ec2 Mon Sep 17 00:00:00 2001 +From: Christophe JAILLET +Date: Sun, 20 Nov 2022 10:34:41 +0100 +Subject: hwmon: (gsc-hwmon) Switch to flexible array to simplify code + +Using flexible array is more straight forward. It + - saves 1 pointer in the 'gsc_hwmon_platform_data' structure + - saves an indirection when using this array + - saves some LoC and avoids some always spurious pointer arithmetic + +Signed-off-by: Christophe JAILLET +Link: https://lore.kernel.org/r/61a23e1d642397cfcecc4ac3bb0ab485d257987d.1668936855.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/gsc-hwmon.c | 6 ++---- + include/linux/platform_data/gsc_hwmon.h | 5 ++--- + 2 files changed, 4 insertions(+), 7 deletions(-) + +diff --git a/drivers/hwmon/gsc-hwmon.c b/drivers/hwmon/gsc-hwmon.c +index b60ec95b5edbf..73e5d92b200b0 100644 +--- a/drivers/hwmon/gsc-hwmon.c ++++ b/drivers/hwmon/gsc-hwmon.c +@@ -257,13 +257,10 @@ gsc_hwmon_get_devtree_pdata(struct device *dev) + if (nchannels == 0) + return ERR_PTR(-ENODEV); + +- pdata = devm_kzalloc(dev, +- sizeof(*pdata) + nchannels * sizeof(*ch), ++ pdata = devm_kzalloc(dev, struct_size(pdata, channels, nchannels), + GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); +- ch = (struct gsc_hwmon_channel *)(pdata + 1); +- pdata->channels = ch; + pdata->nchannels = nchannels; + + /* fan controller base address */ +@@ -277,6 +274,7 @@ gsc_hwmon_get_devtree_pdata(struct device *dev) + + of_node_put(fan); + ++ ch = pdata->channels; + /* allocate structures for channels and count instances of each type */ + device_for_each_child_node(dev, child) { + if (fwnode_property_read_string(child, "label", &ch->name)) { +diff --git a/include/linux/platform_data/gsc_hwmon.h b/include/linux/platform_data/gsc_hwmon.h +index 281f499eda979..f2781aa7eff85 100644 +--- a/include/linux/platform_data/gsc_hwmon.h ++++ b/include/linux/platform_data/gsc_hwmon.h +@@ -29,18 +29,17 @@ struct gsc_hwmon_channel { + + /** + * struct gsc_hwmon_platform_data - platform data for gsc_hwmon driver +- * @channels: pointer to array of gsc_hwmon_channel structures +- * describing channels + * @nchannels: number of elements in @channels array + * @vreference: voltage reference (mV) + * @resolution: ADC bit resolution + * @fan_base: register base for FAN controller ++ * @channels: array of gsc_hwmon_channel structures describing channels + */ + struct gsc_hwmon_platform_data { +- const struct gsc_hwmon_channel *channels; + int nchannels; + unsigned int resolution; + unsigned int vreference; + unsigned int fan_base; ++ struct gsc_hwmon_channel channels[]; + }; + #endif +-- +cgit + + +From 3ca0f12a02582c3dd4029294ab0245ba77c27a77 Mon Sep 17 00:00:00 2001 +From: Joaquín Ignacio Aramendía +Date: Fri, 25 Nov 2022 08:49:01 -0300 +Subject: hwmon: (oxp-sensors) Add AOK ZOE and Mini PRO +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add support for the AOK ZOE A1 and OXP Mini PRO handheld devices. +DMI strings are added to this driver since the same EC layout is used and +has similar specs as the OXP mini AMD. + +The added devices are: +- OneXPlayer mini PRO (AMD 6800U) +- AOK ZOE A1 (AMD 6800U) + +Signed-off-by: Joaquín Ignacio Aramendía +Link: https://lore.kernel.org/r/20221125114901.11309-1-samsagax@gmail.com +Signed-off-by: Guenter Roeck +--- + Documentation/hwmon/oxp-sensors.rst | 16 ++++++++++++--- + drivers/hwmon/oxp-sensors.c | 40 +++++++++++++++++++++++++++++++------ + 2 files changed, 47 insertions(+), 9 deletions(-) + +diff --git a/Documentation/hwmon/oxp-sensors.rst b/Documentation/hwmon/oxp-sensors.rst +index f612dddc964ae..39c588ec5c506 100644 +--- a/Documentation/hwmon/oxp-sensors.rst ++++ b/Documentation/hwmon/oxp-sensors.rst +@@ -12,9 +12,19 @@ Description: + One X Player devices from One Netbook provide fan readings and fan control + through its Embedded Controller. + +-Currently only supports AMD boards from the One X Player lineup. 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. ++Currently only supports AMD boards from the One X Player and AOK ZOE lineup. ++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. ++ ++Supported devices ++----------------- ++ ++Currently the driver supports the following handhelds: ++ ++ - AOK ZOE A1 ++ - OneXPlayer AMD ++ - OneXPlayer mini AMD ++ - OneXPlayer mini AMD PRO + + Sysfs entries + ------------- +diff --git a/drivers/hwmon/oxp-sensors.c b/drivers/hwmon/oxp-sensors.c +index b1653eb5e6707..c04277676b727 100644 +--- a/drivers/hwmon/oxp-sensors.c ++++ b/drivers/hwmon/oxp-sensors.c +@@ -3,13 +3,14 @@ + * Platform driver for OXP Handhelds that expose fan reading and control + * via hwmon sysfs. + * +- * All boards have the same DMI strings and they are told appart by the ++ * Old boards have the same DMI strings and they are told appart by the + * boot cpu vendor (Intel/AMD). Currently only AMD boards are supported + * but the code is made to be simple to add other handheld boards in the + * future. +- * Fan control is provided via pwm interface in the range [0-255]. AMD +- * boards use [0-100] as range in the EC, the written value is scaled to +- * accommodate for that. ++ * 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 ++ * scaled to accommodate for that. Newer boards like the mini PRO and ++ * AOK ZOE are not scaled but have the same EC layout. + * + * Copyright (C) 2022 Joaquín I. Aramendía + */ +@@ -39,16 +40,39 @@ static bool unlock_global_acpi_lock(void) + return ACPI_SUCCESS(acpi_release_global_lock(oxp_mutex)); + } + ++enum oxp_board { ++ aok_zoe_a1 = 1, ++ oxp_mini_amd, ++ oxp_mini_amd_pro, ++}; ++ ++static enum oxp_board board; ++ + #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 */ + + static const struct dmi_system_id dmi_table[] = { ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "AOKZOE"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "AOKZOE A1 AR07"), ++ }, ++ .driver_data = (void *) &(enum oxp_board) {aok_zoe_a1}, ++ }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONE XPLAYER"), + }, ++ .driver_data = (void *) &(enum oxp_board) {oxp_mini_amd}, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER Mini Pro"), ++ }, ++ .driver_data = (void *) &(enum oxp_board) {oxp_mini_amd_pro}, + }, + {}, + }; +@@ -137,7 +161,8 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type, + ret = read_from_ec(OXP_SENSOR_PWM_REG, 2, val); + if (ret) + return ret; +- *val = (*val * 255) / 100; ++ if (board == oxp_mini_amd) ++ *val = (*val * 255) / 100; + return 0; + case hwmon_pwm_enable: + return read_from_ec(OXP_SENSOR_PWM_ENABLE_REG, 1, val); +@@ -166,7 +191,8 @@ static int oxp_platform_write(struct device *dev, enum hwmon_sensor_types type, + case hwmon_pwm_input: + if (val < 0 || val > 255) + return -EINVAL; +- val = (val * 100) / 255; ++ if (board == oxp_mini_amd) ++ val = (val * 100) / 255; + return write_to_ec(dev, OXP_SENSOR_PWM_REG, val); + default: + break; +@@ -216,6 +242,8 @@ static int oxp_platform_probe(struct platform_device *pdev) + if (!dmi_entry || boot_cpu_data.x86_vendor != X86_VENDOR_AMD) + return -ENODEV; + ++ board = *((enum oxp_board *) dmi_entry->driver_data); ++ + hwdev = devm_hwmon_device_register_with_info(dev, "oxpec", NULL, + &oxp_ec_chip_info, NULL); + +-- +cgit + + +From c05f477c4ba36e007c03ff4f834f43bc4e37692b Mon Sep 17 00:00:00 2001 +From: Patrick Rudolph +Date: Thu, 24 Nov 2022 20:36:42 +0100 +Subject: hwmon: (pmbus/core) Implement regulator get_status + +Add get_status for pmbus_regulator_ops. + +Signed-off-by: Patrick Rudolph +Signed-off-by: Naresh Solanki +Link: https://lore.kernel.org/r/20221124193642.4081054-1-Naresh.Solanki@9elements.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/pmbus/pmbus_core.c | 44 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c +index 20ca26e19db75..95e95783972ab 100644 +--- a/drivers/hwmon/pmbus/pmbus_core.c ++++ b/drivers/hwmon/pmbus/pmbus_core.c +@@ -2855,6 +2855,49 @@ static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned + return 0; + } + ++static int pmbus_regulator_get_status(struct regulator_dev *rdev) ++{ ++ struct device *dev = rdev_get_dev(rdev); ++ struct i2c_client *client = to_i2c_client(dev->parent); ++ struct pmbus_data *data = i2c_get_clientdata(client); ++ u8 page = rdev_get_id(rdev); ++ int status, ret; ++ ++ mutex_lock(&data->update_lock); ++ status = pmbus_get_status(client, page, PMBUS_STATUS_WORD); ++ if (status < 0) { ++ ret = status; ++ goto unlock; ++ } ++ ++ if (status & PB_STATUS_OFF) { ++ ret = REGULATOR_STATUS_OFF; ++ goto unlock; ++ } ++ ++ /* If regulator is ON & reports power good then return ON */ ++ if (!(status & PB_STATUS_POWER_GOOD_N)) { ++ ret = REGULATOR_STATUS_ON; ++ goto unlock; ++ } ++ ++ ret = pmbus_regulator_get_error_flags(rdev, &status); ++ if (ret) ++ goto unlock; ++ ++ if (status & (REGULATOR_ERROR_UNDER_VOLTAGE | REGULATOR_ERROR_OVER_CURRENT | ++ REGULATOR_ERROR_REGULATION_OUT | REGULATOR_ERROR_FAIL | REGULATOR_ERROR_OVER_TEMP)) { ++ ret = REGULATOR_STATUS_ERROR; ++ goto unlock; ++ } ++ ++ ret = REGULATOR_STATUS_UNDEFINED; ++ ++unlock: ++ mutex_unlock(&data->update_lock); ++ return ret; ++} ++ + static int pmbus_regulator_get_low_margin(struct i2c_client *client, int page) + { + struct pmbus_data *data = i2c_get_clientdata(client); +@@ -2995,6 +3038,7 @@ const struct regulator_ops pmbus_regulator_ops = { + .disable = pmbus_regulator_disable, + .is_enabled = pmbus_regulator_is_enabled, + .get_error_flags = pmbus_regulator_get_error_flags, ++ .get_status = pmbus_regulator_get_status, + .get_voltage = pmbus_regulator_get_voltage, + .set_voltage = pmbus_regulator_set_voltage, + .list_voltage = pmbus_regulator_list_voltage, +-- +cgit + + +From 6ff838f2877dcd5ec7db0745a2652a048a697991 Mon Sep 17 00:00:00 2001 +From: Aleksa Savic +Date: Sat, 26 Nov 2022 08:13:13 +0100 +Subject: hwmon: (aquacomputer_d5next) Add support for Quadro flow sensor + pulses + +Add support for reading and writing flow sensor pulses value on +the Aquacomputer Quadro. Implemented by Leonard Anderweit [1]. + +[1] https://github.com/aleksamagicka/aquacomputer_d5next-hwmon/pull/45 + +Originally-from: Leonard Anderweit +Signed-off-by: Aleksa Savic +Link: https://lore.kernel.org/r/20221126071313.34356-1-savicaleksa83@gmail.com +Signed-off-by: Guenter Roeck +--- + Documentation/hwmon/aquacomputer_d5next.rst | 3 +- + drivers/hwmon/aquacomputer_d5next.c | 66 +++++++++++++++++++++++------ + 2 files changed, 55 insertions(+), 14 deletions(-) + +diff --git a/Documentation/hwmon/aquacomputer_d5next.rst b/Documentation/hwmon/aquacomputer_d5next.rst +index 15226346434dd..637bdbc8fcad4 100644 +--- a/Documentation/hwmon/aquacomputer_d5next.rst ++++ b/Documentation/hwmon/aquacomputer_d5next.rst +@@ -39,7 +39,7 @@ current. + + The Quadro exposes four physical and sixteen virtual temperature sensors, a flow + sensor and four PWM controllable fans, along with their speed (in RPM), power, +-voltage and current. ++voltage and current. Flow sensor pulses are also available. + + The Farbwerk and Farbwerk 360 expose four temperature sensors. Additionally, + sixteen virtual temperature sensors of the Farbwerk 360 are exposed. +@@ -64,6 +64,7 @@ Sysfs entries + temp[1-20]_input Physical/virtual temperature sensors (in millidegrees Celsius) + temp[1-4]_offset Temperature sensor correction offset (in millidegrees Celsius) + fan[1-8]_input Pump/fan speed (in RPM) / Flow speed (in dL/h) ++fan5_pulses Quadro flow sensor pulses + power[1-8]_input Pump/fan power (in micro Watts) + in[0-7]_input Pump/fan voltage (in milli Volts) + curr[1-8]_input Pump/fan current (in milli Amperes) +diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c +index 49d3f9876fe80..9cc10080160b0 100644 +--- a/drivers/hwmon/aquacomputer_d5next.c ++++ b/drivers/hwmon/aquacomputer_d5next.c +@@ -136,6 +136,7 @@ static u8 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 }; + + /* Control report offsets for the Quadro */ + #define QUADRO_TEMP_CTRL_OFFSET 0xA ++#define QUADRO_FLOW_PULSES_CTRL_OFFSET 0x6 + static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 }; /* Fan speed offsets (0-100%) */ + + /* Specs of High Flow Next flow sensor */ +@@ -303,6 +304,7 @@ struct aqc_data { + u16 temp_ctrl_offset; + u16 power_cycle_count_offset; + u8 flow_sensor_offset; ++ u8 flow_pulses_ctrl_offset; + + /* General info, same across all devices */ + u32 serial_number[2]; +@@ -461,20 +463,34 @@ static umode_t aqc_is_visible(const void *data, enum hwmon_sensor_types type, u3 + } + break; + case hwmon_fan: +- switch (priv->kind) { +- case highflownext: +- /* Special case to support flow sensor, water quality and conductivity */ +- if (channel < 3) +- return 0444; ++ switch (attr) { ++ case hwmon_fan_input: ++ case hwmon_fan_label: ++ switch (priv->kind) { ++ case highflownext: ++ /* Special case to support flow sensor, water quality ++ * and conductivity ++ */ ++ if (channel < 3) ++ return 0444; ++ break; ++ case quadro: ++ /* Special case to support flow sensor */ ++ if (channel < priv->num_fans + 1) ++ return 0444; ++ break; ++ default: ++ if (channel < priv->num_fans) ++ return 0444; ++ break; ++ } + break; +- case quadro: +- /* Special case to support flow sensor */ +- if (channel < priv->num_fans + 1) +- return 0444; ++ case hwmon_fan_pulses: ++ /* Special case for Quadro flow sensor */ ++ if (priv->kind == quadro && channel == priv->num_fans) ++ return 0644; + break; + default: +- if (channel < priv->num_fans) +- return 0444; + break; + } + break; +@@ -552,7 +568,18 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, + } + break; + case hwmon_fan: +- *val = priv->speed_input[channel]; ++ switch (attr) { ++ case hwmon_fan_input: ++ *val = priv->speed_input[channel]; ++ break; ++ case hwmon_fan_pulses: ++ ret = aqc_get_ctrl_val(priv, priv->flow_pulses_ctrl_offset, val); ++ if (ret < 0) ++ return ret; ++ break; ++ default: ++ break; ++ } + break; + case hwmon_power: + *val = priv->power_input[channel]; +@@ -632,6 +659,18 @@ static int aqc_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, + return -EOPNOTSUPP; + } + break; ++ case hwmon_fan: ++ switch (attr) { ++ case hwmon_fan_pulses: ++ val = clamp_val(val, 10, 1000); ++ ret = aqc_set_ctrl_val(priv, priv->flow_pulses_ctrl_offset, val); ++ if (ret < 0) ++ return ret; ++ break; ++ default: ++ break; ++ } ++ break; + case hwmon_pwm: + switch (attr) { + case hwmon_pwm_input: +@@ -691,7 +730,7 @@ static const struct hwmon_channel_info *aqc_info[] = { + HWMON_F_INPUT | HWMON_F_LABEL, + HWMON_F_INPUT | HWMON_F_LABEL, + HWMON_F_INPUT | HWMON_F_LABEL, +- HWMON_F_INPUT | HWMON_F_LABEL, ++ HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_PULSES, + HWMON_F_INPUT | HWMON_F_LABEL, + HWMON_F_INPUT | HWMON_F_LABEL, + HWMON_F_INPUT | HWMON_F_LABEL), +@@ -1000,6 +1039,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id) + priv->buffer_size = QUADRO_CTRL_REPORT_SIZE; + + priv->flow_sensor_offset = QUADRO_FLOW_SENSOR_OFFSET; ++ priv->flow_pulses_ctrl_offset = QUADRO_FLOW_PULSES_CTRL_OFFSET; + priv->power_cycle_count_offset = QUADRO_POWER_CYCLES; + + priv->temp_label = label_temp_sensors; +-- +cgit + + +From 0cd3ba682ae27cbe17c41f85b8e6db6da38296b2 Mon Sep 17 00:00:00 2001 +From: Joaquín Ignacio Aramendía +Date: Mon, 28 Nov 2022 15:52:06 -0300 +Subject: hwmon: (oxp-sensors) Fix pwm reading +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +PWM reading is only 1 register long. + +Signed-off-by: Joaquín Ignacio Aramendía +Link: https://lore.kernel.org/r/20221128185206.212022-1-samsagax@gmail.com +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/oxp-sensors.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/oxp-sensors.c b/drivers/hwmon/oxp-sensors.c +index c04277676b727..f84ec8f8eda91 100644 +--- a/drivers/hwmon/oxp-sensors.c ++++ b/drivers/hwmon/oxp-sensors.c +@@ -158,7 +158,7 @@ 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, 2, val); ++ ret = read_from_ec(OXP_SENSOR_PWM_REG, 1, val); + if (ret) + return ret; + if (board == oxp_mini_amd) +-- +cgit + + +From 4e6104b1e70020ad500f0fab7238898dd2ea2a38 Mon Sep 17 00:00:00 2001 +From: ye xingchen +Date: Thu, 1 Dec 2022 11:30:31 +0800 +Subject: hwmon: use sysfs_emit() to instead of scnprintf() + +Replace the open-code with sysfs_emit() to simplify the code. + +Signed-off-by: ye xingchen +Link: https://lore.kernel.org/r/202212011130317080061@zte.com.cn +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/ds1621.c | 2 +- + drivers/hwmon/lm73.c | 6 +++--- + drivers/hwmon/sht3x.c | 12 ++++++------ + 3 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c +index 0886abf6ebab1..e803d6393b9e5 100644 +--- a/drivers/hwmon/ds1621.c ++++ b/drivers/hwmon/ds1621.c +@@ -269,7 +269,7 @@ static ssize_t update_interval_show(struct device *dev, + struct device_attribute *da, char *buf) + { + struct ds1621_data *data = dev_get_drvdata(dev); +- return scnprintf(buf, PAGE_SIZE, "%hu\n", data->update_interval); ++ return sysfs_emit(buf, "%hu\n", data->update_interval); + } + + static ssize_t update_interval_store(struct device *dev, +diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c +index 1346b3b3f4635..b6433ae2d75c3 100644 +--- a/drivers/hwmon/lm73.c ++++ b/drivers/hwmon/lm73.c +@@ -92,7 +92,7 @@ static ssize_t temp_show(struct device *dev, struct device_attribute *da, + /* use integer division instead of equivalent right shift to + guarantee arithmetic shift and preserve the sign */ + temp = (((s16) err) * 250) / 32; +- return scnprintf(buf, PAGE_SIZE, "%d\n", temp); ++ return sysfs_emit(buf, "%d\n", temp); + } + + static ssize_t convrate_store(struct device *dev, struct device_attribute *da, +@@ -137,7 +137,7 @@ static ssize_t convrate_show(struct device *dev, struct device_attribute *da, + int res; + + res = (data->ctrl & LM73_CTRL_RES_MASK) >> LM73_CTRL_RES_SHIFT; +- return scnprintf(buf, PAGE_SIZE, "%hu\n", lm73_convrates[res]); ++ return sysfs_emit(buf, "%hu\n", lm73_convrates[res]); + } + + static ssize_t maxmin_alarm_show(struct device *dev, +@@ -154,7 +154,7 @@ static ssize_t maxmin_alarm_show(struct device *dev, + data->ctrl = ctrl; + mutex_unlock(&data->lock); + +- return scnprintf(buf, PAGE_SIZE, "%d\n", (ctrl >> attr->index) & 1); ++ return sysfs_emit(buf, "%d\n", (ctrl >> attr->index) & 1); + + abort: + mutex_unlock(&data->lock); +diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c +index 3f279aa1cee5e..8305e44d9ab20 100644 +--- a/drivers/hwmon/sht3x.c ++++ b/drivers/hwmon/sht3x.c +@@ -320,7 +320,7 @@ static ssize_t temp1_limit_show(struct device *dev, + u8 index = to_sensor_dev_attr(attr)->index; + int temperature_limit = data->temperature_limits[index]; + +- return scnprintf(buf, PAGE_SIZE, "%d\n", temperature_limit); ++ return sysfs_emit(buf, "%d\n", temperature_limit); + } + + static ssize_t humidity1_limit_show(struct device *dev, +@@ -331,7 +331,7 @@ static ssize_t humidity1_limit_show(struct device *dev, + u8 index = to_sensor_dev_attr(attr)->index; + u32 humidity_limit = data->humidity_limits[index]; + +- return scnprintf(buf, PAGE_SIZE, "%u\n", humidity_limit); ++ return sysfs_emit(buf, "%u\n", humidity_limit); + } + + /* +@@ -483,7 +483,7 @@ static ssize_t temp1_alarm_show(struct device *dev, + if (ret) + return ret; + +- return scnprintf(buf, PAGE_SIZE, "%d\n", !!(buffer[0] & 0x04)); ++ return sysfs_emit(buf, "%d\n", !!(buffer[0] & 0x04)); + } + + static ssize_t humidity1_alarm_show(struct device *dev, +@@ -498,7 +498,7 @@ static ssize_t humidity1_alarm_show(struct device *dev, + if (ret) + return ret; + +- return scnprintf(buf, PAGE_SIZE, "%d\n", !!(buffer[0] & 0x08)); ++ return sysfs_emit(buf, "%d\n", !!(buffer[0] & 0x08)); + } + + static ssize_t heater_enable_show(struct device *dev, +@@ -513,7 +513,7 @@ static ssize_t heater_enable_show(struct device *dev, + if (ret) + return ret; + +- return scnprintf(buf, PAGE_SIZE, "%d\n", !!(buffer[0] & 0x20)); ++ return sysfs_emit(buf, "%d\n", !!(buffer[0] & 0x20)); + } + + static ssize_t heater_enable_store(struct device *dev, +@@ -550,7 +550,7 @@ static ssize_t update_interval_show(struct device *dev, + { + struct sht3x_data *data = dev_get_drvdata(dev); + +- return scnprintf(buf, PAGE_SIZE, "%u\n", ++ return sysfs_emit(buf, "%u\n", + mode_to_update_interval[data->mode]); + } + +-- +cgit + + +From 688fcd047ef0f0aeee16d0fefaff065fa69eb642 Mon Sep 17 00:00:00 2001 +From: Armin Wolf +Date: Wed, 30 Nov 2022 19:34:18 +0100 +Subject: hwmon: (dell-smm) Move error message to make probing silent + +If dell-smm-hwmon loads on unsupported hardware like the +Dell XPS 17 9710, an error message is printed. +This might confuse users, as drivers are expected to be +silent if no supported hardware is found. +Reorder the error message so its only printed when the +driver is loaded with the "force" option being set. +Also reword the error message slightly. + +Tested on a Dell Inspiron 3505. + +Signed-off-by: Armin Wolf +Link: https://lore.kernel.org/r/20221130183418.357246-1-W_Armin@gmx.de +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/dell-smm-hwmon.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c +index 1572b54160158..7ac778aedc68d 100644 +--- a/drivers/hwmon/dell-smm-hwmon.c ++++ b/drivers/hwmon/dell-smm-hwmon.c +@@ -1447,9 +1447,10 @@ static int __init i8k_init(void) + */ + if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) && + i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) { +- pr_err("unable to get SMM Dell signature\n"); + if (!force) + return -ENODEV; ++ ++ pr_err("Unable to get Dell SMM signature\n"); + } + + dell_smm_device = platform_create_bundle(&dell_smm_driver, dell_smm_probe, NULL, 0, NULL, +-- +cgit + + +From 4d50591ebf60ccf79380fff3a4c23659c61c482f Mon Sep 17 00:00:00 2001 +From: Xingjiang Qiao +Date: Tue, 6 Dec 2022 13:53:30 +0800 +Subject: hwmon: (emc2305) fix unable to probe emc2301/2/3 + +The definitions of 'EMC2305_REG_PRODUCT_ID' and 'EMC2305_REG_DEVICE' are +both '0xfd', they actually return the same value, but the values returned +by emc2301/2/3/5 are different, so probe emc2301/2/3 will fail, This patch +fixes that. + +Signed-off-by: Xingjiang Qiao +Link: https://lore.kernel.org/r/20221206055331.170459-1-nanpuyue@gmail.com +Fixes: 0d8400c5a2ce1 ("hwmon: (emc2305) add support for EMC2301/2/3/5 RPM-based PWM Fan Speed Controller.") +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/emc2305.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/hwmon/emc2305.c b/drivers/hwmon/emc2305.c +index f222fcf3b6aa1..232238e3231b0 100644 +--- a/drivers/hwmon/emc2305.c ++++ b/drivers/hwmon/emc2305.c +@@ -16,7 +16,6 @@ static const unsigned short + emc2305_normal_i2c[] = { 0x27, 0x2c, 0x2d, 0x2e, 0x2f, 0x4c, 0x4d, I2C_CLIENT_END }; + + #define EMC2305_REG_DRIVE_FAIL_STATUS 0x27 +-#define EMC2305_REG_DEVICE 0xfd + #define EMC2305_REG_VENDOR 0xfe + #define EMC2305_FAN_MAX 0xff + #define EMC2305_FAN_MIN 0x00 +@@ -524,7 +523,7 @@ static int emc2305_probe(struct i2c_client *client) + struct device *dev = &client->dev; + struct emc2305_data *data; + struct emc2305_platform_data *pdata; +- int vendor, device; ++ int vendor; + int ret; + int i; + +@@ -535,10 +534,6 @@ static int emc2305_probe(struct i2c_client *client) + if (vendor != EMC2305_VENDOR) + return -ENODEV; + +- device = i2c_smbus_read_byte_data(client, EMC2305_REG_DEVICE); +- if (device != EMC2305_DEVICE) +- return -ENODEV; +- + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; +-- +cgit + + +From 364ffd2537c44cb6914ff5669153f4a86fffad29 Mon Sep 17 00:00:00 2001 +From: Xingjiang Qiao +Date: Tue, 6 Dec 2022 13:53:31 +0800 +Subject: hwmon: (emc2305) fix pwm never being able to set lower + +There are fields 'last_hwmon_state' and 'last_thermal_state' in the +structure 'emc2305_cdev_data', which respectively store the cooling state +set by the 'hwmon' and 'thermal' subsystem, and the driver author hopes +that if the state set by 'hwmon' is lower than the value set by 'thermal', +the driver will just save it without actually setting the pwm. Currently, +the 'last_thermal_state' also be updated by 'hwmon', which will cause the +cooling state to never be set to a lower value. This patch fixes that. + +Signed-off-by: Xingjiang Qiao +Link: https://lore.kernel.org/r/20221206055331.170459-2-nanpuyue@gmail.com +Fixes: 0d8400c5a2ce1 ("hwmon: (emc2305) add support for EMC2301/2/3/5 RPM-based PWM Fan Speed Controller.") +[groeck: renamed emc2305_set_cur_state_shim -> __emc2305_set_cur_state] +Signed-off-by: Guenter Roeck +--- + drivers/hwmon/emc2305.c | 37 ++++++++++++++++++++++++------------- + 1 file changed, 24 insertions(+), 13 deletions(-) + +diff --git a/drivers/hwmon/emc2305.c b/drivers/hwmon/emc2305.c +index 232238e3231b0..6ad055e5868e6 100644 +--- a/drivers/hwmon/emc2305.c ++++ b/drivers/hwmon/emc2305.c +@@ -171,22 +171,12 @@ static int emc2305_get_max_state(struct thermal_cooling_device *cdev, unsigned l + return 0; + } + +-static int emc2305_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) ++static int __emc2305_set_cur_state(struct emc2305_data *data, int cdev_idx, unsigned long state) + { +- int cdev_idx, ret; +- struct emc2305_data *data = cdev->devdata; ++ int ret; + struct i2c_client *client = data->client; + u8 val, i; + +- if (state > data->max_state) +- return -EINVAL; +- +- cdev_idx = emc2305_get_cdev_idx(cdev); +- if (cdev_idx < 0) +- return cdev_idx; +- +- /* Save thermal state. */ +- data->cdev_data[cdev_idx].last_thermal_state = state; + state = max_t(unsigned long, state, data->cdev_data[cdev_idx].last_hwmon_state); + + val = EMC2305_PWM_STATE2DUTY(state, data->max_state, EMC2305_FAN_MAX); +@@ -211,6 +201,27 @@ static int emc2305_set_cur_state(struct thermal_cooling_device *cdev, unsigned l + return 0; + } + ++static int emc2305_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) ++{ ++ int cdev_idx, ret; ++ struct emc2305_data *data = cdev->devdata; ++ ++ if (state > data->max_state) ++ return -EINVAL; ++ ++ cdev_idx = emc2305_get_cdev_idx(cdev); ++ if (cdev_idx < 0) ++ return cdev_idx; ++ ++ /* Save thermal state. */ ++ data->cdev_data[cdev_idx].last_thermal_state = state; ++ ret = __emc2305_set_cur_state(data, cdev_idx, state); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ + static const struct thermal_cooling_device_ops emc2305_cooling_ops = { + .get_max_state = emc2305_get_max_state, + .get_cur_state = emc2305_get_cur_state, +@@ -401,7 +412,7 @@ emc2305_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int ch + */ + if (data->cdev_data[cdev_idx].last_hwmon_state >= + data->cdev_data[cdev_idx].last_thermal_state) +- return emc2305_set_cur_state(data->cdev_data[cdev_idx].cdev, ++ return __emc2305_set_cur_state(data, cdev_idx, + data->cdev_data[cdev_idx].last_hwmon_state); + return 0; + } +-- +cgit + diff --git a/packages/kernel/linux/patches/X86_64/002-ayaneo-sensors.patch b/packages/kernel/linux/patches/X86_64/002-ayaneo-sensors.patch new file mode 100644 index 000000000..fd0128646 --- /dev/null +++ b/packages/kernel/linux/patches/X86_64/002-ayaneo-sensors.patch @@ -0,0 +1,246 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id EEFD6C4332F + for ; Wed, 14 Dec 2022 15:48:10 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S238903AbiLNPsJ (ORCPT ); + Wed, 14 Dec 2022 10:48:09 -0500 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50528 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S238850AbiLNPrd (ORCPT + ); + Wed, 14 Dec 2022 10:47:33 -0500 +Received: from mail-oo1-xc34.google.com (mail-oo1-xc34.google.com [IPv6:2607:f8b0:4864:20::c34]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BEC4A27FE6; + Wed, 14 Dec 2022 07:47:17 -0800 (PST) +Received: by mail-oo1-xc34.google.com with SMTP id f184-20020a4a58c1000000b004a3c01646a0so2310106oob.12; + Wed, 14 Dec 2022 07:47:17 -0800 (PST) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20210112; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:from:to:cc:subject:date + :message-id:reply-to; + bh=MB+cjJ0APVSPLYKSXokJmYfJJzb5hyUnGFn3uvrOCQs=; + b=VknEFKrJmu9Pr/B/X9LlnnHGqp1nZzP9w+qqAkBG+UBa5JNhLLcWpOlBltqY/z9/7+ + yd/oHDf6H8tbtxDUCWGQbI2O9B7Cq+P/cB0vV0cIuUDigV1N/ZMx5dtjATaUcwo+Zrjl + pmdtVyaS8CoZuYBs9Kqfs1DR/B5acRfI25qWN6pkBgKx8b1DrswACaCx29NwOzKrtjYj + GMdHgzxZIefyoePCFeX3IxhD5rOIoyFRtUMWQ3yPdmM/KVlwUPT8od2t7PxnIcfW4PLG + 3ztosdgEWlInX6BtPzv4V7SZx3DXs5KGg3hQsA93dc30TbVwo8p0iGSxREgbbRITpz74 + IU+g== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20210112; + h=content-transfer-encoding:mime-version:references:in-reply-to + :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc + :subject:date:message-id:reply-to; + bh=MB+cjJ0APVSPLYKSXokJmYfJJzb5hyUnGFn3uvrOCQs=; + b=gJSFFXFO0IF56KU5C3PhOBBKUC5CCCJX0g1n6EL4TWuaRxI6spTFWE1dC9LqtvM4uh + bkdrpXOGgHSCGK7ZtQiqjwb7SrmbgC4HgikinJc/bS0fbF/fFrpmVSF+OKaz2JeJNJAt + 7Veor+PQn8vK91kTmKT6J9oJ8OZ3EKPmjTgdhDBI2+Fy4NO7U+tBPurecFA7M3yu+gGH + PDkKs5qW48VfmpzovIyvDw1bVWwUp+AIj6W0ht9AIKKsWaNbF5LsshLyRF4TR34Q00r1 + MBWR3ysNw0cAMO/HN7ESaTVCimbcZrACYh9gUxnhbF4CdgTOQo625JjsESmqhVEvjseC + QFFA== +X-Gm-Message-State: ANoB5plWAiyiI7vMPOkGQW+T6H38IIy8U9DdPTldcBUkaNvcBJ+RiUqa + fWsx0XmVox36DHMI8L5ivtk= +X-Google-Smtp-Source: AA0mqf4haL+cQbuRxCnem1h+c5sf2MFQ7DNmFMcC4n1xjH0BM9e9aVMOR8ADEbdobsXs41hj7MitqA== +X-Received: by 2002:a4a:e511:0:b0:4a0:9e4e:11ac with SMTP id r17-20020a4ae511000000b004a09e4e11acmr11549450oot.7.1671032837009; + Wed, 14 Dec 2022 07:47:17 -0800 (PST) +Received: from localhost.localdomain (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) + by smtp.gmail.com with ESMTPSA id v9-20020a4ae049000000b004a3543fbfbbsm2386367oos.14.2022.12.14.07.47.16 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Wed, 14 Dec 2022 07:47:16 -0800 (PST) +From: "Derek J. Clark" +To: linux@roeck-us.net +Cc: "Derek J. Clark" , + Jean Delvare , + Jonathan Corbet , + =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?= + , linux-hwmon@vger.kernel.org, + linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org +Subject: [PATCH v2] hwmon: (oxp-sensors) Add AYANEO AIR and AIR Pro +Date: Wed, 14 Dec 2022 07:47:13 -0800 +Message-Id: <20221214154713.100648-1-derekjohn.clark@gmail.com> +X-Mailer: git-send-email 2.38.1 +In-Reply-To: +References: +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: +X-Mailing-List: linux-kernel@vger.kernel.org + +Add support for the AYANEO AIR and AYANEO AIR Pro models of handheld +devices. These devices use the same EC registers and logic as the One X +Player mini AMD. Previous AYANEO models are not supported as they use a +different EC and do not have the necessary fan speed write enable and +setting registers. Tihe driver is tested on Aya Neo AIR while AIR Pro +model EC functionality and DMI data were verified using command line +tools by another user. + +The added devices are: +- AYANEO AIR (AMD 5560U) +- AYANEO AIR Pro (AMD 5560U) +- AYANEO AIR Pro (AMD 5825U) + +Signed-off-by: Derek J. Clark +--- + Documentation/hwmon/oxp-sensors.rst | 19 ++++++---- + MAINTAINERS | 1 + + drivers/hwmon/oxp-sensors.c | 54 ++++++++++++++++++++++++----- + 3 files changed, 59 insertions(+), 15 deletions(-) + +diff --git a/Documentation/hwmon/oxp-sensors.rst b/Documentation/hwmon/oxp-sensors.rst +index 39c588ec5c50..a53c961065b2 100644 +--- a/Documentation/hwmon/oxp-sensors.rst ++++ b/Documentation/hwmon/oxp-sensors.rst +@@ -3,18 +3,21 @@ + Kernel driver oxp-sensors + ========================= + +-Author: ++Authors: ++ - Derek John Clark + - Joaquín Ignacio Aramendía + +-Description: ++Description + ------------ + +-One X Player devices from One Netbook provide fan readings and fan control +-through its Embedded Controller. ++Handheld devices from One Netbook and Aya Neo provide fan readings and fan ++control through their embedded controllers. + +-Currently only supports AMD boards from the One X Player and AOK ZOE lineup. +-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. ++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 usable as the EC model ++is different and do not appear to have manual control capabiltities. + + Supported devices + ----------------- +@@ -22,6 +25,8 @@ Supported devices + Currently the driver supports the following handhelds: + + - AOK ZOE A1 ++ - Aya Neo AIR ++ - Aya Neo AIR Pro + - OneXPlayer AMD + - OneXPlayer mini AMD + - OneXPlayer mini AMD PRO +diff --git a/MAINTAINERS b/MAINTAINERS +index 90220659206c..8bce95170f12 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -15346,6 +15346,7 @@ F: drivers/mtd/nand/onenand/ + F: include/linux/mtd/onenand*.h + + ONEXPLAYER FAN DRIVER ++M: Derek John Clark + M: Joaquín Ignacio Aramendía + L: linux-hwmon@vger.kernel.org + S: Maintained +diff --git a/drivers/hwmon/oxp-sensors.c b/drivers/hwmon/oxp-sensors.c +index f84ec8f8eda9..7adc0199ea66 100644 +--- a/drivers/hwmon/oxp-sensors.c ++++ b/drivers/hwmon/oxp-sensors.c +@@ -1,12 +1,12 @@ + // SPDX-License-Identifier: GPL-2.0+ + /* +- * Platform driver for OXP Handhelds that expose fan reading and control +- * via hwmon sysfs. ++ * Platform driver for Handhelds that expose fan reading and control via ++ * hwmon sysfs. + * +- * Old boards have the same DMI strings and they are told appart by the +- * boot cpu vendor (Intel/AMD). Currently only AMD boards are supported +- * but the code is made to be simple to add other handheld boards in the +- * future. ++ * Old OXP boards have the same DMI strings and they are told appart by ++ * the boot cpu vendor (Intel/AMD). Currently only AMD boards are ++ * supported but the code is made to be simple to add other handheld ++ * boards in the future. + * 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 + * scaled to accommodate for that. Newer boards like the mini PRO and +@@ -42,6 +42,8 @@ static bool unlock_global_acpi_lock(void) + + enum oxp_board { + aok_zoe_a1 = 1, ++ aya_neo_air, ++ aya_neo_air_pro, + oxp_mini_amd, + oxp_mini_amd_pro, + }; +@@ -60,6 +62,20 @@ static const struct dmi_system_id dmi_table[] = { + }, + .driver_data = (void *) &(enum oxp_board) {aok_zoe_a1}, + }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR"), ++ }, ++ .driver_data = (void *) &(enum oxp_board) {aya_neo_air}, ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), ++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR Pro"), ++ }, ++ .driver_data = (void *) &(enum oxp_board) {aya_neo_air_pro}, ++ }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), +@@ -161,8 +177,19 @@ static int oxp_platform_read(struct device *dev, enum hwmon_sensor_types type, + ret = read_from_ec(OXP_SENSOR_PWM_REG, 1, val); + if (ret) + return ret; +- if (board == oxp_mini_amd) ++ switch (board) { ++ case aok_zoe_a1: ++ break; ++ case aya_neo_air: ++ case aya_neo_air_pro: ++ case oxp_mini_amd: + *val = (*val * 255) / 100; ++ break; ++ case oxp_mini_amd_pro: ++ break; ++ default: ++ break; ++ } + return 0; + case hwmon_pwm_enable: + return read_from_ec(OXP_SENSOR_PWM_ENABLE_REG, 1, val); +@@ -191,8 +218,19 @@ static int oxp_platform_write(struct device *dev, enum hwmon_sensor_types type, + case hwmon_pwm_input: + if (val < 0 || val > 255) + return -EINVAL; +- if (board == oxp_mini_amd) ++ switch (board) { ++ case aok_zoe_a1: ++ break; ++ case aya_neo_air: ++ case aya_neo_air_pro: ++ case oxp_mini_amd: + val = (val * 100) / 255; ++ break; ++ case oxp_mini_amd_pro: ++ break; ++ default: ++ break; ++ } + return write_to_ec(dev, OXP_SENSOR_PWM_REG, val); + default: + break; +-- +2.38.1 + diff --git a/packages/kernel/linux/patches/X86_64/patch-6.1-rc7-rt5.patch b/packages/kernel/linux/patches/X86_64/003-patch-6.1-rc7-rt5.patch similarity index 100% rename from packages/kernel/linux/patches/X86_64/patch-6.1-rc7-rt5.patch rename to packages/kernel/linux/patches/X86_64/003-patch-6.1-rc7-rt5.patch diff --git a/packages/kernel/linux/patches/X86_64/steam-deck-controller.patch b/packages/kernel/linux/patches/X86_64/004-steam-deck-controller.patch similarity index 100% rename from packages/kernel/linux/patches/X86_64/steam-deck-controller.patch rename to packages/kernel/linux/patches/X86_64/004-steam-deck-controller.patch diff --git a/packages/sysutils/autostart/package.mk b/packages/sysutils/autostart/package.mk new file mode 100644 index 000000000..7855f10dc --- /dev/null +++ b/packages/sysutils/autostart/package.mk @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2020-present Fewtarius + +PKG_NAME="autostart" +PKG_VERSION="$(date +%Y%m%d)" +PKG_ARCH="any" +PKG_LICENSE="apache2" +PKG_SITE="" +PKG_URL="" +PKG_DEPENDS_TARGET="toolchain" +PKG_SHORTDESC="Autostart is a systemd helper that starts/configures device specific services and parameters." +PKG_IS_ADDON="no" +PKG_AUTORECONF="no" +PKG_TOOLCHAIN="manual" + +makeinstall_target() { + mkdir -p ${INSTALL}/usr/bin + cp ${PKG_DIR}/sources/autostart ${INSTALL}/usr/bin + mkdir -p ${INSTALL}/usr/lib/autostart/common + mkdir -p ${INSTALL}/usr/lib/autostart/daemons + cp ${PKG_DIR}/sources/common/* ${INSTALL}/usr/lib/autostart/common + cp ${PKG_DIR}/sources/daemons/* ${INSTALL}/usr/lib/autostart/daemons + chmod -R 0755 ${INSTALL}/usr/lib/autostart ${INSTALL}/usr/bin/autostart + mkdir -p ${INSTALL}/usr/lib/autostart/quirks + cp -r ${PKG_DIR}/sources/quirks/* ${INSTALL}/usr/lib/autostart/quirks +} diff --git a/packages/jelos/sources/autostart/autostart b/packages/sysutils/autostart/sources/autostart similarity index 100% rename from packages/jelos/sources/autostart/autostart rename to packages/sysutils/autostart/sources/autostart diff --git a/packages/jelos/sources/autostart/common/001-setup b/packages/sysutils/autostart/sources/common/001-setup similarity index 100% rename from packages/jelos/sources/autostart/common/001-setup rename to packages/sysutils/autostart/sources/common/001-setup diff --git a/packages/jelos/sources/autostart/common/002-kernel b/packages/sysutils/autostart/sources/common/002-kernel similarity index 100% rename from packages/jelos/sources/autostart/common/002-kernel rename to packages/sysutils/autostart/sources/common/002-kernel diff --git a/packages/jelos/sources/autostart/common/003-logging b/packages/sysutils/autostart/sources/common/003-logging similarity index 100% rename from packages/jelos/sources/autostart/common/003-logging rename to packages/sysutils/autostart/sources/common/003-logging diff --git a/packages/jelos/sources/autostart/common/004-upgrade b/packages/sysutils/autostart/sources/common/004-upgrade similarity index 100% rename from packages/jelos/sources/autostart/common/004-upgrade rename to packages/sysutils/autostart/sources/common/004-upgrade diff --git a/packages/jelos/sources/autostart/common/005-alsa b/packages/sysutils/autostart/sources/common/005-alsa similarity index 100% rename from packages/jelos/sources/autostart/common/005-alsa rename to packages/sysutils/autostart/sources/common/005-alsa diff --git a/packages/jelos/sources/autostart/common/006-brightness b/packages/sysutils/autostart/sources/common/006-brightness similarity index 100% rename from packages/jelos/sources/autostart/common/006-brightness rename to packages/sysutils/autostart/sources/common/006-brightness diff --git a/packages/jelos/sources/autostart/common/007-rootpw b/packages/sysutils/autostart/sources/common/007-rootpw similarity index 100% rename from packages/jelos/sources/autostart/common/007-rootpw rename to packages/sysutils/autostart/sources/common/007-rootpw diff --git a/packages/jelos/sources/autostart/common/008-network b/packages/sysutils/autostart/sources/common/008-network similarity index 100% rename from packages/jelos/sources/autostart/common/008-network rename to packages/sysutils/autostart/sources/common/008-network diff --git a/packages/jelos/sources/autostart/common/009-bluetooth b/packages/sysutils/autostart/sources/common/009-bluetooth similarity index 100% rename from packages/jelos/sources/autostart/common/009-bluetooth rename to packages/sysutils/autostart/sources/common/009-bluetooth diff --git a/packages/jelos/sources/autostart/common/010-uimode b/packages/sysutils/autostart/sources/common/010-uimode similarity index 100% rename from packages/jelos/sources/autostart/common/010-uimode rename to packages/sysutils/autostart/sources/common/010-uimode diff --git a/packages/jelos/sources/autostart/common/098-wireguard b/packages/sysutils/autostart/sources/common/098-wireguard similarity index 100% rename from packages/jelos/sources/autostart/common/098-wireguard rename to packages/sysutils/autostart/sources/common/098-wireguard diff --git a/packages/jelos/sources/autostart/common/099-networkservices b/packages/sysutils/autostart/sources/common/099-networkservices similarity index 100% rename from packages/jelos/sources/autostart/common/099-networkservices rename to packages/sysutils/autostart/sources/common/099-networkservices diff --git a/packages/jelos/sources/autostart/daemons/001-ssh b/packages/sysutils/autostart/sources/daemons/001-ssh similarity index 100% rename from packages/jelos/sources/autostart/daemons/001-ssh rename to packages/sysutils/autostart/sources/daemons/001-ssh diff --git a/packages/jelos/sources/autostart/daemons/002-samba b/packages/sysutils/autostart/sources/daemons/002-samba similarity index 100% rename from packages/jelos/sources/autostart/daemons/002-samba rename to packages/sysutils/autostart/sources/daemons/002-samba diff --git a/packages/jelos/sources/autostart/daemons/003-wait-time-sync b/packages/sysutils/autostart/sources/daemons/003-wait-time-sync similarity index 100% rename from packages/jelos/sources/autostart/daemons/003-wait-time-sync rename to packages/sysutils/autostart/sources/daemons/003-wait-time-sync diff --git a/packages/jelos/sources/autostart/daemons/004-tailscaled b/packages/sysutils/autostart/sources/daemons/004-tailscaled similarity index 100% rename from packages/jelos/sources/autostart/daemons/004-tailscaled rename to packages/sysutils/autostart/sources/daemons/004-tailscaled diff --git a/packages/jelos/sources/autostart/daemons/005-fstrim b/packages/sysutils/autostart/sources/daemons/005-fstrim similarity index 100% rename from packages/jelos/sources/autostart/daemons/005-fstrim rename to packages/sysutils/autostart/sources/daemons/005-fstrim diff --git a/packages/jelos/sources/autostart/quirks/ATARI VCS 800 Onyx/001-audio b/packages/sysutils/autostart/sources/quirks/ATARI VCS 800 Onyx/001-audio similarity index 100% rename from packages/jelos/sources/autostart/quirks/ATARI VCS 800 Onyx/001-audio rename to packages/sysutils/autostart/sources/quirks/ATARI VCS 800 Onyx/001-audio diff --git a/packages/jelos/sources/autostart/quirks/AYANEO AIR Pro b/packages/sysutils/autostart/sources/quirks/AYANEO AIR Pro similarity index 100% rename from packages/jelos/sources/autostart/quirks/AYANEO AIR Pro rename to packages/sysutils/autostart/sources/quirks/AYANEO AIR Pro diff --git a/packages/jelos/sources/autostart/quirks/AYANEO AIR/001-audio b/packages/sysutils/autostart/sources/quirks/AYANEO AIR/001-audio similarity index 66% rename from packages/jelos/sources/autostart/quirks/AYANEO AIR/001-audio rename to packages/sysutils/autostart/sources/quirks/AYANEO AIR/001-audio index d057ca347..b8e252f6d 100644 --- a/packages/jelos/sources/autostart/quirks/AYANEO AIR/001-audio +++ b/packages/sysutils/autostart/sources/quirks/AYANEO AIR/001-audio @@ -16,3 +16,8 @@ then set-audio esset "Master" reboot fi + +### Disables speaker output when headphones are connected. +alsactl restore -f /storage/.config/asound.state +/usr/bin/amixer -c 1 sset "Auto-Mute Mode" Enabled +alsactl store -f /storage/.config/asound.state diff --git a/packages/sysutils/autostart/sources/quirks/AYANEO AIR/002-fancontrol b/packages/sysutils/autostart/sources/quirks/AYANEO AIR/002-fancontrol new file mode 100644 index 000000000..db2e6d458 --- /dev/null +++ b/packages/sysutils/autostart/sources/quirks/AYANEO AIR/002-fancontrol @@ -0,0 +1,18 @@ +#!/bin/bash +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2021-present Fewtarius (https://github.com/fewtarius) + +. /etc/profile + +if [ ! -d "/storage/.config/profile.d" ] +then + mkdir -p /storage/.config/profile.d +fi + +cat </storage/.config/profile.d/002-fancontrol +DEVICE_HAS_FAN=true +DEVICE_PWM_FAN="/sys/devices/platform/oxp-platform/hwmon/hwmon4/pwm1" +DEVICE_TEMP_SENSOR="/sys/class/hwmon/*/temp1_input" +echo 1 >/sys/devices/platform/oxp-platform/hwmon/hwmon4/pwm1_enable +EOF + diff --git a/packages/jelos/sources/autostart/quirks/Anbernic RG351MP b/packages/sysutils/autostart/sources/quirks/Anbernic RG351MP similarity index 100% rename from packages/jelos/sources/autostart/quirks/Anbernic RG351MP rename to packages/sysutils/autostart/sources/quirks/Anbernic RG351MP diff --git a/packages/jelos/sources/autostart/quirks/Anbernic RG351P/001-hardwareinit b/packages/sysutils/autostart/sources/quirks/Anbernic RG351P/001-hardwareinit similarity index 100% rename from packages/jelos/sources/autostart/quirks/Anbernic RG351P/001-hardwareinit rename to packages/sysutils/autostart/sources/quirks/Anbernic RG351P/001-hardwareinit diff --git a/packages/jelos/sources/autostart/quirks/Anbernic RG351V b/packages/sysutils/autostart/sources/quirks/Anbernic RG351V similarity index 100% rename from packages/jelos/sources/autostart/quirks/Anbernic RG351V rename to packages/sysutils/autostart/sources/quirks/Anbernic RG351V diff --git a/packages/jelos/sources/autostart/quirks/Anbernic RG353P-M/001-hardwareinit b/packages/sysutils/autostart/sources/quirks/Anbernic RG353P-M/001-hardwareinit similarity index 100% rename from packages/jelos/sources/autostart/quirks/Anbernic RG353P-M/001-hardwareinit rename to packages/sysutils/autostart/sources/quirks/Anbernic RG353P-M/001-hardwareinit diff --git a/packages/jelos/sources/autostart/quirks/Anbernic RG353V b/packages/sysutils/autostart/sources/quirks/Anbernic RG353V similarity index 100% rename from packages/jelos/sources/autostart/quirks/Anbernic RG353V rename to packages/sysutils/autostart/sources/quirks/Anbernic RG353V diff --git a/packages/jelos/sources/autostart/quirks/Anbernic RG503 b/packages/sysutils/autostart/sources/quirks/Anbernic RG503 similarity index 100% rename from packages/jelos/sources/autostart/quirks/Anbernic RG503 rename to packages/sysutils/autostart/sources/quirks/Anbernic RG503 diff --git a/packages/jelos/sources/autostart/quirks/Anbernic RG552/001-hardwareinit b/packages/sysutils/autostart/sources/quirks/Anbernic RG552/001-hardwareinit similarity index 100% rename from packages/jelos/sources/autostart/quirks/Anbernic RG552/001-hardwareinit rename to packages/sysutils/autostart/sources/quirks/Anbernic RG552/001-hardwareinit diff --git a/packages/jelos/sources/autostart/quirks/Anbernic RG552/002-audiomixer b/packages/sysutils/autostart/sources/quirks/Anbernic RG552/002-audiomixer similarity index 100% rename from packages/jelos/sources/autostart/quirks/Anbernic RG552/002-audiomixer rename to packages/sysutils/autostart/sources/quirks/Anbernic RG552/002-audiomixer diff --git a/packages/jelos/sources/autostart/quirks/PowKiddy RGB20S/001-hardwareinit b/packages/sysutils/autostart/sources/quirks/PowKiddy RGB20S/001-hardwareinit similarity index 100% rename from packages/jelos/sources/autostart/quirks/PowKiddy RGB20S/001-hardwareinit rename to packages/sysutils/autostart/sources/quirks/PowKiddy RGB20S/001-hardwareinit diff --git a/packages/sysutils/busybox/scripts/init b/packages/sysutils/busybox/scripts/init index db53d8279..7f28ea948 100755 --- a/packages/sysutils/busybox/scripts/init +++ b/packages/sysutils/busybox/scripts/init @@ -485,17 +485,36 @@ load_splash() { if [ -z "${SPLASHIMAGE}" ]; then vres="$(fbset 2>/dev/null | awk '/geometry/ { print $3 }')" hres="$(fbset 2>/dev/null | awk '/geometry/ { print $2 }')" - + rotation="$(cat /sys/devices/virtual/graphics/fbcon/rotate)" # Test to determine if the display is rotated # and set the splash to suit. - if [ ${vres} -gt ${hres} ] + if [ ${vres} -gt ${hres} ] && \ + [ -e "/splash/splashl.png" ] then - RES="l" + SPLASHIMAGE="/splash/splashl.png" + elif [ ! -e "/splash/splashl.png" ] + then + ### When we don't define a splash + case ${rotation} in + 0) + SPLASHIMAGE="/splash/splash.png" + ;; + 1) + SPLASHIMAGE="/splash/splash_90.png" + ;; + 2) + SPLASHIMAGE="/splash/splash_180.png" + ;; + 3) + SPLASHIMAGE="/splash/splash_270.png" + ;; + esac + else + ### When we don't know what to do. + SPLASHIMAGE="/splash/splash.png" fi - SPLASHIMAGE="/splash/splash${RES}.png" - fi if [ -n "${SPLASHIMAGE}" -a -f "${SPLASHIMAGE}" ]; then diff --git a/packages/sysutils/sleep/package.mk b/packages/sysutils/sleep/package.mk index 445ec89b7..0341f02db 100644 --- a/packages/sysutils/sleep/package.mk +++ b/packages/sysutils/sleep/package.mk @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (C) 2020-present Fewtarius + PKG_NAME="sleep" PKG_VERSION="" PKG_SHA256="" @@ -10,10 +13,11 @@ PKG_LONGDESC="Sleep configuration" PKG_TOOLCHAIN="manual" makeinstall_target() { - mkdir -p $INSTALL/usr/config/sleep.conf.d - cp sleep.conf $INSTALL/usr/config/sleep.conf.d/sleep.conf + mkdir -p ${INSTALL}/usr/config/sleep.conf.d + cp sleep.conf ${INSTALL}/usr/config/sleep.conf.d/sleep.conf + cp modules.bad ${INSTALL}/usr/config - mkdir -p $INSTALL/usr/lib/systemd/system-sleep/ - cp sleep.sh $INSTALL/usr/lib/systemd/system-sleep/sleep - chmod +x $INSTALL/usr/lib/systemd/system-sleep/sleep + mkdir -p ${INSTALL}/usr/lib/systemd/system-sleep/ + cp sleep.sh ${INSTALL}/usr/lib/systemd/system-sleep/sleep + chmod +x ${INSTALL}/usr/lib/systemd/system-sleep/sleep } diff --git a/packages/sysutils/sleep/sources/modules.bad b/packages/sysutils/sleep/sources/modules.bad new file mode 100644 index 000000000..e19fcc338 --- /dev/null +++ b/packages/sysutils/sleep/sources/modules.bad @@ -0,0 +1,2 @@ +dwc2 +mt7921e diff --git a/packages/sysutils/sleep/sources/sleep.sh b/packages/sysutils/sleep/sources/sleep.sh index 597472510..18a183641 100755 --- a/packages/sysutils/sleep/sources/sleep.sh +++ b/packages/sysutils/sleep/sources/sleep.sh @@ -17,12 +17,6 @@ case $1 in nohup systemctl stop volume & >/dev/null 2>&1 fi - # RG351x devices are notorious for losing USB when they sleep. - if [[ "${HW_DEVICE}" =~ RG351 ]] || [[ "${HW_DEVICE}" =~ RGB20S ]] - then - modprobe -r dwc2 - fi - nohup alsactl store -f /storage/.config/asound.state >/dev/null 2>&1 if [ "$(get_setting bluetooth.enabled)" == "1" ] @@ -30,9 +24,13 @@ case $1 in nohup systemctl stop bluetooth >/dev/null 2>&1 fi - if [ "${DEVICE_WIFI_MODULE_SLEEPS}" = false ] + if [ -e "/usr/config/modules.bad" ] then - rmmod ${DEVICE_WIFI_MODULE} >/dev/null 2>&1 + for module in $(cat /usr/config/modules.bad) + do + echo ${module} >>/tmp/modules.load + modprobe -r ${module} + done fi wait @@ -42,9 +40,13 @@ case $1 in post) alsactl restore -f /storage/.config/asound.state - if [[ "${HW_DEVICE}" =~ RG351 ]] || [[ "${HW_DEVICE}" =~ RGB20S ]] + if [ -e "/tmp/modules.load" ] then - modprobe -i dwc2 + for module in $(cat /tmp/modules.load) + do + modprobe ${module} + done + rm -f /tmp/modules.load fi if [ "${DEVICE_FAKE_JACKSENSE}" == "true" ] @@ -57,11 +59,6 @@ case $1 in nohup systemctl start volume & >/dev/null 2>&1 fi - if [ "${DEVICE_WIFI_MODULE_SLEEPS}" = false ] - then - modprobe ${DEVICE_WIFI_MODULE} >/dev/null 2>&1 - fi - if [ "$(get_setting wifi.enabled)" == "1" ] then nohup wifictl reconnect & >/dev/null 2>&1 diff --git a/packages/sysutils/system-utils/sources/scripts/fancontrol b/packages/sysutils/system-utils/sources/scripts/fancontrol index f5ad06a1d..8677ed496 100755 --- a/packages/sysutils/system-utils/sources/scripts/fancontrol +++ b/packages/sysutils/system-utils/sources/scripts/fancontrol @@ -33,19 +33,19 @@ then TEMPS=(55000 45000 0) elif [ "${COOLING_PROFILE}" = "moderate" ] then - SPEEDS=(255 190 125 85) + SPEEDS=(255 192 128 96) TEMPS=(65000 55000 45000 0) else # Quiet. - SPEEDS=(255 127 85 0) - TEMPS=(75000 65000 55000 0) + SPEEDS=(255 192 128 96 64) + TEMPS=(70000 60000 55000 50000 0) fi fi while true do INDEX=0 - CPU_TEMP=$(printf "%.0f" $(cat /sys/devices/virtual/thermal/thermal_zone*/temp | awk '{ total += $1; count++ } END { print total/count }')) + CPU_TEMP=$(printf "%.0f" $(cat ${DEVICE_TEMP_SENSOR} | awk '{ total += $1; count++ } END { print total/count }')) $DEBUG && echo "CPU TEMP: ${CPU_TEMP}" 2>/dev/null for TEMP in "${TEMPS[@]}" do diff --git a/packages/sysutils/system-utils/system.d/fancontrol.service b/packages/sysutils/system-utils/system.d/fancontrol.service index 97802a2c2..f5a7c7d58 100644 --- a/packages/sysutils/system-utils/system.d/fancontrol.service +++ b/packages/sysutils/system-utils/system.d/fancontrol.service @@ -1,6 +1,5 @@ [Unit] Description=Simple Fan Control Service -ConditionPathExists=/sys/class/hwmon/hwmon1/pwm1 Before=jelos.target [Service] diff --git a/packages/ui/emulationstation/package.mk b/packages/ui/emulationstation/package.mk index 10cbe569e..2dc1b2602 100644 --- a/packages/ui/emulationstation/package.mk +++ b/packages/ui/emulationstation/package.mk @@ -3,7 +3,7 @@ # Copyright (C) 2020-present Fewtarius PKG_NAME="emulationstation" -PKG_VERSION="c14c587" +PKG_VERSION="6a24c96" PKG_GIT_CLONE_BRANCH="main" PKG_REV="1" PKG_ARCH="any" diff --git a/packages/ui/splash/package.mk b/packages/ui/splash/package.mk index f36f68f7d..a30600e90 100644 --- a/packages/ui/splash/package.mk +++ b/packages/ui/splash/package.mk @@ -36,7 +36,9 @@ mksplash() { convert ${SPLASH} -rotate 270 -quality 100 -background black -resize ${SPLASH_RESOLUTION} -gravity center -extent ${SPLASH_RESOLUTION} ${1}/splashl.png else cp ${SPLASH} ${1} - convert ${SPLASH} -rotate 90 -quality 100 -background black -gravity center ${1}/splashl.png + convert ${SPLASH} -rotate 90 -quality 100 -background black -gravity center ${1}/splash_90.png + convert ${SPLASH} -rotate 180 -quality 100 -background black -gravity center ${1}/splash_180.png + convert ${SPLASH} -rotate 270 -quality 100 -background black -gravity center ${1}/splash_270.png fi } diff --git a/projects/PC/devices/handheld/linux/linux.x86_64.conf b/projects/PC/devices/handheld/linux/linux.x86_64.conf index 49e58aae2..0edfc52a5 100644 --- a/projects/PC/devices/handheld/linux/linux.x86_64.conf +++ b/projects/PC/devices/handheld/linux/linux.x86_64.conf @@ -3278,6 +3278,7 @@ CONFIG_SENSORS_JC42=m # CONFIG_SENSORS_NPCM7XX is not set # CONFIG_SENSORS_NZXT_KRAKEN2 is not set # CONFIG_SENSORS_NZXT_SMART2 is not set +CONFIG_SENSORS_OXP=m # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set # CONFIG_SENSORS_SBTSI is not set diff --git a/projects/Rockchip/devices/RG552/device.config b/projects/Rockchip/devices/RG552/device.config index 7183b499b..3cd8bb240 100644 --- a/projects/Rockchip/devices/RG552/device.config +++ b/projects/Rockchip/devices/RG552/device.config @@ -20,6 +20,7 @@ DEVICE_WIFI_MODULE="8188fu" DEVICE_WIFI="113" DEVICE_PWM_MOTOR="pwmchip3" DEVICE_PWM_FAN="/sys/class/hwmon/hwmon1/pwm1" +DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone*/temp" #DEVICE_JACK="" # FREQ Governors