linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Update ASUS WMI supported boards.
@ 2021-10-02 21:08 Denis Pauk
  2021-10-02 21:08 ` [PATCH 1/3] hwmon: (nct6775) Add additional ASUS motherboards Denis Pauk
                   ` (5 more replies)
  0 siblings, 6 replies; 19+ messages in thread
From: Denis Pauk @ 2021-10-02 21:08 UTC (permalink / raw)
  Cc: pauk.denis, Eugene Shalygin, matt-testalltheway, Kamil Dudka,
	Robert Swiecki, Kamil Pietrzak, Igor, Tor Vic, Poezevara,
	Andy Shevchenko, Guenter Roeck, Jean Delvare, linux-kernel,
	linux-hwmon

Add support to nct6775:
* PRIME B360-PLUS
* PRIME X570-PRO
* ROG CROSSHAIR VIII FORMULA
* ROG STRIX B550-I GAMING
* ROG STRIX X570-F GAMING
* ROG STRIX Z390-E GAMING
* TUF GAMING B550-PRO
* TUF GAMING Z490-PLUS
* TUF GAMING Z490-PLUS (WI-FI)

Add sensors driver for ASUS motherboards to read sensors from the embedded 
controller. Based on https://github.com/zeule/asus-wmi-ec-sensors.

Could you please review?

@Andy Shevchenko, @Guenter Roeck should I split last patch in some way?
Should I add to MAINTAINERS:
--
ASUS WMI HARDWARE MONITOR DRIVER
M:     Eugene Shalygin <eugene.shalygin@gmail.com>
M:     Denis Pauk <pauk.denis@gmail.com>
L:     linux-hwmon@vger.kernel.org
S:     Maintained
F:     drivers/hwmon/asus_wmi_sensors.c
--


BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
Co-developed-by: Eugene Shalygin <eugene.shalygin@gmail.com>
Signed-off-by: Eugene Shalygin <eugene.shalygin@gmail.com>
Tested-by: matt-testalltheway <sefoci9222@rerunway.com>
Tested-by: Kamil Dudka <kdudka@redhat.com>
Tested-by: Robert Swiecki <robert@swiecki.net>
Tested-by: Kamil Pietrzak <kpietrzak@disroot.org>
Tested-by: Igor <igor@svelig.com>
Tested-by: Tor Vic <torvic9@mailbox.org>
Tested-by: Poezevara <nephartyz@gmail.com>
Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Guenter Roeck <linux@roeck-us.net>

---
Denis Pauk (3):
  hwmon: (nct6775) Add additional ASUS motherboards.
  hwmon: (nct6775) Use custom scale for ASUS motherboards.
  hwmon: (asus_wmi_sensors) Support access via Asus WMI.

 drivers/hwmon/Kconfig            |  12 +
 drivers/hwmon/Makefile           |   1 +
 drivers/hwmon/asus_wmi_sensors.c | 595 +++++++++++++++++++++++++++++++
 drivers/hwmon/nct6775.c          |  41 ++-
 4 files changed, 643 insertions(+), 6 deletions(-)
 create mode 100644 drivers/hwmon/asus_wmi_sensors.c

-- 
2.33.0


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 1/3] hwmon: (nct6775) Add additional ASUS motherboards.
  2021-10-02 21:08 [PATCH 0/3] Update ASUS WMI supported boards Denis Pauk
@ 2021-10-02 21:08 ` Denis Pauk
  2021-10-03  9:48   ` Andy Shevchenko
  2021-10-02 21:08 ` [PATCH 2/3] hwmon: (nct6775) Use custom scale for " Denis Pauk
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Denis Pauk @ 2021-10-02 21:08 UTC (permalink / raw)
  Cc: pauk.denis, matt-testalltheway, Kamil Dudka, Robert Swiecki,
	Kamil Pietrzak, Igor, Tor Vic, Poezevara, Andy Shevchenko,
	Guenter Roeck, Jean Delvare, linux-kernel, linux-hwmon

Add support:
* PRIME B360-PLUS
* PRIME X570-PRO
* ROG CROSSHAIR VIII FORMULA
* ROG STRIX B550-I GAMING
* ROG STRIX X570-F GAMING
* ROG STRIX Z390-E GAMING
* TUF GAMING B550-PRO
* TUF GAMING Z490-PLUS
* TUF GAMING Z490-PLUS (WI-FI)

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
Tested-by: matt-testalltheway <sefoci9222@rerunway.com>
Tested-by: Kamil Dudka <kdudka@redhat.com>
Tested-by: Robert Swiecki <robert@swiecki.net>
Tested-by: Kamil Pietrzak <kpietrzak@disroot.org>
Tested-by: Igor <igor@svelig.com>
Tested-by: Tor Vic <torvic9@mailbox.org>
Tested-by: Poezevara <nephartyz@gmail.com>
Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Guenter Roeck <linux@roeck-us.net>
---
 drivers/hwmon/nct6775.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index aa58ead0ad43..8eaf86ea2433 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -4986,20 +4986,29 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
 static struct platform_device *pdev[2];
 
 static const char * const asus_wmi_boards[] = {
+	"PRIME B360-PLUS",
 	"PRIME B460-PLUS",
+	"PRIME X570-PRO",
 	"ROG CROSSHAIR VIII DARK HERO",
+	"ROG CROSSHAIR VIII FORMULA",
 	"ROG CROSSHAIR VIII HERO",
 	"ROG CROSSHAIR VIII IMPACT",
 	"ROG STRIX B550-E GAMING",
 	"ROG STRIX B550-F GAMING",
 	"ROG STRIX B550-F GAMING (WI-FI)",
+	"ROG STRIX B550-I GAMING",
+	"ROG STRIX X570-F GAMING",
+	"ROG STRIX Z390-E GAMING",
 	"ROG STRIX Z490-I GAMING",
 	"TUF GAMING B550M-PLUS",
 	"TUF GAMING B550M-PLUS (WI-FI)",
 	"TUF GAMING B550-PLUS",
+	"TUF GAMING B550-PRO",
 	"TUF GAMING X570-PLUS",
 	"TUF GAMING X570-PLUS (WI-FI)",
 	"TUF GAMING X570-PRO (WI-FI)",
+	"TUF GAMING Z490-PLUS",
+	"TUF GAMING Z490-PLUS (WI-FI)",
 };
 
 static int __init sensors_nct6775_init(void)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 2/3] hwmon: (nct6775) Use custom scale for ASUS motherboards.
  2021-10-02 21:08 [PATCH 0/3] Update ASUS WMI supported boards Denis Pauk
  2021-10-02 21:08 ` [PATCH 1/3] hwmon: (nct6775) Add additional ASUS motherboards Denis Pauk
@ 2021-10-02 21:08 ` Denis Pauk
  2021-10-03  6:30   ` Andy Shevchenko
  2021-10-05 13:52   ` Guenter Roeck
  2021-10-02 21:08 ` [PATCH 3/3] hwmon: (asus_wmi_sensors) Support access via Asus WMI Denis Pauk
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 19+ messages in thread
From: Denis Pauk @ 2021-10-02 21:08 UTC (permalink / raw)
  Cc: pauk.denis, Kamil Pietrzak, Andy Shevchenko, Guenter Roeck,
	Jean Delvare, linux-kernel, linux-hwmon

Use custom scaling factor for:
* TUF GAMING Z490-PLUS
* TUF GAMING Z490-PLUS (WI-FI)

Voltage scaling factors are based on Asus software on Windows.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
Tested-by: Kamil Pietrzak <kpietrzak@disroot.org>
Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Guenter Roeck <linux@roeck-us.net>
---
 drivers/hwmon/nct6775.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index 8eaf86ea2433..ba18c1cbf572 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -140,6 +140,7 @@ struct nct6775_sio_data {
 	int ld;
 	enum kinds kind;
 	enum sensor_access access;
+	bool custom_scale;
 
 	/* superio_() callbacks  */
 	void (*sio_outb)(struct nct6775_sio_data *sio_data, int reg, int val);
@@ -1159,14 +1160,19 @@ static const u16 scale_in[15] = {
 	800, 800
 };
 
-static inline long in_from_reg(u8 reg, u8 nr)
+static const u16 scale_in_z490[15] = {
+	888, 4000, 1600, 1600, 9600, 800, 800, 1600, 1600, 1600, 1600, 1600, 800,
+	800, 800
+};
+
+static inline long in_from_reg(u8 reg, u8 nr, const u16 *scale)
 {
-	return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
+	return DIV_ROUND_CLOSEST(reg * scale[nr], 100);
 }
 
-static inline u8 in_to_reg(u32 val, u8 nr)
+static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scale)
 {
-	return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255);
+	return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale[nr]), 0, 255);
 }
 
 /*
@@ -1323,6 +1329,9 @@ struct nct6775_data {
 	u8 fandiv2;
 	u8 sio_reg_enable;
 
+	/* voltage scaling factors */
+	const u16 *scale;
+
 	/* nct6775_*() callbacks  */
 	u16 (*read_value)(struct nct6775_data *data, u16 reg);
 	int (*write_value)(struct nct6775_data *data, u16 reg, u16 value);
@@ -2026,7 +2035,7 @@ show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
 	int index = sattr->index;
 	int nr = sattr->nr;
 
-	return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr));
+	return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr, data->scale));
 }
 
 static ssize_t
@@ -2044,7 +2053,7 @@ store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
 	if (err < 0)
 		return err;
 	mutex_lock(&data->update_lock);
-	data->in[nr][index] = in_to_reg(val, nr);
+	data->in[nr][index] = in_to_reg(val, nr, data->scale);
 	data->write_value(data, data->REG_IN_MINMAX[index - 1][nr],
 			  data->in[nr][index]);
 	mutex_unlock(&data->update_lock);
@@ -3980,6 +3989,11 @@ static int nct6775_probe(struct platform_device *pdev)
 		data->write_value = nct6775_wmi_write_value;
 	}
 
+	if (sio_data->custom_scale)
+		data->scale = scale_in_z490;
+	else
+		data->scale = scale_in;
+
 	mutex_init(&data->update_lock);
 	data->name = nct6775_device_names[data->kind];
 	data->bank = 0xff;		/* Force initial bank selection */
@@ -5020,6 +5034,7 @@ static int __init sensors_nct6775_init(void)
 	struct nct6775_sio_data sio_data;
 	int sioaddr[2] = { 0x2e, 0x4e };
 	enum sensor_access access = access_direct;
+	bool custom_scale = false;
 	const char *board_vendor, *board_name;
 	u8 tmp;
 
@@ -5043,6 +5058,10 @@ static int __init sensors_nct6775_init(void)
 				pr_err("Can't read ChipID by Asus WMI.\n");
 			}
 		}
