]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
hwmon: (pmbus/ucd9000) Add support for UCD90320 Power Sequencer
authorJim Wright <wrightj@linux.vnet.ibm.com>
Thu, 5 Dec 2019 23:24:11 +0000 (17:24 -0600)
committerGuenter Roeck <linux@roeck-us.net>
Thu, 23 Jan 2020 21:15:09 +0000 (13:15 -0800)
Add support for the UCD90320 chip and its expanded set of GPIO pins.

Signed-off-by: Jim Wright <wrightj@linux.vnet.ibm.com>
Link: https://lore.kernel.org/r/20191205232411.21492-3-wrightj@linux.vnet.ibm.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Documentation/hwmon/ucd9000.rst
drivers/hwmon/pmbus/Kconfig
drivers/hwmon/pmbus/ucd9000.c

index 746f21fcb48ccc9c77f74f3fd0e435622bb31425..704f0cbd95d3b3e9ccc27738dd379ca768e37182 100644 (file)
@@ -3,9 +3,10 @@ Kernel driver ucd9000
 
 Supported chips:
 
-  * TI UCD90120, UCD90124, UCD90160, UCD9090, and UCD90910
+  * TI UCD90120, UCD90124, UCD90160, UCD90320, UCD9090, and UCD90910
 
-    Prefixes: 'ucd90120', 'ucd90124', 'ucd90160', 'ucd9090', 'ucd90910'
+    Prefixes: 'ucd90120', 'ucd90124', 'ucd90160', 'ucd90320', 'ucd9090',
+              'ucd90910'
 
     Addresses scanned: -
 
@@ -14,6 +15,7 @@ Supported chips:
        - http://focus.ti.com/lit/ds/symlink/ucd90120.pdf
        - http://focus.ti.com/lit/ds/symlink/ucd90124.pdf
        - http://focus.ti.com/lit/ds/symlink/ucd90160.pdf
+       - http://focus.ti.com/lit/ds/symlink/ucd90320.pdf
        - http://focus.ti.com/lit/ds/symlink/ucd9090.pdf
        - http://focus.ti.com/lit/ds/symlink/ucd90910.pdf
 
@@ -45,6 +47,12 @@ power-on reset signals, external interrupts, cascading, or other system
 functions. Twelve of these pins offer PWM functionality. Using these pins, the
 UCD90160 offers support for margining, and general-purpose PWM functions.
 
+The UCD90320 is a 32-rail PMBus/I2C addressable power-supply sequencer and
+monitor. The 24 integrated ADC channels (AMONx) monitor the power supply
+voltage, current, and temperature. Of the 84 GPIO pins, 8 can be used as
+digital monitors (DMONx), 32 to enable the power supply (ENx), 24 for margining
+(MARx), 16 for logical GPO, and 32 GPIs for cascading, and system function.
+
 The UCD9090 is a 10-rail PMBus/I2C addressable power-supply sequencer and
 monitor. The device integrates a 12-bit ADC for monitoring up to 10 power-supply
 voltage inputs. Twenty-three GPIO pins can be used for power supply enables,
index 59859979571df5a24cc8b78b564c4af380110ddc..48ae5a5419c50d124d92f8c82423272f2d4f28d8 100644 (file)
@@ -209,11 +209,11 @@ config SENSORS_TPS53679
          be called tps53679.
 
 config SENSORS_UCD9000
-       tristate "TI UCD90120, UCD90124, UCD90160, UCD9090, UCD90910"
+       tristate "TI UCD90120, UCD90124, UCD90160, UCD90320, UCD9090, UCD90910"
        help
          If you say yes here you get hardware monitoring support for TI
-         UCD90120, UCD90124, UCD90160, UCD9090, UCD90910, Sequencer and System
-         Health Controllers.
+         UCD90120, UCD90124, UCD90160, UCD90320, UCD9090, UCD90910, Sequencer
+         and System Health Controllers.
 
          This driver can also be built as a module. If so, the module will
          be called ucd9000.
index a9229c6b0e84dcc7435d18bd9e19bef9a60227ae..23ea3415f1664d93459ee84e865a0ad3a14dc375 100644 (file)
@@ -18,7 +18,8 @@
 #include <linux/gpio/driver.h>
 #include "pmbus.h"
 
-enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 };
+enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd90320, ucd9090,
+            ucd90910 };
 
 #define UCD9000_MONITOR_CONFIG         0xd5
 #define UCD9000_NUM_PAGES              0xd6
@@ -38,7 +39,7 @@ enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 };
 #define UCD9000_GPIO_OUTPUT            1
 
 #define UCD9000_MON_TYPE(x)    (((x) >> 5) & 0x07)
