Re: [PATCH v8 1/3] hwmon: (asus_wmi_ec_sensors) Support B550 Asus WMI.
From: Andy Shevchenko <hidden>
Date: 2021-10-25 19:49:18
Also in:
linux-hwmon, lkml, platform-driver-x86
On Mon, Oct 25, 2021 at 10:20:17PM +0300, Andy Shevchenko wrote:
On Fri, Oct 22, 2021 at 11:00:29PM +0300, Denis Pauk wrote:quoted
Linux HWMON sensors driver for ASUS motherboards to read sensors from the embedded controller. Many ASUS motherboards do not publish all the available sensors via the Super I/O chip but the missing ones are available through the embedded controller (EC) registers. This driver implements reading those sensor data via the WMI method BREC, which is known to be present in all ASUS motherboards based on the AMD 500 series chipsets (and probably is available in other models too). The driver needs to know exact register addresses for the sensors and thus support for each motherboard has to be added explicitly. The EC registers do not provide critical values for the sensors and as such they are not published to the HWMON. Supported motherboards: * PRIME X570-PRO * Pro WS X570-ACE * ROG CROSSHAIR VIII HERO * ROG CROSSHAIR VIII DARK HERO * ROG CROSSHAIR VIII FORMULA * ROG STRIX X570-E GAMING * ROG STRIX B550-E GAMINGBelow is a follow up, I have not compiled it. Feel free to take fully or partially.
...
-static int asus_wmi_ec_decode_reply_buffer(const u8 *inp, u8 *out, u32 length)
+static int asus_wmi_ec_decode_reply_buffer(const u8 *in, u32 length, u8 *out)
{
char buffer[ASUSWMI_MAX_BUF_LEN * 2];
- const char *pos = buffer;
- const u8 *data = inp + 2;
u32 len;
- /* Minimum of size of response and size of ACPI result*/
- len = min_t(u32, inp[0] / 4, (length - 2) / 4);
- len = min_t(u32, len, ASUSWMI_MAX_BUF_LEN);
+ /* Minimum of size of response and size of ACPI result (in bytes) */
+ len = min_t(u32, in[0], length - 2);
Of course this should be
len = min_t(u32, get_unaligned_le16(in), length - 2);
(compare to the opposite below).
- utf16s_to_utf8s((wchar_t *)data, len * 2, UTF16_LITTLE_ENDIAN, buffer, len * 2);
+ utf16s_to_utf8s((wchar_t *)(in + 2), len / 2, UTF16_LITTLE_ENDIAN, buffer, sizeof(buffer));
- return hex2bin(out, pos, len);
+ return hex2bin(out, buffer, len / 2);
}
-static void asus_wmi_ec_encode_registers(const u16 *registers, u8 len, char *out)
+static void asus_wmi_ec_encode_registers(const u8 *in, u32 length, char *out)
{
char buffer[ASUSWMI_MAX_BUF_LEN * 2];
- char *pos = buffer;
- unsigned int i;
- u8 byte;
-
- *out++ = len * 8;
- *out++ = 0;
-
- for (i = 0; i < len; i++) {
- byte = registers[i] >> 8;
- pos = bin2hex(pos, &byte, 1);
- byte = registers[i];
- pos = bin2hex(pos, &byte, 1);
- }
+ u16 len = nr_registers * 2;
+
+ put_unaligned_le16(len * 2, out);
+
+ bin2hex(buffer, in, len);
- utf8s_to_utf16s(buffer, len * 4, UTF16_LITTLE_ENDIAN, (wchar_t *)out, len * 4);
+ utf8s_to_utf16s(buffer, len * 2, UTF16_LITTLE_ENDIAN, (wchar_t *)(out + 2), len);
}-- With Best Regards, Andy Shevchenko