Lines Matching +full:i2c +full:- +full:retry +full:- +full:count
1 // SPDX-License-Identifier: GPL-2.0-only
6 * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface
10 * Bi-Directional Current/Power Monitor with I2C Interface
14 * Bi-Directional Current/Power Monitor with I2C Interface
18 * Bi-directional Current/Power Monitor with I2C Interface
30 #include <linux/i2c.h>
32 #include <linux/hwmon-sysfs.h>
54 /* register count */
60 /* settings - depend on use case */
189 return regmap_write(data->regmap, INA2XX_CALIBRATION, in ina2xx_calibrate()
190 data->config->calibration_value); in ina2xx_calibrate()
198 int ret = regmap_write(data->regmap, INA2XX_CONFIG, in ina2xx_init()
199 data->config->config_default); in ina2xx_init()
209 int ret, retry; in ina2xx_read_reg() local
213 for (retry = 5; retry; retry--) { in ina2xx_read_reg()
215 ret = regmap_read(data->regmap, reg, regval); in ina2xx_read_reg()
232 ret = regmap_read(data->regmap, INA2XX_CALIBRATION, in ina2xx_read_reg()
261 return -ENODEV; in ina2xx_read_reg()
272 val = DIV_ROUND_CLOSEST((s16)regval, data->config->shunt_div); in ina2xx_get_value()
275 val = (regval >> data->config->bus_voltage_shift) in ina2xx_get_value()
276 * data->config->bus_voltage_lsb; in ina2xx_get_value()
280 val = regval * data->power_lsb_uW; in ina2xx_get_value()
284 val = (s16)regval * data->current_lsb_uA; in ina2xx_get_value()
307 int err = ina2xx_read_reg(dev, attr->index, ®val); in ina2xx_value_show()
312 return sysfs_emit(buf, "%d\n", ina2xx_get_value(data, attr->index, regval)); in ina2xx_value_show()
349 val *= data->config->shunt_div; in ina226_alert_to_reg()
353 val = (val * 1000) << data->config->bus_voltage_shift; in ina226_alert_to_reg()
354 val = DIV_ROUND_CLOSEST(val, data->config->bus_voltage_lsb); in ina226_alert_to_reg()
357 val = DIV_ROUND_CLOSEST(val, data->power_lsb_uW); in ina226_alert_to_reg()
375 mutex_lock(&data->config_lock); in ina226_alert_show()
376 ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); in ina226_alert_show()
380 if (regval & BIT(attr->index)) { in ina226_alert_show()
381 ret = regmap_read(data->regmap, INA226_ALERT_LIMIT, ®val); in ina226_alert_show()
384 val = ina226_reg_to_alert(data, attr->index, regval); in ina226_alert_show()
389 mutex_unlock(&data->config_lock); in ina226_alert_show()
395 const char *buf, size_t count) in ina226_alert_store() argument
409 * if the value is non-zero. in ina226_alert_store()
411 mutex_lock(&data->config_lock); in ina226_alert_store()
412 ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE, in ina226_alert_store()
417 ret = regmap_write(data->regmap, INA226_ALERT_LIMIT, in ina226_alert_store()
418 ina226_alert_to_reg(data, attr->index, val)); in ina226_alert_store()
423 ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE, in ina226_alert_store()
425 BIT(attr->index)); in ina226_alert_store()
430 ret = count; in ina226_alert_store()
432 mutex_unlock(&data->config_lock); in ina226_alert_store()
445 ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); in ina226_alarm_show()
449 alarm = (regval & BIT(attr->index)) && in ina226_alarm_show()
463 data->config->shunt_div); in ina2xx_set_shunt()
465 return -EINVAL; in ina2xx_set_shunt()
467 mutex_lock(&data->config_lock); in ina2xx_set_shunt()
468 data->rshunt = val; in ina2xx_set_shunt()
469 data->current_lsb_uA = DIV_ROUND_CLOSEST(dividend, val); in ina2xx_set_shunt()
470 data->power_lsb_uW = data->config->power_lsb_factor * in ina2xx_set_shunt()
471 data->current_lsb_uA; in ina2xx_set_shunt()
472 mutex_unlock(&data->config_lock); in ina2xx_set_shunt()
482 return sysfs_emit(buf, "%li\n", data->rshunt); in ina2xx_shunt_show()
487 const char *buf, size_t count) in ina2xx_shunt_store() argument
500 return count; in ina2xx_shunt_store()
505 const char *buf, size_t count) in ina226_interval_store() argument
516 return -EINVAL; in ina226_interval_store()
518 status = regmap_update_bits(data->regmap, INA2XX_CONFIG, in ina226_interval_store()
524 return count; in ina226_interval_store()
534 status = regmap_read(data->regmap, INA2XX_CONFIG, ®val); in ina226_interval_show()
570 /* over-limit power alert setting and alarm */
619 struct device *dev = &client->dev; in ina2xx_probe()
626 if (client->dev.of_node) in ina2xx_probe()
627 chip = (uintptr_t)of_device_get_match_data(&client->dev); in ina2xx_probe()
629 chip = i2c_match_id(ina2xx_id, client)->driver_data; in ina2xx_probe()
633 return -ENOMEM; in ina2xx_probe()
636 data->config = &ina2xx_config[chip]; in ina2xx_probe()
637 mutex_init(&data->config_lock); in ina2xx_probe()
639 if (of_property_read_u32(dev->of_node, "shunt-resistor", &val) < 0) { in ina2xx_probe()
643 val = pdata->shunt_uohms; in ina2xx_probe()
650 ina2xx_regmap_config.max_register = data->config->registers; in ina2xx_probe()
652 data->regmap = devm_regmap_init_i2c(client, &ina2xx_regmap_config); in ina2xx_probe()
653 if (IS_ERR(data->regmap)) { in ina2xx_probe()
655 return PTR_ERR(data->regmap); in ina2xx_probe()
665 return -ENODEV; in ina2xx_probe()
668 data->groups[group++] = &ina2xx_group; in ina2xx_probe()
670 data->groups[group++] = &ina226_group; in ina2xx_probe()
672 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, in ina2xx_probe()
673 data, data->groups); in ina2xx_probe()
678 client->name, data->rshunt); in ina2xx_probe()
691 MODULE_DEVICE_TABLE(i2c, ina2xx_id);
729 MODULE_AUTHOR("Lothar Felten <l-felten@ti.com>");