mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
hwmon: (pmbus/adm1275) Support ROHM BD12790
Add support for ROHM BD12790 hot-swap controller which is largely similar to Analog Devices adm1272. The BD12790 uses the same selectable 60V/100V voltage ranges and 15mV/30mV current-sense ranges as the ADM1272, and the same VRANGE (bit 5) and IRANGE (bit 0) layout in PMON_CONFIG. It therefore uses a dedicated coefficient table that mirrors adm1272_coefficients, with the following differences derived from BD12790 datasheet Table 1 (p.18): - power 60V/30mV: m=17560 (vs. 17561) - power 100V/30mV: m=10536 (vs. 10535) - temperature: b=31880 (vs. 31871, reflecting T[11:0] = 4.2*T + 3188) Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com> Assisted-by: GitHub Copilot:claude-sonnet-4.6 Link: https://lore.kernel.org/r/b209c1b47712b69f17b52cfd7a7a38ed76024ca7.1782458224.git.mazziesaccount@gmail.com [groeck: Fixed comment describing BD12790 coefficients] Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
committed by
Guenter Roeck
parent
b66f500d62
commit
73a76fa6e8
@@ -52,8 +52,8 @@ config SENSORS_ADM1275
|
||||
help
|
||||
If you say yes here you get hardware monitoring support for Analog
|
||||
Devices ADM1075, ADM1272, ADM1273, ADM1275, ADM1276, ADM1278, ADM1281,
|
||||
ADM1293, ADM1294, ROHM BD12780, and SQ24905C Hot-Swap Controller and
|
||||
Digital Power Monitors.
|
||||
ADM1293, ADM1294, ROHM BD12780, ROHM BD12790, and SQ24905C
|
||||
Hot-Swap Controller and Digital Power Monitors.
|
||||
|
||||
This driver can also be built as a module. If so, the module will
|
||||
be called adm1275.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "pmbus.h"
|
||||
|
||||
enum chips { adm1075, adm1272, adm1273, adm1275, adm1276, adm1278, adm1281,
|
||||
adm1293, adm1294, bd12780, sq24905c };
|
||||
adm1293, adm1294, bd12780, bd12790, sq24905c };
|
||||
|
||||
#define ADM1275_MFR_STATUS_IOUT_WARN2 BIT(0)
|
||||
#define ADM1293_MFR_STATUS_VAUX_UV_WARN BIT(5)
|
||||
@@ -47,7 +47,7 @@ enum chips { adm1075, adm1272, adm1273, adm1275, adm1276, adm1278, adm1281,
|
||||
#define ADM1278_VOUT_EN BIT(1)
|
||||
|
||||
#define ADM1278_PMON_DEFCONFIG (ADM1278_VOUT_EN | ADM1278_TEMP1_EN | ADM1278_TSFILT)
|
||||
/* The BD12780 data sheets mark TSFILT bit as reserved. */
|
||||
/* The BD127[89]0 data sheets mark TSFILT bit as reserved. */
|
||||
#define BD12780_PMON_DEFCONFIG (ADM1278_VOUT_EN | ADM1278_TEMP1_EN)
|
||||
|
||||
#define ADM1293_IRANGE_25 0
|
||||
@@ -136,6 +136,30 @@ static const struct coefficients adm1272_coefficients[] = {
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* BD12790 coefficients derived from preliminary datasheet, Table 1 (p.18)
|
||||
* and the PMBus direct-format relationship X = (Y * 10^(-R) - b) / m.
|
||||
*
|
||||
* Voltage: V[V] = 14.77e-3 * code (60V) / 24.62e-3 * code (100V)
|
||||
* -> m = 6770, R=-2 / m = 4062, R=-2
|
||||
* Current: code = I[A] * RS * 132802.1 + 2048 (15mV) / * 66401.06 + 2048 (30mV)
|
||||
* -> m = 1328, b = 2048 * 10^(-R) = 20480, R=-1 / m = 664, same b and R
|
||||
* Power: code = k * RS * PIN, k = 35119.94 / 17559.97 / 21071.44 / 10535.72
|
||||
* -> m = round(k * 10^(-3-R)), R=-2 for 60V/15mV, R=-3 for the other three
|
||||
* Temperature: code = 4.2 * T + 3188 -> m = 42, b = 3188 * 10 = 31880, R=-1
|
||||
*/
|
||||
static const struct coefficients bd12790_coefficients[] = {
|
||||
[0] = { 6770, 0, -2 }, /* voltage, vrange 60V */
|
||||
[1] = { 4062, 0, -2 }, /* voltage, vrange 100V */
|
||||
[2] = { 1328, 20480, -1 }, /* current, vsense range 15mV */
|
||||
[3] = { 664, 20480, -1 }, /* current, vsense range 30mV */
|
||||
[4] = { 3512, 0, -2 }, /* power, vrange 60V, irange 15mV */
|
||||
[5] = { 21071, 0, -3 }, /* power, vrange 100V, irange 15mV */
|
||||
[6] = { 17560, 0, -3 }, /* power, vrange 60V, irange 30mV */
|
||||
[7] = { 10536, 0, -3 }, /* power, vrange 100V, irange 30mV */
|
||||
[8] = { 42, 31880, -1 }, /* temperature */
|
||||
};
|
||||
|
||||
static const struct coefficients adm1275_coefficients[] = {
|
||||
[0] = { 19199, 0, -2 }, /* voltage, vrange set */
|
||||
[1] = { 6720, 0, -1 }, /* voltage, vrange not set */
|
||||
@@ -490,6 +514,7 @@ static const struct i2c_device_id adm1275_id[] = {
|
||||
{ .name = "adm1293", .driver_data = adm1293 },
|
||||
{ .name = "adm1294", .driver_data = adm1294 },
|
||||
{ .name = "bd12780", .driver_data = bd12780 },
|
||||
{ .name = "bd12790", .driver_data = bd12790 },
|
||||
{ .name = "mc09c", .driver_data = sq24905c },
|
||||
{ }
|
||||
};
|
||||
@@ -567,7 +592,8 @@ static int adm1275_probe(struct i2c_client *client)
|
||||
if (mid->driver_data == adm1272 || mid->driver_data == adm1273 ||
|
||||
mid->driver_data == adm1278 || mid->driver_data == adm1281 ||
|
||||
mid->driver_data == adm1293 || mid->driver_data == adm1294 ||
|
||||
mid->driver_data == bd12780 || mid->driver_data == sq24905c)
|
||||
mid->driver_data == bd12780 || mid->driver_data == bd12790 ||
|
||||
mid->driver_data == sq24905c)
|
||||
config_read_fn = i2c_smbus_read_word_data;
|
||||
else
|
||||
config_read_fn = i2c_smbus_read_byte_data;
|
||||
@@ -647,6 +673,7 @@ static int adm1275_probe(struct i2c_client *client)
|
||||
data->have_power_sampling = true;
|
||||
|
||||
coefficients = adm1272_coefficients;
|
||||
|
||||
vindex = (config & ADM1275_VRANGE) ? 1 : 0;
|
||||
cindex = (config & ADM1272_IRANGE) ? 3 : 2;
|
||||
/* pindex depends on the combination of the above */
|
||||
@@ -679,6 +706,51 @@ static int adm1275_probe(struct i2c_client *client)
|
||||
if (config & ADM1278_VIN_EN)
|
||||
info->func[0] |= PMBUS_HAVE_VIN;
|
||||
break;
|
||||
|
||||
/*
|
||||
* The BD12790 is almost identical to the adm1272. Only the defconfig
|
||||
* and coefficients have minor differences.
|
||||
*/
|
||||
case bd12790:
|
||||
data->have_vout = true;
|
||||
data->have_pin_max = true;
|
||||
data->have_temp_max = true;
|
||||
data->have_power_sampling = true;
|
||||
|
||||
coefficients = bd12790_coefficients;
|
||||
|
||||
vindex = (config & ADM1275_VRANGE) ? 1 : 0;
|
||||
cindex = (config & ADM1272_IRANGE) ? 3 : 2;
|
||||
/* pindex depends on the combination of the above */
|
||||
switch (config & (ADM1275_VRANGE | ADM1272_IRANGE)) {
|
||||
case 0:
|
||||
default:
|
||||
pindex = 4;
|
||||
break;
|
||||
case ADM1275_VRANGE:
|
||||
pindex = 5;
|
||||
break;
|
||||
case ADM1272_IRANGE:
|
||||
pindex = 6;
|
||||
break;
|
||||
case ADM1275_VRANGE | ADM1272_IRANGE:
|
||||
pindex = 7;
|
||||
break;
|
||||
}
|
||||
tindex = 8;
|
||||
|
||||
info->func[0] |= PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT |
|
||||
PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
|
||||
PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
|
||||
|
||||
ret = adm1275_enable_vout_temp(data, client, config,
|
||||
BD12780_PMON_DEFCONFIG);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (config & ADM1278_VIN_EN)
|
||||
info->func[0] |= PMBUS_HAVE_VIN;
|
||||
break;
|
||||
case adm1275:
|
||||
if (device_config & ADM1275_IOUT_WARN2_SELECT)
|
||||
data->have_oc_fault = true;
|
||||
@@ -919,6 +991,7 @@ static const struct of_device_id adm1275_of_match[] = {
|
||||
{ .compatible = "adi,adm1293", },
|
||||
{ .compatible = "adi,adm1294", },
|
||||
{ .compatible = "rohm,bd12780", },
|
||||
{ .compatible = "rohm,bd12790", },
|
||||
{ .compatible = "silergy,mc09c", },
|
||||
{ }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user