From 104705cbdd13661ac3517846204d0fb5b51ea1a7 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Thu, 15 Apr 2021 10:18:46 +0300 Subject: [PATCH] Add inversion and value translation to SMCSuperIO EC generic sensor --- Docs/EmbeddedControllers.md | 3 +++ Sensors/SMCSuperIO/ECDeviceGeneric.cpp | 21 ++++++++++++++++++++- Sensors/SMCSuperIO/ECDeviceGeneric.hpp | 11 +++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Docs/EmbeddedControllers.md b/Docs/EmbeddedControllers.md index 631346c..5dc7c90 100644 --- a/Docs/EmbeddedControllers.md +++ b/Docs/EmbeddedControllers.md @@ -36,6 +36,9 @@ inject other properties describing the amount of fans, their addresses, value si - `fan0-addr` — 0 fan address, defaults to `0`. - `fan0-size` — 0 fan size, defaults to `1`, can be `1` or `2`. - `fan0-big` — 0 fan endianness, defaults to `0` (little endian), can also be `1` (big endian). +- `fan0-inverse` — 0 fan is reported in inverse values (maximum value is off, minimum value is on), defaults to `0`, normal mode. +- `fan0-mul` — 0 fan speed multipler used to translate sensor values to RPM, defaults to `1`, cannot be 0. +- `fan0-div` — 0 fan speed divisor used to translate sensor values to RPM, defaults to `1`, cannot be 0. Use `fan1-addr` for the second fan and so on. diff --git a/Sensors/SMCSuperIO/ECDeviceGeneric.cpp b/Sensors/SMCSuperIO/ECDeviceGeneric.cpp index 3bc270b..7195be2 100644 --- a/Sensors/SMCSuperIO/ECDeviceGeneric.cpp +++ b/Sensors/SMCSuperIO/ECDeviceGeneric.cpp @@ -18,7 +18,10 @@ namespace EC { uint16_t ECDeviceGeneric::updateTachometer(uint8_t index) { auto &t = tachometers[index]; - return readValue(t.addr, t.size == sizeof(uint16_t), t.bigEndian); + auto val = readValue(t.addr, t.size == sizeof(uint16_t), t.bigEndian); + if (t.inverse) + val = (t.size == sizeof(uint16_t) ? 0xFFFF : 0xFF) - val; + return val * t.mul / t.div; } const char *ECDeviceGeneric::getTachometerName(uint8_t index) { @@ -51,17 +54,33 @@ namespace EC { char name[64]; snprintf(name, sizeof(name), "fan%u-addr", i); WIOKit::getOSDataValue(lpc, name, tachometers[i].addr); + snprintf(name, sizeof(name), "fan%u-size", i); uint32_t tmp = 1; if (WIOKit::getOSDataValue(lpc, name, tmp) && (tmp == 0 || tmp > sizeof(uint16_t))) tmp = 1; tachometers[i].size = tmp; + tmp = 0; snprintf(name, sizeof(name), "fan%u-big", i); if (WIOKit::getOSDataValue(lpc, name, tmp) && (tmp != 0 && tmp != 1)) tmp = 0; tachometers[i].bigEndian = tmp != 0; + tmp = 0; + snprintf(name, sizeof(name), "fan%u-inverse", i); + if (WIOKit::getOSDataValue(lpc, name, tmp) && (tmp != 0 && tmp != 1)) + tmp = 0; + tachometers[i].inverse = tmp != 0; + + snprintf(name, sizeof(name), "fan%u-mul", i); + if (WIOKit::getOSDataValue(lpc, name, tachometers[i].mul) && tachometers[i].mul == 0) + tachometers[i].mul = 1; + + snprintf(name, sizeof(name), "fan%u-div", i); + if (WIOKit::getOSDataValue(lpc, name, tachometers[i].div) && tachometers[i].div == 0) + tachometers[i].div = 1; + DBGLOG("ssio", "added tach%u at 0x%04X (%d bytes, %s)", i, tachometers[i].addr, tachometers[i].size, tachometers[i].bigEndian ? "big" : "little"); } diff --git a/Sensors/SMCSuperIO/ECDeviceGeneric.hpp b/Sensors/SMCSuperIO/ECDeviceGeneric.hpp index 0bca8f2..346deeb 100644 --- a/Sensors/SMCSuperIO/ECDeviceGeneric.hpp +++ b/Sensors/SMCSuperIO/ECDeviceGeneric.hpp @@ -22,10 +22,13 @@ namespace EC { static constexpr uint32_t MaxTachometerCount {5}; struct Tachometer { - const char *name; - uint32_t addr; - uint8_t size; - bool bigEndian; + const char *name {"FAN"}; + uint32_t addr {0}; + uint32_t mul {1}; + uint32_t div {1}; + uint8_t size {sizeof(uint8_t)}; + bool bigEndian {false}; + bool inverse {false}; }; Tachometer tachometers[MaxTachometerCount] {};