All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Review request for Acbel PSU driver
@ 2023-03-15 17:40 Lakshmi Yadlapati
  2023-03-15 17:40 ` [PATCH 1/4] dt-bindings: vendor-prefixes: Add prefix for acbel Lakshmi Yadlapati
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Lakshmi Yadlapati @ 2023-03-15 17:40 UTC (permalink / raw)
  To: linux-kernel; +Cc: Lakshmi Yadlapati, ylakshmi

New Acbel PSU driver for Power Supply. Update the device tree with correct
device address.

Lakshmi Yadlapati (4):
  dt-bindings: vendor-prefixes: Add prefix for acbel
  dt-bindings: trivial-devices: Add acbel,crps
  hwmon: (pmbus/acbel-crps) Add Acbel CRPS power supply driver
  ARM: dts: aspeed: p10bmc: Change power supply info

 .../devicetree/bindings/trivial-devices.yaml  |   2 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm/boot/dts/aspeed-bmc-ibm-bonnell.dts  |  12 +-
 drivers/hwmon/pmbus/Kconfig                   |   9 +
 drivers/hwmon/pmbus/Makefile                  |   1 +
 drivers/hwmon/pmbus/acbel-crps.c              | 311 ++++++++++++++++++
 6 files changed, 331 insertions(+), 6 deletions(-)
 create mode 100644 drivers/hwmon/pmbus/acbel-crps.c

-- 
2.37.2


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

* [PATCH 1/4] dt-bindings: vendor-prefixes: Add prefix for acbel
  2023-03-15 17:40 [PATCH 0/4] Review request for Acbel PSU driver Lakshmi Yadlapati
@ 2023-03-15 17:40 ` Lakshmi Yadlapati
  2023-03-16 11:30   ` Krzysztof Kozlowski
  2023-03-15 17:40 ` [PATCH 2/4] dt-bindings: trivial-devices: Add acbel,crps Lakshmi Yadlapati
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Lakshmi Yadlapati @ 2023-03-15 17:40 UTC (permalink / raw)
  To: linux-kernel; +Cc: Lakshmi Yadlapati, ylakshmi

Add a vendor prefix entry for acbel (https://www.acbel.com)

Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index ed64e06ecca4..9dbb8f69be65 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -37,6 +37,8 @@ patternProperties:
     description: Abracon Corporation
   "^abt,.*":
     description: ShenZhen Asia Better Technology Ltd.
+  "^acbel,.*":
+    description: Acbel Polytech Inc.
   "^acer,.*":
     description: Acer Inc.
   "^acme,.*":
-- 
2.37.2


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

* [PATCH 2/4] dt-bindings: trivial-devices: Add acbel,crps
  2023-03-15 17:40 [PATCH 0/4] Review request for Acbel PSU driver Lakshmi Yadlapati
  2023-03-15 17:40 ` [PATCH 1/4] dt-bindings: vendor-prefixes: Add prefix for acbel Lakshmi Yadlapati
@ 2023-03-15 17:40 ` Lakshmi Yadlapati
  2023-03-15 17:40 ` [PATCH 3/4] hwmon: (pmbus/acbel-crps) Add Acbel CRPS power supply driver Lakshmi Yadlapati
  2023-03-15 17:40 ` [PATCH 4/4] ARM: dts: aspeed: p10bmc: Change power supply info Lakshmi Yadlapati
  3 siblings, 0 replies; 8+ messages in thread
From: Lakshmi Yadlapati @ 2023-03-15 17:40 UTC (permalink / raw)
  To: linux-kernel; +Cc: Lakshmi Yadlapati, ylakshmi

Add Acbel CRPS Series power supply to trivial devices.

Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
---
 Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml
index 6f482a254a1d..ae2cf4411b39 100644
--- a/Documentation/devicetree/bindings/trivial-devices.yaml
+++ b/Documentation/devicetree/bindings/trivial-devices.yaml
@@ -30,6 +30,8 @@ properties:
     items:
       - enum:
             # SMBus/I2C Digital Temperature Sensor in 6-Pin SOT with SMBus Alert and Over Temperature Pin
+          - acbel,crps
+            # Acbel CRPS Series power supply
           - ad,ad7414
             # ADM9240: Complete System Hardware Monitor for uProcessor-Based Systems
           - ad,adm9240
-- 
2.37.2


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

* [PATCH 3/4] hwmon: (pmbus/acbel-crps) Add Acbel CRPS power supply driver
  2023-03-15 17:40 [PATCH 0/4] Review request for Acbel PSU driver Lakshmi Yadlapati
  2023-03-15 17:40 ` [PATCH 1/4] dt-bindings: vendor-prefixes: Add prefix for acbel Lakshmi Yadlapati
  2023-03-15 17:40 ` [PATCH 2/4] dt-bindings: trivial-devices: Add acbel,crps Lakshmi Yadlapati
@ 2023-03-15 17:40 ` Lakshmi Yadlapati
  2023-03-15 17:40 ` [PATCH 4/4] ARM: dts: aspeed: p10bmc: Change power supply info Lakshmi Yadlapati
  3 siblings, 0 replies; 8+ messages in thread
From: Lakshmi Yadlapati @ 2023-03-15 17:40 UTC (permalink / raw)
  To: linux-kernel; +Cc: Lakshmi Yadlapati, ylakshmi

Add the driver to support Acbel CRPS power supply.

Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
---
 drivers/hwmon/pmbus/Kconfig      |   9 +
 drivers/hwmon/pmbus/Makefile     |   1 +
 drivers/hwmon/pmbus/acbel-crps.c | 311 +++++++++++++++++++++++++++++++
 3 files changed, 321 insertions(+)
 create mode 100644 drivers/hwmon/pmbus/acbel-crps.c

diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 59d9a7430499..9fe7ac94cfa2 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -27,6 +27,15 @@ config SENSORS_PMBUS
 	  This driver can also be built as a module. If so, the module will
 	  be called pmbus.
 
+config SENSORS_ACBEL_CRPS
+	tristate "ACBEL CRPS Power Supply"
+	help
+	  If you say yes here you get hardware monitoring support for the ACBEL
+	  CRPS power supply.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called acbel-crps.
+
 config SENSORS_ADM1266
 	tristate "Analog Devices ADM1266 Sequencer"
 	select CRC8
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 3ae019916267..39aef0cb9934 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_PMBUS)		+= pmbus_core.o
 obj-$(CONFIG_SENSORS_PMBUS)	+= pmbus.o
+obj-$(CONFIG_SENSORS_ACBEL_CRPS) += acbel-crps.o
 obj-$(CONFIG_SENSORS_ADM1266)	+= adm1266.o
 obj-$(CONFIG_SENSORS_ADM1275)	+= adm1275.o
 obj-$(CONFIG_SENSORS_BEL_PFE)	+= bel-pfe.o
