Re: [PATCH 3/7] hwmon: adm1275: Support ROHM BD12780
From: Guenter Roeck
Date: Wed Jun 17 2026 - 09:50:23 EST
On 6/16/26 22:48, Matti Vaittinen wrote:
Thanks for taking the time to review this! Feedback is appreciated :)
On 16/06/2026 17:13, Guenter Roeck wrote:
On 6/15/26 23:36, Matti Vaittinen wrote:
From: Matti Vaittinen <mazziesaccount@xxxxxxxxx>
ROHM BD12780 and BD12780A are hot-swap controllers. They are largely
similar to Analog Devices ADM1278. Besides the ID registers and some
added functionality, the BD12780 and BD12780A mark PMON_CONFIG bits
[15:14] as reserved. Hence TSFILT setting must be omitted on these ICs.
The BD12780 has 3 pins usable for configuring the I2C address. The
BD12780A lists the ADDR3-pin as "not connect".
Support ROHM BD12780 and BD12780A controllers.
Signed-off-by: Matti Vaittinen <mazziesaccount@xxxxxxxxx>
---
drivers/hwmon/pmbus/Kconfig | 2 +-
drivers/hwmon/pmbus/adm1275.c | 46 +++++++++++++++++++++++++++++------
2 files changed, 39 insertions(+), 9 deletions(-)
// snip
@@ -487,6 +489,21 @@ static const struct i2c_device_id adm1275_id[] = {
{ "adm1281", adm1281 },
{ "adm1293", adm1293 },
{ "adm1294", adm1294 },
+ /*
+ * The BD12780a is functionally identical to BD12780(*). Even the pmbus ID
+ * register contents are same. When instantiated from the DT, it is required
+ * to have the bd12780 as a fall-back. We still need the bd12780a ID here,
+ * because the i2c_device_id is created from the first compatible, not from
+ * the fall-back entry.
+ * (*)Until proven to differ. I prefer having own compatible for these
+ * variants for that day. Please note that even though the probe is called
+ * based on the 'bd12780a' -entry, the ID is picked at probe based on the
+ * pmbus register contents and not by DT entry. Thus, if the bd12780 and
+ * bd12780a are found to require different handling, then this needs to be
+ * changed, or bd12780a is handled as bd12780.
+ */
+ { "bd12780", bd12780 },
+ { "bd12780a", /* driver data unused, see --^ */ },
We don't usually do that. There are various A/B/C variants for many chips,
and we just use the base name unless a difference is warranted. Either this
is needed, and driver data is needed as well, or it isn't. If it is not needed,
it should be dropped.
At the moment the only difference I know is reduced amount of I2C slave addresses. This shouldn't be visible to this driver.
My problem is that I don't know for sure if we later notice something that requires differentiating. Thus I would like to have different DT compatibles (or other source of I2C IDs if those are used to instantiate the driver). If we don't do this, then we have problems if we later find out that these ICs require different handling as users because we can't differentiate these ICs if they are described with same compatible/I2C ID.
The "fun" thing is that both variants have exactly same MFR_MODEL and MFR_REVISION register contents. Thus, these ICs can't be differentiated by reading PMBus registers.
This is also why the driver data entry gets unused. The existing probe mechanism in this driver, scans the names in this ID list and compares it to the PMBus MFR_MODEL, and then picks-up the driver data to use. Now because BD12780 and BD12780A both have same MFR_MODEL, the scan in probe will always pick the same driver data entry, no matter what ID was matched by bus code. That's why I added the comment here.
If I drop the { "bd12780a", /* driver data unused, see --^ */ } -entry from the ID list and add the of_device_ids, then I think this problem is solved for the DT-platforms. As far as I understand, this would still cause any non DT platform to describe both variants as "bd12780", making it impossible to later differentiate ICs in the driver, right? I can do this, but for me it feels a bit like asking for problems...
My thinking was to have different IDs for these variants so hardware description could have different IDs for different ICs. Then, if we later need to differentiate these ICs, we still have an option to change the probe to trust the i2c_get_match_data() when PMBus indicates the bd12780.
This however is some extra complexity, and I would like to add it to the probe only if it really is required.
But yeah, having an ID entry in the list and driver data not used even when the matching IC is found, is unusual and would have caught me off guard. Hence I added the (long) comment.
It is unusual and unnecessary. If for whatever reason it turns out to be necessary
later to have a separate ID, add it then. Again, there are lots of chips with A/B/C
variants. We only add separate entries for them if/when needed just for "in case".
Better that than embedded if statements. At some point it would
{ "mc09c", sq24905c },
{ }
};
// snip
@@ -712,7 +732,16 @@ static int adm1275_probe(struct i2c_client *client)
break;
case adm1278:
case adm1281:
+ case bd12780:
case sq24905c:
+ {
+ u16 defconfig;
+
+ if (data->id == bd12780)
+ defconfig = BD12780_PMON_DEFCONFIG;
+ else
+ defconfig = ADM1278_PMON_DEFCONFIG;
+
Please add a separate case statement for the new chip
and do not overload existing chip data.
I originally did just that. I, however, was not happy with this as it resulted quite long own case this IC, which is almost identical to this other (adm1278, adm1281, sq24905c) case. I wanted the code to shout that the DB12780 is indeed (almost) identical to the adm1278. But yeah, I agree, having "if (foo)" in "switch (foo)" case can get confusing.
probably make sense to rework the driver to use per-chip configuration
data, similar to other drivers such as lm90. But that would be a separate
effort. Until then, please keep per-chip configuration in separate case
statements.
Thanks,
Guenter