Lines Matching +full:milli +full:- +full:ohm
1 // SPDX-License-Identifier: GPL-2.0
10 #include <linux/clk-provider.h>
15 #include <linux/hwmon-sysfs.h>
115 #define LTC4282_CLKIN_RANGE (LTC4282_CLKIN_MAX - LTC4282_CLKIN_MIN + 1)
168 return regmap_update_bits(st->map, LTC4282_CLK_DIV, LTC4282_CLKOUT_MASK, in ltc4282_set_rate()
197 ret = regmap_read(st->map, LTC4282_CLK_DIV, &clkdiv); in ltc4282_recalc_rate()
215 regmap_clear_bits(st->map, LTC4282_CLK_DIV, LTC4282_CLKOUT_MASK); in ltc4282_disable()
224 ret = regmap_bulk_read(st->map, reg, &in, sizeof(in)); in ltc4282_read_voltage_word()
246 ret = regmap_read(st->map, reg, &in); in ltc4282_read_voltage_byte_cached()
267 ret = regmap_read(st->map, reg, &alarm); in __ltc4282_read_alarm()
275 return regmap_clear_bits(st->map, reg, mask); in __ltc4282_read_alarm()
283 guard(mutex)(&st->lock); in ltc4282_read_alarm()
290 guard(mutex)(&st->lock); in ltc4282_vdd_source_read_in()
291 if (!st->in0_1_cache[channel].en) in ltc4282_vdd_source_read_in()
292 return -ENODATA; in ltc4282_vdd_source_read_in()
294 return ltc4282_read_voltage_word(st, LTC4282_VSOURCE, st->vfs_out, val); in ltc4282_vdd_source_read_in()
302 guard(mutex)(&st->lock); in ltc4282_vdd_source_read_hist()
303 if (!st->in0_1_cache[channel].en) { in ltc4282_vdd_source_read_hist()
308 ret = ltc4282_read_voltage_word(st, reg, st->vfs_out, val); in ltc4282_vdd_source_read_hist()
319 guard(mutex)(&st->lock); in ltc4282_vdd_source_read_lim()
320 if (!st->in0_1_cache[channel].en) in ltc4282_vdd_source_read_lim()
321 return ltc4282_read_voltage_byte_cached(st, reg, st->vfs_out, in ltc4282_vdd_source_read_lim()
324 return ltc4282_read_voltage_byte(st, reg, st->vfs_out, val); in ltc4282_vdd_source_read_lim()
330 guard(mutex)(&st->lock); in ltc4282_vdd_source_read_alm()
331 if (!st->in0_1_cache[channel].en) { in ltc4282_vdd_source_read_alm()
365 &st->in0_1_cache[channel].in_highest, val); in ltc4282_read_in()
373 &st->in0_1_cache[channel].in_lowest, val); in ltc4282_read_in()
404 &st->in0_1_cache[channel].in_max_raw, val); in ltc4282_read_in()
412 &st->in0_1_cache[channel].in_min_raw, val); in ltc4282_read_in()
414 scoped_guard(mutex, &st->lock) { in ltc4282_read_in()
415 *val = st->in0_1_cache[channel].en; in ltc4282_read_in()
426 return -EOPNOTSUPP; in ltc4282_read_in()
440 ret = ltc4282_read_voltage_word(st, reg, DECA * 40 * MILLI, &in); in ltc4282_read_current_word()
444 *val = DIV_ROUND_CLOSEST(in * MILLI, st->rsense); in ltc4282_read_current_word()
455 ret = ltc4282_read_voltage_byte(st, reg, DECA * 40 * MILLI, &in); in ltc4282_read_current_byte()
459 *val = DIV_ROUND_CLOSEST(in * MILLI, st->rsense); in ltc4282_read_current_byte()
490 return -EOPNOTSUPP; in ltc4282_read_curr()
497 u64 temp = DECA * 40ULL * st->vfs_out * BIT(16), temp_2; in ltc4282_read_power_word()
502 ret = regmap_bulk_read(st->map, reg, &raw, sizeof(raw)); in ltc4282_read_power_word()
509 * P = CODE(16b) * 0.040 * Vfs(out) * 2^16 / ((2^16 - 1)^2 * Rsense) in ltc4282_read_power_word()
514 U16_MAX * (u64)st->rsense); in ltc4282_read_power_word()
519 st->rsense * int_pow(U16_MAX, 2)); in ltc4282_read_power_word()
531 ret = regmap_read(st->map, reg, &power); in ltc4282_read_power_byte()
535 temp = power * 40 * DECA * st->vfs_out * BIT_ULL(8); in ltc4282_read_power_byte()
537 int_pow(U8_MAX, 2) * st->rsense); in ltc4282_read_power_byte()
548 ret = regmap_bulk_read(st->map, LTC4282_ENERGY, &raw, 6); in ltc4282_read_energy()
556 * ((2^16 - 1)^2 * Rsense) in ltc4282_read_energy()
562 * As Rsense can have tenths of micro-ohm resolution, we need to in ltc4282_read_energy()
565 if (check_mul_overflow(DECA * st->vfs_out * 40 * BIT(8), energy, &temp)) { in ltc4282_read_energy()
566 temp = DIV_ROUND_CLOSEST(DECA * st->vfs_out * 40 * BIT(8), U16_MAX); in ltc4282_read_energy()
567 *val = DIV_ROUND_CLOSEST_ULL(temp * energy, st->rsense); in ltc4282_read_energy()
571 *val = DIV64_U64_ROUND_CLOSEST(temp, U16_MAX * (u64)st->rsense); in ltc4282_read_energy()
597 return -EOPNOTSUPP; in ltc4282_read_power()
614 scoped_guard(mutex, &st->lock) { in ltc4282_read()
615 *val = st->energy_en; in ltc4282_read()
619 return -EOPNOTSUPP; in ltc4282_read()
629 if (val > st->power_max) in ltc4282_write_power_byte()
630 val = st->power_max; in ltc4282_write_power_byte()
632 temp = val * int_pow(U8_MAX, 2) * st->rsense; in ltc4282_write_power_byte()
634 MICRO * DECA * 256ULL * st->vfs_out * 40); in ltc4282_write_power_byte()
636 return regmap_write(st->map, reg, power); in ltc4282_write_power_byte()
642 u64 temp = int_pow(U16_MAX, 2) * st->rsense, temp_2; in ltc4282_write_power_word()
649 40ULL * BIT(16) * st->vfs_out); in ltc4282_write_power_word()
651 temp = DECA * MICRO * 40ULL * BIT(16) * st->vfs_out; in ltc4282_write_power_word()
656 return regmap_bulk_write(st->map, reg, &__raw, sizeof(__raw)); in ltc4282_write_power_word()
670 ret = regmap_bulk_write(st->map, reg, &__raw, 2); in __ltc4282_in_write_history()
678 return regmap_bulk_write(st->map, reg + 2, &__raw, 2); in __ltc4282_in_write_history()
684 guard(mutex)(&st->lock); in ltc4282_in_write_history()
692 guard(mutex)(&st->lock); in ltc4282_power_reset_hist()
695 st->power_max); in ltc4282_power_reset_hist()
704 return regmap_clear_bits(st->map, LTC4282_FAULT_LOG, in ltc4282_power_reset_hist()
719 return -EOPNOTSUPP; in ltc4282_write_power()
737 return regmap_write(st->map, reg, in); in ltc4282_write_voltage_byte_cached()
751 ret = ltc4282_read_voltage_word(st, LTC4282_VSOURCE_LOWEST, st->vfs_out, in ltc4282_cache_history()
756 st->in0_1_cache[channel].in_lowest = val; in ltc4282_cache_history()
759 st->vfs_out, &val); in ltc4282_cache_history()
763 st->in0_1_cache[channel].in_highest = val; in ltc4282_cache_history()
765 ret = regmap_read(st->map, LTC4282_VSOURCE_MIN, in ltc4282_cache_history()
766 &st->in0_1_cache[channel].in_min_raw); in ltc4282_cache_history()
770 return regmap_read(st->map, LTC4282_VSOURCE_MAX, in ltc4282_cache_history()
771 &st->in0_1_cache[channel].in_max_raw); in ltc4282_cache_history()
779 st->in0_1_cache[channel].in_lowest, in ltc4282_cache_sync()
780 st->in0_1_cache[channel].in_highest, in ltc4282_cache_sync()
781 st->vfs_out); in ltc4282_cache_sync()
785 ret = regmap_write(st->map, LTC4282_VSOURCE_MIN, in ltc4282_cache_sync()
786 st->in0_1_cache[channel].in_min_raw); in ltc4282_cache_sync()
790 return regmap_write(st->map, LTC4282_VSOURCE_MAX, in ltc4282_cache_sync()
791 st->in0_1_cache[channel].in_max_raw); in ltc4282_cache_sync()
799 guard(mutex)(&st->lock); in ltc4282_vdd_source_write_lim()
800 if (st->in0_1_cache[channel].en) in ltc4282_vdd_source_write_lim()
801 ret = ltc4282_write_voltage_byte(st, reg, st->vfs_out, val); in ltc4282_vdd_source_write_lim()
803 ret = ltc4282_write_voltage_byte_cached(st, reg, st->vfs_out, in ltc4282_vdd_source_write_lim()
811 long lowest = st->vfs_out; in ltc4282_vdd_source_reset_hist()
815 lowest = st->vdd; in ltc4282_vdd_source_reset_hist()
817 guard(mutex)(&st->lock); in ltc4282_vdd_source_reset_hist()
818 if (st->in0_1_cache[channel].en) { in ltc4282_vdd_source_reset_hist()
820 lowest, 0, st->vfs_out); in ltc4282_vdd_source_reset_hist()
825 st->in0_1_cache[channel].in_lowest = lowest; in ltc4282_vdd_source_reset_hist()
826 st->in0_1_cache[channel].in_highest = 0; in ltc4282_vdd_source_reset_hist()
837 return regmap_clear_bits(st->map, LTC4282_FAULT_LOG, in ltc4282_vdd_source_reset_hist()
840 return regmap_clear_bits(st->map, LTC4282_FAULT_LOG, in ltc4282_vdd_source_reset_hist()
849 * automatically have the reverse effect on VSOURCE and vice-versa.
857 guard(mutex)(&st->lock); in ltc4282_vdd_source_enable()
858 if (st->in0_1_cache[channel].en == !!val) in ltc4282_vdd_source_enable()
865 ret = regmap_update_bits(st->map, LTC4282_ILIM_ADJUST, in ltc4282_vdd_source_enable()
871 st->in0_1_cache[channel].en = !!val; in ltc4282_vdd_source_enable()
872 st->in0_1_cache[other_chan].en = !val; in ltc4282_vdd_source_enable()
874 if (st->in0_1_cache[channel].en) { in ltc4282_vdd_source_enable()
907 &st->in0_1_cache[channel].in_max_raw, val); in ltc4282_write_in()
915 &st->in0_1_cache[channel].in_min_raw, val); in ltc4282_write_in()
926 return -EOPNOTSUPP; in ltc4282_write_in()
934 guard(mutex)(&st->lock); in ltc4282_curr_reset_hist()
937 st->vsense_max, 0, 40 * MILLI); in ltc4282_curr_reset_hist()
942 return regmap_clear_bits(st->map, LTC4282_FAULT_LOG, in ltc4282_curr_reset_hist()
950 u32 in = DIV_ROUND_CLOSEST_ULL((u64)val * st->rsense, DECA * MICRO); in ltc4282_write_curr()
962 return -EOPNOTSUPP; in ltc4282_write_curr()
970 guard(mutex)(&st->lock); in ltc4282_energy_enable_set()
972 ret = regmap_update_bits(st->map, LTC4282_ADC_CTRL, in ltc4282_energy_enable_set()
978 st->energy_en = !!val; in ltc4282_energy_enable_set()
999 return -EOPNOTSUPP; in ltc4282_write()
1103 return -EOPNOTSUPP; in ltc4282_read_labels()
1114 guard(mutex)(&st->lock); in ltc4282_energy_show()
1115 if (!st->energy_en) in ltc4282_energy_show()
1116 return -ENODATA; in ltc4282_energy_show()
1141 init.name = devm_kasprintf(dev, GFP_KERNEL, "%s-clk", in ltc428_clk_provider_setup()
1144 return -ENOMEM; in ltc428_clk_provider_setup()
1148 st->clk_hw.init = &init; in ltc428_clk_provider_setup()
1150 ret = devm_clk_hw_register(dev, &st->clk_hw); in ltc428_clk_provider_setup()
1155 &st->clk_hw); in ltc428_clk_provider_setup()
1178 return dev_err_probe(dev, -EINVAL, in ltc428_clks_setup()
1189 return regmap_update_bits(st->map, LTC4282_CLK_DIV, in ltc428_clks_setup()
1203 ret = regmap_read(st->map, LTC4282_ADC_CTRL, ®_val); in ltc4282_get_defaults()
1207 st->energy_en = !FIELD_GET(LTC4282_METER_HALT_MASK, reg_val); in ltc4282_get_defaults()
1209 ret = regmap_read(st->map, LTC4282_CTRL_MSB, ®_val); in ltc4282_get_defaults()
1215 ret = regmap_read(st->map, LTC4282_ILIM_ADJUST, ®_val); in ltc4282_get_defaults()
1220 st->vsense_max = ltc4282_curr_lim_uv[ilm_adjust]; in ltc4282_get_defaults()
1222 st->in0_1_cache[LTC4282_CHAN_VSOURCE].en = FIELD_GET(LTC4282_VDD_MONITOR_MASK, in ltc4282_get_defaults()
1224 if (!st->in0_1_cache[LTC4282_CHAN_VSOURCE].en) { in ltc4282_get_defaults()
1225 st->in0_1_cache[LTC4282_CHAN_VDD].en = true; in ltc4282_get_defaults()
1226 return regmap_read(st->map, LTC4282_VSOURCE_MAX, in ltc4282_get_defaults()
1227 &st->in0_1_cache[LTC4282_CHAN_VSOURCE].in_max_raw); in ltc4282_get_defaults()
1230 return regmap_read(st->map, LTC4282_VSOURCE_MAX, in ltc4282_get_defaults()
1231 &st->in0_1_cache[LTC4282_CHAN_VDD].in_max_raw); in ltc4282_get_defaults()
1248 ret = ltc4282_write_voltage_byte(st, LTC4282_VSENSE_MAX, 40 * MILLI, in ltc4282_set_max_limits()
1249 st->vsense_max); in ltc4282_set_max_limits()
1254 st->power_max = DIV_ROUND_CLOSEST(st->vsense_max * DECA * MILLI, st->rsense) * st->vfs_out; in ltc4282_set_max_limits()
1255 ret = ltc4282_write_power_byte(st, LTC4282_POWER_MAX, st->power_max); in ltc4282_set_max_limits()
1259 if (st->in0_1_cache[LTC4282_CHAN_VDD].en) { in ltc4282_set_max_limits()
1260 st->in0_1_cache[LTC4282_CHAN_VSOURCE].in_lowest = st->vfs_out; in ltc4282_set_max_limits()
1262 st->vdd, 0, st->vfs_out); in ltc4282_set_max_limits()
1265 st->in0_1_cache[LTC4282_CHAN_VDD].in_lowest = st->vdd; in ltc4282_set_max_limits()
1267 st->vfs_out, 0, st->vfs_out); in ltc4282_set_max_limits()
1283 ret = device_property_read_string(dev, "adi,gpio1-mode", &func); in ltc4282_gpio_setup()
1292 ret = regmap_update_bits(st->map, LTC4282_GPIO_CONFIG, in ltc4282_gpio_setup()
1299 ret = device_property_read_string(dev, "adi,gpio2-mode", &func); in ltc4282_gpio_setup()
1309 ret = regmap_set_bits(st->map, LTC4282_ILIM_ADJUST, in ltc4282_gpio_setup()
1312 ret = regmap_update_bits(st->map, LTC4282_GPIO_CONFIG, in ltc4282_gpio_setup()
1321 if (!device_property_read_bool(dev, "adi,gpio3-monitor-enable")) in ltc4282_gpio_setup()
1325 return dev_err_probe(dev, -EINVAL, in ltc4282_gpio_setup()
1328 return regmap_clear_bits(st->map, LTC4282_ILIM_ADJUST, in ltc4282_gpio_setup()
1359 ret = device_property_read_u32(dev, "adi,rsense-nano-ohms", in ltc4282_setup()
1360 &st->rsense); in ltc4282_setup()
1363 "Failed to read adi,rsense-nano-ohms\n"); in ltc4282_setup()
1364 if (st->rsense < CENTI) in ltc4282_setup()
1365 return dev_err_probe(dev, -EINVAL, in ltc4282_setup()
1366 "adi,rsense-nano-ohms too small (< %lu)\n", in ltc4282_setup()
1375 st->rsense /= CENTI; in ltc4282_setup()
1378 ret = device_property_read_u32(dev, "adi,vin-mode-microvolt", &val); in ltc4282_setup()
1394 return dev_err_probe(dev, -EINVAL, in ltc4282_setup()
1395 "Invalid val(%u) for vin-mode-microvolt\n", in ltc4282_setup()
1399 ret = regmap_update_bits(st->map, LTC4282_CTRL_MSB, in ltc4282_setup()
1406 ret = regmap_update_bits(st->map, LTC4282_ILIM_ADJUST, in ltc4282_setup()
1413 st->vfs_out = ltc4282_vfs_milli[val]; in ltc4282_setup()
1414 st->vdd = ltc4282_vdd_milli[val]; in ltc4282_setup()
1416 ret = device_property_read_u32(dev, "adi,current-limit-sense-microvolt", in ltc4282_setup()
1417 &st->vsense_max); in ltc4282_setup()
1447 return dev_err_probe(dev, -EINVAL, in ltc4282_setup()
1448 "Invalid val(%u) for adi,current-limit-microvolt\n", in ltc4282_setup()
1449 st->vsense_max); in ltc4282_setup()
1452 ret = regmap_update_bits(st->map, LTC4282_ILIM_ADJUST, in ltc4282_setup()
1463 ret = device_property_read_string(dev, "adi,overvoltage-dividers", in ltc4282_setup()
1469 return dev_err_probe(dev, -EINVAL, in ltc4282_setup()
1470 "Invalid val(%s) for adi,overvoltage-divider\n", in ltc4282_setup()
1473 ret = regmap_update_bits(st->map, LTC4282_CTRL_MSB, in ltc4282_setup()
1478 ret = device_property_read_string(dev, "adi,undervoltage-dividers", in ltc4282_setup()
1484 return dev_err_probe(dev, -EINVAL, in ltc4282_setup()
1485 "Invalid val(%s) for adi,undervoltage-divider\n", in ltc4282_setup()
1488 ret = regmap_update_bits(st->map, LTC4282_CTRL_MSB, in ltc4282_setup()
1493 if (device_property_read_bool(dev, "adi,overcurrent-retry")) { in ltc4282_setup()
1494 ret = regmap_set_bits(st->map, LTC4282_CTRL_LSB, in ltc4282_setup()
1500 if (device_property_read_bool(dev, "adi,overvoltage-retry-disable")) { in ltc4282_setup()
1501 ret = regmap_clear_bits(st->map, LTC4282_CTRL_LSB, in ltc4282_setup()
1507 if (device_property_read_bool(dev, "adi,undervoltage-retry-disable")) { in ltc4282_setup()
1508 ret = regmap_clear_bits(st->map, LTC4282_CTRL_LSB, in ltc4282_setup()
1514 if (device_property_read_bool(dev, "adi,fault-log-enable")) { in ltc4282_setup()
1515 ret = regmap_set_bits(st->map, LTC4282_ADC_CTRL, in ltc4282_setup()
1521 if (device_property_read_bool(dev, "adi,fault-log-enable")) { in ltc4282_setup()
1522 ret = regmap_set_bits(st->map, LTC4282_ADC_CTRL, LTC4282_FAULT_LOG_EN_MASK); in ltc4282_setup()
1527 ret = device_property_read_u32(dev, "adi,fet-bad-timeout-ms", &val); in ltc4282_setup()
1530 return dev_err_probe(dev, -EINVAL, in ltc4282_setup()
1531 "Invalid value(%u) for adi,fet-bad-timeout-ms", in ltc4282_setup()
1534 ret = regmap_write(st->map, LTC4282_FET_BAD_FAULT_TIMEOUT, val); in ltc4282_setup()
1693 debugfs_name = devm_kasprintf(&i2c->dev, GFP_KERNEL, "ltc4282-%s", in ltc4282_debugfs_init()
1702 ret = devm_add_action_or_reset(&i2c->dev, ltc4282_debugfs_remove, in ltc4282_debugfs_init()
1723 struct device *dev = &i2c->dev, *hwmon; in ltc4282_probe()
1729 return dev_err_probe(dev, -ENOMEM, in ltc4282_probe()
1732 st->map = devm_regmap_init_i2c(i2c, <c4282_regmap_config); in ltc4282_probe()
1733 if (IS_ERR(st->map)) in ltc4282_probe()
1734 return dev_err_probe(dev, PTR_ERR(st->map), in ltc4282_probe()
1738 ret = regmap_set_bits(st->map, LTC4282_ADC_CTRL, LTC4282_RESET_MASK); in ltc4282_probe()
1753 mutex_init(&st->lock); in ltc4282_probe()