Skip to contentSkip to conversation

*DO NOT MERGE* Driver support for reading Vdd current on Zaius

PATCH New Xo Wang 1 participant 5 messages Jul 11, 2017

Subsystems (3)
lore
Share & tools
lore

Xo Wang

author
#0 lore raw

cover *DO NOT MERGE* Driver support for reading Vdd current on Zaius

To help with Adrian Barrera's debugging for AVSBus current readouts, I'm mailing our driver for the Intersil voltage regulator modules (VRMs). The authors haven't yet mailed these to the appropriate mainline maintainers, so please do not merge to the OpenBMC tree.

Maxim Sloyko (2):
HWMon Driver for Intersil ISL68137 PWM Controller Add Infineon and Intersil regulators to the device tree

Robert Lippert (2):
hwmon: (isl68137) add accessors to enable/disable AVS mode
hwmon: (isl68137) add accessors for changing VOUT_MAX

 arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts |  61 +++++++-
 drivers/hwmon/pmbus/Kconfig                |  10 ++
 drivers/hwmon/pmbus/Makefile               |   1 +
 drivers/hwmon/pmbus/isl68137.c             | 238 +++++++++++++++++++++++++++++
 4 files changed, 305 insertions(+), 5 deletions(-)
 create mode 100644 drivers/hwmon/pmbus/isl68137.c
Signature · 1 line
2.13.2.725.g09c95d1e9-goog
author
#1 lore raw

PATCH 1/4 HWMon Driver for Intersil ISL68137 PWM Controller

From: Maxim Sloyko <[email protected]>

---
 drivers/hwmon/pmbus/Kconfig    | 10 +++++
 drivers/hwmon/pmbus/Makefile   |  1 +
 drivers/hwmon/pmbus/isl68137.c | 86 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 97 insertions(+)
 create mode 100644 drivers/hwmon/pmbus/isl68137.c
drivers/hwmon/pmbus/Kconfig +10 -0
index 68d717a3fd59..e4f101e0c504 100644
@@ -47,6 +47,16 @@ config SENSORS_IR35221
 	  This driver can also be built as a module. If so, the module will
 	  be called ir35521.
 
+config SENSORS_ISL68137
+	tristate "Intersil ISL68137"
+	default y
+	help
+	  If you say yes here you get hardware monitoring support for Intersil
+	  ISL68137.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called isl68137.
+
 config SENSORS_LM25066
 	tristate "National Semiconductor LM25066 and compatibles"
 	default n
drivers/hwmon/pmbus/Makefile +1 -0
index 75bb7ca619d9..252048a8985a 100644
@@ -6,6 +6,7 @@ obj-$(CONFIG_PMBUS)		+= pmbus_core.o
 obj-$(CONFIG_SENSORS_PMBUS)	+= pmbus.o
 obj-$(CONFIG_SENSORS_ADM1275)	+= adm1275.o
 obj-$(CONFIG_SENSORS_IR35221)	+= ir35221.o
+obj-$(CONFIG_SENSORS_ISL68137)	+= isl68137.o
 obj-$(CONFIG_SENSORS_LM25066)	+= lm25066.o
 obj-$(CONFIG_SENSORS_LTC2978)	+= ltc2978.o
 obj-$(CONFIG_SENSORS_LTC3815)	+= ltc3815.o
drivers/hwmon/pmbus/isl68137.c new file +86 -0

86 lines not on this page · raw message

Signature · 1 line
2.13.2.725.g09c95d1e9-goog
author
#2 lore raw

PATCH 2/4 hwmon: (isl68137) add accessors to enable/disable AVS mode

In reply to Xo Wang

From: Robert Lippert <[email protected]>

This patch adds sysfs files avs(0|1)_enabled underneath the I2C device to control the AVS state of each rail and perform the appropriate hacks when enabling AVS.

The ISL68137 has issues wrt AVS operation mode that require it to be enabled/disabled at runtime.

