hwmon: (adm1275) Allow setting shunt reg value

The ADM series of hotswap controllers support extending
the current measurement range by using a sensing resistor
value other than the typical 1 mOhm. For example, using a 0.5 mOhm
sensing resistor doubles the maximal current can be measured.

Current driver assumes a shunt resistor value of 1 mOhm in calculation,
meaning for other resistor values, hwmon will report scaled
current/power measurements. This patch parses device tree parameter
"shunt-resistor-micro-ohms", if there is one.

Signed-off-by: Kun Yi <kunyi@google.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
Kun Yi 2018-10-17 15:26:39 -07:00 committed by Guenter Roeck
parent f567035a61
commit 6e5c06ad94
2 changed files with 16 additions and 2 deletions

View File

@ -58,6 +58,9 @@ The ADM1075, unlike many other PMBus devices, does not support internal voltage
or current scaling. Reported voltages, currents, and power are raw measurements, or current scaling. Reported voltages, currents, and power are raw measurements,
and will typically have to be scaled. and will typically have to be scaled.
The shunt value in micro-ohms can be set via device tree at compile-time. Please
refer to the Documentation/devicetree/bindings/hwmon/adm1275.txt for bindings
if the device tree is used.
Platform data support Platform data support
--------------------- ---------------------

View File

@ -373,6 +373,7 @@ static int adm1275_probe(struct i2c_client *client,
const struct coefficients *coefficients; const struct coefficients *coefficients;
int vindex = -1, voindex = -1, cindex = -1, pindex = -1; int vindex = -1, voindex = -1, cindex = -1, pindex = -1;
int tindex = -1; int tindex = -1;
u32 shunt;
if (!i2c_check_functionality(client->adapter, if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_BYTE_DATA I2C_FUNC_SMBUS_READ_BYTE_DATA
@ -421,6 +422,13 @@ static int adm1275_probe(struct i2c_client *client,
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
if (of_property_read_u32(client->dev.of_node,
"shunt-resistor-micro-ohms", &shunt))
shunt = 1000; /* 1 mOhm if not set via DT */
if (shunt == 0)
return -EINVAL;
data->id = mid->driver_data; data->id = mid->driver_data;
info = &data->info; info = &data->info;
@ -654,12 +662,15 @@ static int adm1275_probe(struct i2c_client *client,
info->R[PSC_VOLTAGE_OUT] = coefficients[voindex].R; info->R[PSC_VOLTAGE_OUT] = coefficients[voindex].R;
} }
if (cindex >= 0) { if (cindex >= 0) {
info->m[PSC_CURRENT_OUT] = coefficients[cindex].m; /* Scale current with sense resistor value */
info->m[PSC_CURRENT_OUT] =
coefficients[cindex].m * shunt / 1000;
info->b[PSC_CURRENT_OUT] = coefficients[cindex].b; info->b[PSC_CURRENT_OUT] = coefficients[cindex].b;
info->R[PSC_CURRENT_OUT] = coefficients[cindex].R; info->R[PSC_CURRENT_OUT] = coefficients[cindex].R;
} }
if (pindex >= 0) { if (pindex >= 0) {
info->m[PSC_POWER] = coefficients[pindex].m; info->m[PSC_POWER] =
coefficients[pindex].m * shunt / 1000;
info->b[PSC_POWER] = coefficients[pindex].b; info->b[PSC_POWER] = coefficients[pindex].b;
info->R[PSC_POWER] = coefficients[pindex].R; info->R[PSC_POWER] = coefficients[pindex].R;
} }