diff --git a/drivers/hwmon/pmbus/acbel-crps.c b/drivers/hwmon/pmbus/acbel-crps.c
new file mode 100644
index 000000000000..f7779f0fbb2d
--- /dev/null
+++ b/drivers/hwmon/pmbus/acbel-crps.c
@@ -0,0 +1,311 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2023 IBM Corp.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pmbus.h>
+#include <linux/hwmon-sysfs.h>
+#include "pmbus.h"
+
+#define CRPS_MFG_ID_CMD                 0x99
+#define CRPS_MFG_MODEL_CMD              0x9A
+#define CRPS_MFG_REVISION_CMD           0x9B
+#define CRPS_MFG_LOCATION_CMD           0x9C
+#define CRPS_MFG_SERIAL_CMD             0x9E
+#define CRPS_CCIN_CMD                   CRPS_MFG_SERIAL_CMD
+
+/* STATUS_VOUT */
+#define CRPS_STATUS_UV_FAULT            BIT(4)
+#define CRPS_STATUS_OV_FAULT            BIT(7)
+
+/* STATUS_IOUT */
+#define CRPS_STATUS_OP_WARNING          BIT(0)
+#define CRPS_STATUS_OP_FAULT            BIT(1)
+#define CRPS_STATUS_OC_WARNING          BIT(5)
+#define CRPS_STATUS_OC_FAULT            BIT(7)
+
+/* STATUS_TEMP */
+#define CRPS_STATUS_OT_WARNING          BIT(6)
+#define CRPS_STATUS_OT_FAULT            BIT(7)
+
+/* STATUS_FAN12 */
+#define CRPS_FAN1_SPEED_OVERRIDE        BIT(2)
+#define CRPS_FAN1_WARNING               BIT(5)
+#define CRPS_FAN1_FAULT                 BIT(7)
+
+enum {
+	CRPS_DEBUGFS_MFG_ID,
+	CRPS_DEBUGFS_MFG_MODEL,
+	CRPS_DEBUGFS_MFG_REVISION,
+	CRPS_DEBUGFS_MFG_LOCATION,
+	CRPS_DEBUGFS_MFG_SERIAL,
+	CRPS_DEBUGFS_CCIN,
+	CRPS_DEBUGFS_NUM_ENTRIES
+};
+
+struct acbel_crps {
+	struct i2c_client *client;
+	int debugfs_entries[CRPS_DEBUGFS_NUM_ENTRIES];
+};
+
+static const struct i2c_device_id acbel_crps_id[] = {
+	{ "acbel_crps" },
+	{ }
+};
+#define to_psu(x, y) container_of((x), struct acbel_crps, debugfs_entries[(y)])
+
+static ssize_t acbel_crps_debugfs_read(struct file *file, char __user *buf,
+				       size_t count, loff_t *ppos)
+{
+	u8 cmd;
+	int rc;
+	int *idxp = file->private_data;
+	int idx = *idxp;
+	struct acbel_crps *psu = to_psu(idxp, idx);
+	char data[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
+
+	pmbus_set_page(psu->client, 0, 0xff);
+
+	switch (idx) {
+	case CRPS_DEBUGFS_MFG_ID:
+		cmd = CRPS_MFG_ID_CMD;
+		break;
+	case CRPS_DEBUGFS_MFG_MODEL:
+		cmd = CRPS_MFG_MODEL_CMD;
+		break;
+	case CRPS_DEBUGFS_MFG_REVISION:
+		cmd = CRPS_MFG_REVISION_CMD;
+		break;
+	case CRPS_DEBUGFS_MFG_LOCATION:
+		cmd = CRPS_MFG_LOCATION_CMD;
+		break;
+	case CRPS_DEBUGFS_MFG_SERIAL:
+		cmd = CRPS_MFG_SERIAL_CMD;
+		break;
+	case CRPS_DEBUGFS_CCIN:
+		cmd = CRPS_CCIN_CMD;
+		rc = i2c_smbus_read_block_data(psu->client, cmd, data);
+		if (rc < 0)
+			return rc;
+		data[4] = '\n';
+		data[5] = '\0';
+		rc = 6;
+		goto done;
+	default:
+		return -EINVAL;
+	}
+
+	rc = i2c_smbus_read_block_data(psu->client, cmd, data);
+	if (rc < 0)
+		return rc;
+	data[rc] = '\n';
+	rc += 2;
+done:
+	return simple_read_from_buffer(buf, count, ppos, data, rc);
+}
+
+static const struct file_operations acbel_crps_fops = {
+	.llseek = noop_llseek,
+	.read = acbel_crps_debugfs_read,
+	.open = simple_open,
+};
+
+static int acbel_crps_read_word_data(struct i2c_client *client, int page,
+				     int phase, int reg)
+{
+	int ret = 0;
+
+	if (page > 0)
+		return -ENXIO;
+
+	switch (reg) {
+	case PMBUS_VOUT_OV_FAULT_LIMIT:
+	case PMBUS_VOUT_UV_FAULT_LIMIT:
+	case PMBUS_IOUT_OC_FAULT_LIMIT:
+	case PMBUS_IOUT_OC_WARN_LIMIT:
+	case PMBUS_OT_WARN_LIMIT:
+	case PMBUS_IIN_OC_FAULT_LIMIT:
+	case PMBUS_IIN_OC_WARN_LIMIT:
+	case PMBUS_POUT_OP_FAULT_LIMIT:
+	case PMBUS_POUT_OP_WARN_LIMIT:
+	case PMBUS_MFR_VIN_MIN:
+	case PMBUS_MFR_VIN_MAX:
+	case PMBUS_MFR_IIN_MAX:
+	case PMBUS_MFR_PIN_MAX:
+	case PMBUS_MFR_VOUT_MIN:
+	case PMBUS_MFR_VOUT_MAX:
+	case PMBUS_MFR_IOUT_MAX:
+	case PMBUS_MFR_POUT_MAX:
+	case PMBUS_PIN_OP_WARN_LIMIT:
+	case PMBUS_READ_VIN:
+	case PMBUS_READ_IIN:
+	case PMBUS_READ_VOUT:
+	case PMBUS_READ_IOUT:
+	case PMBUS_READ_TEMPERATURE_1:
+	case PMBUS_READ_TEMPERATURE_2:
+	case PMBUS_READ_TEMPERATURE_3:
+	case PMBUS_READ_FAN_SPEED_1:
+	case PMBUS_READ_POUT:
+	case PMBUS_READ_PIN:
+		ret = pmbus_read_word_data(client, page, 0xff, reg);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+	return ret;
+}
+
+static int acbel_crps_read_byte_data(struct i2c_client *client, int page,
+				     int reg)
+{
+	int ret = 0;
+	int mfg_status;
+
+	if (page >= 0) {
+		ret = pmbus_set_page(client, page, 0xff);
+		if (ret < 0)
+			return ret;
+	}
+
+	switch (reg) {
+	case PMBUS_STATUS_VOUT:
+	case PMBUS_STATUS_IOUT:
+	case PMBUS_STATUS_TEMPERATURE:
+	case PMBUS_STATUS_FAN_12:
+		mfg_status = pmbus_read_word_data(client, 0, 0xff,
+						  PMBUS_STATUS_MFR_SPECIFIC);
+		if (mfg_status < 0)
+			return mfg_status;
+
+		if (reg == PMBUS_STATUS_VOUT) {
+			if (mfg_status & CRPS_STATUS_OV_FAULT)
+				ret |= PB_VOLTAGE_OV_FAULT;
+			else if (mfg_status & CRPS_STATUS_UV_FAULT)
+				ret |= PB_VOLTAGE_UV_FAULT;
+		} else if (reg == PMBUS_STATUS_IOUT) {
+			if (mfg_status & CRPS_STATUS_OC_FAULT)
+				ret |= PB_IOUT_OC_FAULT;
+			else if (mfg_status & CRPS_STATUS_OC_WARNING)
+				ret |= PB_IOUT_OC_WARNING;
+			else if (mfg_status & CRPS_STATUS_OP_FAULT)
+				ret |= PB_POUT_OP_FAULT;
+			else if (mfg_status & CRPS_STATUS_OP_WARNING)
+				ret |= PB_POUT_OP_WARNING;
+		} else if (reg == PMBUS_STATUS_TEMPERATURE) {
+			if (mfg_status & CRPS_STATUS_OT_FAULT)
+				ret |= PB_TEMP_OT_FAULT;
+			else if (mfg_status & CRPS_STATUS_OT_WARNING)
+				ret |= PB_TEMP_OT_WARNING;
+		} else if (reg == PMBUS_STATUS_FAN_12) {
+			if (mfg_status & CRPS_FAN1_FAULT)
+				ret |= PB_FAN_FAN1_FAULT;
+			else if (mfg_status & CRPS_FAN1_WARNING)
+				ret |= PB_FAN_FAN1_WARNING;
+			else if (mfg_status & CRPS_FAN1_SPEED_OVERRIDE)
+				ret |= PB_FAN_FAN1_SPEED_OVERRIDE;
+		}
+		break;
+	default:
+		ret = -ENODATA;
+		break;
+	}
+	return ret;
+}
+
+static struct pmbus_driver_info acbel_crps_info = {
+        .pages = 1,
+        .func[0] =  PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN |
+                    PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT |
+                    PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 |
+                    PMBUS_HAVE_FAN12 |
+                    PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
+                    PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_INPUT |
+                    PMBUS_HAVE_STATUS_FAN12 | PMBUS_MFR_IIN_MAX,
+        .read_word_data = acbel_crps_read_word_data,
+        .read_byte_data = acbel_crps_read_byte_data,
+};
+
+
+static int acbel_crps_probe(struct i2c_client *client)
+{
+	struct dentry *acbel_crps_dir;
+	struct dentry *debugfs;
+	struct acbel_crps *psu;
+	int rc, i;
+
+	rc = pmbus_do_probe(client, &acbel_crps_info);
+        if (rc)
+                return rc;
+	/*
+         * Don't fail the probe if there isn't enough memory for debugfs.
+         */
+	psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);
+	if (!psu)
+		return 0;
+
+	psu->client = client;
+
+	debugfs = pmbus_get_debugfs_dir(client);
+	if (!debugfs)
+		return 0;
+
+	acbel_crps_dir = debugfs_create_dir(client->name, debugfs);
+	if (!acbel_crps_dir)
+		return 0;
+
+	for (i = 0; i < CRPS_DEBUGFS_NUM_ENTRIES; ++i)
+		psu->debugfs_entries[i] = i;
+
+	debugfs_create_file("mfg_id", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_ID],
+			    &acbel_crps_fops);
+
+	debugfs_create_file("part_number", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_MODEL],
+			    &acbel_crps_fops);
+
+	debugfs_create_file("fw_version", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_REVISION],
+			    &acbel_crps_fops);
+
+	debugfs_create_file("mfg_location", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_LOCATION],
+			    &acbel_crps_fops);
+
+	debugfs_create_file("serial_number", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_SERIAL],
+			    &acbel_crps_fops);
+
+	debugfs_create_file("ccin", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_CCIN],
+			    &acbel_crps_fops);
+	return 0;
+}
+
+static const struct of_device_id acbel_crps_of_match[] = {
+	{ .compatible = "acbel,crps"},
+	{}
+};
+MODULE_DEVICE_TABLE(of, acbel_crps_of_match);
+
+static struct i2c_driver acbel_crps_driver = {
+	.driver = {
+		.name = "acbel-crps",
+		.of_match_table = acbel_crps_of_match,
+	},
+	.probe_new = acbel_crps_probe,
+	.id_table = acbel_crps_id,
+};
+
+module_i2c_driver(acbel_crps_driver);
+
+MODULE_AUTHOR("Lakshmi Yadlapati");
+MODULE_DESCRIPTION("PMBus driver for AcBel Power System power supplies");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PMBUS);
-- 
2.37.2


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