Additionally enabling AVS mode requires a hack to set the VOUT value before enabling to make sure that the device does not switch to an old cached AVS provided value and is instead in a "clean" state before booting.

---
 drivers/hwmon/pmbus/isl68137.c | 112 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 110 insertions(+), 2 deletions(-)
drivers/hwmon/pmbus/isl68137.c +110 -2
index 2a5322e4a286..cc95a3d339af 100644
@@ -19,8 +19,11 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
+#include <linux/hwmon-sysfs.h>
 #include "pmbus.h"
 
+#define ISL68137_VOUT_AVS 0x30
+
 static struct pmbus_driver_info isl68137_info = {
 	.pages = 2,
 	.format[PSC_VOLTAGE_IN] = direct,
@@ -56,10 +59,115 @@ static struct pmbus_driver_info isl68137_info = {
 	    | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
 };
 
+static ssize_t isl68137_avs_enable_show_page(struct i2c_client *client,
+					     int page,
+					     char *buf)
+{
+	int val = pmbus_read_byte_data(client, page, PMBUS_OPERATION);
+
+	return sprintf(buf, "%d\n",
+		       (val & ISL68137_VOUT_AVS) == ISL68137_VOUT_AVS ? 1 : 0);
+}
+
+static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client,
+					      int page,
+					      const char *buf, size_t count)
+{
+	int rc, op_val;
+
+	if (count < 1) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	switch (buf[0]) {
+		case '0': op_val = 0; break;
+		case '1': op_val = ISL68137_VOUT_AVS; break;
+		default: rc = -EINVAL; goto out; break;
+	}
+
+	/*
+	 * Writes to VOUT setpoint over AVSBus will persist after the VRM is
+	 * switched to PMBus control. Switching back to AVSBus control
+	 * restores this persisted setpoint rather than re-initializing to
+	 * PMBus VOUT_COMMAND. Writing VOUT_COMMAND first over PMBus before
+	 * enabling AVS control is the workaround.
+	 */
+	if (op_val == ISL68137_VOUT_AVS) {
+		int vout_command = pmbus_read_byte_data(client, page,
+							PMBUS_VOUT_COMMAND);
+		rc = pmbus_write_byte_data(client, page, PMBUS_VOUT_COMMAND,
+					   vout_command);
+		if (rc)
+			goto out;
+	}
+
+	rc = pmbus_update_byte_data(client, page, PMBUS_OPERATION,
+				    ISL68137_VOUT_AVS, op_val);
+
+out:
+	return rc < 0 ? rc : count;
+}
+
+static ssize_t isl68137_avs_enable_show(struct device *dev,
+					struct device_attribute *devattr,
+					char *buf)
+{
+	struct i2c_client *client = kobj_to_i2c_client(&dev->kobj);
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	return isl68137_avs_enable_show_page(client, attr->index, buf);
+}
+
+static ssize_t isl68137_avs_enable_store(struct device *dev,
+				struct device_attribute *devattr,
+				const char *buf, size_t count)
+{
+	struct i2c_client *client = kobj_to_i2c_client(&dev->kobj);
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	return isl68137_avs_enable_store_page(client, attr->index, buf, count);
+}
+
+static SENSOR_DEVICE_ATTR_2(avs0_enabled, 0644,
+			    isl68137_avs_enable_show, isl68137_avs_enable_store,
+			    0, 0);
+static SENSOR_DEVICE_ATTR_2(avs1_enabled, 0644,
+			    isl68137_avs_enable_show, isl68137_avs_enable_store,
+			    0, 1);
+
+static int isl68137_remove(struct i2c_client *client);
+
 static int isl68137_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
