public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver
@ 2024-05-29  6:27 Thomas Weißschuh
  2024-05-29  6:27 ` [PATCH v4 1/3] platform/chrome: cros_ec_proto: Introduce cros_ec_cmd_readmem() Thomas Weißschuh
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Thomas Weißschuh @ 2024-05-29  6:27 UTC (permalink / raw)
  To: Jean Delvare, Guenter Roeck, Benson Leung, Lee Jones,
	Tzung-Bi Shih
  Cc: Guenter Roeck, linux-kernel, linux-hwmon, chrome-platform,
	Dustin Howett, Mario Limonciello, Moritz Fischer, Stephen Horvath,
	Rajas Paranjpe, Thomas Weißschuh

Add a hwmon driver that reports fan and temperature readings from the
ChromeOS Embedded controller.

There was an earlier effort in 2017 to add such a driver [0], but there
was no followup after v1.
The new driver is complete reimplementation based on newer APIs and with
more features (temp sensor names).

It only works on LPC-connected ECs, as only those implement direct
memory-map access.
For other busses the data would need to be read with a command.
Adding some helpers was discussed in the previous patchset [1].

The EC protocols also support reading and writing fan curves but that is
not implemented.

Tested on a Framework 13 AMD, Firmware 3.05.

[0] https://lore.kernel.org/all/1491602410-31518-1-git-send-email-moritz.fischer@ettus.com/
[1] https://lore.kernel.org/all/ac61bfca-bfa0-143b-c9ca-365b8026ce8d@roeck-us.net/

---
Changes in v4:
- Don't try to support variable-length reading in cros_ec_cmd_readmem()
  (Tzung-Bi)
- Stylistic changes (Tzung-Bi)
- Return -EOPNOTSUPP from read callbacks by default
- Use nested if-blocks in read callback
- Only allocate priv data after checking thermal version in memmap
- Simplify calling protocol of _read() functions
- Replace cros_ec_hwmon_read_temp_sensor_info() with cros_ec_cmd()
- Link to v3: https://lore.kernel.org/r/20240527-cros_ec-hwmon-v3-0-e5cd5ab5ba37@weissschuh.net

Changes in v3:
- Drop Mario's Reviewed-by tag, as the code has changed
- Introduce cros_ec_cmd_readmem() for non-LPC compatibility
- Report fault state for fans and temp sensors
- Avoid adding unnecessary space characters to channel label
- Drop thermal_version from priv data
- Read fans during probing only once
- Don't include linux/kernel.h
- Move _read_temp_sensor_info to similar functions
- Insert MFD entry alphabetically
- Link to v2: https://lore.kernel.org/r/20240507-cros_ec-hwmon-v2-0-1222c5fca0f7@weissschuh.net

Changes in v2:
- drop unnecessary range checks (Guenter)
- only validate thermal_version during probing
- reorder some variable declarations
- validate thermal_version directly in cros_ec_hwmon_probe (Mario)
- drop return value from probe_temp_sensors as it can't fail anymore
- fail with -ENODEV if cmd_readmem is missing to avoid spurious warnings
- Link to v1: https://lore.kernel.org/r/20240507-cros_ec-hwmon-v1-0-2c47c5ce8e85@weissschuh.net

---
Thomas Weißschuh (3):
      platform/chrome: cros_ec_proto: Introduce cros_ec_cmd_readmem()
      hwmon: add ChromeOS EC driver
      mfd: cros_ec: Register hardware monitoring subdevice

 Documentation/hwmon/cros_ec_hwmon.rst       |  26 +++
 Documentation/hwmon/index.rst               |   1 +
 MAINTAINERS                                 |   8 +
 drivers/hwmon/Kconfig                       |  11 ++
 drivers/hwmon/Makefile                      |   1 +
 drivers/hwmon/cros_ec_hwmon.c               | 286 ++++++++++++++++++++++++++++
 drivers/mfd/cros_ec_dev.c                   |   1 +
 drivers/platform/chrome/cros_ec_proto.c     |  27 +++
 include/linux/platform_data/cros_ec_proto.h |   2 +
 9 files changed, 363 insertions(+)
---
base-commit: 2bfcfd584ff5ccc8bb7acde19b42570414bf880b
change-id: 20240506-cros_ec-hwmon-24634b07cf6f

Best regards,
-- 
Thomas Weißschuh <linux@weissschuh.net>


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

* [PATCH v4 1/3] platform/chrome: cros_ec_proto: Introduce cros_ec_cmd_readmem()
  2024-05-29  6:27 [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver Thomas Weißschuh
@ 2024-05-29  6:27 ` Thomas Weißschuh
  2024-05-31 21:32   ` Guenter Roeck
  2024-05-29  6:27 ` [PATCH v4 2/3] hwmon: add ChromeOS EC driver Thomas Weißschuh
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Thomas Weißschuh @ 2024-05-29  6:27 UTC (permalink / raw)
  To: Jean Delvare, Guenter Roeck, Benson Leung, Lee Jones,
	Tzung-Bi Shih
  Cc: Guenter Roeck, linux-kernel, linux-hwmon, chrome-platform,
	Dustin Howett, Mario Limonciello, Moritz Fischer, Stephen Horvath,
	Rajas Paranjpe, Thomas Weißschuh