* [PATCH 4/4] ARM: dts: aspeed: p10bmc: Change power supply info
  2023-03-15 17:40 [PATCH 0/4] Review request for Acbel PSU driver Lakshmi Yadlapati
                   ` (2 preceding siblings ...)
  2023-03-15 17:40 ` [PATCH 3/4] hwmon: (pmbus/acbel-crps) Add Acbel CRPS power supply driver Lakshmi Yadlapati
@ 2023-03-15 17:40 ` Lakshmi Yadlapati
  3 siblings, 0 replies; 8+ messages in thread
From: Lakshmi Yadlapati @ 2023-03-15 17:40 UTC (permalink / raw)
  To: linux-kernel; +Cc: Lakshmi Yadlapati, ylakshmi

Change power supply driver and device address.

Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
---
 arch/arm/boot/dts/aspeed-bmc-ibm-bonnell.dts | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-bonnell.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-bonnell.dts
index a5be0ee048ec..414191b5aeba 100644
--- a/arch/arm/boot/dts/aspeed-bmc-ibm-bonnell.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-ibm-bonnell.dts
@@ -552,14 +552,14 @@ ucd90160@64 {
 &i2c3 {
 	status = "okay";
 
-	power-supply@58 {
-		compatible = "ibm,cffps";
-		reg = <0x58>;
+	power-supply@5a {
+		compatible = "acbel,crps";
+		reg = <0x5a>;
 	};
 
-	power-supply@59 {
-		compatible = "ibm,cffps";
-		reg = <0x59>;
+	power-supply@5b {
+		compatible = "acbel,crps";
+		reg = <0x5b>;
 	};
 };
 
-- 
2.37.2


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

* Re: [PATCH 1/4] dt-bindings: vendor-prefixes: Add prefix for acbel
  2023-03-15 17:40 ` [PATCH 1/4] dt-bindings: vendor-prefixes: Add prefix for acbel Lakshmi Yadlapati