+
+		if (strcmp(board_name, "TUF GAMING Z490-PLUS") == 0 ||
+		    strcmp(board_name, "TUF GAMING Z490-PLUS (WI-FI)") == 0)
+			custom_scale = true;
 	}
 
 	/*
@@ -5066,6 +5085,7 @@ static int __init sensors_nct6775_init(void)
 		found = true;
 
 		sio_data.access = access;
+		sio_data.custom_scale = custom_scale;
 
 		if (access == access_asuswmi) {
 			sio_data.sio_outb = superio_wmi_outb;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 3/3] hwmon: (asus_wmi_sensors) Support access via Asus WMI.
  2021-10-02 21:08 [PATCH 0/3] Update ASUS WMI supported boards Denis Pauk
  2021-10-02 21:08 ` [PATCH 1/3] hwmon: (nct6775) Add additional ASUS motherboards Denis Pauk
  2021-10-02 21:08 ` [PATCH 2/3] hwmon: (nct6775) Use custom scale for " Denis Pauk
@ 2021-10-02 21:08 ` Denis Pauk
  2021-10-02 21:56   ` Eugene Shalygin
  2021-10-03 10:34   ` Andy Shevchenko
  2021-10-02 21:34 ` [PATCH 0/3] Update ASUS WMI supported boards Denis Pauk
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 19+ messages in thread
From: Denis Pauk @ 2021-10-02 21:08 UTC (permalink / raw)
  Cc: pauk.denis, Eugene Shalygin, Andy Shevchenko, Guenter Roeck,
	Jean Delvare, linux-kernel, linux-hwmon

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.

Supported motherboards:
* ROG CROSSHAIR VIII HERO
* ROG CROSSHAIR VIII DARK HERO
* ROG CROSSHAIR VIII FORMULA
* ROG STRIX X570-E GAMING
* ROG STRIX B550-E GAMING

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
Co-developed-by: Eugene Shalygin <eugene.shalygin@gmail.com>
Signed-off-by: Eugene Shalygin <eugene.shalygin@gmail.com>
Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Guenter Roeck <linux@roeck-us.net>
---
 drivers/hwmon/Kconfig            |  12 +
 drivers/hwmon/Makefile           |   1 +
 drivers/hwmon/asus_wmi_sensors.c | 595 +++++++++++++++++++++++++++++++
 3 files changed, 608 insertions(+)
 create mode 100644 drivers/hwmon/asus_wmi_sensors.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 7fde4c6e1e7f..cb8c8ebb0dab 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -2215,6 +2215,18 @@ config SENSORS_ATK0110
 	  This driver can also be built as a module. If so, the module
 	  will be called asus_atk0110.
 
+config SENSORS_ASUS_WMI
+	tristate "ASUS WMI"
+	depends on X86
+	help
+	  If you say yes here you get support for the ACPI hardware
+	  monitoring interface found in many ASUS motherboards. This
+	  driver will provide readings of fans, voltages and temperatures
+	  through the system firmware.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called asus_wmi_sensors.
+
 endif # ACPI
 
 endif # HWMON
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index baee6a8d4dd1..dbadc79b890d 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_HWMON_VID)		+= hwmon-vid.o
 # APCI drivers
 obj-$(CONFIG_SENSORS_ACPI_POWER) += acpi_power_meter.o
 obj-$(CONFIG_SENSORS_ATK0110)	+= asus_atk0110.o
+obj-$(CONFIG_SENSORS_ASUS_WMI)	+= asus_wmi_sensors.o
 
 # Native drivers
 # asb100, then w83781d go first, as they can override other drivers' addresses.
diff --git a/drivers/hwmon/asus_wmi_sensors.c b/drivers/hwmon/asus_wmi_sensors.c
new file mode 100644
index 000000000000..6b04fad18891
--- /dev/null
+++ b/drivers/hwmon/asus_wmi_sensors.c
@@ -0,0 +1,595 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * HWMON driver for ASUS motherboards that publish some sensor values
+ * via the embedded controller registers
+ *
+ * Copyright (C) 2021 Eugene Shalygin <eugene.shalygin@gmail.com>
+ * Copyright (C) 2018-2019 Ed Brindley <kernel@maidavale.org>
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define DRVNAME "asus_wmi_sensors"
+
+#include <linux/dmi.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/acpi.h>
+#include <linux/wmi.h>
+
+#define ASUSWMI_MONITORING_GUID		"466747A0-70EC-11DE-8A39-0800200C9A66"
+#define ASUSWMI_METHODID_BLOCK_READ_EC		0x42524543 /* BREC */
+
+#define HWMON_MAX	9
+
+#define ASUS_WMI_BLOCK_READ_REGISTERS_MAX 0x10 /* from the ASUS DSDT source */
+/* from the ASUS_WMI_BLOCK_READ_REGISTERS_MAX value */
+#define ASUS_WMI_MAX_BUF_LEN 0x80
+#define MAX_SENSOR_LABEL_LENGTH 0x10
+
+#define ASUSWMI_SENSORS_MAX 11
+#define ASUS_EC_KNOWN_EC_REGISTERS 14
+
+enum asus_wmi_ec_board {
+	BOARD_R_C8H, // ROG Crosshair VIII Hero
+	BOARD_R_C8DH, // ROG Crosshair VIII Dark Hero
+	BOARD_R_C8F, // ROG Crosshair VIII Formula
+	BOARD_RS_X570_E_G, // ROG STRIX X570-E GAMING
+	BOARD_RS_B550_E_G, // ROG STRIX B550-E GAMING
+};
+
+/* boards with EC support */
+static const char *const asus_wmi_ec_boards_names[] = {
+	[BOARD_R_C8H] = "ROG CROSSHAIR VIII HERO",
+	[BOARD_R_C8DH] = "ROG CROSSHAIR VIII DARK HERO",
+	[BOARD_R_C8F] = "ROG CROSSHAIR VIII FORMULA",
+	[BOARD_RS_X570_E_G] = "ROG STRIX X570-E GAMING",
+	[BOARD_RS_B550_E_G] = "ROG STRIX B550-E GAMING",
+};
+
+static u32 hwmon_attributes[] = {
+	[hwmon_chip] = HWMON_C_REGISTER_TZ,
+	[hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL,
+	[hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL,
+	[hwmon_curr] = HWMON_C_INPUT | HWMON_C_LABEL,
+	[hwmon_fan] = HWMON_F_INPUT | HWMON_F_LABEL,
+};
+
+union asus_wmi_ec_sensor_address {
+	u32 value;
+	struct {
+		u8 index;
+		u8 bank;
+		u8 size;
+		u8 dummy;
+	} addr;
+};
+
+struct asus_wmi_ec_sensor_info {
+	char label[MAX_SENSOR_LABEL_LENGTH];
+	enum hwmon_sensor_types type;
+	union asus_wmi_ec_sensor_address addr;
+	u32 cached_value;
+};
+
+struct asus_wmi_ec_info {
+	struct asus_wmi_ec_sensor_info sensors[ASUSWMI_SENSORS_MAX];
+	/* UTF-16 string to pass to BRxx() WMI function */
+	char read_arg[((ASUS_WMI_BLOCK_READ_REGISTERS_MAX * 4) + 1) * 2];
+	u8 read_buffer[ASUS_WMI_BLOCK_READ_REGISTERS_MAX];
+	u8 nr_sensors; /* number of board EC sensors */
+	/* number of EC registers to read (sensor might span more than 1 register) */
+	u8 nr_registers;
+	unsigned long last_updated; /* in jiffies */
+};
+
+struct asus_wmi_sensors {
+	/* lock access to instrnal cache */
+	struct mutex lock;
+	struct asus_wmi_ec_info ec;
+
+	int ec_board;
+};
+
+struct asus_wmi_data {
+	int ec_board;
+};
+
+static inline union asus_wmi_ec_sensor_address asus_wmi_ec_make_sensor_address(u8 size,
+									       u8 bank,
+									       u8 index)
+{
+	union asus_wmi_ec_sensor_address res;
+
+	res.value = (size << 16) + (bank << 8) + index;
+	return res;
+}
+
+static inline void asus_wmi_ec_set_sensor_info(struct asus_wmi_ec_sensor_info *sensor_info,
+					       const char *label,
+					       enum hwmon_sensor_types type,
+					       union asus_wmi_ec_sensor_address addr,
+					       u8 *nr_regs)
+{
+	sensor_info->type = type;
+	strcpy(sensor_info->label, label);
+	sensor_info->cached_value = 0;
+	sensor_info->addr.value = addr.value;
+	*nr_regs += sensor_info->addr.addr.size;
+}
+
+static void asus_wmi_ec_fill_board_sensors(struct asus_wmi_ec_info *ec, int board)
+{
+	struct asus_wmi_ec_sensor_info *si;
+
+	si = ec->sensors;
+	ec->nr_registers = 0;
+
+	switch (board) {
+	case BOARD_RS_B550_E_G:
+	case BOARD_RS_X570_E_G:
+	case BOARD_R_C8H:
+	case BOARD_R_C8DH:
+	case BOARD_R_C8F:
+		asus_wmi_ec_set_sensor_info(si++, "Chipset", hwmon_temp,
+					    asus_wmi_ec_make_sensor_address(1, 0x00, 0x3A),
+					    &ec->nr_registers);
+		asus_wmi_ec_set_sensor_info(si++, "CPU", hwmon_temp,
+					    asus_wmi_ec_make_sensor_address(1, 0x00, 0x3B),
+					    &ec->nr_registers);
+		asus_wmi_ec_set_sensor_info(si++, "Motherboard", hwmon_temp,
+					    asus_wmi_ec_make_sensor_address(1, 0x00, 0x3C),
+					    &ec->nr_registers);
+		asus_wmi_ec_set_sensor_info(si++, "T_Sensor", hwmon_temp,
+					    asus_wmi_ec_make_sensor_address(1, 0x00, 0x3D),
+					    &ec->nr_registers);
+		asus_wmi_ec_set_sensor_info(si++, "VRM", hwmon_temp,
+					    asus_wmi_ec_make_sensor_address(1, 0x00, 0x3E),
+					    &ec->nr_registers);
+	}
+
+	switch (board) {
+	case BOARD_RS_X570_E_G:
+	case BOARD_R_C8H:
+	case BOARD_R_C8DH:
+	case BOARD_R_C8F:
+		asus_wmi_ec_set_sensor_info(si++, "CPU_Opt", hwmon_fan,
+					    asus_wmi_ec_make_sensor_address(2, 0x00, 0xB0),
+					    &ec->nr_registers);
+		asus_wmi_ec_set_sensor_info(si++, "CPU", hwmon_curr,
+					    asus_wmi_ec_make_sensor_address(1, 0x00, 0xF4),
+					    &ec->nr_registers);
+	}
+
+	switch (board) {
+	case BOARD_RS_X570_E_G:
+	case BOARD_R_C8H:
+	case BOARD_R_C8F:
+		asus_wmi_ec_set_sensor_info(si++, "Chipset", hwmon_fan,
+					    asus_wmi_ec_make_sensor_address(2, 0x00, 0xB4),
+					    &ec->nr_registers);
+	}
+
+	switch (board) {
+	case BOARD_R_C8H:
+	case BOARD_R_C8DH:
+	case BOARD_R_C8F:
+		asus_wmi_ec_set_sensor_info(si++, "Water", hwmon_fan,
+					    asus_wmi_ec_make_sensor_address(2, 0x00, 0xBC),
+					    &ec->nr_registers);
+		asus_wmi_ec_set_sensor_info(si++, "Water_In", hwmon_temp,
+					    asus_wmi_ec_make_sensor_address(1, 0x01, 0x00),
+					    &ec->nr_registers);
+		asus_wmi_ec_set_sensor_info(si++, "Water_Out", hwmon_temp,
+					    asus_wmi_ec_make_sensor_address(1, 0x01, 0x01),
+					    &ec->nr_registers);
+	}
+
+	ec->nr_sensors = si - ec->sensors;
+}
+
+/*
+ * The next four functions converts to/from BRxx string argument format
+ * The format of the string is as follows:
+ * The string consists of two-byte UTF-16 characters
+ * The value of the very first byte int the string is equal to the total length
+ * of the next string in bytes, thus excluding the first two-byte character
+ * The rest of the string encodes pairs of (bank, index) pairs, where both
+ * values are byte-long (0x00 to 0xFF)
+ * Numbers are encoded as UTF-16 hex values
+ */
+
+static inline char *asus_wmi_ec_hex_utf_16_le_pack(char *buf, u8 byte)
+{
+	*buf++ = hex_asc_hi(byte);
+	*buf++ = 0;
+	*buf++ = hex_asc_lo(byte);
+	*buf++ = 0;
+	return buf;
+}
+
+static void asus_wmi_ec_decode_reply_buffer(const u8 *inp, u8 *out)
+{
+	u8 len = ACPI_MIN(ASUS_WMI_MAX_BUF_LEN, inp[0] / 4);
+	const u8 *data = inp + 2;
+	u8 i;
+
+	for (i = 0; i < len; ++i, data += 4)
+		out[i] = (hex_to_bin(data[0]) << 4) + hex_to_bin(data[2]);
+}
+
+static void asus_wmi_ec_encode_registers(u16 *registers, u8 len, char *out)
+{
+	u8 i;
+
+	// assert(len <= 30)
+	*out++ = len * 8;
+	*out++ = 0;
+	for (i = 0; i < len; ++i) {
+		out = asus_wmi_ec_hex_utf_16_le_pack(out, (registers[i] & 0xFF00) >> 8);
+		out = asus_wmi_ec_hex_utf_16_le_pack(out, (registers[i] & 0x00FF));
+	}
+}
+
+static void asus_wmi_ec_make_block_read_query(struct asus_wmi_ec_info *ec)
+{
+	u16 registers[ASUS_EC_KNOWN_EC_REGISTERS];
+	u8 i, j, register_idx = 0;
+
+	/* if we can get values for all the registers in a single query,
+	 * the query will not change from call to call
+	 */
+	if (ec->nr_registers <= ASUS_WMI_BLOCK_READ_REGISTERS_MAX &&
+	    ec->read_arg[0] > 0) {
+		/* no need to update */
+		return;
+	}
+
+	for (i = 0; i < ec->nr_sensors; ++i) {
+		for (j = 0; j < ec->sensors[i].addr.addr.size;
+		     ++j, ++register_idx) {
+			registers[register_idx] =
+				(ec->sensors[i].addr.addr.bank << 8) +
+				ec->sensors[i].addr.addr.index + j;
+		}
+	}
+
+	asus_wmi_ec_encode_registers(registers, ec->nr_registers, ec->read_arg);
+}
+
+static int asus_wmi_ec_block_read(u32 method_id, const char *query, u8 *out)
+{
+	struct acpi_buffer input;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER,
+				      NULL }; // TODO use pre-allocated buffer
+	acpi_status status;
+	union acpi_object *obj;
+
+	/* the first byte of the BRxx() argument string has to be the string size */
+	input.length = (acpi_size)query[0] + 2;
+	input.pointer = (void *)query;
+	status = wmi_evaluate_method(ASUSWMI_MONITORING_GUID, 0, method_id, &input,
+				     &output);
+
+	if (ACPI_FAILURE(status)) {
+		acpi_os_free(output.pointer);
+		return -EIO;
+	}
+
+	obj = output.pointer;
+	if (!obj || obj->type != ACPI_TYPE_BUFFER) {
+		pr_err("unexpected reply type from ASUS ACPI code");
+		acpi_os_free(output.pointer);
+		return -EIO;
+	}
+	asus_wmi_ec_decode_reply_buffer(obj->buffer.pointer, out);
+	acpi_os_free(output.pointer);
+	return 0;
+}
+
+static int asus_wmi_ec_update_ec_sensors(struct asus_wmi_ec_info *ec)
+{
+	struct asus_wmi_ec_sensor_info *si;
+	u32 value;
+	int status;
+	u8 i_sensor, read_reg_ct, i_sensor_register;
+
+	asus_wmi_ec_make_block_read_query(ec);
+	status = asus_wmi_ec_block_read(ASUSWMI_METHODID_BLOCK_READ_EC,
+					ec->read_arg,
+					ec->read_buffer);
+	if (status)
+		return status;
+
+	read_reg_ct = 0;
+	for (i_sensor = 0; i_sensor < ec->nr_sensors; ++i_sensor) {
+		si = &ec->sensors[i_sensor];
+		value = ec->read_buffer[read_reg_ct++];
+		for (i_sensor_register = 1;
+		     i_sensor_register < si->addr.addr.size;
+		     ++i_sensor_register) {
+			value <<= 8;
+			value += ec->read_buffer[read_reg_ct++];
+		}
+		si->cached_value = value;
+	}
+	return 0;
+}
+
+static int asus_wmi_ec_scale_sensor_value(u32 value, int data_type)
+{
+	switch (data_type) {
+	case hwmon_curr:
+	case hwmon_temp:
+	case hwmon_in:
+		return value * 1000;
+	default:
+		return value;
+	}
+}
+
+static u8 asus_wmi_ec_find_sensor_index(const struct asus_wmi_ec_info *ec,
+					enum hwmon_sensor_types type, int channel)
+{
+	u8 i;
+
+	for (i = 0; i < ec->nr_sensors; ++i) {
+		if (ec->sensors[i].type == type) {
+			if (channel == 0)
+				return i;
+
+			--channel;
+		}
+	}
+	return 0xFF;
+}
+
+static int asus_wmi_ec_get_cached_value_or_update(int sensor_index,
+						  struct asus_wmi_sensors *state,
+						  u32 *value)
+{
+	int ret;
+
+	if (time_after(jiffies, state->ec.last_updated + HZ)) {
+		ret = asus_wmi_ec_update_ec_sensors(&state->ec);
+
+		if (ret) {
+			pr_err("asus_wmi_ec_update_ec_sensors() failure\n");
+			return -EIO;
+		}
+
+		state->ec.last_updated = jiffies;
+	}
+
+	*value = state->ec.sensors[sensor_index].cached_value;
+	return 0;
+}
+
+/*
+ * Now follow the functions that implement the hwmon interface
+ */
+
+static int asus_wmi_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+				  u32 attr, int channel, long *val)
+{
+	int ret;
+	u32 value = 0;
+	struct asus_wmi_sensors *sensor_data = dev_get_drvdata(dev);
+
+	u8 sidx = asus_wmi_ec_find_sensor_index(&sensor_data->ec, type, channel);
+
+	mutex_lock(&sensor_data->lock);
+
+	ret = asus_wmi_ec_get_cached_value_or_update(sidx, sensor_data, &value);
+	mutex_unlock(&sensor_data->lock);
+
+	if (!ret)
+		*val = asus_wmi_ec_scale_sensor_value(value, sensor_data->ec.sensors[sidx].type);
+
+	return ret;
+}
+
+static int asus_wmi_ec_hwmon_read_string(struct device *dev,
+					 enum hwmon_sensor_types type, u32 attr,
+					 int channel, const char **str)
+{
+	struct asus_wmi_sensors *sensor_data = dev_get_drvdata(dev);
+
+	u8 sensor_index = asus_wmi_ec_find_sensor_index(&sensor_data->ec, type, channel);
+	*str = sensor_data->ec.sensors[sensor_index].label;
+
+	return 0;
+}
+
+static umode_t asus_wmi_ec_hwmon_is_visible(const void *drvdata,
+					    enum hwmon_sensor_types type, u32 attr,
+					    int channel)
+{
+	const struct asus_wmi_sensors *sensor_data = drvdata;
+
+	return asus_wmi_ec_find_sensor_index(&sensor_data->ec, type, channel) != 0xFF ?
+			     0444 :
+			     0;
+}
+
+static int asus_wmi_hwmon_add_chan_info(struct hwmon_channel_info *asus_wmi_hwmon_chan,
+					struct device *dev, int num,
+					enum hwmon_sensor_types type, u32 config)
+{
+	int i;
+	u32 *cfg = devm_kcalloc(dev, num + 1, sizeof(*cfg), GFP_KERNEL);
+
+	if (!cfg)
+		return -ENOMEM;
+
+	asus_wmi_hwmon_chan->type = type;
+	asus_wmi_hwmon_chan->config = cfg;
+	for (i = 0; i < num; i++, cfg++)
+		*cfg = config;
+
+	return 0;
+}
+
+static const struct hwmon_ops asus_wmi_ec_hwmon_ops = {
+	.is_visible = asus_wmi_ec_hwmon_is_visible,
+	.read = asus_wmi_ec_hwmon_read,
+	.read_string = asus_wmi_ec_hwmon_read_string,
+};
+
+static struct hwmon_chip_info asus_wmi_ec_chip_info = {
+	.ops = &asus_wmi_ec_hwmon_ops,
+	.info = NULL,
+};
+
+static int asus_wmi_ec_configure_sensor_setup(struct platform_device *pdev,
+					      struct asus_wmi_sensors *sensor_data)
+{
+	int i;
+	int nr_count[HWMON_MAX] = { 0 }, nr_types = 0;
+	struct device *hwdev;
+	struct device *dev = &pdev->dev;
+	struct hwmon_channel_info *asus_wmi_hwmon_chan;
+	const struct hwmon_channel_info **ptr_asus_wmi_ci;
+	const struct hwmon_chip_info *chip_info;
+	const struct asus_wmi_ec_sensor_info *si;
+	enum hwmon_sensor_types type;
+
+	if (sensor_data->ec_board < 0)
+		return 0;
+
+	asus_wmi_ec_fill_board_sensors(&sensor_data->ec, sensor_data->ec_board);
+
+	if (!sensor_data->ec.nr_sensors)
+		return -ENODEV;
+
+	for (i = 0; i < sensor_data->ec.nr_sensors; ++i) {
+		si = &sensor_data->ec.sensors[i];
+		if (!nr_count[si->type])
+			++nr_types;
+		++nr_count[si->type];
+	}
+
+	if (nr_count[hwmon_temp])
+		nr_count[hwmon_chip]++, nr_types++;
+
+	asus_wmi_hwmon_chan = devm_kcalloc(dev, nr_types,
+					   sizeof(*asus_wmi_hwmon_chan),
+					   GFP_KERNEL);
+	if (!asus_wmi_hwmon_chan)
+		return -ENOMEM;
+
+	ptr_asus_wmi_ci = devm_kcalloc(dev, nr_types + 1,
+				       sizeof(*ptr_asus_wmi_ci), GFP_KERNEL);
+	if (!ptr_asus_wmi_ci)
+		return -ENOMEM;
+
+	asus_wmi_ec_chip_info.info = ptr_asus_wmi_ci;
+	chip_info = &asus_wmi_ec_chip_info;
+
+	for (type = 0; type < HWMON_MAX; type++) {
+		if (!nr_count[type])
+			continue;
+
+		asus_wmi_hwmon_add_chan_info(asus_wmi_hwmon_chan, dev,
+					     nr_count[type], type,
+					     hwmon_attributes[type]);
+		*ptr_asus_wmi_ci++ = asus_wmi_hwmon_chan++;
+	}
+
+	pr_info("%s board has %d EC sensors that span %d registers",
+		asus_wmi_ec_boards_names[sensor_data->ec_board],
+		sensor_data->ec.nr_sensors,
+		sensor_data->ec.nr_registers);
+
+	hwdev = devm_hwmon_device_register_with_info(dev, "asuswmiecsensors",
+						     sensor_data, chip_info, NULL);
+
+	return PTR_ERR_OR_ZERO(hwdev);
+}
+
+static int asus_wmi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct asus_wmi_data *data = dev_get_platdata(dev);
+	struct asus_wmi_sensors *sensor_data;
+	int err;
+
+	sensor_data = devm_kzalloc(dev, sizeof(struct asus_wmi_sensors),
+				   GFP_KERNEL);
+	if (!sensor_data)
+		return -ENOMEM;
+
+	mutex_init(&sensor_data->lock);
+	sensor_data->ec_board = data->ec_board;
+
+	platform_set_drvdata(pdev, sensor_data);
+
+	/* ec init */
+	err = asus_wmi_ec_configure_sensor_setup(pdev,
+						 sensor_data);
+
+	return err;
+}
+
+static struct platform_driver asus_wmi_sensors_platform_driver = {
+	.driver = {
+		.name	= "asus-wmi-sensors",
+	},
+	.probe = asus_wmi_probe
+};
+
+static struct platform_device *sensors_pdev;
+
+static int __init asus_wmi_init(void)
+{
+	const char *board_vendor, *board_name;
+	struct asus_wmi_data data;
+
+	data.ec_board = -1;
+
+	board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
+	board_name = dmi_get_system_info(DMI_BOARD_NAME);
+
+	if (board_vendor && board_name &&
+	    !strcmp(board_vendor, "ASUSTeK COMPUTER INC.")) {
+		if (!wmi_has_guid(ASUSWMI_MONITORING_GUID))
+			return -ENODEV;
+
+		data.ec_board = match_string(asus_wmi_ec_boards_names,
+					     ARRAY_SIZE(asus_wmi_ec_boards_names),
+					     board_name);
+	}
+
+	/* Nothing to support */
+	if (data.ec_board < 0)
+		return -ENODEV;
+
+	sensors_pdev = platform_create_bundle(&asus_wmi_sensors_platform_driver,
+					      asus_wmi_probe,
+					      NULL, 0,
+					      &data, sizeof(struct asus_wmi_data));
+
+	if (IS_ERR(sensors_pdev))
+		return PTR_ERR(sensors_pdev);
+
+	return 0;
+}
+
+static void __exit asus_wmi_exit(void)
+{
+	platform_device_unregister(sensors_pdev);
+	platform_driver_unregister(&asus_wmi_sensors_platform_driver);
+}
+
+MODULE_AUTHOR("Ed Brindley <kernel@maidavale.org>");
+MODULE_AUTHOR("Eugene Shalygin <eugene.shalygin@gmail.com>");
+MODULE_DESCRIPTION("Asus WMI Sensors Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1");
+
+module_init(asus_wmi_init);
+module_exit(asus_wmi_exit);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 0/3] Update ASUS WMI supported boards.
  2021-10-02 21:08 [PATCH 0/3] Update ASUS WMI supported boards Denis Pauk
                   ` (2 preceding siblings ...)
  2021-10-02 21:08 ` [PATCH 3/3] hwmon: (asus_wmi_sensors) Support access via Asus WMI Denis Pauk