To read from the EC memory different mechanism are possible.
ECs connected via LPC expose their memory via a ->cmd_readmem operation.
Other protocols require the usage of EC_CMD_READ_MEMMAP, which on the
other hand is not implemented by LPC ECs.

Provide a helper that automatically selects the correct mechanism.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 drivers/platform/chrome/cros_ec_proto.c     | 27 +++++++++++++++++++++++++++
 include/linux/platform_data/cros_ec_proto.h |  2 ++
 2 files changed, 29 insertions(+)

diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
index 945b1b15a04c..daddc8731cef 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -1035,3 +1035,30 @@ int cros_ec_cmd(struct cros_ec_device *ec_dev,
 	return ret;
 }
 EXPORT_SYMBOL_GPL(cros_ec_cmd);
+
+/**
+ * cros_ec_cmd_readmem - Read from EC memory.
+ *
+ * @ec_dev: EC device
+ * @offset: Is within EC_LPC_ADDR_MEMMAP region.
+ * @size: Number of bytes to read.
+ * @dest: EC command output data
+ *
+ * Return: >= 0 on success, negative error number on failure.
+ */
+int cros_ec_cmd_readmem(struct cros_ec_device *ec_dev, u8 offset, u8 size, void *dest)
+{
+	struct ec_params_read_memmap params = {};
+
+	if (!size)
+		return -EINVAL;
+
+	if (ec_dev->cmd_readmem)
+		return ec_dev->cmd_readmem(ec_dev, offset, size, dest);
+
+	params.offset = offset;
+	params.size = size;
+	return cros_ec_cmd(ec_dev, 0, EC_CMD_READ_MEMMAP,
+			   &params, sizeof(params), dest, size);
+}
+EXPORT_SYMBOL_GPL(cros_ec_cmd_readmem);
diff --git a/include/linux/platform_data/cros_ec_proto.h b/include/linux/platform_data/cros_ec_proto.h
index 8865e350c12a..1ddc52603f9a 100644
--- a/include/linux/platform_data/cros_ec_proto.h
+++ b/include/linux/platform_data/cros_ec_proto.h
@@ -261,6 +261,8 @@ int cros_ec_get_sensor_count(struct cros_ec_dev *ec);
 int cros_ec_cmd(struct cros_ec_device *ec_dev, unsigned int version, int command, const void *outdata,
 		    size_t outsize, void *indata, size_t insize);
 