@ 2023-03-16 11:30   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Kozlowski @ 2023-03-16 11:30 UTC (permalink / raw)
  To: Lakshmi Yadlapati, linux-kernel; +Cc: ylakshmi

On 15/03/2023 18:40, Lakshmi Yadlapati wrote:
> Add a vendor prefix entry for acbel (https://www.acbel.com)
> 
> Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++

I already reviewed this... please version your patches and provide
changelog.

Best regards,
Krzysztof


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

* Re: [PATCH 3/4] hwmon: (pmbus/acbel-crps) Add Acbel CRPS power supply driver
  2023-03-15 18:53 [PATCH 3/4] hwmon: (pmbus/acbel-crps) Add Acbel CRPS power supply driver Lakshmi Yadlapati
@ 2023-03-15 19:47 ` Guenter Roeck
  0 siblings, 0 replies; 8+ messages in thread
From: Guenter Roeck @ 2023-03-15 19:47 UTC (permalink / raw)
  To: Lakshmi Yadlapati, jdelvare, linux-kernel, linux-hwmon

On 3/15/23 11:53, Lakshmi Yadlapati wrote:
> Add the driver to support Acbel CRPS power supply.
> 
> Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
> ---
>   drivers/hwmon/pmbus/Kconfig      |   9 +
>   drivers/hwmon/pmbus/Makefile     |   1 +
>   drivers/hwmon/pmbus/acbel-crps.c | 311 +++++++++++++++++++++++++++++++

Documentation/hwmon/acbel-crps.rst is missing.

>   3 files changed, 321 insertions(+)
>   create mode 100644 drivers/hwmon/pmbus/acbel-crps.c
> 
> diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
> index 59d9a7430499..9fe7ac94cfa2 100644
> --- a/drivers/hwmon/pmbus/Kconfig
> +++ b/drivers/hwmon/pmbus/Kconfig
> @@ -27,6 +27,15 @@ config SENSORS_PMBUS
>   	  This driver can also be built as a module. If so, the module will
>   	  be called pmbus.
>   
> +config SENSORS_ACBEL_CRPS
> +	tristate "ACBEL CRPS Power Supply"
> +	help
> +	  If you say yes here you get hardware monitoring support for the ACBEL
> +	  CRPS power supply.
> +

This is way too generic. This company has lots of power supplies solde under
"CRPS" (whatever that means). It seems highly unlikely that this driver works
for all of them.

Besides, terms like "CRPS" really need to be explained.

> +	  This driver can also be built as a module. If so, the module will
> +	  be called acbel-crps.
> +
>   config SENSORS_ADM1266
>   	tristate "Analog Devices ADM1266 Sequencer"
>   	select CRC8
> diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
> index 3ae019916267..39aef0cb9934 100644
> --- a/drivers/hwmon/pmbus/Makefile
> +++ b/drivers/hwmon/pmbus/Makefile
> @@ -5,6 +5,7 @@
>   
>   obj-$(CONFIG_PMBUS)		+= pmbus_core.o
>   obj-$(CONFIG_SENSORS_PMBUS)	+= pmbus.o
> +obj-$(CONFIG_SENSORS_ACBEL_CRPS) += acbel-crps.o
>   obj-$(CONFIG_SENSORS_ADM1266)	+= adm1266.o
>   obj-$(CONFIG_SENSORS_ADM1275)	+= adm1275.o
>   obj-$(CONFIG_SENSORS_BEL_PFE)	+= bel-pfe.o
> diff --git a/drivers/hwmon/pmbus/acbel-crps.c b/drivers/hwmon/pmbus/acbel-crps.c
> new file mode 100644
> index 000000000000..f7779f0fbb2d
> --- /dev/null
> +++ b/drivers/hwmon/pmbus/acbel-crps.c
> @@ -0,0 +1,311 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright 2023 IBM Corp.
> + */
> +
> +#include <linux/debugfs.h>
> +#include <linux/device.h>
> +#include <linux/fs.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/pmbus.h>
> +#include <linux/hwmon-sysfs.h>
> +#include "pmbus.h"
> +
> +#define CRPS_MFG_ID_CMD                 0x99
> +#define CRPS_MFG_MODEL_CMD              0x9A
> +#define CRPS_MFG_REVISION_CMD           0x9B
> +#define CRPS_MFG_LOCATION_CMD           0x9C
> +#define CRPS_MFG_SERIAL_CMD             0x9E
> +#define CRPS_CCIN_CMD                   CRPS_MFG_SERIAL_CMD
> +
> +/* STATUS_VOUT */
> +#define CRPS_STATUS_UV_FAULT            BIT(4)
> +#define CRPS_STATUS_OV_FAULT            BIT(7)
> +
> +/* STATUS_IOUT */
> +#define CRPS_STATUS_OP_WARNING          BIT(0)
> +#define CRPS_STATUS_OP_FAULT            BIT(1)
> +#define CRPS_STATUS_OC_WARNING          BIT(5)
> +#define CRPS_STATUS_OC_FAULT            BIT(7)
> +
> +/* STATUS_TEMP */
> +#define CRPS_STATUS_OT_WARNING          BIT(6)
> +#define CRPS_STATUS_OT_FAULT            BIT(7)
> +
> +/* STATUS_FAN12 */
> +#define CRPS_FAN1_SPEED_OVERRIDE        BIT(2)
> +#define CRPS_FAN1_WARNING               BIT(5)
> +#define CRPS_FAN1_FAULT                 BIT(7)
> +
> +enum {
> +	CRPS_DEBUGFS_MFG_ID,
> +	CRPS_DEBUGFS_MFG_MODEL,
> +	CRPS_DEBUGFS_MFG_REVISION,
> +	CRPS_DEBUGFS_MFG_LOCATION,
> +	CRPS_DEBUGFS_MFG_SERIAL,
> +	CRPS_DEBUGFS_CCIN,
> +	CRPS_DEBUGFS_NUM_ENTRIES
> +};
> +
> +struct acbel_crps {
> +	struct i2c_client *client;
> +	int debugfs_entries[CRPS_DEBUGFS_NUM_ENTRIES];
> +};
> +
> +static const struct i2c_device_id acbel_crps_id[] = {
> +	{ "acbel_crps" },
> +	{ }
> +};
> +#define to_psu(x, y) container_of((x), struct acbel_crps, debugfs_entries[(y)])
> +
> +static ssize_t acbel_crps_debugfs_read(struct file *file, char __user *buf,
> +				       size_t count, loff_t *ppos)
> +{
> +	u8 cmd;
> +	int rc;
> +	int *idxp = file->private_data;
> +	int idx = *idxp;
> +	struct acbel_crps *psu = to_psu(idxp, idx);
> +	char data[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
> +
> +	pmbus_set_page(psu->client, 0, 0xff);
> +
> +	switch (idx) {
> +	case CRPS_DEBUGFS_MFG_ID:
> +		cmd = ;
> +		break;
> +	case CRPS_DEBUGFS_MFG_MODEL:
> +		cmd = CRPS_MFG_MODEL_CMD;
> +		break;
> +	case CRPS_DEBUGFS_MFG_REVISION:
> +		cmd = CRPS_MFG_REVISION_CMD;
> +		break;
> +	case CRPS_DEBUGFS_MFG_LOCATION:
> +		cmd = CRPS_MFG_LOCATION_CMD;
> +		break;
> +	case CRPS_DEBUGFS_MFG_SERIAL:
> +		cmd = CRPS_MFG_SERIAL_CMD;
> +		break;
> +	case CRPS_DEBUGFS_CCIN:
> +		cmd = CRPS_CCIN_CMD;
> +		rc = i2c_smbus_read_block_data(psu->client, cmd, data);
> +		if (rc < 0)
> +			return rc;
> +		data[4] = '\n';
> +		data[5] = '\0';
> +		rc = 6;

Needs explanation. Why not report the ret os the data ?
Also, what if rc < 4 ?

> +		goto done;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	rc = i2c_smbus_read_block_data(psu->client, cmd, data);
> +	if (rc < 0)
> +		return rc;
> +	data[rc] = '\n';
> +	rc += 2;
> +done:
> +	return simple_read_from_buffer(buf, count, ppos, data, rc);
> +}
> +
> +static const struct file_operations acbel_crps_fops = {
> +	.llseek = noop_llseek,
> +	.read = acbel_crps_debugfs_read,
> +	.open = simple_open,
> +};
> +
> +static int acbel_crps_read_word_data(struct i2c_client *client, int page,
> +				     int phase, int reg)
> +{
> +	int ret = 0;
> +
> +	if (page > 0)
> +		return -ENXIO;
> +

The driver only supports a single page, so all page command handling is unnecessary.

> +	switch (reg) {
> +	case PMBUS_VOUT_OV_FAULT_LIMIT:
> +	case PMBUS_VOUT_UV_FAULT_LIMIT:
> +	case PMBUS_IOUT_OC_FAULT_LIMIT:
> +	case PMBUS_IOUT_OC_WARN_LIMIT:
> +	case PMBUS_OT_WARN_LIMIT:
> +	case PMBUS_IIN_OC_FAULT_LIMIT:
> +	case PMBUS_IIN_OC_WARN_LIMIT:
> +	case PMBUS_POUT_OP_FAULT_LIMIT:
> +	case PMBUS_POUT_OP_WARN_LIMIT:
> +	case PMBUS_MFR_VIN_MIN:
> +	case PMBUS_MFR_VIN_MAX:
> +	case PMBUS_MFR_IIN_MAX:
> +	case PMBUS_MFR_PIN_MAX:
> +	case PMBUS_MFR_VOUT_MIN:
> +	case PMBUS_MFR_VOUT_MAX:
> +	case PMBUS_MFR_IOUT_MAX:
> +	case PMBUS_MFR_POUT_MAX:
> +	case PMBUS_PIN_OP_WARN_LIMIT:
> +	case PMBUS_READ_VIN:
> +	case PMBUS_READ_IIN:
> +	case PMBUS_READ_VOUT:
> +	case PMBUS_READ_IOUT:
> +	case PMBUS_READ_TEMPERATURE_1:
> +	case PMBUS_READ_TEMPERATURE_2:
> +	case PMBUS_READ_TEMPERATURE_3:
> +	case PMBUS_READ_FAN_SPEED_1:
> +	case PMBUS_READ_POUT:
> +	case PMBUS_READ_PIN:
> +		ret = pmbus_read_word_data(client, page, 0xff, reg);
> +		break;

Needs explanation. What happens if unsupported registers/commands
are executed ?

> +	default:
> +		ret = -EOPNOTSUPP;
> +		break;
> +	}
> +	return ret;
> +}
> +
> +static int acbel_crps_read_byte_data(struct i2c_client *client, int page,
> +				     int reg)
> +{
> +	int ret = 0;
> +	int mfg_status;
> +
> +	if (page >= 0) {
> +		ret = pmbus_set_page(client, page, 0xff);
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	switch (reg) {
> +	case PMBUS_STATUS_VOUT:
> +	case PMBUS_STATUS_IOUT:
> +	case PMBUS_STATUS_TEMPERATURE:
> +	case PMBUS_STATUS_FAN_12:

Needs explanation. Why not use standard commands ?

> +		mfg_status = pmbus_read_word_data(client, 0, 0xff,
> +						  PMBUS_STATUS_MFR_SPECIFIC);
> +		if (mfg_status < 0)
> +			return mfg_status;
> +
> +		if (reg == PMBUS_STATUS_VOUT) {
> +			if (mfg_status & CRPS_STATUS_OV_FAULT)
> +				ret |= PB_VOLTAGE_OV_FAULT;
> +			else if (mfg_status & CRPS_STATUS_UV_FAULT)
> +				ret |= PB_VOLTAGE_UV_FAULT;
> +		} else if (reg == PMBUS_STATUS_IOUT) {
> +			if (mfg_status & CRPS_STATUS_OC_FAULT)
> +				ret |= PB_IOUT_OC_FAULT;
> +			else if (mfg_status & CRPS_STATUS_OC_WARNING)
> +				ret |= PB_IOUT_OC_WARNING;
> +			else if (mfg_status & CRPS_STATUS_OP_FAULT)
> +				ret |= PB_POUT_OP_FAULT;
> +			else if (mfg_status & CRPS_STATUS_OP_WARNING)
> +				ret |= PB_POUT_OP_WARNING;
> +		} else if (reg == PMBUS_STATUS_TEMPERATURE) {
> +			if (mfg_status & CRPS_STATUS_OT_FAULT)
> +				ret |= PB_TEMP_OT_FAULT;
> +			else if (mfg_status & CRPS_STATUS_OT_WARNING)
> +				ret |= PB_TEMP_OT_WARNING;
> +		} else if (reg == PMBUS_STATUS_FAN_12) {

Unnecessary else.

> +			if (mfg_status & CRPS_FAN1_FAULT)
> +				ret |= PB_FAN_FAN1_FAULT;
> +			else if (mfg_status & CRPS_FAN1_WARNING)
> +				ret |= PB_FAN_FAN1_WARNING;
> +			else if (mfg_status & CRPS_FAN1_SPEED_OVERRIDE)
> +				ret |= PB_FAN_FAN1_SPEED_OVERRIDE;
> +		}
> +		break;
> +	default:
> +		ret = -ENODATA;

Needs explanation. Executing other potentially unsupported byte commands
is ok, but not executing unsupported word commands ?

> +		break;
> +	}
> +	return ret;
> +}
> +
> +static struct pmbus_driver_info acbel_crps_info = {
> +        .pages = 1,
> +        .func[0] =  PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN |
> +                    PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT |
> +                    PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 |
> +                    PMBUS_HAVE_FAN12 |
> +                    PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
> +                    PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_INPUT |
> +                    PMBUS_HAVE_STATUS_FAN12 | PMBUS_MFR_IIN_MAX,

PMBUS_MFR_IIN_MAX is wrong. This is a register/command name, not a flag.

> +        .read_word_data = acbel_crps_read_word_data,
> +        .read_byte_data = acbel_crps_read_byte_data,
> +};
> +
> +
> +static int acbel_crps_probe(struct i2c_client *client)
> +{
> +	struct dentry *acbel_crps_dir;
> +	struct dentry *debugfs;
> +	struct acbel_crps *psu;
> +	int rc, i;
> +
There is no validation that this is indeed a supported power supply.
Please add such a validation.

> +	rc = pmbus_do_probe(client, &acbel_crps_info);
> +        if (rc)
> +                return rc;
> +	/*
> +         * Don't fail the probe if there isn't enough memory for debugfs.
> +         */

Formatting. That made me run checkpatch --strict, and I get:

total: 14 errors, 15 warnings, 2 checks, 333 lines checked

Please check your patches for coding style, and please consider reading
and following Documentation/hwmon/submitting-patches.rst.

> +	psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);
> +	if (!psu)
> +		return 0;
> +
> +	psu->client = client;
> +
> +	debugfs = pmbus_get_debugfs_dir(client);
> +	if (!debugfs)
> +		return 0;
> +

Please handle debugfs initialization in a separate function.

> +	acbel_crps_dir = debugfs_create_dir(client->name, debugfs);
> +	if (!acbel_crps_dir)
> +		return 0;
> +
Please explain why you don't use pmbus_get_debugfs_dir().
Anyway, I am at loss why you don't use the already existing
debugfs support, which does report exactly the same information
(and more). Please explain.

> +	for (i = 0; i < CRPS_DEBUGFS_NUM_ENTRIES; ++i)
> +		psu->debugfs_entries[i] = i;
> +
> +	debugfs_create_file("mfg_id", 0444, acbel_crps_dir,
> +			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_ID],
> +			    &acbel_crps_fops);
> +
> +	debugfs_create_file("part_number", 0444, acbel_crps_dir,
> +			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_MODEL],
> +			    &acbel_crps_fops);
> +
> +	debugfs_create_file("fw_version", 0444, acbel_crps_dir,
> +			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_REVISION],
> +			    &acbel_crps_fops);
> +
> +	debugfs_create_file("mfg_location", 0444, acbel_crps_dir,
> +			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_LOCATION],
> +			    &acbel_crps_fops);
> +
> +	debugfs_create_file("serial_number", 0444, acbel_crps_dir,
> +			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_SERIAL],
> +			    &acbel_crps_fops);
> +
> +	debugfs_create_file("ccin", 0444, acbel_crps_dir,
> +			    &psu->debugfs_entries[CRPS_DEBUGFS_CCIN],
> +			    &acbel_crps_fops);
> +	return 0;
> +}
> +
> +static const struct of_device_id acbel_crps_of_match[] = {
> +	{ .compatible = "acbel,crps"},
> +	{}

This suggests that the driver is expected to be used in systems using devicetree.
"acbel,crps" must be documented, either as trivial device or with an appropriate
devicetree description file.

> +};
> +MODULE_DEVICE_TABLE(of, acbel_crps_of_match);
> +
> +static struct i2c_driver acbel_crps_driver = {
> +	.driver = {
> +		.name = "acbel-crps",
> +		.of_match_table = acbel_crps_of_match,
> +	},
> +	.probe_new = acbel_crps_probe,
> +	.id_table = acbel_crps_id,
> +};
> +
> +module_i2c_driver(acbel_crps_driver);
> +
> +MODULE_AUTHOR("Lakshmi Yadlapati");
> +MODULE_DESCRIPTION("PMBus driver for AcBel Power System power supplies");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS(PMBUS);


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

* [PATCH 3/4] hwmon: (pmbus/acbel-crps) Add Acbel CRPS power supply driver
@ 2023-03-15 18:53 Lakshmi Yadlapati
  2023-03-15 19:47 ` Guenter Roeck
  0 siblings, 1 reply; 8+ messages in thread
From: Lakshmi Yadlapati @ 2023-03-15 18:53 UTC (permalink / raw)
  To: linux, jdelvare, linux-kernel, linux-hwmon; +Cc: Lakshmi Yadlapati

Add the driver to support Acbel CRPS power supply.

Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
---
 drivers/hwmon/pmbus/Kconfig      |   9 +
 drivers/hwmon/pmbus/Makefile     |   1 +
 drivers/hwmon/pmbus/acbel-crps.c | 311 +++++++++++++++++++++++++++++++
 3 files changed, 321 insertions(+)
 create mode 100644 drivers/hwmon/pmbus/acbel-crps.c

diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 59d9a7430499..9fe7ac94cfa2 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -27,6 +27,15 @@ config SENSORS_PMBUS
 	  This driver can also be built as a module. If so, the module will
 	  be called pmbus.
 
+config SENSORS_ACBEL_CRPS
+	tristate "ACBEL CRPS Power Supply"
+	help
+	  If you say yes here you get hardware monitoring support for the ACBEL
+	  CRPS power supply.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called acbel-crps.
+
 config SENSORS_ADM1266
 	tristate "Analog Devices ADM1266 Sequencer"
 	select CRC8
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 3ae019916267..39aef0cb9934 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_PMBUS)		+= pmbus_core.o
 obj-$(CONFIG_SENSORS_PMBUS)	+= pmbus.o