@ 2021-10-02 21:34 ` Denis Pauk
  2021-10-03  6:24   ` Andy Shevchenko
  2021-10-03  6:39 ` Andy Shevchenko
  2021-10-03 11:50 ` Oleksandr Natalenko
  5 siblings, 1 reply; 19+ messages in thread
From: Denis Pauk @ 2021-10-02 21:34 UTC (permalink / raw)
  Cc: Eugene Shalygin, matt-testalltheway, Kamil Dudka, Robert Swiecki,
	Kamil Pietrzak, Igor, Tor Vic, Poezevara, Andy Shevchenko,
	Guenter Roeck, Jean Delvare, linux-kernel, linux-hwmon

On Sun,  3 Oct 2021 00:08:53 +0300
Denis Pauk <pauk.denis@gmail.com> wrote:

Patches should be applied over
git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git:hwmon-next
(0889b7c73a4d8eaaa321eafcf66835979ead862a)

> Add support to nct6775:
> * PRIME B360-PLUS
> * PRIME X570-PRO
> * ROG CROSSHAIR VIII FORMULA
> * ROG STRIX B550-I GAMING
> * ROG STRIX X570-F GAMING
> * ROG STRIX Z390-E GAMING
> * TUF GAMING B550-PRO
> * TUF GAMING Z490-PLUS
> * TUF GAMING Z490-PLUS (WI-FI)
> 
> Add sensors driver for ASUS motherboards to read sensors from the
> embedded controller. Based on
> https://github.com/zeule/asus-wmi-ec-sensors.
> 
> Could you please review?
> 
> @Andy Shevchenko, @Guenter Roeck should I split last patch in some
> way? Should I add to MAINTAINERS:
> --
> ASUS WMI HARDWARE MONITOR DRIVER
> M:     Eugene Shalygin <eugene.shalygin@gmail.com>
> M:     Denis Pauk <pauk.denis@gmail.com>
> L:     linux-hwmon@vger.kernel.org
> S:     Maintained
> F:     drivers/hwmon/asus_wmi_sensors.c
> --
> 
> 
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
> Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
> Co-developed-by: Eugene Shalygin <eugene.shalygin@gmail.com>
> Signed-off-by: Eugene Shalygin <eugene.shalygin@gmail.com>
> Tested-by: matt-testalltheway <sefoci9222@rerunway.com>
> Tested-by: Kamil Dudka <kdudka@redhat.com>
> Tested-by: Robert Swiecki <robert@swiecki.net>
> Tested-by: Kamil Pietrzak <kpietrzak@disroot.org>
> Tested-by: Igor <igor@svelig.com>
> Tested-by: Tor Vic <torvic9@mailbox.org>
> Tested-by: Poezevara <nephartyz@gmail.com>
> Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
> Cc: Guenter Roeck <linux@roeck-us.net>
> 
> ---
> Denis Pauk (3):
>   hwmon: (nct6775) Add additional ASUS motherboards.
>   hwmon: (nct6775) Use custom scale for ASUS motherboards.
>   hwmon: (asus_wmi_sensors) Support access via Asus WMI.
> 
>  drivers/hwmon/Kconfig            |  12 +
>  drivers/hwmon/Makefile           |   1 +
>  drivers/hwmon/asus_wmi_sensors.c | 595
> +++++++++++++++++++++++++++++++ drivers/hwmon/nct6775.c          |
> 41 ++- 4 files changed, 643 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/hwmon/asus_wmi_sensors.c
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/3] hwmon: (asus_wmi_sensors) Support access via Asus WMI.
  2021-10-02 21:08 ` [PATCH 3/3] hwmon: (asus_wmi_sensors) Support access via Asus WMI Denis Pauk
@ 2021-10-02 21:56   ` Eugene Shalygin
  2021-10-03 18:35     ` Eugene Shalygin
  2021-10-03 20:48     ` Denis Pauk
  2021-10-03 10:34   ` Andy Shevchenko
  1 sibling, 2 replies; 19+ messages in thread
From: Eugene Shalygin @ 2021-10-02 21:56 UTC (permalink / raw)
  To: Denis Pauk
  Cc: Andy Shevchenko, Guenter Roeck, Jean Delvare, linux-kernel, linux-hwmon

Hi, Denis!

Thank you for submitting this driver to the mainline! I have a few
comments/suggestions, please find them below.

> +#define HWMON_MAX      9

There is a hwmon_max enum member, whose current value is 10.

> +#define ASUS_WMI_BLOCK_READ_REGISTERS_MAX 0x10 /* from the ASUS DSDT source */
> +/* from the ASUS_WMI_BLOCK_READ_REGISTERS_MAX value */
> +#define ASUS_WMI_MAX_BUF_LEN 0x80
Suggestion:
#define ASUS_WMI_MAX_BUF_LEN 0x80 /* from the
ASUS_WMI_BLOCK_READ_REGISTERS_MAX value */

> +#define ASUSWMI_SENSORS_MAX 11
This one is for the EC only, maybe rename it accordingly?

> +struct asus_wmi_data {
> +       int ec_board;
> +};

Duplicates the value in the asus_wmi_sensors struct. Refactoring artifact?

             asus_wmi_ec_set_sensor_info(si++, "Water", hwmon_fan,
> +                                           asus_wmi_ec_make_sensor_address(2, 0x00, 0xBC),
> +                                           &ec->nr_registers);
This one is named "W_FLOW" in the BIOS and ASUS software. Maybe append
"_flow" to the label?

> + * The next four functions converts to/from BRxx string argument format
convert (remove "s")

> +       // assert(len <= 30)
Makes little sense in the kernel.

> +static void asus_wmi_ec_make_block_read_query(struct asus_wmi_ec_info *ec)
> +{
> +       u16 registers[ASUS_EC_KNOWN_EC_REGISTERS];
> +       u8 i, j, register_idx = 0;
> +
> +       /* if we can get values for all the registers in a single query,
> +        * the query will not change from call to call
> +        */
> +       if (ec->nr_registers <= ASUS_WMI_BLOCK_READ_REGISTERS_MAX &&
> +           ec->read_arg[0] > 0) {
> +               /* no need to update */
> +               return;
> +       }
> +
I would add a test for ec->nr_registers >
ASUS_WMI_BLOCK_READ_REGISTERS_MAX and a warning log message here.

> +static int asus_wmi_probe(struct platform_device *pdev)

Can we add a module alias or to load the module automatically by other
means? For module aliases we know DMI parameters for the supported
boards.

Best regards,
Eugene

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 0/3] Update ASUS WMI supported boards.
  2021-10-02 21:34 ` [PATCH 0/3] Update ASUS WMI supported boards Denis Pauk