-#define UCD9000_MON_PAGE(x)    ((x) & 0x0f)
+#define UCD9000_MON_PAGE(x)    ((x) & 0x1f)
 
 #define UCD9000_MON_VOLTAGE    1
 #define UCD9000_MON_TEMPERATURE        2
@@ -50,10 +51,12 @@ enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 };
 #define UCD9000_GPIO_NAME_LEN  16
 #define UCD9090_NUM_GPIOS      23
 #define UCD901XX_NUM_GPIOS     26
+#define UCD90320_NUM_GPIOS     84
 #define UCD90910_NUM_GPIOS     26
 
 #define UCD9000_DEBUGFS_NAME_LEN       24
 #define UCD9000_GPI_COUNT              8
+#define UCD90320_GPI_COUNT             32
 
 struct ucd9000_data {
        u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX];
@@ -131,6 +134,7 @@ static const struct i2c_device_id ucd9000_id[] = {
        {"ucd90120", ucd90120},
        {"ucd90124", ucd90124},
        {"ucd90160", ucd90160},
+       {"ucd90320", ucd90320},
        {"ucd9090", ucd9090},
        {"ucd90910", ucd90910},
        {}
@@ -154,6 +158,10 @@ static const struct of_device_id __maybe_unused ucd9000_of_match[] = {
                .compatible = "ti,ucd90160",
                .data = (void *)ucd90160
        },
+       {
+               .compatible = "ti,ucd90320",
+               .data = (void *)ucd90320
+       },
        {
                .compatible = "ti,ucd9090",
                .data = (void *)ucd9090
@@ -322,6 +330,9 @@ static void ucd9000_probe_gpio(struct i2c_client *client,
        case ucd90160:
                data->gpio.ngpio = UCD901XX_NUM_GPIOS;
                break;
+       case ucd90320:
+               data->gpio.ngpio = UCD90320_NUM_GPIOS;
+               break;
        case ucd90910:
                data->gpio.ngpio = UCD90910_NUM_GPIOS;
                break;
@@ -372,17 +383,18 @@ static int ucd9000_debugfs_show_mfr_status_bit(void *data, u64 *val)
        struct ucd9000_debugfs_entry *entry = data;
        struct i2c_client *client = entry->client;
        u8 buffer[I2C_SMBUS_BLOCK_MAX];
-       int ret;
+       int ret, i;
 
        ret = ucd9000_get_mfr_status(client, buffer);
        if (ret < 0)
                return ret;
 
        /*
-        * Attribute only created for devices with gpi fault bits at bits
-        * 16-23, which is the second byte of the response.
+        * GPI fault bits are in sets of 8, two bytes from end of response.
         */
-       *val = !!(buffer[1] & BIT(entry->index));
+       i = ret - 3 - entry->index / 8;
+       if (i >= 0)
+               *val = !!(buffer[i] & BIT(entry->index % 8));
 
        return 0;
 }
@@ -422,7 +434,7 @@ static int ucd9000_init_debugfs(struct i2c_client *client,
 {
        struct dentry *debugfs;
        struct ucd9000_debugfs_entry *entries;
-       int i;
+       int i, gpi_count;
        char name[UCD9000_DEBUGFS_NAME_LEN];
 
        debugfs = pmbus_get_debugfs_dir(client);
@@ -435,18 +447,21 @@ static int ucd9000_init_debugfs(struct i2c_client *client,
 
        /*
         * Of the chips this driver supports, only the UCD9090, UCD90160,
-        * and UCD90910 report GPI faults in their MFR_STATUS register, so only
-        * create the GPI fault debugfs attributes for those chips.
+        * UCD90320, and UCD90910 report GPI faults in their MFR_STATUS
+        * register, so only create the GPI fault debugfs attributes for those
+        * chips.
         */
        if (mid->driver_data == ucd9090 || mid->driver_data == ucd90160 ||
-           mid->driver_data == ucd90910) {
+           mid->driver_data == ucd90320 || mid->driver_data == ucd90910) {
+               gpi_count = mid->driver_data == ucd90320 ? UCD90320_GPI_COUNT
+                                                        : UCD9000_GPI_COUNT;
                entries = devm_kcalloc(&client->dev,
-                                      UCD9000_GPI_COUNT, sizeof(*entries),
+                                      gpi_count, sizeof(*entries),
                                       GFP_KERNEL);
                if (!entries)
                        return -ENOMEM;
 
-               for (i = 0; i < UCD9000_GPI_COUNT; i++) {
+               for (i = 0; i < gpi_count; i++) {
                        entries[i].client = client;
                        entries[i].index = i;
                        scnprintf(name, UCD9000_DEBUGFS_NAME_LEN,