+obj-$(CONFIG_SENSORS_ACBEL_CRPS) += acbel-crps.o
 obj-$(CONFIG_SENSORS_ADM1266)	+= adm1266.o
 obj-$(CONFIG_SENSORS_ADM1275)	+= adm1275.o
 obj-$(CONFIG_SENSORS_BEL_PFE)	+= bel-pfe.o
diff --git a/drivers/hwmon/pmbus/acbel-crps.c b/drivers/hwmon/pmbus/acbel-crps.c
new file mode 100644
index 000000000000..f7779f0fbb2d
--- /dev/null
+++ b/drivers/hwmon/pmbus/acbel-crps.c
@@ -0,0 +1,311 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2023 IBM Corp.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pmbus.h>
+#include <linux/hwmon-sysfs.h>
+#include "pmbus.h"
+
+#define CRPS_MFG_ID_CMD                 0x99
+#define CRPS_MFG_MODEL_CMD              0x9A
+#define CRPS_MFG_REVISION_CMD           0x9B
+#define CRPS_MFG_LOCATION_CMD           0x9C
+#define CRPS_MFG_SERIAL_CMD             0x9E
+#define CRPS_CCIN_CMD                   CRPS_MFG_SERIAL_CMD
+
+/* STATUS_VOUT */
+#define CRPS_STATUS_UV_FAULT            BIT(4)
+#define CRPS_STATUS_OV_FAULT            BIT(7)
+
+/* STATUS_IOUT */
+#define CRPS_STATUS_OP_WARNING          BIT(0)
+#define CRPS_STATUS_OP_FAULT            BIT(1)
+#define CRPS_STATUS_OC_WARNING          BIT(5)
+#define CRPS_STATUS_OC_FAULT            BIT(7)
+
+/* STATUS_TEMP */
+#define CRPS_STATUS_OT_WARNING          BIT(6)
+#define CRPS_STATUS_OT_FAULT            BIT(7)
+
+/* STATUS_FAN12 */
+#define CRPS_FAN1_SPEED_OVERRIDE        BIT(2)
+#define CRPS_FAN1_WARNING               BIT(5)
+#define CRPS_FAN1_FAULT                 BIT(7)
+
+enum {
+	CRPS_DEBUGFS_MFG_ID,
+	CRPS_DEBUGFS_MFG_MODEL,
+	CRPS_DEBUGFS_MFG_REVISION,
+	CRPS_DEBUGFS_MFG_LOCATION,
+	CRPS_DEBUGFS_MFG_SERIAL,
+	CRPS_DEBUGFS_CCIN,
+	CRPS_DEBUGFS_NUM_ENTRIES
+};
+
+struct acbel_crps {
+	struct i2c_client *client;
+	int debugfs_entries[CRPS_DEBUGFS_NUM_ENTRIES];
+};
+
+static const struct i2c_device_id acbel_crps_id[] = {
+	{ "acbel_crps" },
+	{ }
+};
+#define to_psu(x, y) container_of((x), struct acbel_crps, debugfs_entries[(y)])
+
+static ssize_t acbel_crps_debugfs_read(struct file *file, char __user *buf,
+				       size_t count, loff_t *ppos)
+{
+	u8 cmd;
+	int rc;
+	int *idxp = file->private_data;
+	int idx = *idxp;
+	struct acbel_crps *psu = to_psu(idxp, idx);
+	char data[I2C_SMBUS_BLOCK_MAX + 2] = { 0 };
+
+	pmbus_set_page(psu->client, 0, 0xff);
+
+	switch (idx) {
+	case CRPS_DEBUGFS_MFG_ID:
+		cmd = CRPS_MFG_ID_CMD;
+		break;
+	case CRPS_DEBUGFS_MFG_MODEL:
+		cmd = CRPS_MFG_MODEL_CMD;
+		break;
+	case CRPS_DEBUGFS_MFG_REVISION:
+		cmd = CRPS_MFG_REVISION_CMD;
+		break;
+	case CRPS_DEBUGFS_MFG_LOCATION:
+		cmd = CRPS_MFG_LOCATION_CMD;
+		break;
+	case CRPS_DEBUGFS_MFG_SERIAL:
+		cmd = CRPS_MFG_SERIAL_CMD;
+		break;
+	case CRPS_DEBUGFS_CCIN:
+		cmd = CRPS_CCIN_CMD;
+		rc = i2c_smbus_read_block_data(psu->client, cmd, data);
+		if (rc < 0)
+			return rc;
+		data[4] = '\n';
+		data[5] = '\0';
+		rc = 6;
+		goto done;
+	default:
+		return -EINVAL;
+	}
+
+	rc = i2c_smbus_read_block_data(psu->client, cmd, data);
+	if (rc < 0)
+		return rc;
+	data[rc] = '\n';
+	rc += 2;
+done:
+	return simple_read_from_buffer(buf, count, ppos, data, rc);
+}
+
+static const struct file_operations acbel_crps_fops = {
+	.llseek = noop_llseek,
+	.read = acbel_crps_debugfs_read,
+	.open = simple_open,
+};
+
+static int acbel_crps_read_word_data(struct i2c_client *client, int page,
+				     int phase, int reg)
+{
+	int ret = 0;
+
+	if (page > 0)
+		return -ENXIO;
+
+	switch (reg) {
+	case PMBUS_VOUT_OV_FAULT_LIMIT:
+	case PMBUS_VOUT_UV_FAULT_LIMIT:
+	case PMBUS_IOUT_OC_FAULT_LIMIT:
+	case PMBUS_IOUT_OC_WARN_LIMIT:
+	case PMBUS_OT_WARN_LIMIT:
+	case PMBUS_IIN_OC_FAULT_LIMIT:
+	case PMBUS_IIN_OC_WARN_LIMIT:
+	case PMBUS_POUT_OP_FAULT_LIMIT:
+	case PMBUS_POUT_OP_WARN_LIMIT:
+	case PMBUS_MFR_VIN_MIN:
+	case PMBUS_MFR_VIN_MAX:
+	case PMBUS_MFR_IIN_MAX:
+	case PMBUS_MFR_PIN_MAX:
+	case PMBUS_MFR_VOUT_MIN:
+	case PMBUS_MFR_VOUT_MAX:
+	case PMBUS_MFR_IOUT_MAX:
+	case PMBUS_MFR_POUT_MAX:
+	case PMBUS_PIN_OP_WARN_LIMIT:
+	case PMBUS_READ_VIN:
+	case PMBUS_READ_IIN:
+	case PMBUS_READ_VOUT:
+	case PMBUS_READ_IOUT:
+	case PMBUS_READ_TEMPERATURE_1:
+	case PMBUS_READ_TEMPERATURE_2:
+	case PMBUS_READ_TEMPERATURE_3:
+	case PMBUS_READ_FAN_SPEED_1:
+	case PMBUS_READ_POUT:
+	case PMBUS_READ_PIN:
+		ret = pmbus_read_word_data(client, page, 0xff, reg);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+	return ret;
+}
+
+static int acbel_crps_read_byte_data(struct i2c_client *client, int page,
+				     int reg)
+{
+	int ret = 0;
+	int mfg_status;
+
+	if (page >= 0) {
+		ret = pmbus_set_page(client, page, 0xff);
+		if (ret < 0)
+			return ret;
+	}
+
+	switch (reg) {
+	case PMBUS_STATUS_VOUT:
+	case PMBUS_STATUS_IOUT:
+	case PMBUS_STATUS_TEMPERATURE:
+	case PMBUS_STATUS_FAN_12:
+		mfg_status = pmbus_read_word_data(client, 0, 0xff,
+						  PMBUS_STATUS_MFR_SPECIFIC);
+		if (mfg_status < 0)
+			return mfg_status;
+
+		if (reg == PMBUS_STATUS_VOUT) {
+			if (mfg_status & CRPS_STATUS_OV_FAULT)
+				ret |= PB_VOLTAGE_OV_FAULT;
+			else if (mfg_status & CRPS_STATUS_UV_FAULT)
+				ret |= PB_VOLTAGE_UV_FAULT;
+		} else if (reg == PMBUS_STATUS_IOUT) {
+			if (mfg_status & CRPS_STATUS_OC_FAULT)
+				ret |= PB_IOUT_OC_FAULT;
+			else if (mfg_status & CRPS_STATUS_OC_WARNING)
+				ret |= PB_IOUT_OC_WARNING;
+			else if (mfg_status & CRPS_STATUS_OP_FAULT)
+				ret |= PB_POUT_OP_FAULT;
+			else if (mfg_status & CRPS_STATUS_OP_WARNING)
+				ret |= PB_POUT_OP_WARNING;
+		} else if (reg == PMBUS_STATUS_TEMPERATURE) {
+			if (mfg_status & CRPS_STATUS_OT_FAULT)
+				ret |= PB_TEMP_OT_FAULT;
+			else if (mfg_status & CRPS_STATUS_OT_WARNING)
+				ret |= PB_TEMP_OT_WARNING;
+		} else if (reg == PMBUS_STATUS_FAN_12) {
+			if (mfg_status & CRPS_FAN1_FAULT)
+				ret |= PB_FAN_FAN1_FAULT;
+			else if (mfg_status & CRPS_FAN1_WARNING)
+				ret |= PB_FAN_FAN1_WARNING;
+			else if (mfg_status & CRPS_FAN1_SPEED_OVERRIDE)
+				ret |= PB_FAN_FAN1_SPEED_OVERRIDE;
+		}
+		break;
+	default:
+		ret = -ENODATA;
+		break;
+	}
+	return ret;
+}
+
+static struct pmbus_driver_info acbel_crps_info = {
+        .pages = 1,
+        .func[0] =  PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN |
+                    PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT |
+                    PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 |
+                    PMBUS_HAVE_FAN12 |
+                    PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
+                    PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_INPUT |
+                    PMBUS_HAVE_STATUS_FAN12 | PMBUS_MFR_IIN_MAX,
+        .read_word_data = acbel_crps_read_word_data,
+        .read_byte_data = acbel_crps_read_byte_data,
+};
+
+
+static int acbel_crps_probe(struct i2c_client *client)
+{
+	struct dentry *acbel_crps_dir;
+	struct dentry *debugfs;
+	struct acbel_crps *psu;
+	int rc, i;
+
+	rc = pmbus_do_probe(client, &acbel_crps_info);
+        if (rc)
+                return rc;
+	/*
+         * Don't fail the probe if there isn't enough memory for debugfs.
+         */
+	psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);
+	if (!psu)
+		return 0;
+
+	psu->client = client;
+
+	debugfs = pmbus_get_debugfs_dir(client);
+	if (!debugfs)
+		return 0;
+
+	acbel_crps_dir = debugfs_create_dir(client->name, debugfs);
+	if (!acbel_crps_dir)
+		return 0;
+
+	for (i = 0; i < CRPS_DEBUGFS_NUM_ENTRIES; ++i)
+		psu->debugfs_entries[i] = i;
+
+	debugfs_create_file("mfg_id", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_ID],
+			    &acbel_crps_fops);
+
+	debugfs_create_file("part_number", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_MODEL],
+			    &acbel_crps_fops);
+
+	debugfs_create_file("fw_version", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_REVISION],
+			    &acbel_crps_fops);
+
+	debugfs_create_file("mfg_location", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_LOCATION],
+			    &acbel_crps_fops);
+
+	debugfs_create_file("serial_number", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_MFG_SERIAL],
+			    &acbel_crps_fops);
+
+	debugfs_create_file("ccin", 0444, acbel_crps_dir,
+			    &psu->debugfs_entries[CRPS_DEBUGFS_CCIN],
+			    &acbel_crps_fops);
+	return 0;
+}
+
+static const struct of_device_id acbel_crps_of_match[] = {
+	{ .compatible = "acbel,crps"},
+	{}
+};
+MODULE_DEVICE_TABLE(of, acbel_crps_of_match);
+
+static struct i2c_driver acbel_crps_driver = {
+	.driver = {
+		.name = "acbel-crps",
+		.of_match_table = acbel_crps_of_match,
+	},
+	.probe_new = acbel_crps_probe,
+	.id_table = acbel_crps_id,
+};
+
+module_i2c_driver(acbel_crps_driver);
+
+MODULE_AUTHOR("Lakshmi Yadlapati");
+MODULE_DESCRIPTION("PMBus driver for AcBel Power System power supplies");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PMBUS);
-- 
2.37.2


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

end of thread, other threads:[~2023-03-16 11:31 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-15 17:40 [PATCH 0/4] Review request for Acbel PSU driver Lakshmi Yadlapati
2023-03-15 17:40 ` [PATCH 1/4] dt-bindings: vendor-prefixes: Add prefix for acbel Lakshmi Yadlapati
2023-03-16 11:30   ` Krzysztof Kozlowski
2023-03-15 17:40 ` [PATCH 2/4] dt-bindings: trivial-devices: Add acbel,crps Lakshmi Yadlapati
2023-03-15 17:40 ` [PATCH 3/4] hwmon: (pmbus/acbel-crps) Add Acbel CRPS power supply driver Lakshmi Yadlapati
2023-03-15 17:40 ` [PATCH 4/4] ARM: dts: aspeed: p10bmc: Change power supply info Lakshmi Yadlapati
2023-03-15 18:53 [PATCH 3/4] hwmon: (pmbus/acbel-crps) Add Acbel CRPS power supply driver Lakshmi Yadlapati
2023-03-15 19:47 ` Guenter Roeck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.