-	return pmbus_do_probe(client, id, &isl68137_info);
+	int rc;
+
+	rc = pmbus_do_probe(client, id, &isl68137_info);
+	if (rc)
+		return rc;
+
+	rc = device_create_file(&client->dev,
+				&sensor_dev_attr_avs0_enabled.dev_attr);
+	if (rc)
+		goto out_fail;
+	rc = device_create_file(&client->dev,
+				&sensor_dev_attr_avs1_enabled.dev_attr);
+	if (rc)
+		goto out_fail;
+
+	return rc;
+
+out_fail:
+	isl68137_remove(client);
+	return rc;
+}
+
+static int isl68137_remove(struct i2c_client *client)
+{
+	device_remove_file(&client->dev,
+			   &sensor_dev_attr_avs1_enabled.dev_attr);
+	device_remove_file(&client->dev,
+			   &sensor_dev_attr_avs0_enabled.dev_attr);
+	return pmbus_do_remove(client);
 }
 
 static const struct i2c_device_id isl68137_id[] = {
@@ -75,7 +183,7 @@ static struct i2c_driver isl68137_driver = {
 		   .name = "isl68137",
 		   },
 	.probe = isl68137_probe,
-	.remove = pmbus_do_remove,
+	.remove = isl68137_remove,
 	.id_table = isl68137_id,
 };
 
Signature · 1 line
2.13.2.725.g09c95d1e9-goog
author
#3 lore raw

PATCH 3/4 hwmon: (isl68137) add accessors for changing VOUT_MAX

In reply to Xo Wang

From: Robert Lippert <[email protected]>

To workaround a controller errata, VOUT_MAX must be changed dynamically on some early Zaius boards. PMBus core framework does not have any support for making this value settable so add some device-specific sysfs files to expose the value.

---
 drivers/hwmon/pmbus/isl68137.c | 44 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)
drivers/hwmon/pmbus/isl68137.c +44 -0
index cc95a3d339af..2341f376bc2b 100644
@@ -134,6 +134,38 @@ static SENSOR_DEVICE_ATTR_2(avs1_enabled, 0644,
 			    isl68137_avs_enable_show, isl68137_avs_enable_store,
 			    0, 1);
 
