]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
hwmon: (pmbus/adm1266) add firmware_revision debugfs entry
authorAbdurrahman Hussain <abdurrahman@nexthop.ai>
Tue, 12 May 2026 18:56:24 +0000 (11:56 -0700)
committerGuenter Roeck <linux@roeck-us.net>
Tue, 9 Jun 2026 15:23:00 +0000 (08:23 -0700)
The ADM1266 reports its firmware revision via the IC_DEVICE_REV
manufacturer-specific block-read command (0xAE, datasheet Rev. D
Table 80). The first three returned bytes are the firmware
major.minor.patch fields. This is useful when correlating field
behaviour against ADI release notes; expose it through debugfs
alongside the existing sequencer_state entry.

The standard PMBus MFR_REVISION (0x9B) register is already exposed
by pmbus_core's debugfs auto-create path and reports the
manufacturer revision, which is a separate thing from the firmware
running on the device.

Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
Link: https://lore.kernel.org/r/20260512-adm1266-v3-1-a81a479b0bb0@nexthop.ai
[groeck: Squashed patch adding serialization with pmbus_lock]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/pmbus/adm1266.c

index 360a7730b807015c9c8461d89c8e21b4bcc090af..7f4dbc98d92a062227c0a616d3137d40a16d71a4 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/timekeeping.h>
 
+#define ADM1266_IC_DEVICE_REV  0xAE
 #define ADM1266_BLACKBOX_CONFIG        0xD3
 #define ADM1266_PDIO_CONFIG    0xD4
 #define ADM1266_READ_STATE     0xD9
@@ -345,6 +346,31 @@ static int adm1266_state_read(struct seq_file *s, void *pdata)
        return 0;
 }
 
+/*
+ * IC_DEVICE_REV (0xAE) returns an 8-byte block (datasheet Rev. D, Table 80):
+ *   [2:0] firmware revision  major.minor.patch
+ *   [5:3] bootloader revision major.minor.patch
+ *   [7:6] silicon revision    two ASCII characters
+ */
+static int adm1266_firmware_revision_read(struct seq_file *s, void *pdata)
+{
+       struct device *dev = s->private;
+       struct i2c_client *client = to_i2c_client(dev);
+       u8 buf[I2C_SMBUS_BLOCK_MAX];
+       int ret;
+
+       guard(pmbus_lock)(client);
+       ret = i2c_smbus_read_block_data(client, ADM1266_IC_DEVICE_REV, buf);
+       if (ret < 0)
+               return ret;
+       if (ret < 3)
+               return -EIO;
+
+       seq_printf(s, "%u.%u.%u\n", buf[0], buf[1], buf[2]);
+
+       return 0;
+}
+
 static void adm1266_init_debugfs(struct adm1266_data *data)
 {
        struct dentry *root;
@@ -357,6 +383,8 @@ static void adm1266_init_debugfs(struct adm1266_data *data)
 
        debugfs_create_devm_seqfile(&data->client->dev, "sequencer_state", data->debugfs_dir,
                                    adm1266_state_read);
+       debugfs_create_devm_seqfile(&data->client->dev, "firmware_revision", data->debugfs_dir,
+                                   adm1266_firmware_revision_read);
 }
 
 static int adm1266_nvmem_read_blackbox(struct adm1266_data *data, u8 *read_buff)