Lines Matching +full:summation +full:- +full:disable

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/
11 #include <linux/hwmon-sysfs.h>
54 #define INA3221_CONFIG_CHx_EN(x) BIT(14 - (x))
71 /* Alert Flags: SF is the summation-alert flag */
99 * struct ina3221_input - channel input source specific information
103 * @summation_disable: channel summation status of input source
113 * struct ina3221_data - device specific information
121 * @summation_shunt_resistor: equivalent shunt resistor value for summation
123 * @single_shot: running in single-shot operating mode
141 /* Summation channel checks shunt resistor values */ in ina3221_is_enabled()
143 return ina->summation_shunt_resistor != 0; in ina3221_is_enabled()
145 return pm_runtime_active(ina->pm_dev) && in ina3221_is_enabled()
146 (ina->reg_config & INA3221_CONFIG_CHx_EN(channel)); in ina3221_is_enabled()
150 * Helper function to return the resistor value for current summation.
152 * There is a condition to calculate current summation -- all the shunt
154 * current summation = shunt voltage summation / shunt resistor
160 struct ina3221_input *input = ina->inputs; in ina3221_summation_shunt_resistor()
171 /* No summation if resistor values are different */ in ina3221_summation_shunt_resistor()
218 wait = ina3221_reg_to_interval_us(ina->reg_config); in ina3221_wait_for_data()
221 return regmap_field_read_poll_timeout(ina->fields[F_CVRF], in ina3221_wait_for_data()
231 ret = regmap_read(ina->regmap, reg, &regval); in ina3221_read_value()
236 * Shunt Voltage Sum register has 14-bit value with 1-bit shift in ina3221_read_value()
237 * Other Shunt Voltage registers have 12 bits with 3-bit shift in ina3221_read_value()
264 regval = INA3221_CONFIG_AVG(ina->reg_config); in ina3221_read_chip()
269 *val = ina3221_reg_to_interval_us(ina->reg_config); in ina3221_read_chip()
273 return -EOPNOTSUPP; in ina3221_read_chip()
286 * the 7th channel (6 since being 0-aligned) is for summation. in ina3221_read_in()
294 return -ENODATA; in ina3221_read_in()
296 /* Write CONFIG register to trigger a single-shot measurement */ in ina3221_read_in()
297 if (ina->single_shot) { in ina3221_read_in()
298 regmap_write(ina->regmap, INA3221_CONFIG, in ina3221_read_in()
299 ina->reg_config); in ina3221_read_in()
320 return -EOPNOTSUPP; in ina3221_read_in()
338 struct ina3221_input *input = ina->inputs; in ina3221_read_curr()
344 resistance_uo = ina->summation_shunt_resistor; in ina3221_read_curr()
351 return -ENODATA; in ina3221_read_curr()
353 /* Write CONFIG register to trigger a single-shot measurement */ in ina3221_read_curr()
354 if (ina->single_shot) { in ina3221_read_curr()
355 regmap_write(ina->regmap, INA3221_CONFIG, in ina3221_read_curr()
356 ina->reg_config); in ina3221_read_curr()
367 return -ENODATA; in ina3221_read_curr()
386 ret = regmap_field_read(ina->fields[reg], &regval); in ina3221_read_curr()
392 return -EOPNOTSUPP; in ina3221_read_curr()
407 tmp = (ina->reg_config & ~INA3221_CONFIG_AVG_MASK) | in ina3221_write_chip()
409 ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp); in ina3221_write_chip()
414 ina->reg_config = tmp; in ina3221_write_chip()
417 tmp = ina3221_interval_ms_to_conv_time(ina->reg_config, val); in ina3221_write_chip()
423 tmp = (ina->reg_config & ~tmp) | in ina3221_write_chip()
426 ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp); in ina3221_write_chip()
431 ina->reg_config = tmp; in ina3221_write_chip()
434 return -EOPNOTSUPP; in ina3221_write_chip()
442 struct ina3221_input *input = ina->inputs; in ina3221_write_curr()
448 resistance_uo = ina->summation_shunt_resistor; in ina3221_write_curr()
453 return -EOPNOTSUPP; in ina3221_write_curr()
463 voltage_uv = clamp_val(voltage_uv, -163800, 163800); in ina3221_write_curr()
470 * Shunt Voltage Sum register left-shifts 1 bit in ina3221_write_curr()
474 * SHUNT[1-3]: (1 / 40uV) << 3 = 1 / 5uV in ina3221_write_curr()
481 return regmap_write(ina->regmap, reg, regval); in ina3221_write_curr()
488 u16 config_old = ina->reg_config & mask; in ina3221_write_enable()
500 ret = pm_runtime_resume_and_get(ina->pm_dev); in ina3221_write_enable()
507 /* Enable or disable the channel */ in ina3221_write_enable()
508 tmp = (ina->reg_config & ~mask) | (config & mask); in ina3221_write_enable()
509 ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp); in ina3221_write_enable()
514 ina->reg_config = tmp; in ina3221_write_enable()
518 pm_runtime_put_sync(ina->pm_dev); in ina3221_write_enable()
526 pm_runtime_put_sync(ina->pm_dev); in ina3221_write_enable()
538 mutex_lock(&ina->lock); in ina3221_read()
545 /* 0-align channel ID */ in ina3221_read()
546 ret = ina3221_read_in(dev, attr, channel - 1, val); in ina3221_read()
552 ret = -EOPNOTSUPP; in ina3221_read()
556 mutex_unlock(&ina->lock); in ina3221_read()
567 mutex_lock(&ina->lock); in ina3221_write()
574 /* 0-align channel ID */ in ina3221_write()
575 ret = ina3221_write_enable(dev, channel - 1, val); in ina3221_write()
581 ret = -EOPNOTSUPP; in ina3221_write()
585 mutex_unlock(&ina->lock); in ina3221_write()
594 int index = channel - 1; in ina3221_read_string()
599 *str = ina->inputs[index].label; in ina3221_read_string()
627 if (channel - 1 <= INA3221_CHANNEL3) in ina3221_is_visible()
628 input = &ina->inputs[channel - 1]; in ina3221_is_visible()
632 return (input && input->label) ? 0444 : 0; in ina3221_is_visible()
668 /* 1-3: input voltage Channels */
672 /* 4-6: shunt voltage Channels */
676 /* 7: summation of shunt voltage channels */
679 /* 1-3: current channels*/
683 /* 4: summation of current channels */
706 unsigned int channel = sd_attr->index; in ina3221_shunt_show()
707 struct ina3221_input *input = &ina->inputs[channel]; in ina3221_shunt_show()
709 return sysfs_emit(buf, "%d\n", input->shunt_resistor); in ina3221_shunt_show()
718 unsigned int channel = sd_attr->index; in ina3221_shunt_store()
719 struct ina3221_input *input = &ina->inputs[channel]; in ina3221_shunt_store()
729 input->shunt_resistor = val; in ina3221_shunt_store()
731 /* Update summation_shunt_resistor for summation channel */ in ina3221_shunt_store()
732 ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina); in ina3221_shunt_store()
783 return -EINVAL; in ina3221_probe_child_from_dt()
786 input = &ina->inputs[val]; in ina3221_probe_child_from_dt()
790 input->disconnected = true; in ina3221_probe_child_from_dt()
795 of_property_read_string(child, "label", &input->label); in ina3221_probe_child_from_dt()
797 /* summation channel control */ in ina3221_probe_child_from_dt()
798 input->summation_disable = of_property_read_bool(child, "ti,summation-disable"); in ina3221_probe_child_from_dt()
801 if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", &val)) { in ina3221_probe_child_from_dt()
805 return -EINVAL; in ina3221_probe_child_from_dt()
807 input->shunt_resistor = val; in ina3221_probe_child_from_dt()
815 const struct device_node *np = dev->of_node; in ina3221_probe_from_dt()
818 /* Compatible with non-DT platforms */ in ina3221_probe_from_dt()
822 ina->single_shot = of_property_read_bool(np, "ti,single-shot"); in ina3221_probe_from_dt()
835 struct device *dev = &client->dev; in ina3221_probe()
843 return -ENOMEM; in ina3221_probe()
845 ina->regmap = devm_regmap_init_i2c(client, &ina3221_regmap_config); in ina3221_probe()
846 if (IS_ERR(ina->regmap)) { in ina3221_probe()
848 return PTR_ERR(ina->regmap); in ina3221_probe()
852 ina->fields[i] = devm_regmap_field_alloc(dev, in ina3221_probe()
853 ina->regmap, in ina3221_probe()
855 if (IS_ERR(ina->fields[i])) { in ina3221_probe()
857 return PTR_ERR(ina->fields[i]); in ina3221_probe()
862 ina->inputs[i].shunt_resistor = INA3221_RSHUNT_DEFAULT; in ina3221_probe()
871 ina->reg_config = INA3221_CONFIG_DEFAULT; in ina3221_probe()
873 /* Clear continuous bit to use single-shot mode */ in ina3221_probe()
874 if (ina->single_shot) in ina3221_probe()
875 ina->reg_config &= ~INA3221_CONFIG_MODE_CONTINUOUS; in ina3221_probe()
877 /* Disable channels if their inputs are disconnected */ in ina3221_probe()
879 if (ina->inputs[i].disconnected) in ina3221_probe()
880 ina->reg_config &= ~INA3221_CONFIG_CHx_EN(i); in ina3221_probe()
883 /* Initialize summation_shunt_resistor for summation channel control */ in ina3221_probe()
884 ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina); in ina3221_probe()
886 if (!ina->inputs[i].summation_disable) in ina3221_probe()
887 ina->summation_channel_control |= BIT(14 - i); in ina3221_probe()
890 ina->pm_dev = dev; in ina3221_probe()
891 mutex_init(&ina->lock); in ina3221_probe()
894 /* Enable PM runtime -- status is suspended by default */ in ina3221_probe()
895 pm_runtime_enable(ina->pm_dev); in ina3221_probe()
899 if (ina->inputs[i].disconnected) in ina3221_probe()
902 ret = pm_runtime_get_sync(ina->pm_dev); in ina3221_probe()
907 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, ina, in ina3221_probe()
916 scnprintf(name, sizeof(name), "%s-%s", INA3221_DRIVER_NAME, dev_name(dev)); in ina3221_probe()
917 ina->debugfs = debugfs_create_dir(name, NULL); in ina3221_probe()
921 debugfs_create_bool(name, 0400, ina->debugfs, in ina3221_probe()
922 &ina->inputs[i].summation_disable); in ina3221_probe()
928 pm_runtime_disable(ina->pm_dev); in ina3221_probe()
929 pm_runtime_set_suspended(ina->pm_dev); in ina3221_probe()
932 pm_runtime_put_noidle(ina->pm_dev); in ina3221_probe()
933 mutex_destroy(&ina->lock); in ina3221_probe()
940 struct ina3221_data *ina = dev_get_drvdata(&client->dev); in ina3221_remove()
943 debugfs_remove_recursive(ina->debugfs); in ina3221_remove()
945 pm_runtime_disable(ina->pm_dev); in ina3221_remove()
946 pm_runtime_set_suspended(ina->pm_dev); in ina3221_remove()
950 pm_runtime_put_noidle(ina->pm_dev); in ina3221_remove()
952 mutex_destroy(&ina->lock); in ina3221_remove()
960 /* Save config register value and enable cache-only */ in ina3221_suspend()
961 ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config); in ina3221_suspend()
965 /* Set to power-down mode for power saving */ in ina3221_suspend()
966 ret = regmap_update_bits(ina->regmap, INA3221_CONFIG, in ina3221_suspend()
972 regcache_cache_only(ina->regmap, true); in ina3221_suspend()
973 regcache_mark_dirty(ina->regmap); in ina3221_suspend()
983 regcache_cache_only(ina->regmap, false); in ina3221_resume()
986 ret = regmap_field_write(ina->fields[F_RST], true); in ina3221_resume()
993 ret = regcache_sync(ina->regmap); in ina3221_resume()
998 ret = regmap_write(ina->regmap, INA3221_CONFIG, ina->reg_config); in ina3221_resume()
1002 /* Initialize summation channel control */ in ina3221_resume()
1003 if (ina->summation_shunt_resistor) { in ina3221_resume()
1005 * Sum only channels that are not disabled for summation. in ina3221_resume()
1007 * be 0, so it does not matter for summation. in ina3221_resume()
1009 ret = regmap_update_bits(ina->regmap, INA3221_MASK_ENABLE, in ina3221_resume()
1011 ina->summation_channel_control); in ina3221_resume()
1013 dev_err(dev, "Unable to control summation channel\n"); in ina3221_resume()