+static ssize_t isl68137_word_show(struct device *dev,
+				  struct device_attribute *devattr, char *buf)
+{
+	struct i2c_client *client = kobj_to_i2c_client(&dev->kobj);
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	int val = pmbus_read_word_data(client, attr->index, attr->nr);
+	return snprintf(buf, PAGE_SIZE, "%d\n", val);
+}
+
+static ssize_t isl68137_word_store(struct device *dev,
+				   struct device_attribute *devattr,
+				   const char *buf, size_t count)
+{
+	struct i2c_client *client = kobj_to_i2c_client(&dev->kobj);
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+	char *end;
+	int rc;
+	long new = simple_strtol(buf, &end, 0);
+	if (end == buf || new > INT_MAX || new < INT_MIN)
+		return -EINVAL;
+
+	rc = pmbus_write_word_data(client, attr->index, attr->nr, new);
+	return rc < 0 ? rc : count;
+}
+
+static SENSOR_DEVICE_ATTR_2(vout0_max, 0644,
+			    isl68137_word_show, isl68137_word_store,
+			    PMBUS_VOUT_MAX, 0);
+static SENSOR_DEVICE_ATTR_2(vout1_max, 0644,
+			    isl68137_word_show, isl68137_word_store,
+			    PMBUS_VOUT_MAX, 1);
+
 static int isl68137_remove(struct i2c_client *client);
 
 static int isl68137_probe(struct i2c_client *client,
@@ -153,6 +185,14 @@ static int isl68137_probe(struct i2c_client *client,
 				&sensor_dev_attr_avs1_enabled.dev_attr);
 	if (rc)
 		goto out_fail;
+	rc = device_create_file(&client->dev,
+				&sensor_dev_attr_vout0_max.dev_attr);
+	if (rc)
+		goto out_fail;
+	rc = device_create_file(&client->dev,
+				&sensor_dev_attr_vout1_max.dev_attr);
+	if (rc)
+		goto out_fail;
 
 	return rc;
 
@@ -163,6 +203,10 @@ static int isl68137_probe(struct i2c_client *client,
 
 static int isl68137_remove(struct i2c_client *client)
 {
+	device_remove_file(&client->dev,
+			   &sensor_dev_attr_vout1_max.dev_attr);
+	device_remove_file(&client->dev,
+			   &sensor_dev_attr_vout0_max.dev_attr);
 	device_remove_file(&client->dev,
 			   &sensor_dev_attr_avs1_enabled.dev_attr);
 	device_remove_file(&client->dev,
Signature · 1 line
2.13.2.725.g09c95d1e9-goog
author
#4 lore raw

PATCH 4/4 Add Infineon and Intersil regulators to the device tree

In reply to Xo Wang

From: Maxim Sloyko <[email protected]>

---
 arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts | 61 +++++++++++++++++++++++++++---
 1 file changed, 56 insertions(+), 5 deletions(-)
arch/arm/boot/dts/aspeed-bmc-opp-zaius.dts +56 -5
index c6200153a065..bffc0d0a2516 100644
@@ -274,6 +274,32 @@
 				reg = <0x10>;
 			};
 		};
+
+	};
+
+	vrm@64 {
+		compatible = "intersil,isl68137";
+		reg = <0x64>;
+	};
+
+	vrm@40 {
+		compatible = "intersil,isl68137";
+		reg = <0x40>;
+	};
+
+	vrm@60 {
+		compatible = "intersil,isl68137";
+		reg = <0x60>;
+	};
+
+	vrm@43 {
+		compatible = "infineon,ir38064";
+		reg = <0x43>;
+	};
+
+	vrm@41 {
+		compatible = "intersil,isl68137";
+		reg = <0x41>;
 	};
 
 	/* Master selector PCA9541A @70h (other master: CPU0)
@@ -289,18 +315,43 @@
 	/* CPU0 VR ISL68137 0.7V, 0.96V PMBUS @64h */
 	/* CPU0 VR ISL68137 1.2V CH03 PMBUS @40h */
 	/* CPU0 VR ISL68137 0.8V PMBUS @60h */
-	/* CPU0 VR 1.0V IR38064 I2C @11h, PMBUS @41h */
+	/* CPU0 VR 1.0V IR38064 I2C @11h, PMBUS @43h */
 	/* CPU0 VR ISL68137 1.2V CH47 PMBUS @41h */
 };
 
 &i2c8 {
 	status = "okay";
 
-	/* CPU1 VR ISL68137 0.7V, 0.96V PMBUS @65h */
-	/* CPU1 VR ISL68137 1.2V CH03 PMBUS @44h */
-	/* CPU1 VR ISL68137 0.8V PMBUS @61h */
+	vrm@64 {
+		compatible = "intersil,isl68137";
+		reg = <0x64>;
+	};
+
+	vrm@40 {
+		compatible = "intersil,isl68137";
+		reg = <0x40>;
+	};
+
+	vrm@41 {
+		compatible = "intersil,isl68137";
+		reg = <0x41>;
+	};
+
+	vrm@42 {
+		compatible = "infineon,ir38064";
+		reg = <0x42>;
+	};
+
+	vrm@60 {
+		compatible = "intersil,isl68137";
+		reg = <0x60>;
+	};
+
+	/* CPU1 VR ISL68137 0.7V, 0.96V PMBUS @64h */
+	/* CPU1 VR ISL68137 1.2V CH03 PMBUS @40h */
+	/* CPU1 VR ISL68137 1.2V CH47 PMBUS @41h */
 	/* CPU1 VR 1.0V IR38064 I2C @12h, PMBUS @42h */
-	/* CPU0 VR ISL68137 1.2V CH47 PMBUS @45h */
+	/* CPU1 VR ISL68137 0.8V PMBUS @60h */
 };
 
 
Signature · 1 line
2.13.2.725.g09c95d1e9-goog