@ 2021-10-03  6:24   ` Andy Shevchenko
  0 siblings, 0 replies; 19+ messages in thread
From: Andy Shevchenko @ 2021-10-03  6:24 UTC (permalink / raw)
  To: Denis Pauk
  Cc: Eugene Shalygin, matt-testalltheway, Kamil Dudka, Robert Swiecki,
	Kamil Pietrzak, Igor, Tor Vic, Poezevara, Andy Shevchenko,
	Guenter Roeck, Jean Delvare, Linux Kernel Mailing List,
	linux-hwmon

On Sun, Oct 3, 2021 at 12:37 AM Denis Pauk <pauk.denis@gmail.com> wrote:
>
> On Sun,  3 Oct 2021 00:08:53 +0300
> Denis Pauk <pauk.denis@gmail.com> wrote:
>
> Patches should be applied over
> git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git:hwmon-next
> (0889b7c73a4d8eaaa321eafcf66835979ead862a)

You may use --base parameter to git format-patch for this.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/3] hwmon: (nct6775) Use custom scale for ASUS motherboards.
  2021-10-02 21:08 ` [PATCH 2/3] hwmon: (nct6775) Use custom scale for " Denis Pauk
@ 2021-10-03  6:30   ` Andy Shevchenko
  2021-10-05 13:52   ` Guenter Roeck
  1 sibling, 0 replies; 19+ messages in thread
From: Andy Shevchenko @ 2021-10-03  6:30 UTC (permalink / raw)
  To: Denis Pauk
  Cc: Kamil Pietrzak, Andy Shevchenko, Guenter Roeck, Jean Delvare,
	Linux Kernel Mailing List, linux-hwmon

On Sun, Oct 3, 2021 at 12:10 AM Denis Pauk <pauk.denis@gmail.com> wrote:
>
> Use custom scaling factor for:
> * TUF GAMING Z490-PLUS
> * TUF GAMING Z490-PLUS (WI-FI)
>
> Voltage scaling factors are based on Asus software on Windows.
>
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
> Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
> Tested-by: Kamil Pietrzak <kpietrzak@disroot.org>

> Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
> Cc: Guenter Roeck <linux@roeck-us.net>

Instead of repeating it in each message, use mail headers, i.e. pass
--cc 'Name One <email@one>, Name Two <email@two>' to git format-patch.

...

> +
> +               if (strcmp(board_name, "TUF GAMING Z490-PLUS") == 0 ||
> +                   strcmp(board_name, "TUF GAMING Z490-PLUS (WI-FI)") == 0)

I would expect this to grow, so do the same trick with match_string().

> +                       custom_scale = true;
>         }


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 0/3] Update ASUS WMI supported boards.
  2021-10-02 21:08 [PATCH 0/3] Update ASUS WMI supported boards Denis Pauk
                   ` (3 preceding siblings ...)
  2021-10-02 21:34 ` [PATCH 0/3] Update ASUS WMI supported boards Denis Pauk
@ 2021-10-03  6:39 ` Andy Shevchenko
  2021-10-03 11:50 ` Oleksandr Natalenko
  5 siblings, 0 replies; 19+ messages in thread
From: Andy Shevchenko @ 2021-10-03  6:39 UTC (permalink / raw)
  To: Denis Pauk
  Cc: Eugene Shalygin, matt-testalltheway, Kamil Dudka, Robert Swiecki,
	Kamil Pietrzak, Igor, Tor Vic, Poezevara, Andy Shevchenko,
	Guenter Roeck, Jean Delvare, Linux Kernel Mailing List,
	linux-hwmon

On Sun, Oct 3, 2021 at 12:10 AM Denis Pauk <pauk.denis@gmail.com> wrote:
>
> Add support to nct6775:
> * PRIME B360-PLUS
> * PRIME X570-PRO
> * ROG CROSSHAIR VIII FORMULA
> * ROG STRIX B550-I GAMING
> * ROG STRIX X570-F GAMING
> * ROG STRIX Z390-E GAMING
> * TUF GAMING B550-PRO
> * TUF GAMING Z490-PLUS
> * TUF GAMING Z490-PLUS (WI-FI)
>
> Add sensors driver for ASUS motherboards to read sensors from the embedded
> controller. Based on https://github.com/zeule/asus-wmi-ec-sensors.
>
> Could you please review?

I will look at the last patch later on.

> @Andy Shevchenko, @Guenter Roeck should I split last patch in some way?
> Should I add to MAINTAINERS:
> --
> ASUS WMI HARDWARE MONITOR DRIVER
> M:     Eugene Shalygin <eugene.shalygin@gmail.com>
> M:     Denis Pauk <pauk.denis@gmail.com>
> L:     linux-hwmon@vger.kernel.org
> S:     Maintained
> F:     drivers/hwmon/asus_wmi_sensors.c

I don't see right now if the last patch needs a split, but MAINTAINERS
update is better to have.

...

> Signed-off-by: Denis Pauk <pauk.denis@gmail.com>

This makes a little sense in a cover letter (have you used
--cover-letter parameter?).

> Co-developed-by: Eugene Shalygin <eugene.shalygin@gmail.com>
> Signed-off-by: Eugene Shalygin <eugene.shalygin@gmail.com>

This in a similar way, except the outcome is an appearing above
mentioned name in the Cc.

> Tested-by: matt-testalltheway <sefoci9222@rerunway.com>
> Tested-by: Kamil Dudka <kdudka@redhat.com>
> Tested-by: Robert Swiecki <robert@swiecki.net>
> Tested-by: Kamil Pietrzak <kpietrzak@disroot.org>
> Tested-by: Igor <igor@svelig.com>
> Tested-by: Tor Vic <torvic9@mailbox.org>
> Tested-by: Poezevara <nephartyz@gmail.com>

This is fine (and will be reflected in Cc)

> Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
> Cc: Guenter Roeck <linux@roeck-us.net>

This I already talked about.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/3] hwmon: (nct6775) Add additional ASUS motherboards.
  2021-10-02 21:08 ` [PATCH 1/3] hwmon: (nct6775) Add additional ASUS motherboards Denis Pauk
@ 2021-10-03  9:48   ` Andy Shevchenko
  0 siblings, 0 replies; 19+ messages in thread
From: Andy Shevchenko @ 2021-10-03  9:48 UTC (permalink / raw)
  To: Denis Pauk
  Cc: matt-testalltheway, Kamil Dudka, Robert Swiecki, Kamil Pietrzak,
	Igor, Tor Vic, Poezevara, Andy Shevchenko, Guenter Roeck,
	Jean Delvare, Linux Kernel Mailing List, linux-hwmon

On Sun, Oct 3, 2021 at 12:10 AM Denis Pauk <pauk.denis@gmail.com> wrote:
>
> Add support:
> * PRIME B360-PLUS
> * PRIME X570-PRO
> * ROG CROSSHAIR VIII FORMULA
> * ROG STRIX B550-I GAMING
> * ROG STRIX X570-F GAMING
> * ROG STRIX Z390-E GAMING
> * TUF GAMING B550-PRO
> * TUF GAMING Z490-PLUS
> * TUF GAMING Z490-PLUS (WI-FI)

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
> Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
> Tested-by: matt-testalltheway <sefoci9222@rerunway.com>
> Tested-by: Kamil Dudka <kdudka@redhat.com>
> Tested-by: Robert Swiecki <robert@swiecki.net>
> Tested-by: Kamil Pietrzak <kpietrzak@disroot.org>
> Tested-by: Igor <igor@svelig.com>
> Tested-by: Tor Vic <torvic9@mailbox.org>
> Tested-by: Poezevara <nephartyz@gmail.com>
> Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
> Cc: Guenter Roeck <linux@roeck-us.net>
> ---
>  drivers/hwmon/nct6775.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
> index aa58ead0ad43..8eaf86ea2433 100644
> --- a/drivers/hwmon/nct6775.c
> +++ b/drivers/hwmon/nct6775.c
> @@ -4986,20 +4986,29 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
>  static struct platform_device *pdev[2];
>
>  static const char * const asus_wmi_boards[] = {
> +       "PRIME B360-PLUS",
>         "PRIME B460-PLUS",
> +       "PRIME X570-PRO",
>         "ROG CROSSHAIR VIII DARK HERO",
> +       "ROG CROSSHAIR VIII FORMULA",
>         "ROG CROSSHAIR VIII HERO",
>         "ROG CROSSHAIR VIII IMPACT",
>         "ROG STRIX B550-E GAMING",
>         "ROG STRIX B550-F GAMING",
>         "ROG STRIX B550-F GAMING (WI-FI)",
> +       "ROG STRIX B550-I GAMING",
> +       "ROG STRIX X570-F GAMING",
> +       "ROG STRIX Z390-E GAMING",
>         "ROG STRIX Z490-I GAMING",
>         "TUF GAMING B550M-PLUS",
>         "TUF GAMING B550M-PLUS (WI-FI)",
>         "TUF GAMING B550-PLUS",
> +       "TUF GAMING B550-PRO",
>         "TUF GAMING X570-PLUS",
>         "TUF GAMING X570-PLUS (WI-FI)",
>         "TUF GAMING X570-PRO (WI-FI)",
> +       "TUF GAMING Z490-PLUS",
> +       "TUF GAMING Z490-PLUS (WI-FI)",
>  };
>
>  static int __init sensors_nct6775_init(void)
> --
> 2.33.0
>


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/3] hwmon: (asus_wmi_sensors) Support access via Asus WMI.
  2021-10-02 21:08 ` [PATCH 3/3] hwmon: (asus_wmi_sensors) Support access via Asus WMI Denis Pauk
  2021-10-02 21:56   ` Eugene Shalygin
@ 2021-10-03 10:34   ` Andy Shevchenko
  1 sibling, 0 replies; 19+ messages in thread
From: Andy Shevchenko @ 2021-10-03 10:34 UTC (permalink / raw)
  To: Denis Pauk
  Cc: Eugene Shalygin, Andy Shevchenko, Guenter Roeck, Jean Delvare,
	Linux Kernel Mailing List, linux-hwmon

On Sun, Oct 3, 2021 at 12:10 AM Denis Pauk <pauk.denis@gmail.com> wrote:
>
> 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.
>
> Supported motherboards:
> * ROG CROSSHAIR VIII HERO
> * ROG CROSSHAIR VIII DARK HERO
> * ROG CROSSHAIR VIII FORMULA
> * ROG STRIX X570-E GAMING
> * ROG STRIX B550-E GAMING

...

> +config SENSORS_ASUS_WMI
> +       tristate "ASUS WMI"

Provide a better short description here.

> +       depends on X86

COMPILE_TEST ?

> +       help
> +         If you say yes here you get support for the ACPI hardware
> +         monitoring interface found in many ASUS motherboards. This
> +         driver will provide readings of fans, voltages and temperatures
> +         through the system firmware.
> +
> +         This driver can also be built as a module. If so, the module
> +         will be called asus_wmi_sensors.

...

> +/*

> + * HWMON driver for ASUS motherboards that publish some sensor values
> + * via the embedded controller registers

I would drop the word 'some' here and...

> + *
> + * Copyright (C) 2021 Eugene Shalygin <eugene.shalygin@gmail.com>
> + * Copyright (C) 2018-2019 Ed Brindley <kernel@maidavale.org>

...add a bit more elaborative text here to explain what values are
provided and what aren't.

> + */
...

> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

Any real need for this?

...

> +#define DRVNAME "asus_wmi_sensors"

Can you use this directly?

...

> +#include <linux/dmi.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/init.h>
> +#include <linux/jiffies.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/platform_device.h>
> +#include <linux/acpi.h>
> +#include <linux/wmi.h>

Sorted?

...

> +struct asus_wmi_ec_info {
> +       struct asus_wmi_ec_sensor_info sensors[ASUSWMI_SENSORS_MAX];
> +       /* UTF-16 string to pass to BRxx() WMI function */
> +       char read_arg[((ASUS_WMI_BLOCK_READ_REGISTERS_MAX * 4) + 1) * 2];
> +       u8 read_buffer[ASUS_WMI_BLOCK_READ_REGISTERS_MAX];
> +       u8 nr_sensors; /* number of board EC sensors */
> +       /* number of EC registers to read (sensor might span more than 1 register) */
> +       u8 nr_registers;
> +       unsigned long last_updated; /* in jiffies */
> +};

Convert those comments to a proper kernel doc format?

...

> +/*
> + * The next four functions converts to/from BRxx string argument format
> + * The format of the string is as follows:
> + * The string consists of two-byte UTF-16 characters
> + * The value of the very first byte int the string is equal to the total length
> + * of the next string in bytes, thus excluding the first two-byte character
> + * The rest of the string encodes pairs of (bank, index) pairs, where both
> + * values are byte-long (0x00 to 0xFF)
> + * Numbers are encoded as UTF-16 hex values
> + */

All above can probably use existing functions?
https://elixir.bootlin.com/linux/latest/source/fs/nls/nls_base.c#L132

...

> +static void asus_wmi_ec_make_block_read_query(struct asus_wmi_ec_info *ec)
> +{
> +       u16 registers[ASUS_EC_KNOWN_EC_REGISTERS];
> +       u8 i, j, register_idx = 0;

> +       /* if we can get values for all the registers in a single query,
> +        * the query will not change from call to call
> +        */

/*
 * Wrong multi-line style is in
 * use. Compare to this comment.
 */

> +       if (ec->nr_registers <= ASUS_WMI_BLOCK_READ_REGISTERS_MAX &&
> +           ec->read_arg[0] > 0) {
> +               /* no need to update */
> +               return;
> +       }
> +
> +       for (i = 0; i < ec->nr_sensors; ++i) {
> +               for (j = 0; j < ec->sensors[i].addr.addr.size;

> +                    ++j, ++register_idx) {

Here and in plenty other places, why _pre_-increment (or
_pre_-decrement in some cases)?

> +                       registers[register_idx] =
> +                               (ec->sensors[i].addr.addr.bank << 8) +
> +                               ec->sensors[i].addr.addr.index + j;
> +               }
> +       }
> +
> +       asus_wmi_ec_encode_registers(registers, ec->nr_registers, ec->read_arg);
> +}
> +
> +static int asus_wmi_ec_block_read(u32 method_id, const char *query, u8 *out)
> +{
> +       struct acpi_buffer input;

> +       struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER,
> +                                     NULL }; // TODO use pre-allocated buffer

One line and drop this TODO, or fulfil it.

> +       acpi_status status;
> +       union acpi_object *obj;
> +
> +       /* the first byte of the BRxx() argument string has to be the string size */
> +       input.length = (acpi_size)query[0] + 2;

> +       input.pointer = (void *)query;

Redundant casting. Or is this due to const qualifier?

> +       status = wmi_evaluate_method(ASUSWMI_MONITORING_GUID, 0, method_id, &input,
> +                                    &output);

> +

Here and in plenty of other places, redundant blank lines.

> +       if (ACPI_FAILURE(status)) {

> +               acpi_os_free(output.pointer);

Is it needed?

> +               return -EIO;
> +       }
> +
> +       obj = output.pointer;
> +       if (!obj || obj->type != ACPI_TYPE_BUFFER) {

> +               pr_err("unexpected reply type from ASUS ACPI code");

dev_err()

> +               acpi_os_free(output.pointer);

When !obj, this is not needed.

> +               return -EIO;
> +       }
> +       asus_wmi_ec_decode_reply_buffer(obj->buffer.pointer, out);
> +       acpi_os_free(output.pointer);
> +       return 0;
> +}
> +
> +static int asus_wmi_ec_update_ec_sensors(struct asus_wmi_ec_info *ec)
> +{
> +       struct asus_wmi_ec_sensor_info *si;
> +       u32 value;
> +       int status;
> +       u8 i_sensor, read_reg_ct, i_sensor_register;

Here and in all cases, reversed xmas tree order?

> +       asus_wmi_ec_make_block_read_query(ec);
> +       status = asus_wmi_ec_block_read(ASUSWMI_METHODID_BLOCK_READ_EC,
> +                                       ec->read_arg,
> +                                       ec->read_buffer);
> +       if (status)
> +               return status;
> +
> +       read_reg_ct = 0;
> +       for (i_sensor = 0; i_sensor < ec->nr_sensors; ++i_sensor) {

Why _pre_-increment?

> +               si = &ec->sensors[i_sensor];
> +               value = ec->read_buffer[read_reg_ct++];
> +               for (i_sensor_register = 1;
> +                    i_sensor_register < si->addr.addr.size;

> +                    ++i_sensor_register) {

Why _pre_-increment?

> +                       value <<= 8;
> +                       value += ec->read_buffer[read_reg_ct++];
> +               }

Is it something like get_unaligned_...32()?
Or some ...32_to_cpu() ?

Also provide the corresponding __le32/__be32 types where it's needed.

> +               si->cached_value = value;
> +       }
> +       return 0;
> +}

...

> +static int asus_wmi_ec_scale_sensor_value(u32 value, int data_type)
> +{
> +       switch (data_type) {
> +       case hwmon_curr:
> +       case hwmon_temp:
> +       case hwmon_in:

> +               return value * 1000;

In units.h we have SI multipliers, can you use one to show what is this exactly?

> +       default:
> +               return value;
> +       }
> +}
> +
> +static u8 asus_wmi_ec_find_sensor_index(const struct asus_wmi_ec_info *ec,
> +                                       enum hwmon_sensor_types type, int channel)
> +{
> +       u8 i;

In some cases you are using int i, here u8 i. Be consistent and use, e.g.
unsigned int i;
everywhere for (never been negative) counters.

> +       for (i = 0; i < ec->nr_sensors; ++i) {
> +               if (ec->sensors[i].type == type) {
> +                       if (channel == 0)
> +                               return i;

> +                       --channel;

Why _pre_-decrement?

> +               }
> +       }

> +       return 0xFF;

0xff, but why? Can't you use the proper error code instead?

> +}
> +
> +static int asus_wmi_ec_get_cached_value_or_update(int sensor_index,
> +                                                 struct asus_wmi_sensors *state,
> +                                                 u32 *value)
> +{
> +       int ret;
> +
> +       if (time_after(jiffies, state->ec.last_updated + HZ)) {

> +               ret = asus_wmi_ec_update_ec_sensors(&state->ec);

> +

Redundant blank line.

> +               if (ret) {

> +                       pr_err("asus_wmi_ec_update_ec_sensors() failure\n");

Can you use dev_err()?

> +                       return -EIO;

Why shadowed the real error code? Or is it not an error code there?

> +               }
> +
> +               state->ec.last_updated = jiffies;
> +       }
> +
> +       *value = state->ec.sensors[sensor_index].cached_value;
> +       return 0;
> +}
> +
> +/*
> + * Now follow the functions that implement the hwmon interface
> + */
> +
> +static int asus_wmi_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
> +                                 u32 attr, int channel, long *val)
> +{
> +       int ret;
> +       u32 value = 0;
> +       struct asus_wmi_sensors *sensor_data = dev_get_drvdata(dev);
> +
> +       u8 sidx = asus_wmi_ec_find_sensor_index(&sensor_data->ec, type, channel);
> +
> +       mutex_lock(&sensor_data->lock);

> +

Seems redundant blank line.

> +       ret = asus_wmi_ec_get_cached_value_or_update(sidx, sensor_data, &value);
> +       mutex_unlock(&sensor_data->lock);

> +       if (!ret)
> +               *val = asus_wmi_ec_scale_sensor_value(value, sensor_data->ec.sensors[sidx].type);
> +
> +       return ret;

Why not the standard pattern?

mutex_lock(...);
ret = ...;
mutex_unlock(...);
if (ret)
  return ret;

*val = ...
return 0;


> +}

...

> +static umode_t asus_wmi_ec_hwmon_is_visible(const void *drvdata,
> +                                           enum hwmon_sensor_types type, u32 attr,
> +                                           int channel)
> +{
> +       const struct asus_wmi_sensors *sensor_data = drvdata;

> +       return asus_wmi_ec_find_sensor_index(&sensor_data->ec, type, channel) != 0xFF ?
> +                            0444 :
> +                            0;

This will look better with temporary variables

... index;

index = asus_wmi_ec_find_sensor_index();
return index == 0xff ? 0 : 0444;

(also note small letters for hex value).

> +}
> +
> +static int asus_wmi_hwmon_add_chan_info(struct hwmon_channel_info *asus_wmi_hwmon_chan,
> +                                       struct device *dev, int num,
> +                                       enum hwmon_sensor_types type, u32 config)
> +{
> +       int i;

> +       u32 *cfg = devm_kcalloc(dev, num + 1, sizeof(*cfg), GFP_KERNEL);
> +
> +       if (!cfg)
> +               return -ENOMEM;

Use the following pattern which is slightly better.

u32 *cfg;

cfg = ...;
if (!cfg)
  return -ENOMEM;

> +       asus_wmi_hwmon_chan->type = type;
> +       asus_wmi_hwmon_chan->config = cfg;

> +       for (i = 0; i < num; i++, cfg++)
> +               *cfg = config;

memset32() ?

> +       return 0;
> +}

...

> +static struct hwmon_chip_info asus_wmi_ec_chip_info = {
> +       .ops = &asus_wmi_ec_hwmon_ops,

> +       .info = NULL,

Redundant assignment.

> +};
> +
> +static int asus_wmi_ec_configure_sensor_setup(struct platform_device *pdev,
> +                                             struct asus_wmi_sensors *sensor_data)
> +{
> +       int i;
> +       int nr_count[HWMON_MAX] = { 0 }, nr_types = 0;
> +       struct device *hwdev;
> +       struct device *dev = &pdev->dev;
> +       struct hwmon_channel_info *asus_wmi_hwmon_chan;
> +       const struct hwmon_channel_info **ptr_asus_wmi_ci;
> +       const struct hwmon_chip_info *chip_info;
> +       const struct asus_wmi_ec_sensor_info *si;
> +       enum hwmon_sensor_types type;

Reversed xmas tree order?

> +       if (sensor_data->ec_board < 0)
> +               return 0;

Is it ever possible?

> +       asus_wmi_ec_fill_board_sensors(&sensor_data->ec, sensor_data->ec_board);
> +
> +       if (!sensor_data->ec.nr_sensors)
> +               return -ENODEV;
> +
> +       for (i = 0; i < sensor_data->ec.nr_sensors; ++i) {
> +               si = &sensor_data->ec.sensors[i];
> +               if (!nr_count[si->type])
> +                       ++nr_types;
> +               ++nr_count[si->type];

What's wrong with post increments?

> +       }

> +       if (nr_count[hwmon_temp])
> +               nr_count[hwmon_chip]++, nr_types++;

This is suspicious code. Refactor to make it easier to understand.

> +       asus_wmi_hwmon_chan = devm_kcalloc(dev, nr_types,
> +                                          sizeof(*asus_wmi_hwmon_chan),
> +                                          GFP_KERNEL);
> +       if (!asus_wmi_hwmon_chan)
> +               return -ENOMEM;
> +
> +       ptr_asus_wmi_ci = devm_kcalloc(dev, nr_types + 1,
> +                                      sizeof(*ptr_asus_wmi_ci), GFP_KERNEL);
> +       if (!ptr_asus_wmi_ci)
> +               return -ENOMEM;
> +
> +       asus_wmi_ec_chip_info.info = ptr_asus_wmi_ci;
> +       chip_info = &asus_wmi_ec_chip_info;
> +
> +       for (type = 0; type < HWMON_MAX; type++) {
> +               if (!nr_count[type])
> +                       continue;
> +
> +               asus_wmi_hwmon_add_chan_info(asus_wmi_hwmon_chan, dev,
> +                                            nr_count[type], type,
> +                                            hwmon_attributes[type]);
> +               *ptr_asus_wmi_ci++ = asus_wmi_hwmon_chan++;
> +       }

> +       pr_info("%s board has %d EC sensors that span %d registers",
> +               asus_wmi_ec_boards_names[sensor_data->ec_board],
> +               sensor_data->ec.nr_sensors,
> +               sensor_data->ec.nr_registers);

First of all, why not dev_info()? Second, do you really need this?
Seems to me like a debug leftover.

> +       hwdev = devm_hwmon_device_register_with_info(dev, "asuswmiecsensors",

No delimiters, like -, _ or spaces?

> +                                                    sensor_data, chip_info, NULL);
> +
> +       return PTR_ERR_OR_ZERO(hwdev);
> +}
> +
> +static int asus_wmi_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct asus_wmi_data *data = dev_get_platdata(dev);
> +       struct asus_wmi_sensors *sensor_data;
> +       int err;
> +
> +       sensor_data = devm_kzalloc(dev, sizeof(struct asus_wmi_sensors),
> +                                  GFP_KERNEL);
> +       if (!sensor_data)
> +               return -ENOMEM;
> +
> +       mutex_init(&sensor_data->lock);
> +       sensor_data->ec_board = data->ec_board;
> +
> +       platform_set_drvdata(pdev, sensor_data);
> +
> +       /* ec init */

> +       err = asus_wmi_ec_configure_sensor_setup(pdev,
> +                                                sensor_data);
> +
> +       return err;

return asus_wmi_ec_configure_sensor_setup(...);

> +}

...

> +static struct platform_driver asus_wmi_sensors_platform_driver = {
> +       .driver = {
> +               .name   = "asus-wmi-sensors",
> +       },
> +       .probe = asus_wmi_probe

+ Comma.

> +};

...

> +static int __init asus_wmi_init(void)
> +{
> +       const char *board_vendor, *board_name;
> +       struct asus_wmi_data data;
> +
> +       data.ec_board = -1;
> +
> +       board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
> +       board_name = dmi_get_system_info(DMI_BOARD_NAME);
> +
> +       if (board_vendor && board_name &&
> +           !strcmp(board_vendor, "ASUSTeK COMPUTER INC.")) {
> +               if (!wmi_has_guid(ASUSWMI_MONITORING_GUID))
> +                       return -ENODEV;
> +
> +               data.ec_board = match_string(asus_wmi_ec_boards_names,
> +                                            ARRAY_SIZE(asus_wmi_ec_boards_names),
> +                                            board_name);
> +       }
> +
> +       /* Nothing to support */
> +       if (data.ec_board < 0)
> +               return -ENODEV;
> +
> +       sensors_pdev = platform_create_bundle(&asus_wmi_sensors_platform_driver,
> +                                             asus_wmi_probe,
> +                                             NULL, 0,
> +                                             &data, sizeof(struct asus_wmi_data));

> +       if (IS_ERR(sensors_pdev))
> +               return PTR_ERR(sensors_pdev);
> +
> +       return 0;

return PTR_ERR_OR_ZERO();

> +}
> +
> +static void __exit asus_wmi_exit(void)
> +{
> +       platform_device_unregister(sensors_pdev);
> +       platform_driver_unregister(&asus_wmi_sensors_platform_driver);
> +}

Can we decouple driver and board code? And put board code to the PDx86 folder?

...

> +MODULE_VERSION("1");

No, the version of the driver is the same as git commit ID. Drop this.

...

> +module_init(asus_wmi_init);
> +module_exit(asus_wmi_exit);

Can you move this to the respective functions?

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 0/3] Update ASUS WMI supported boards.
  2021-10-02 21:08 [PATCH 0/3] Update ASUS WMI supported boards Denis Pauk
                   ` (4 preceding siblings ...)
  2021-10-03  6:39 ` Andy Shevchenko
@ 2021-10-03 11:50 ` Oleksandr Natalenko
  2021-10-03 12:47   ` Oleksandr Natalenko
  5 siblings, 1 reply; 19+ messages in thread
From: Oleksandr Natalenko @ 2021-10-03 11:50 UTC (permalink / raw)
  To: Denis Pauk
  Cc: pauk.denis, Eugene Shalygin, matt-testalltheway, Kamil Dudka,
	Robert Swiecki, Kamil Pietrzak, Igor, Tor Vic, Poezevara,
	Andy Shevchenko, Guenter Roeck, Jean Delvare, linux-kernel,
	linux-hwmon

Hello.

On sobota 2. října 2021 23:08:53 CEST Denis Pauk wrote:
> Add support to nct6775:
> * PRIME B360-PLUS
> * PRIME X570-PRO
> * ROG CROSSHAIR VIII FORMULA
> * ROG STRIX B550-I GAMING
> * ROG STRIX X570-F GAMING
> * ROG STRIX Z390-E GAMING
> * TUF GAMING B550-PRO
> * TUF GAMING Z490-PLUS
> * TUF GAMING Z490-PLUS (WI-FI)

Thank you for this submission.

Do you happen to know whether it can be extended with another ASUS board which 
is:

```
Manufacturer: ASUSTeK COMPUTER INC.
Product Name: Pro WS X570-ACE
```

?

I've got one, and in case any info or testing is needed, I'd be happy to 
contribute.

Currently, this board is kinda working after adding 
`acpi_enforce_resources=lax`, but I assume a proper support is needed instead.

Thanks.

> Add sensors driver for ASUS motherboards to read sensors from the embedded
> controller. Based on https://github.com/zeule/asus-wmi-ec-sensors.
> 
> Could you please review?
> 
> @Andy Shevchenko, @Guenter Roeck should I split last patch in some way?
> Should I add to MAINTAINERS:
> --
> ASUS WMI HARDWARE MONITOR DRIVER
> M:     Eugene Shalygin <eugene.shalygin@gmail.com>
> M:     Denis Pauk <pauk.denis@gmail.com>
> L:     linux-hwmon@vger.kernel.org
> S:     Maintained
> F:     drivers/hwmon/asus_wmi_sensors.c
> --
> 
> 
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
> Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
> Co-developed-by: Eugene Shalygin <eugene.shalygin@gmail.com>
> Signed-off-by: Eugene Shalygin <eugene.shalygin@gmail.com>
> Tested-by: matt-testalltheway <sefoci9222@rerunway.com>
> Tested-by: Kamil Dudka <kdudka@redhat.com>
> Tested-by: Robert Swiecki <robert@swiecki.net>
> Tested-by: Kamil Pietrzak <kpietrzak@disroot.org>
> Tested-by: Igor <igor@svelig.com>
> Tested-by: Tor Vic <torvic9@mailbox.org>
> Tested-by: Poezevara <nephartyz@gmail.com>
> Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
> Cc: Guenter Roeck <linux@roeck-us.net>
> 
> ---
> Denis Pauk (3):
>   hwmon: (nct6775) Add additional ASUS motherboards.
>   hwmon: (nct6775) Use custom scale for ASUS motherboards.
>   hwmon: (asus_wmi_sensors) Support access via Asus WMI.
> 
>  drivers/hwmon/Kconfig            |  12 +
>  drivers/hwmon/Makefile           |   1 +
>  drivers/hwmon/asus_wmi_sensors.c | 595 +++++++++++++++++++++++++++++++
>  drivers/hwmon/nct6775.c          |  41 ++-
>  4 files changed, 643 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/hwmon/asus_wmi_sensors.c


-- 
Oleksandr Natalenko (post-factum)



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 0/3] Update ASUS WMI supported boards.
  2021-10-03 11:50 ` Oleksandr Natalenko
