Lines Matching +full:shunt +full:- +full:gain

1 // SPDX-License-Identifier: GPL-2.0-only
59 * based on a fixed shunt resistor value. This allows for conversion within the
61 * relative to the shunt resistor value within the driver. This is similar to
64 * The end result of this is that increasing shunt values (from a fixed 20 mOhm
65 * shunt) increase the effective current/power accuracy whilst limiting the
66 * range and decreasing shunt values decrease the effective accuracy but
70 * Current (A) = (shunt voltage register * 5) * calibration / 81920
72 * The maximum shunt voltage is 163.835 mV (0x7fff, ADC_RANGE = 0, gain = 4).
73 * With the maximum current value of 0x7fff and a fixed shunt value results in
84 * to be scaled by the difference between the fixed shunt resistor and the
85 * actual shunt resistor:
87 * shunt = 0x4000 / (819.2 * 10^6) / 0.001 = 20000 uOhms (with 1mA/lsb)
89 * Current (mA) = register value * 20000 / rshunt / 4 * gain
90 * Power (W) = 0.2 * register value * 20000 / rshunt / 4 * gain
110 int gain; member
118 /* 24-bit register read */ in ina238_read_reg24()
123 return -EIO; in ina238_read_reg24()
158 return -EOPNOTSUPP; in ina238_read_in()
181 return -EOPNOTSUPP; in ina238_read_in()
185 return -EOPNOTSUPP; in ina238_read_in()
188 err = regmap_read(data->regmap, reg, &regval); in ina238_read_in()
199 /* gain of 1 -> LSB / 4 */ in ina238_read_in()
201 (1000 * (4 - data->gain + 1)); in ina238_read_in()
221 return -EOPNOTSUPP; in ina238_write_in()
226 /* signed value, clamp to max range +/-163 mV */ in ina238_write_in()
227 regval = clamp_val(val, -163, 163); in ina238_write_in()
228 regval = (regval * 1000 * (4 - data->gain + 1)) / in ina238_write_in()
234 return regmap_write(data->regmap, in ina238_write_in()
237 return regmap_write(data->regmap, in ina238_write_in()
240 return -EOPNOTSUPP; in ina238_write_in()
250 return regmap_write(data->regmap, in ina238_write_in()
253 return regmap_write(data->regmap, in ina238_write_in()
256 return -EOPNOTSUPP; in ina238_write_in()
259 return -EOPNOTSUPP; in ina238_write_in()
271 err = regmap_read(data->regmap, INA238_CURRENT, &regval); in ina238_read_current()
276 *val = div_s64((s16)regval * INA238_FIXED_SHUNT * data->gain, in ina238_read_current()
277 data->rshunt * 4); in ina238_read_current()
280 return -EOPNOTSUPP; in ina238_read_current()
295 err = ina238_read_reg24(data->client, INA238_POWER, &regval); in ina238_read_power()
301 data->gain, 20 * data->rshunt); in ina238_read_power()
306 err = regmap_read(data->regmap, INA238_POWER_LIMIT, &regval); in ina238_read_power()
311 * Truncated 24-bit compare register, lower 8-bits are in ina238_read_power()
315 data->gain, 20 * data->rshunt); in ina238_read_power()
320 err = regmap_read(data->regmap, INA238_DIAG_ALERT, &regval); in ina238_read_power()
327 return -EOPNOTSUPP; in ina238_read_power()
339 return -EOPNOTSUPP; in ina238_write_power()
342 * Unsigned postive values. Compared against the 24-bit power register, in ina238_write_power()
343 * lower 8-bits are truncated. Same conversion to/from uW as POWER in ina238_write_power()
347 regval = div_u64(val * 20ULL * data->rshunt, in ina238_write_power()
348 1000ULL * INA238_FIXED_SHUNT * data->gain); in ina238_write_power()
351 return regmap_write(data->regmap, INA238_POWER_LIMIT, regval); in ina238_write_power()
362 err = regmap_read(data->regmap, INA238_DIE_TEMP, &regval); in ina238_read_temp()
366 /* Signed, bits 15-4 of register, result in mC */ in ina238_read_temp()
370 err = regmap_read(data->regmap, INA238_TEMP_LIMIT, &regval); in ina238_read_temp()
374 /* Signed, bits 15-4 of register, result in mC */ in ina238_read_temp()
378 err = regmap_read(data->regmap, INA238_DIAG_ALERT, &regval); in ina238_read_temp()
385 return -EOPNOTSUPP; in ina238_read_temp()
397 return -EOPNOTSUPP; in ina238_write_temp()
399 /* Signed, bits 15-4 of register */ in ina238_write_temp()
403 return regmap_write(data->regmap, INA238_TEMP_LIMIT, regval); in ina238_write_temp()
419 return -EOPNOTSUPP; in ina238_read()
430 mutex_lock(&data->config_lock); in ina238_write()
443 err = -EOPNOTSUPP; in ina238_write()
447 mutex_unlock(&data->config_lock); in ina238_write()
506 /* 0: shunt voltage */
511 /* 0: current through shunt */
535 struct ina2xx_platform_data *pdata = dev_get_platdata(&client->dev); in ina238_probe()
536 struct device *dev = &client->dev; in ina238_probe()
544 return -ENOMEM; in ina238_probe()
546 data->client = client; in ina238_probe()
547 mutex_init(&data->config_lock); in ina238_probe()
549 data->regmap = devm_regmap_init_i2c(client, &ina238_regmap_config); in ina238_probe()
550 if (IS_ERR(data->regmap)) { in ina238_probe()
552 return PTR_ERR(data->regmap); in ina238_probe()
555 /* load shunt value */ in ina238_probe()
556 data->rshunt = INA238_RSHUNT_DEFAULT; in ina238_probe()
557 if (device_property_read_u32(dev, "shunt-resistor", &data->rshunt) < 0 && pdata) in ina238_probe()
558 data->rshunt = pdata->shunt_uohms; in ina238_probe()
559 if (data->rshunt == 0) { in ina238_probe()
560 dev_err(dev, "invalid shunt resister value %u\n", data->rshunt); in ina238_probe()
561 return -EINVAL; in ina238_probe()
564 /* load shunt gain value */ in ina238_probe()
565 if (device_property_read_u32(dev, "ti,shunt-gain", &data->gain) < 0) in ina238_probe()
566 data->gain = 4; /* Default of ADCRANGE = 0 */ in ina238_probe()
567 if (data->gain != 1 && data->gain != 4) { in ina238_probe()
568 dev_err(dev, "invalid shunt gain value %u\n", data->gain); in ina238_probe()
569 return -EINVAL; in ina238_probe()
574 if (data->gain == 1) in ina238_probe()
576 ret = regmap_write(data->regmap, INA238_CONFIG, config); in ina238_probe()
579 return -ENODEV; in ina238_probe()
583 ret = regmap_write(data->regmap, INA238_ADC_CONFIG, in ina238_probe()
587 return -ENODEV; in ina238_probe()
591 ret = regmap_write(data->regmap, INA238_SHUNT_CALIBRATION, in ina238_probe()
595 return -ENODEV; in ina238_probe()
599 ret = regmap_write(data->regmap, INA238_DIAG_ALERT, in ina238_probe()
603 return -ENODEV; in ina238_probe()
606 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, in ina238_probe()
612 dev_info(dev, "power monitor %s (Rshunt = %u uOhm, gain = %u)\n", in ina238_probe()
613 client->name, data->rshunt, data->gain); in ina238_probe()