Skip to content

Commit

Permalink
Add inversion and value translation to SMCSuperIO EC generic sensor
Browse files Browse the repository at this point in the history
  • Loading branch information
vit9696 committed Apr 15, 2021
1 parent f11bdfc commit 104705c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
3 changes: 3 additions & 0 deletions Docs/EmbeddedControllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
21 changes: 20 additions & 1 deletion Sensors/SMCSuperIO/ECDeviceGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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");
}
Expand Down
11 changes: 7 additions & 4 deletions Sensors/SMCSuperIO/ECDeviceGeneric.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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] {};
Expand Down

0 comments on commit 104705c

Please sign in to comment.