@ 2021-10-03 12:47   ` Oleksandr Natalenko
  2021-10-03 12:53     ` Eugene Shalygin
  0 siblings, 1 reply; 19+ messages in thread
From: Oleksandr Natalenko @ 2021-10-03 12:47 UTC (permalink / raw)
  To: Denis Pauk
  Cc: pauk.denis, Eugene Shalygin, matt-testalltheway, Kamil Dudka,
	Robert Swiecki, Kamil Pietrzak, Igor, Tor Vic, Poezevara,
	Andy Shevchenko, Guenter Roeck, Jean Delvare, linux-kernel,
	linux-hwmon

Hello.

On neděle 3. října 2021 13:50:12 CEST Oleksandr Natalenko wrote:
> On sobota 2. října 2021 23:08:53 CEST Denis Pauk wrote:
> > Add support to nct6775:
> > * PRIME B360-PLUS
> > * PRIME X570-PRO
> > * ROG CROSSHAIR VIII FORMULA
> > * ROG STRIX B550-I GAMING
> > * ROG STRIX X570-F GAMING
> > * ROG STRIX Z390-E GAMING
> > * TUF GAMING B550-PRO
> > * TUF GAMING Z490-PLUS
> > * TUF GAMING Z490-PLUS (WI-FI)
> 
> Thank you for this submission.
> 
> Do you happen to know whether it can be extended with another ASUS board
> which is:
> 
> ```
> Manufacturer: ASUSTeK COMPUTER INC.
> Product Name: Pro WS X570-ACE
> ```
> 
> ?
> 
> I've got one, and in case any info or testing is needed, I'd be happy to
> contribute.
> 
> Currently, this board is kinda working after adding
> `acpi_enforce_resources=lax`, but I assume a proper support is needed
> instead.

Partially answering to myself, but still need some clarification.

I did this on top of your recent submissions:

```
diff --git a/drivers/hwmon/asus_wmi_sensors.c b/drivers/hwmon/
asus_wmi_sensors.c
index 6b04fad18891..f6817ec9de29 100644
--- a/drivers/hwmon/asus_wmi_sensors.c
+++ b/drivers/hwmon/asus_wmi_sensors.c
@@ -35,6 +35,7 @@
 #define ASUS_EC_KNOWN_EC_REGISTERS 14
 
 enum asus_wmi_ec_board {
+	BOARD_PW_X570_A, // Pro WS X570-ACE
 	BOARD_R_C8H, // ROG Crosshair VIII Hero
 	BOARD_R_C8DH, // ROG Crosshair VIII Dark Hero
 	BOARD_R_C8F, // ROG Crosshair VIII Formula
@@ -44,6 +45,7 @@ enum asus_wmi_ec_board {
 
 /* boards with EC support */
 static const char *const asus_wmi_ec_boards_names[] = {
+	[BOARD_PW_X570_A] = "Pro WS X570-ACE",
 	[BOARD_R_C8H] = "ROG CROSSHAIR VIII HERO",
 	[BOARD_R_C8DH] = "ROG CROSSHAIR VIII DARK HERO",
 	[BOARD_R_C8F] = "ROG CROSSHAIR VIII FORMULA",
@@ -130,6 +132,7 @@ static void asus_wmi_ec_fill_board_sensors(struct 
asus_wmi_ec_info *ec, int boar
 	ec->nr_registers = 0;
 
 	switch (board) {
+	case BOARD_PW_X570_A:
 	case BOARD_RS_B550_E_G:
 	case BOARD_RS_X570_E_G:
 	case BOARD_R_C8H:
@@ -153,6 +156,7 @@ static void asus_wmi_ec_fill_board_sensors(struct 
asus_wmi_ec_info *ec, int boar
 	}
 
 	switch (board) {
+	case BOARD_PW_X570_A:
 	case BOARD_RS_X570_E_G:
 	case BOARD_R_C8H:
 	case BOARD_R_C8DH:
@@ -166,6 +170,7 @@ static void asus_wmi_ec_fill_board_sensors(struct 
asus_wmi_ec_info *ec, int boar
 	}
 
 	switch (board) {
+	case BOARD_PW_X570_A:
 	case BOARD_RS_X570_E_G:
 	case BOARD_R_C8H:
 	case BOARD_R_C8F:
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index ba18c1cbf572..ff28ba70a8b3 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -5000,6 +5000,7 @@ static int __init nct6775_find(int sioaddr, struct 
nct6775_sio_data *sio_data)
 static struct platform_device *pdev[2];
 
 static const char * const asus_wmi_boards[] = {
+	"Pro WS X570-ACE",
 	"PRIME B360-PLUS",
 	"PRIME B460-PLUS",
 	"PRIME X570-PRO",
```

Now, with nct6775 I do not need `acpi_enforce_resources=lax` any more, and it 
works straight away:

```
nct6798-isa-0290
Adapter: ISA adapter
in0:                        1.06 V  (min =  +0.00 V, max =  +1.74 V)
in1:                        1.02 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in2:                        3.38 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in3:                        3.36 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in4:                        1.74 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in5:                      592.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in6:                        1.09 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in7:                        3.38 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in8:                        3.25 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in9:                      888.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in10:                       8.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in11:                      80.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
in12:                       1.02 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in13:                       1.35 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
in14:                     888.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
fan1:                      743 RPM  (min =    0 RPM)
fan2:                      366 RPM  (min =    0 RPM)
fan3:                      724 RPM  (min =    0 RPM)
fan4:                        0 RPM  (min =    0 RPM)
fan7:                        0 RPM  (min =    0 RPM)
SYSTIN:                    +35.0°C  (high = +80.0°C, hyst = +75.0°C)  sensor = 
thermistor
CPUTIN:                    +43.0°C  (high = +80.0°C, hyst = +75.0°C)  sensor = 
thermistor
AUXTIN0:                   +22.0°C    sensor = thermistor
AUXTIN1:                  +127.0°C    sensor = thermistor
AUXTIN2:                  +109.0°C    sensor = thermistor
AUXTIN3:                   +32.0°C    sensor = thermistor
PECI Agent 0 Calibration:  +44.5°C
PCH_CHIP_CPU_MAX_TEMP:      +0.0°C
PCH_CHIP_TEMP:              +0.0°C
PCH_CPU_TEMP:               +0.0°C
intrusion0:               ALARM
intrusion1:               OK
beep_enable:              disabled
```

With asus_wmi_sensors I get this:

```
asuswmiecsensors-isa-0000
Adapter: ISA adapter
CPU_Opt:        0 RPM
Chipset:     1733 RPM
Chipset:      +58.0°C  
CPU:          +45.0°C  
Motherboard:  +35.0°C  
T_Sensor:    +216.0°C  
VRM:          +34.0°C  
CPU:           7.00 A
```

Everything seems to be good except that `T_Sensor`. Probably, I should exclude 
it on this board?

If you are fine with the approach above, I'll post 2 patches for this board.

Thanks.