+int cros_ec_cmd_readmem(struct cros_ec_device *ec_dev, u8 offset, u8 size, void *dest);
+
 /**
  * cros_ec_get_time_ns() - Return time in ns.
  *

-- 
2.45.1


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

* [PATCH v4 2/3] hwmon: add ChromeOS EC driver
  2024-05-29  6:27 [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver Thomas Weißschuh
  2024-05-29  6:27 ` [PATCH v4 1/3] platform/chrome: cros_ec_proto: Introduce cros_ec_cmd_readmem() Thomas Weißschuh
@ 2024-05-29  6:27 ` Thomas Weißschuh
  2024-05-31 21:31   ` Guenter Roeck
  2024-05-29  6:27 ` [PATCH v4 3/3] mfd: cros_ec: Register hardware monitoring subdevice Thomas Weißschuh
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Thomas Weißschuh @ 2024-05-29  6:27 UTC (permalink / raw)
  To: Jean Delvare, Guenter Roeck, Benson Leung, Lee Jones,
	Tzung-Bi Shih
  Cc: Guenter Roeck, linux-kernel, linux-hwmon, chrome-platform,
	Dustin Howett, Mario Limonciello, Moritz Fischer, Stephen Horvath,
	Rajas Paranjpe, Thomas Weißschuh

The ChromeOS Embedded Controller exposes fan speed and temperature
readings.
Expose this data through the hwmon subsystem.

The driver is designed to be probed via the cros_ec mfd device.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 Documentation/hwmon/cros_ec_hwmon.rst |  26 ++++
 Documentation/hwmon/index.rst         |   1 +
 MAINTAINERS                           |   8 +
 drivers/hwmon/Kconfig                 |  11 ++
 drivers/hwmon/Makefile                |   1 +
 drivers/hwmon/cros_ec_hwmon.c         | 286 ++++++++++++++++++++++++++++++++++
 6 files changed, 333 insertions(+)

diff --git a/Documentation/hwmon/cros_ec_hwmon.rst b/Documentation/hwmon/cros_ec_hwmon.rst
new file mode 100644
index 000000000000..47ecae983bdb
--- /dev/null
+++ b/Documentation/hwmon/cros_ec_hwmon.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Kernel driver cros_ec_hwmon
+===========================
+
+Supported chips:
+
+  * ChromeOS embedded controllers.
+
+    Prefix: 'cros_ec'
+
+    Addresses scanned: -
+
+Author:
+
+  - Thomas Weißschuh <linux@weissschuh.net>
+
+Description
+-----------
+
+This driver implements support for hardware monitoring commands exposed by the
+ChromeOS embedded controller used in Chromebooks and other devices.
+
+The channel labels exposed via hwmon are retrieved from the EC itself.
+
+Fan and temperature readings are supported.
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 03d313af469a..342ea5deba24 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -58,6 +58,7 @@ Hardware Monitoring Kernel Drivers
    coretemp
    corsair-cpro
    corsair-psu
+   cros_ec_hwmon
    da9052
    da9055
    dell-smm-hwmon
diff --git a/MAINTAINERS b/MAINTAINERS
index d6c90161c7bf..0c85aa5073e7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5135,6 +5135,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
 F:	sound/soc/codecs/cros_ec_codec.*
 
+CHROMEOS EC HARDWARE MONITORING
+M:	Thomas Weißschuh <thomas@weissschuh.net>
+L:	chrome-platform@lists.linux.dev
+L:	linux-hwmon@vger.kernel.org
+S:	Maintained
+F:	Documentation/hwmon/chros_ec_hwmon.rst
+F:	drivers/hwmon/cros_ec_hwmon.c
+
 CHROMEOS EC SUBDRIVERS
 M:	Benson Leung <bleung@chromium.org>
 R:	Guenter Roeck <groeck@chromium.org>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e14ae18a973b..702dc45ea405 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -506,6 +506,17 @@ config SENSORS_CORSAIR_PSU
 	  This driver can also be built as a module. If so, the module
 	  will be called corsair-psu.
 
+config SENSORS_CROS_EC
+	tristate "ChromeOS Embedded Controller sensors"
+	depends on MFD_CROS_EC_DEV
+	default MFD_CROS_EC_DEV
+	help
+	  If you say yes here you get support for ChromeOS Embedded Controller
+	  sensors.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called cros_ec_hwmon.
+
 config SENSORS_DRIVETEMP
 	tristate "Hard disk drives with temperature sensors"
 	depends on SCSI && ATA
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index e3f25475d1f0..4fb14dd1eafd 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_SENSORS_CHIPCAP2) += chipcap2.o
 obj-$(CONFIG_SENSORS_CORETEMP)	+= coretemp.o
 obj-$(CONFIG_SENSORS_CORSAIR_CPRO) += corsair-cpro.o
 obj-$(CONFIG_SENSORS_CORSAIR_PSU) += corsair-psu.o
+obj-$(CONFIG_SENSORS_CROS_EC)	+= cros_ec_hwmon.o
 obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
 obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o
 obj-$(CONFIG_SENSORS_DELL_SMM)	+= dell-smm-hwmon.o
diff --git a/drivers/hwmon/cros_ec_hwmon.c b/drivers/hwmon/cros_ec_hwmon.c
new file mode 100644
index 000000000000..f503f9343364
--- /dev/null
+++ b/drivers/hwmon/cros_ec_hwmon.c
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  ChromeOS EC driver for hwmon
+ *
+ *  Copyright (C) 2024 Thomas Weißschuh <linux@weissschuh.net>
+ */
+
+#include <linux/device.h>
+#include <linux/hwmon.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/cros_ec_commands.h>
+#include <linux/platform_data/cros_ec_proto.h>
+#include <linux/types.h>
+#include <linux/units.h>
+
+#define DRV_NAME	"cros-ec-hwmon"
+
+struct cros_ec_hwmon_priv {
+	struct cros_ec_device *cros_ec;
+	const char *temp_sensor_names[EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES];
+	u8 usable_fans;
+};
+
+static int cros_ec_hwmon_read_fan_speed(struct cros_ec_device *cros_ec, u8 index, u16 *speed)
+{
+	int ret;
+
+	ret = cros_ec_cmd_readmem(cros_ec, EC_MEMMAP_FAN + index * 2, 2, speed);
+	if (ret < 0)
+		return ret;
+
+	*speed = le16_to_cpu(*speed);
+	return 0;
+}
+
+static int cros_ec_hwmon_read_temp(struct cros_ec_device *cros_ec, u8 index, u8 *temp)
+{
+	unsigned int offset;
+	int ret;
+
+	if (index < EC_TEMP_SENSOR_ENTRIES)
+		offset = EC_MEMMAP_TEMP_SENSOR + index;
+	else
+		offset = EC_MEMMAP_TEMP_SENSOR_B + index - EC_TEMP_SENSOR_ENTRIES;
+
+	ret = cros_ec_cmd_readmem(cros_ec, offset, 1, temp);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static bool cros_ec_hwmon_is_error_fan(u16 speed)
+{
+	return speed == EC_FAN_SPEED_NOT_PRESENT || speed == EC_FAN_SPEED_STALLED;
+}
+
+static bool cros_ec_hwmon_is_error_temp(u8 temp)
+{
+	return temp == EC_TEMP_SENSOR_NOT_PRESENT     ||
+	       temp == EC_TEMP_SENSOR_ERROR           ||
+	       temp == EC_TEMP_SENSOR_NOT_POWERED     ||
+	       temp == EC_TEMP_SENSOR_NOT_CALIBRATED;
+}
+
+static long cros_ec_hwmon_temp_to_millicelsius(u8 temp)
+{
+	return kelvin_to_millicelsius((((long)temp) + EC_TEMP_SENSOR_OFFSET));
+}
+
+static int cros_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+			      u32 attr, int channel, long *val)
+{
+	struct cros_ec_hwmon_priv *priv = dev_get_drvdata(dev);
+	int ret = -EOPNOTSUPP;
+	u16 speed;
+	u8 temp;
+
+	if (type == hwmon_fan) {
+		if (attr == hwmon_fan_input) {
+			ret = cros_ec_hwmon_read_fan_speed(priv->cros_ec, channel, &speed);
+			if (ret == 0) {
+				if (cros_ec_hwmon_is_error_fan(speed))
+					ret = -ENODATA;
+				else
+					*val = speed;
+			}
+
+		} else if (attr == hwmon_fan_fault) {
+			ret = cros_ec_hwmon_read_fan_speed(priv->cros_ec, channel, &speed);
+			if (ret == 0)
+				*val = cros_ec_hwmon_is_error_fan(speed);
+		}
+
+	} else if (type == hwmon_temp) {
+		if (attr == hwmon_temp_input) {
+			ret = cros_ec_hwmon_read_temp(priv->cros_ec, channel, &temp);
+			if (ret == 0) {
+				if (cros_ec_hwmon_is_error_temp(temp))
+					ret = -ENODATA;
+				else
+					*val = cros_ec_hwmon_temp_to_millicelsius(temp);
+			}
+
+		} else if (attr == hwmon_temp_fault) {
+			ret = cros_ec_hwmon_read_temp(priv->cros_ec, channel, &temp);
+			if (ret == 0)
+				*val = cros_ec_hwmon_is_error_temp(temp);
+		}
+	}
+
+	return ret;
+}
+
+static int cros_ec_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type,
+				     u32 attr, int channel, const char **str)
+{
+	struct cros_ec_hwmon_priv *priv = dev_get_drvdata(dev);
+
+	if (type == hwmon_temp && attr == hwmon_temp_label) {
+		*str = priv->temp_sensor_names[channel];
+		return 0;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static umode_t cros_ec_hwmon_is_visible(const void *data, enum hwmon_sensor_types type,
+					u32 attr, int channel)
+{
+	const struct cros_ec_hwmon_priv *priv = data;
+
+	if (type == hwmon_fan) {
+		if (priv->usable_fans & BIT(channel))
+			return 0444;
+
+	} else if (type == hwmon_temp) {
+		if (priv->temp_sensor_names[channel])
+			return 0444;
+	}
+
+	return 0;
+}
+
+static const struct hwmon_channel_info * const cros_ec_hwmon_info[] = {
+	HWMON_CHANNEL_INFO(fan,
+			   HWMON_F_INPUT | HWMON_F_FAULT,
+			   HWMON_F_INPUT | HWMON_F_FAULT,
+			   HWMON_F_INPUT | HWMON_F_FAULT,
+			   HWMON_F_INPUT | HWMON_F_FAULT),
+	HWMON_CHANNEL_INFO(temp,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL,
+			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_LABEL),
+	NULL
+};
+
+static const struct hwmon_ops cros_ec_hwmon_ops = {
+	.read = cros_ec_hwmon_read,
+	.read_string = cros_ec_hwmon_read_string,
+	.is_visible = cros_ec_hwmon_is_visible,
+};
+
+static const struct hwmon_chip_info cros_ec_hwmon_chip_info = {
+	.ops = &cros_ec_hwmon_ops,
+	.info = cros_ec_hwmon_info,
+};
+
+static void cros_ec_hwmon_probe_temp_sensors(struct device *dev, struct cros_ec_hwmon_priv *priv,
+					     u8 thermal_version)
+{
+	struct ec_params_temp_sensor_get_info req = {};
+	struct ec_response_temp_sensor_get_info resp;
+	size_t candidates, i, sensor_name_size;
+	int ret;
+	u8 temp;
+
+	if (thermal_version < 2)
+		candidates = EC_TEMP_SENSOR_ENTRIES;
+	else
+		candidates = ARRAY_SIZE(priv->temp_sensor_names);
+
+	for (i = 0; i < candidates; i++) {
+		if (cros_ec_hwmon_read_temp(priv->cros_ec, i, &temp) < 0)
+			continue;
+
+		if (temp == EC_TEMP_SENSOR_NOT_PRESENT)
+			continue;
+
+		req.id = i;
+		ret = cros_ec_cmd(priv->cros_ec, 0, EC_CMD_TEMP_SENSOR_GET_INFO,
+				  &req, sizeof(req), &resp, sizeof(resp));
+		if (ret < 0)
+			continue;
+
+		sensor_name_size = strnlen(resp.sensor_name, sizeof(resp.sensor_name));
+		priv->temp_sensor_names[i] = devm_kasprintf(dev, GFP_KERNEL, "%*s",
+							    (int)sensor_name_size,
+							    resp.sensor_name);
+	}
+}
+
+static void cros_ec_hwmon_probe_fans(struct cros_ec_hwmon_priv *priv)
+{
+	u16 speed;
+	size_t i;
+	int ret;
+
+	for (i = 0; i < EC_FAN_SPEED_ENTRIES; i++) {
+		ret = cros_ec_hwmon_read_fan_speed(priv->cros_ec, i, &speed);
+		if (ret == 0 && speed != EC_FAN_SPEED_NOT_PRESENT)
+			priv->usable_fans |= BIT(i);
+	}
+}
+
+static int cros_ec_hwmon_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent);
+	struct cros_ec_device *cros_ec = ec_dev->ec_dev;
+	struct cros_ec_hwmon_priv *priv;
+	struct device *hwmon_dev;
+	u8 thermal_version;
+	int ret;
+
+	ret = cros_ec_cmd_readmem(cros_ec, EC_MEMMAP_THERMAL_VERSION, 1, &thermal_version);
+	if (ret < 0)
+		return ret;
+
+	/* Covers both fan and temp sensors */
+	if (thermal_version == 0)
+		return -ENODEV;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->cros_ec = cros_ec;
+
+	cros_ec_hwmon_probe_temp_sensors(dev, priv, thermal_version);
+	cros_ec_hwmon_probe_fans(priv);
+
+	hwmon_dev = devm_hwmon_device_register_with_info(dev, "cros_ec", priv,
+							 &cros_ec_hwmon_chip_info, NULL);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct platform_device_id cros_ec_hwmon_id[] = {
+	{ DRV_NAME, 0 },
+	{}
+};
+
+static struct platform_driver cros_ec_hwmon_driver = {
+	.driver.name	= DRV_NAME,
+	.probe		= cros_ec_hwmon_probe,
+	.id_table	= cros_ec_hwmon_id,
+};
+module_platform_driver(cros_ec_hwmon_driver);
+
+MODULE_DEVICE_TABLE(platform, cros_ec_hwmon_id);
+MODULE_DESCRIPTION("ChromeOS EC Hardware Monitoring Driver");
+MODULE_AUTHOR("Thomas Weißschuh <linux@weissschuh.net");
+MODULE_LICENSE("GPL");

-- 
2.45.1


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

* [PATCH v4 3/3] mfd: cros_ec: Register hardware monitoring subdevice
  2024-05-29  6:27 [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver Thomas Weißschuh
  2024-05-29  6:27 ` [PATCH v4 1/3] platform/chrome: cros_ec_proto: Introduce cros_ec_cmd_readmem() Thomas Weißschuh
  2024-05-29  6:27 ` [PATCH v4 2/3] hwmon: add ChromeOS EC driver Thomas Weißschuh
@ 2024-05-29  6:27 ` Thomas Weißschuh
  2024-05-31 16:06   ` (subset) " Lee Jones
  2024-06-03  1:30 ` [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver patchwork-bot+chrome-platform
  2024-06-03  1:30 ` patchwork-bot+chrome-platform
  4 siblings, 1 reply; 9+ messages in thread
From: Thomas Weißschuh @ 2024-05-29  6:27 UTC (permalink / raw)
  To: Jean Delvare, Guenter Roeck, Benson Leung, Lee Jones,
	Tzung-Bi Shih
  Cc: Guenter Roeck, linux-kernel, linux-hwmon, chrome-platform,
	Dustin Howett, Mario Limonciello, Moritz Fischer, Stephen Horvath,
	Rajas Paranjpe, Thomas Weißschuh

Add ChromeOS EC-based hardware monitoring as EC subdevice.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
 drivers/mfd/cros_ec_dev.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
index a52d59cc2b1e..1262d1f8d954 100644
--- a/drivers/mfd/cros_ec_dev.c
+++ b/drivers/mfd/cros_ec_dev.c
@@ -130,6 +130,7 @@ static const struct cros_feature_to_cells cros_subdevices[] = {
 static const struct mfd_cell cros_ec_platform_cells[] = {
 	{ .name = "cros-ec-chardev", },
 	{ .name = "cros-ec-debugfs", },
+	{ .name = "cros-ec-hwmon", },
 	{ .name = "cros-ec-sysfs", },
 };
 

-- 
2.45.1


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

* Re: (subset) [PATCH v4 3/3] mfd: cros_ec: Register hardware monitoring subdevice
  2024-05-29  6:27 ` [PATCH v4 3/3] mfd: cros_ec: Register hardware monitoring subdevice Thomas Weißschuh
@ 2024-05-31 16:06   ` Lee Jones
  0 siblings, 0 replies; 9+ messages in thread
From: Lee Jones @ 2024-05-31 16:06 UTC (permalink / raw)
  To: Jean Delvare, Guenter Roeck, Benson Leung, Lee Jones,
	Tzung-Bi Shih, Thomas Weißschuh
  Cc: Guenter Roeck, linux-kernel, linux-hwmon, chrome-platform,
	Dustin Howett, Mario Limonciello, Moritz Fischer, Stephen Horvath,
	Rajas Paranjpe

On Wed, 29 May 2024 08:27:13 +0200, Thomas Weißschuh wrote:
> Add ChromeOS EC-based hardware monitoring as EC subdevice.
> 
> 

Applied, thanks!

[3/3] mfd: cros_ec: Register hardware monitoring subdevice
      commit: 27e669820cda845d6d4c505809711ef6b4cff9a1

--
Lee Jones [李琼斯]


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

* Re: [PATCH v4 2/3] hwmon: add ChromeOS EC driver
  2024-05-29  6:27 ` [PATCH v4 2/3] hwmon: add ChromeOS EC driver Thomas Weißschuh
@ 2024-05-31 21:31   ` Guenter Roeck
  0 siblings, 0 replies; 9+ messages in thread
From: Guenter Roeck @ 2024-05-31 21:31 UTC (permalink / raw)
  To: Thomas Weißschuh, Jean Delvare, Benson Leung, Lee Jones,
	Tzung-Bi Shih
  Cc: Guenter Roeck, linux-kernel, linux-hwmon, chrome-platform,
	Dustin Howett, Mario Limonciello, Moritz Fischer, Stephen Horvath,
	Rajas Paranjpe

On 5/28/24 23:27, Thomas Weißschuh wrote:
> The ChromeOS Embedded Controller exposes fan speed and temperature
> readings.
> Expose this data through the hwmon subsystem.
> 
> The driver is designed to be probed via the cros_ec mfd device.
> 
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>

I assume this patch and first patch of the series will be applied
through the cros-ec branch.

I don't know if Tzung-Bi has additional comments; from my perspective

Acked-by: Guenter Roeck <linux@roeck-us.net>

Thanks,
Guenter


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

* Re: [PATCH v4 1/3] platform/chrome: cros_ec_proto: Introduce cros_ec_cmd_readmem()
  2024-05-29  6:27 ` [PATCH v4 1/3] platform/chrome: cros_ec_proto: Introduce cros_ec_cmd_readmem() Thomas Weißschuh
@ 2024-05-31 21:32   ` Guenter Roeck
  0 siblings, 0 replies; 9+ messages in thread
From: Guenter Roeck @ 2024-05-31 21:32 UTC (permalink / raw)
  To: Thomas Weißschuh, Jean Delvare, Benson Leung, Lee Jones,
	Tzung-Bi Shih
  Cc: Guenter Roeck, linux-kernel, linux-hwmon, chrome-platform,
	Dustin Howett, Mario Limonciello, Moritz Fischer, Stephen Horvath,
	Rajas Paranjpe

On 5/28/24 23:27, Thomas Weißschuh wrote:
> To read from the EC memory different mechanism are possible.
> ECs connected via LPC expose their memory via a ->cmd_readmem operation.
> Other protocols require the usage of EC_CMD_READ_MEMMAP, which on the
> other hand is not implemented by LPC ECs.
> 
> Provide a helper that automatically selects the correct mechanism.
> 
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>

Reviewed-by: Guenter Roeck <linux@roeck-us.net>


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

* Re: [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver
  2024-05-29  6:27 [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver Thomas Weißschuh
                   ` (3 preceding siblings ...)
  2024-06-03  1:30 ` [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver patchwork-bot+chrome-platform
@ 2024-06-03  1:30 ` patchwork-bot+chrome-platform
  4 siblings, 0 replies; 9+ messages in thread
From: patchwork-bot+chrome-platform @ 2024-06-03  1:30 UTC (permalink / raw)
  To: =?utf-8?q?Thomas_Wei=C3=9Fschuh_=3Clinux=40weissschuh=2Enet=3E?=
  Cc: jdelvare, linux, bleung, lee, tzungbi, groeck, linux-kernel,
	linux-hwmon, chrome-platform, dustin, mario.limonciello, mdf,
	s.horvath, paranjperajas

Hello:

This series was applied to chrome-platform/linux.git (for-kernelci)
by Tzung-Bi Shih <tzungbi@kernel.org>:

On Wed, 29 May 2024 08:27:10 +0200 you wrote:
> Add a hwmon driver that reports fan and temperature readings from the
> ChromeOS Embedded controller.
> 
> There was an earlier effort in 2017 to add such a driver [0], but there
> was no followup after v1.
> The new driver is complete reimplementation based on newer APIs and with
> more features (temp sensor names).
> 
> [...]

Here is the summary with links:
  - [v4,1/3] platform/chrome: cros_ec_proto: Introduce cros_ec_cmd_readmem()
    https://git.kernel.org/chrome-platform/c/a14a569a9918
  - [v4,2/3] hwmon: add ChromeOS EC driver
    https://git.kernel.org/chrome-platform/c/e8665a172378
  - [v4,3/3] mfd: cros_ec: Register hardware monitoring subdevice
    (no matching commit)

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

* Re: [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver
  2024-05-29  6:27 [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver Thomas Weißschuh
                   ` (2 preceding siblings ...)
  2024-05-29  6:27 ` [PATCH v4 3/3] mfd: cros_ec: Register hardware monitoring subdevice Thomas Weißschuh
@ 2024-06-03  1:30 ` patchwork-bot+chrome-platform
  2024-06-03  1:30 ` patchwork-bot+chrome-platform
  4 siblings, 0 replies; 9+ messages in thread
From: patchwork-bot+chrome-platform @ 2024-06-03  1:30 UTC (permalink / raw)
  To: =?utf-8?q?Thomas_Wei=C3=9Fschuh_=3Clinux=40weissschuh=2Enet=3E?=
  Cc: jdelvare, linux, bleung, lee, tzungbi, groeck, linux-kernel,
	linux-hwmon, chrome-platform, dustin, mario.limonciello, mdf,
	s.horvath, paranjperajas

Hello:

This series was applied to chrome-platform/linux.git (for-next)
by Tzung-Bi Shih <tzungbi@kernel.org>:

On Wed, 29 May 2024 08:27:10 +0200 you wrote:
> Add a hwmon driver that reports fan and temperature readings from the
> ChromeOS Embedded controller.
> 
> There was an earlier effort in 2017 to add such a driver [0], but there
> was no followup after v1.
> The new driver is complete reimplementation based on newer APIs and with
> more features (temp sensor names).
> 
> [...]

Here is the summary with links:
  - [v4,1/3] platform/chrome: cros_ec_proto: Introduce cros_ec_cmd_readmem()
    https://git.kernel.org/chrome-platform/c/a14a569a9918
  - [v4,2/3] hwmon: add ChromeOS EC driver
    https://git.kernel.org/chrome-platform/c/e8665a172378
  - [v4,3/3] mfd: cros_ec: Register hardware monitoring subdevice
    (no matching commit)

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2024-06-03  1:30 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-29  6:27 [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver Thomas Weißschuh
2024-05-29  6:27 ` [PATCH v4 1/3] platform/chrome: cros_ec_proto: Introduce cros_ec_cmd_readmem() Thomas Weißschuh
2024-05-31 21:32   ` Guenter Roeck
2024-05-29  6:27 ` [PATCH v4 2/3] hwmon: add ChromeOS EC driver Thomas Weißschuh
2024-05-31 21:31   ` Guenter Roeck
2024-05-29  6:27 ` [PATCH v4 3/3] mfd: cros_ec: Register hardware monitoring subdevice Thomas Weißschuh
2024-05-31 16:06   ` (subset) " Lee Jones
2024-06-03  1:30 ` [PATCH v4 0/3] ChromeOS Embedded controller hwmon driver patchwork-bot+chrome-platform
2024-06-03  1:30 ` patchwork-bot+chrome-platform

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox