hwmon: (pmbus/pli1209bc) Add regulator support
authorMarcello Sylvester Bauer <sylv@sylv.io>
Mon, 21 Feb 2022 09:42:07 +0000 (10:42 +0100)
committerGuenter Roeck <linux@roeck-us.net>
Mon, 28 Feb 2022 01:03:19 +0000 (17:03 -0800)
Add regulator support for PLI1209BC Digital Supervisor.

Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io>
Link: https://lore.kernel.org/r/21b0cdb6dd72654effa451d3b1636ecd07b160e9.1645435888.git.sylv@sylv.io
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/pmbus/Kconfig
drivers/hwmon/pmbus/pli1209bc.c

index f18f67a94697402728d4fb915d6c29993b0333fe..6552467c588d108160068ae17cba9429748dbe93 100644 (file)
@@ -326,6 +326,13 @@ config SENSORS_PLI1209BC
          This driver can also be built as a module. If so, the module will
          be called pli1209bc.
 
+config SENSORS_PLI1209BC_REGULATOR
+       bool "Regulator support for PLI1209BC"
+       depends on SENSORS_PLI1209BC && REGULATOR
+       help
+         If you say yes here you get regulator support for Vicor PLI1209BC
+         Digital Supervisor.
+
 config SENSORS_PM6764TR
        tristate "ST PM6764TR"
        help
index 5f8847307e5591dfafffa26f15baa816c019cf41..05b4ee35ba270004e140229f586f9a461f4f46ad 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/pmbus.h>
+#include <linux/regulator/driver.h>
 #include "pmbus.h"
 
 /*
@@ -33,11 +34,37 @@ static int pli1209bc_read_word_data(struct i2c_client *client, int page,
                        return data;
                data = sign_extend32(data, 15) * 10;
                return clamp_val(data, -32768, 32767) & 0xffff;
+       /*
+        * PMBUS_READ_VOUT and PMBUS_READ_TEMPERATURE_1 return invalid data
+        * when the BCM is turned off. Since it is not possible to return
+        * ENODATA error, return zero instead.
+        */
+       case PMBUS_READ_VOUT:
+       case PMBUS_READ_TEMPERATURE_1:
+               data = pmbus_read_word_data(client, page, phase,
+                                           PMBUS_STATUS_WORD);
+               if (data < 0)
+                       return data;
+               if (data & PB_STATUS_POWER_GOOD_N)
+                       return 0;
+               return pmbus_read_word_data(client, page, phase, reg);
        default:
                return -ENODATA;
        }
 }
 
+#if IS_ENABLED(CONFIG_SENSORS_PLI1209BC_REGULATOR)
+static const struct regulator_desc pli1209bc_reg_desc = {
+       .name = "vout2",
+       .id = 1,
+       .of_match = of_match_ptr("vout2"),
+       .regulators_node = of_match_ptr("regulators"),
+       .ops = &pmbus_regulator_ops,
+       .type = REGULATOR_VOLTAGE,
+       .owner = THIS_MODULE,
+};
+#endif
+
 static struct pmbus_driver_info pli1209bc_info = {
        .pages = 2,
        .format[PSC_VOLTAGE_IN] = direct,
@@ -75,6 +102,10 @@ static struct pmbus_driver_info pli1209bc_info = {
            | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP
            | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT,
        .read_word_data = pli1209bc_read_word_data,
+#if IS_ENABLED(CONFIG_SENSORS_PLI1209BC_REGULATOR)
+       .num_regulators = 1,
+       .reg_desc = &pli1209bc_reg_desc,
+#endif
 };
 
 static int pli1209bc_probe(struct i2c_client *client)