-- 
Oleksandr Natalenko (post-factum)



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 0/3] Update ASUS WMI supported boards.
  2021-10-03 12:47   ` Oleksandr Natalenko
@ 2021-10-03 12:53     ` Eugene Shalygin
  2021-10-03 13:00       ` Oleksandr Natalenko
  0 siblings, 1 reply; 19+ messages in thread
From: Eugene Shalygin @ 2021-10-03 12:53 UTC (permalink / raw)
  To: Oleksandr Natalenko
  Cc: Denis Pauk, matt-testalltheway, Kamil Dudka, Robert Swiecki,
	Kamil Pietrzak, Igor, Tor Vic, Poezevara, Andy Shevchenko,
	Guenter Roeck, Jean Delvare, linux-kernel, linux-hwmon

Hello Oleksandr,

216 ⁰C is a blank value. According to
https://www.asus.com/Motherboards-Components/Motherboards/Workstation/Pro-WS-X570-ACE/techspec/
there is no T_Sensor header on this board.

Best regards,
Eugene

On Sun, 3 Oct 2021 at 14:47, Oleksandr Natalenko
<oleksandr@natalenko.name> wrote:
>
> Hello.
>
> On neděle 3. října 2021 13:50:12 CEST Oleksandr Natalenko wrote:
> > On sobota 2. října 2021 23:08:53 CEST Denis Pauk wrote:
> > > Add support to nct6775:
> > > * PRIME B360-PLUS
> > > * PRIME X570-PRO
> > > * ROG CROSSHAIR VIII FORMULA
> > > * ROG STRIX B550-I GAMING
> > > * ROG STRIX X570-F GAMING
> > > * ROG STRIX Z390-E GAMING
> > > * TUF GAMING B550-PRO
> > > * TUF GAMING Z490-PLUS
> > > * TUF GAMING Z490-PLUS (WI-FI)
> >
> > Thank you for this submission.
> >
> > Do you happen to know whether it can be extended with another ASUS board
> > which is:
> >
> > ```
> > Manufacturer: ASUSTeK COMPUTER INC.
> > Product Name: Pro WS X570-ACE
> > ```
> >
> > ?
> >
> > I've got one, and in case any info or testing is needed, I'd be happy to
> > contribute.
> >
> > Currently, this board is kinda working after adding
> > `acpi_enforce_resources=lax`, but I assume a proper support is needed
> > instead.
>
> Partially answering to myself, but still need some clarification.
>
> I did this on top of your recent submissions:
>
> ```
> diff --git a/drivers/hwmon/asus_wmi_sensors.c b/drivers/hwmon/
> asus_wmi_sensors.c
> index 6b04fad18891..f6817ec9de29 100644
> --- a/drivers/hwmon/asus_wmi_sensors.c
> +++ b/drivers/hwmon/asus_wmi_sensors.c
> @@ -35,6 +35,7 @@
>  #define ASUS_EC_KNOWN_EC_REGISTERS 14
>
>  enum asus_wmi_ec_board {
> +       BOARD_PW_X570_A, // Pro WS X570-ACE
>         BOARD_R_C8H, // ROG Crosshair VIII Hero
>         BOARD_R_C8DH, // ROG Crosshair VIII Dark Hero
>         BOARD_R_C8F, // ROG Crosshair VIII Formula
> @@ -44,6 +45,7 @@ enum asus_wmi_ec_board {
>
>  /* boards with EC support */
>  static const char *const asus_wmi_ec_boards_names[] = {
> +       [BOARD_PW_X570_A] = "Pro WS X570-ACE",
>         [BOARD_R_C8H] = "ROG CROSSHAIR VIII HERO",
>         [BOARD_R_C8DH] = "ROG CROSSHAIR VIII DARK HERO",
>         [BOARD_R_C8F] = "ROG CROSSHAIR VIII FORMULA",
> @@ -130,6 +132,7 @@ static void asus_wmi_ec_fill_board_sensors(struct
> asus_wmi_ec_info *ec, int boar
>         ec->nr_registers = 0;
>
>         switch (board) {
> +       case BOARD_PW_X570_A:
>         case BOARD_RS_B550_E_G:
>         case BOARD_RS_X570_E_G:
>         case BOARD_R_C8H:
> @@ -153,6 +156,7 @@ static void asus_wmi_ec_fill_board_sensors(struct
> asus_wmi_ec_info *ec, int boar
>         }
>
>         switch (board) {
> +       case BOARD_PW_X570_A:
>         case BOARD_RS_X570_E_G:
>         case BOARD_R_C8H:
>         case BOARD_R_C8DH:
> @@ -166,6 +170,7 @@ static void asus_wmi_ec_fill_board_sensors(struct
> asus_wmi_ec_info *ec, int boar
>         }
>
>         switch (board) {
> +       case BOARD_PW_X570_A:
>         case BOARD_RS_X570_E_G:
>         case BOARD_R_C8H:
>         case BOARD_R_C8F:
> diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
> index ba18c1cbf572..ff28ba70a8b3 100644
> --- a/drivers/hwmon/nct6775.c
> +++ b/drivers/hwmon/nct6775.c
> @@ -5000,6 +5000,7 @@ static int __init nct6775_find(int sioaddr, struct
> nct6775_sio_data *sio_data)
>  static struct platform_device *pdev[2];
>
>  static const char * const asus_wmi_boards[] = {
> +       "Pro WS X570-ACE",
>         "PRIME B360-PLUS",
>         "PRIME B460-PLUS",
>         "PRIME X570-PRO",
> ```
>
> Now, with nct6775 I do not need `acpi_enforce_resources=lax` any more, and it
> works straight away:
>
> ```
> nct6798-isa-0290
> Adapter: ISA adapter
> in0:                        1.06 V  (min =  +0.00 V, max =  +1.74 V)
> in1:                        1.02 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
> in2:                        3.38 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
> in3:                        3.36 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
> in4:                        1.74 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
> in5:                      592.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
> in6:                        1.09 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
> in7:                        3.38 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
> in8:                        3.25 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
> in9:                      888.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
> in10:                       8.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
> in11:                      80.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
> in12:                       1.02 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
> in13:                       1.35 V  (min =  +0.00 V, max =  +0.00 V)  ALARM
> in14:                     888.00 mV (min =  +0.00 V, max =  +0.00 V)  ALARM
> fan1:                      743 RPM  (min =    0 RPM)
> fan2:                      366 RPM  (min =    0 RPM)
> fan3:                      724 RPM  (min =    0 RPM)
> fan4:                        0 RPM  (min =    0 RPM)
> fan7:                        0 RPM  (min =    0 RPM)
> SYSTIN:                    +35.0°C  (high = +80.0°C, hyst = +75.0°C)  sensor =
> thermistor
> CPUTIN:                    +43.0°C  (high = +80.0°C, hyst = +75.0°C)  sensor =
> thermistor
> AUXTIN0:                   +22.0°C    sensor = thermistor
> AUXTIN1:                  +127.0°C    sensor = thermistor
> AUXTIN2:                  +109.0°C    sensor = thermistor
> AUXTIN3:                   +32.0°C    sensor = thermistor
> PECI Agent 0 Calibration:  +44.5°C
> PCH_CHIP_CPU_MAX_TEMP:      +0.0°C
> PCH_CHIP_TEMP:              +0.0°C
> PCH_CPU_TEMP:               +0.0°C
> intrusion0:               ALARM
> intrusion1:               OK
> beep_enable:              disabled
> ```
>
> With asus_wmi_sensors I get this:
>
> ```
> asuswmiecsensors-isa-0000
> Adapter: ISA adapter
> CPU_Opt:        0 RPM
> Chipset:     1733 RPM
> Chipset:      +58.0°C
> CPU:          +45.0°C
> Motherboard:  +35.0°C
> T_Sensor:    +216.0°C
> VRM:          +34.0°C
> CPU:           7.00 A
> ```
>
> Everything seems to be good except that `T_Sensor`. Probably, I should exclude
> it on this board?
>
> If you are fine with the approach above, I'll post 2 patches for this board.
>
> Thanks.
>
> --
> Oleksandr Natalenko (post-factum)
>
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 0/3] Update ASUS WMI supported boards.
  2021-10-03 12:53     ` Eugene Shalygin
@ 2021-10-03 13:00       ` Oleksandr Natalenko
  0 siblings, 0 replies; 19+ messages in thread
From: Oleksandr Natalenko @ 2021-10-03 13:00 UTC (permalink / raw)
  To: Eugene Shalygin
  Cc: Denis Pauk, matt-testalltheway, Kamil Dudka, Robert Swiecki,
	Kamil Pietrzak, Igor, Tor Vic, Poezevara, Andy Shevchenko,
	Guenter Roeck, Jean Delvare, linux-kernel, linux-hwmon

Hello.

On neděle 3. října 2021 14:53:32 CEST Eugene Shalygin wrote:
> 216 ⁰C is a blank value. According to
> https://www.asus.com/Motherboards-Components/Motherboards/Workstation/Pro-WS
> -X570-ACE/techspec/ there is no T_Sensor header on this board.

Yup, I've just realized it's a separate header with a separate probe for it. 
Thanks for confirming this!

I'll move `T_Sensor` into a separate `case` then.

-- 
Oleksandr Natalenko (post-factum)



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/3] hwmon: (asus_wmi_sensors) Support access via Asus WMI.
  2021-10-02 21:56   ` Eugene Shalygin
@ 2021-10-03 18:35     ` Eugene Shalygin
  2021-10-03 20:48     ` Denis Pauk
  1 sibling, 0 replies; 19+ messages in thread
From: Eugene Shalygin @ 2021-10-03 18:35 UTC (permalink / raw)
  To: Denis Pauk
  Cc: Andy Shevchenko, Guenter Roeck, Jean Delvare, linux-kernel, linux-hwmon

Hello, Denis,

I've reworked module initialisation [1] to support automatic loading
via MODULE_DEVICE_TABLE(dmi, ...). Could you, please, fetch these
changes?

Best regards,
Eugene

[1] https://github.com/zeule/asus-wmi-ec-sensors/pull/3

On Sat, 2 Oct 2021 at 23:56, Eugene Shalygin <eugene.shalygin@gmail.com> wrote:
>
> Hi, Denis!
>
> Thank you for submitting this driver to the mainline! I have a few
> comments/suggestions, please find them below.
>
> > +#define HWMON_MAX      9
>
> There is a hwmon_max enum member, whose current value is 10.
>
> > +#define ASUS_WMI_BLOCK_READ_REGISTERS_MAX 0x10 /* from the ASUS DSDT source */
> > +/* from the ASUS_WMI_BLOCK_READ_REGISTERS_MAX value */
> > +#define ASUS_WMI_MAX_BUF_LEN 0x80
> Suggestion:
> #define ASUS_WMI_MAX_BUF_LEN 0x80 /* from the
> ASUS_WMI_BLOCK_READ_REGISTERS_MAX value */
>
> > +#define ASUSWMI_SENSORS_MAX 11
> This one is for the EC only, maybe rename it accordingly?
>
> > +struct asus_wmi_data {
> > +       int ec_board;
> > +};
>
> Duplicates the value in the asus_wmi_sensors struct. Refactoring artifact?
>
>              asus_wmi_ec_set_sensor_info(si++, "Water", hwmon_fan,
> > +                                           asus_wmi_ec_make_sensor_address(2, 0x00, 0xBC),
> > +                                           &ec->nr_registers);
> This one is named "W_FLOW" in the BIOS and ASUS software. Maybe append
> "_flow" to the label?
>
> > + * The next four functions converts to/from BRxx string argument format
> convert (remove "s")
>
> > +       // assert(len <= 30)
> Makes little sense in the kernel.
>
> > +static void asus_wmi_ec_make_block_read_query(struct asus_wmi_ec_info *ec)
> > +{
> > +       u16 registers[ASUS_EC_KNOWN_EC_REGISTERS];
> > +       u8 i, j, register_idx = 0;
> > +
> > +       /* if we can get values for all the registers in a single query,
> > +        * the query will not change from call to call
> > +        */
> > +       if (ec->nr_registers <= ASUS_WMI_BLOCK_READ_REGISTERS_MAX &&
> > +           ec->read_arg[0] > 0) {
> > +               /* no need to update */
> > +               return;
> > +       }
> > +
> I would add a test for ec->nr_registers >
> ASUS_WMI_BLOCK_READ_REGISTERS_MAX and a warning log message here.
>
> > +static int asus_wmi_probe(struct platform_device *pdev)
>
> Can we add a module alias or to load the module automatically by other
> means? For module aliases we know DMI parameters for the supported
> boards.
>
> Best regards,
> Eugene

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/3] hwmon: (asus_wmi_sensors) Support access via Asus WMI.
  2021-10-02 21:56   ` Eugene Shalygin
  2021-10-03 18:35     ` Eugene Shalygin
@ 2021-10-03 20:48     ` Denis Pauk
  2021-10-04 14:31       ` Eugene Shalygin
  1 sibling, 1 reply; 19+ messages in thread
From: Denis Pauk @ 2021-10-03 20:48 UTC (permalink / raw)
  To: Eugene Shalygin
  Cc: Andy Shevchenko, Guenter Roeck, Jean Delvare, linux-kernel, linux-hwmon

Hi Eugene,

On Sat, 2 Oct 2021 23:56:20 +0200
Eugene Shalygin <eugene.shalygin@gmail.com> wrote:

> Hi, Denis!
> 
> Thank you for submitting this driver to the mainline! I have a few
> comments/suggestions, please find them below.
> 
> > +#define HWMON_MAX      9  
> 
> There is a hwmon_max enum member, whose current value is 10.
Thank you, I will check.

> 
> > +#define ASUS_WMI_BLOCK_READ_REGISTERS_MAX 0x10 /* from the ASUS
> > DSDT source */ +/* from the ASUS_WMI_BLOCK_READ_REGISTERS_MAX value
> > */ +#define ASUS_WMI_MAX_BUF_LEN 0x80  
> Suggestion:
> #define ASUS_WMI_MAX_BUF_LEN 0x80 /* from the
> ASUS_WMI_BLOCK_READ_REGISTERS_MAX value */
> 
> > +#define ASUSWMI_SENSORS_MAX 11  
> This one is for the EC only, maybe rename it accordingly?
> 
Thank you, I will check.

> > +struct asus_wmi_data {
> > +       int ec_board;
> > +};  
> 
> Duplicates the value in the asus_wmi_sensors struct. Refactoring
> artifact?
>
I have used different structures for data in platform and device.
  
>              asus_wmi_ec_set_sensor_info(si++, "Water", hwmon_fan,
> > +
> > asus_wmi_ec_make_sensor_address(2, 0x00, 0xBC),
> > +                                           &ec->nr_registers);  
> This one is named "W_FLOW" in the BIOS and ASUS software. Maybe append
> "_flow" to the label?
>
Thank you, I will check.
 
> > + * The next four functions converts to/from BRxx string argument
> > format  
> convert (remove "s")
> 
> > +       // assert(len <= 30)  
> Makes little sense in the kernel.
>
Thank you, I will check.
 
> > +static void asus_wmi_ec_make_block_read_query(struct
> > asus_wmi_ec_info *ec) +{
> > +       u16 registers[ASUS_EC_KNOWN_EC_REGISTERS];
> > +       u8 i, j, register_idx = 0;
> > +
> > +       /* if we can get values for all the registers in a single
> > query,
> > +        * the query will not change from call to call
> > +        */
> > +       if (ec->nr_registers <= ASUS_WMI_BLOCK_READ_REGISTERS_MAX &&
> > +           ec->read_arg[0] > 0) {
> > +               /* no need to update */
> > +               return;
> > +       }
> > +  
> I would add a test for ec->nr_registers >
> ASUS_WMI_BLOCK_READ_REGISTERS_MAX and a warning log message here.
>
Thank you, I will check.
 
> > +static int asus_wmi_probe(struct platform_device *pdev)  
> 
> Can we add a module alias or to load the module automatically by other
> means? For module aliases we know DMI parameters for the supported
> boards.
>
I will look, I prefer to reuse same module code for boards with/without
EC endpoints same as in
https://bugzilla.kernel.org/show_bug.cgi?id=204807#c128.

> Best regards,
> Eugene

Best regards,
            Denis.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/3] hwmon: (asus_wmi_sensors) Support access via Asus WMI.
  2021-10-03 20:48     ` Denis Pauk
@ 2021-10-04 14:31       ` Eugene Shalygin
  0 siblings, 0 replies; 19+ messages in thread
From: Eugene Shalygin @ 2021-10-04 14:31 UTC (permalink / raw)
  To: Denis Pauk
  Cc: Andy Shevchenko, Guenter Roeck, Jean Delvare, linux-kernel, linux-hwmon

Hello,

When I first wrote the EC sensor driver, I thought there were only a
few sensor configurations, but it turned out the assumption was wrong
and even with currently supported 6 boards the sensor to board mapping
is already hardly readable. Thus I redone that part in a declarative
way so that the sensor list for each board is condensed and is easy to
digest [1]. Please consider updating the submitted patches.

Best regards,
Eugene

[1] https://github.com/zeule/asus-wmi-ec-sensors/pull/4

On Sun, 3 Oct 2021 at 22:49, Denis Pauk <pauk.denis@gmail.com> wrote:
>
> Hi Eugene,
>
> On Sat, 2 Oct 2021 23:56:20 +0200
> Eugene Shalygin <eugene.shalygin@gmail.com> wrote:
>
> > Hi, Denis!
> >
> > Thank you for submitting this driver to the mainline! I have a few
> > comments/suggestions, please find them below.
> >
> > > +#define HWMON_MAX      9
> >
> > There is a hwmon_max enum member, whose current value is 10.
> Thank you, I will check.
>
> >
> > > +#define ASUS_WMI_BLOCK_READ_REGISTERS_MAX 0x10 /* from the ASUS
> > > DSDT source */ +/* from the ASUS_WMI_BLOCK_READ_REGISTERS_MAX value
> > > */ +#define ASUS_WMI_MAX_BUF_LEN 0x80
> > Suggestion:
> > #define ASUS_WMI_MAX_BUF_LEN 0x80 /* from the
> > ASUS_WMI_BLOCK_READ_REGISTERS_MAX value */
> >
> > > +#define ASUSWMI_SENSORS_MAX 11
> > This one is for the EC only, maybe rename it accordingly?
> >
> Thank you, I will check.
>
> > > +struct asus_wmi_data {
> > > +       int ec_board;
> > > +};
> >
> > Duplicates the value in the asus_wmi_sensors struct. Refactoring
> > artifact?
> >
> I have used different structures for data in platform and device.
>
> >              asus_wmi_ec_set_sensor_info(si++, "Water", hwmon_fan,
> > > +
> > > asus_wmi_ec_make_sensor_address(2, 0x00, 0xBC),
> > > +                                           &ec->nr_registers);
> > This one is named "W_FLOW" in the BIOS and ASUS software. Maybe append
> > "_flow" to the label?
> >
> Thank you, I will check.
>
> > > + * The next four functions converts to/from BRxx string argument
> > > format
> > convert (remove "s")
> >
> > > +       // assert(len <= 30)
> > Makes little sense in the kernel.
> >
> Thank you, I will check.
>
> > > +static void asus_wmi_ec_make_block_read_query(struct
> > > asus_wmi_ec_info *ec) +{
> > > +       u16 registers[ASUS_EC_KNOWN_EC_REGISTERS];
> > > +       u8 i, j, register_idx = 0;
> > > +
> > > +       /* if we can get values for all the registers in a single
> > > query,
> > > +        * the query will not change from call to call
> > > +        */
> > > +       if (ec->nr_registers <= ASUS_WMI_BLOCK_READ_REGISTERS_MAX &&
> > > +           ec->read_arg[0] > 0) {
> > > +               /* no need to update */
> > > +               return;
> > > +       }
> > > +
> > I would add a test for ec->nr_registers >
> > ASUS_WMI_BLOCK_READ_REGISTERS_MAX and a warning log message here.
> >
> Thank you, I will check.
>
> > > +static int asus_wmi_probe(struct platform_device *pdev)
> >
> > Can we add a module alias or to load the module automatically by other
> > means? For module aliases we know DMI parameters for the supported
> > boards.
> >
> I will look, I prefer to reuse same module code for boards with/without
> EC endpoints same as in
> https://bugzilla.kernel.org/show_bug.cgi?id=204807#c128.
>
> > Best regards,
> > Eugene
>
> Best regards,
>             Denis.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/3] hwmon: (nct6775) Use custom scale for ASUS motherboards.
  2021-10-02 21:08 ` [PATCH 2/3] hwmon: (nct6775) Use custom scale for " Denis Pauk
  2021-10-03  6:30   ` Andy Shevchenko
@ 2021-10-05 13:52   ` Guenter Roeck
  1 sibling, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2021-10-05 13:52 UTC (permalink / raw)
  To: Denis Pauk
  Cc: Kamil Pietrzak, Andy Shevchenko, Jean Delvare, linux-kernel, linux-hwmon

On Sun, Oct 03, 2021 at 12:08:55AM +0300, Denis Pauk wrote:
> Use custom scaling factor for:
> * TUF GAMING Z490-PLUS
> * TUF GAMING Z490-PLUS (WI-FI)
> 
> Voltage scaling factors are based on Asus software on Windows.
> 

Scaling is never correct for any SuperIO chips, and is notoriously different
for each and every PC board. I don't want to add per-board scaling data to
the kernel drivers for those chips. This would just create an unsupportable
mess.

Guenter

> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204807
> Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
> Tested-by: Kamil Pietrzak <kpietrzak@disroot.org>
> Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
> Cc: Guenter Roeck <linux@roeck-us.net>
> ---
>  drivers/hwmon/nct6775.c | 32 ++++++++++++++++++++++++++------
>  1 file changed, 26 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
> index 8eaf86ea2433..ba18c1cbf572 100644
> --- a/drivers/hwmon/nct6775.c
> +++ b/drivers/hwmon/nct6775.c
> @@ -140,6 +140,7 @@ struct nct6775_sio_data {
>  	int ld;
>  	enum kinds kind;
>  	enum sensor_access access;
> +	bool custom_scale;
>  
>  	/* superio_() callbacks  */
>  	void (*sio_outb)(struct nct6775_sio_data *sio_data, int reg, int val);
> @@ -1159,14 +1160,19 @@ static const u16 scale_in[15] = {
>  	800, 800
>  };
>  
> -static inline long in_from_reg(u8 reg, u8 nr)
> +static const u16 scale_in_z490[15] = {
> +	888, 4000, 1600, 1600, 9600, 800, 800, 1600, 1600, 1600, 1600, 1600, 800,
> +	800, 800
> +};
> +
> +static inline long in_from_reg(u8 reg, u8 nr, const u16 *scale)
>  {
> -	return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
> +	return DIV_ROUND_CLOSEST(reg * scale[nr], 100);
>  }
>  
> -static inline u8 in_to_reg(u32 val, u8 nr)
> +static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scale)
>  {
> -	return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255);
> +	return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale[nr]), 0, 255);
>  }
>  
>  /*
> @@ -1323,6 +1329,9 @@ struct nct6775_data {
>  	u8 fandiv2;
>  	u8 sio_reg_enable;
>  
> +	/* voltage scaling factors */
> +	const u16 *scale;
> +
>  	/* nct6775_*() callbacks  */
>  	u16 (*read_value)(struct nct6775_data *data, u16 reg);
>  	int (*write_value)(struct nct6775_data *data, u16 reg, u16 value);
> @@ -2026,7 +2035,7 @@ show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
>  	int index = sattr->index;
>  	int nr = sattr->nr;
>  
> -	return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr));
> +	return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr, data->scale));
>  }
>  
>  static ssize_t
> @@ -2044,7 +2053,7 @@ store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
>  	if (err < 0)
>  		return err;
>  	mutex_lock(&data->update_lock);
> -	data->in[nr][index] = in_to_reg(val, nr);
> +	data->in[nr][index] = in_to_reg(val, nr, data->scale);
>  	data->write_value(data, data->REG_IN_MINMAX[index - 1][nr],
>  			  data->in[nr][index]);
>  	mutex_unlock(&data->update_lock);
> @@ -3980,6 +3989,11 @@ static int nct6775_probe(struct platform_device *pdev)
>  		data->write_value = nct6775_wmi_write_value;
>  	}
>  
> +	if (sio_data->custom_scale)
> +		data->scale = scale_in_z490;
> +	else
> +		data->scale = scale_in;
> +
>  	mutex_init(&data->update_lock);
>  	data->name = nct6775_device_names[data->kind];
>  	data->bank = 0xff;		/* Force initial bank selection */
> @@ -5020,6 +5034,7 @@ static int __init sensors_nct6775_init(void)
>  	struct nct6775_sio_data sio_data;
>  	int sioaddr[2] = { 0x2e, 0x4e };
>  	enum sensor_access access = access_direct;
> +	bool custom_scale = false;
>  	const char *board_vendor, *board_name;
>  	u8 tmp;
>  
> @@ -5043,6 +5058,10 @@ static int __init sensors_nct6775_init(void)
>  				pr_err("Can't read ChipID by Asus WMI.\n");
>  			}
>  		}
> +
> +		if (strcmp(board_name, "TUF GAMING Z490-PLUS") == 0 ||
> +		    strcmp(board_name, "TUF GAMING Z490-PLUS (WI-FI)") == 0)
> +			custom_scale = true;
>  	}
>  
>  	/*
> @@ -5066,6 +5085,7 @@ static int __init sensors_nct6775_init(void)
>  		found = true;
>  
>  		sio_data.access = access;
> +		sio_data.custom_scale = custom_scale;
>  
>  		if (access == access_asuswmi) {
>  			sio_data.sio_outb = superio_wmi_outb;
> -- 
> 2.33.0
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2021-10-05 13:56 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-02 21:08 [PATCH 0/3] Update ASUS WMI supported boards Denis Pauk
2021-10-02 21:08 ` [PATCH 1/3] hwmon: (nct6775) Add additional ASUS motherboards Denis Pauk
2021-10-03  9:48   ` Andy Shevchenko
2021-10-02 21:08 ` [PATCH 2/3] hwmon: (nct6775) Use custom scale for " Denis Pauk
2021-10-03  6:30   ` Andy Shevchenko
2021-10-05 13:52   ` Guenter Roeck
2021-10-02 21:08 ` [PATCH 3/3] hwmon: (asus_wmi_sensors) Support access via Asus WMI Denis Pauk
2021-10-02 21:56   ` Eugene Shalygin
2021-10-03 18:35     ` Eugene Shalygin
2021-10-03 20:48     ` Denis Pauk
2021-10-04 14:31       ` Eugene Shalygin
2021-10-03 10:34   ` Andy Shevchenko
2021-10-02 21:34 ` [PATCH 0/3] Update ASUS WMI supported boards Denis Pauk
2021-10-03  6:24   ` Andy Shevchenko
2021-10-03  6:39 ` Andy Shevchenko
2021-10-03 11:50 ` Oleksandr Natalenko
2021-10-03 12:47   ` Oleksandr Natalenko
2021-10-03 12:53     ` Eugene Shalygin
2021-10-03 13:00       ` Oleksandr Natalenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).