Lines Matching +full:pre +full:- +full:multiply
1 // SPDX-License-Identifier: GPL-2.0+
3 * IIO driver for PAC1921 High-Side Power/Current Monitor
75 /* f7bb9932-86ee-4516-a236-7a7a742e55cb */
81 * Pre-computed scale factors for BUS voltage
97 * Pre-computed scales for SENSE voltage
130 * contains integration periods, in microsecs unit, based on table 4-5 from
131 * datasheet considering power integration mode, 14-Bit resolution and post
224 if (!priv->first_integr_started) in pac1921_data_ready()
227 if (!priv->first_integr_done) { in pac1921_data_ready()
235 t_ready = priv->integr_started_time_jiffies + in pac1921_data_ready()
237 usecs_to_jiffies(priv->integr_period_usecs); in pac1921_data_ready()
242 priv->first_integr_done = true; in pac1921_data_ready()
269 for (unsigned int i = 0; i < ARRAY_SIZE(priv->current_scales); i++) { in pac1921_calc_current_scales()
273 pac1921_calc_scale(vsense_lsb, priv->rshunt_uohm, in pac1921_calc_current_scales()
274 &priv->current_scales[i][0], in pac1921_calc_current_scales()
275 &priv->current_scales[i][1]); in pac1921_calc_current_scales()
290 ret = regmap_read(priv->regmap, PAC1921_REG_OVERFLOW_STS, &flags); in pac1921_check_push_overflow()
295 !(priv->prev_ovf_flags & PAC1921_OVERFLOW_VBOV) && in pac1921_check_push_overflow()
296 priv->ovf_enabled_events & PAC1921_OVERFLOW_VBOV) { in pac1921_check_push_overflow()
304 !(priv->prev_ovf_flags & PAC1921_OVERFLOW_VSOV) && in pac1921_check_push_overflow()
305 priv->ovf_enabled_events & PAC1921_OVERFLOW_VSOV) { in pac1921_check_push_overflow()
318 !(priv->prev_ovf_flags & PAC1921_OVERFLOW_VPOV) && in pac1921_check_push_overflow()
319 priv->ovf_enabled_events & PAC1921_OVERFLOW_VPOV) { in pac1921_check_push_overflow()
327 priv->prev_ovf_flags = flags; in pac1921_check_push_overflow()
342 int ret = regmap_bulk_read(priv->regmap, reg, val, sizeof(*val)); in pac1921_read_res()
357 guard(mutex)(&priv->lock); in pac1921_read_raw()
366 return -EBUSY; in pac1921_read_raw()
374 ret = pac1921_read_res(priv, chan->address, &res_val); in pac1921_read_raw()
383 switch (chan->channel) { in pac1921_read_raw()
385 *val = pac1921_vbus_scales[priv->dv_gain][0]; in pac1921_read_raw()
386 *val2 = pac1921_vbus_scales[priv->dv_gain][1]; in pac1921_read_raw()
390 *val = pac1921_vsense_scales[priv->di_gain][0]; in pac1921_read_raw()
391 *val2 = pac1921_vsense_scales[priv->di_gain][1]; in pac1921_read_raw()
395 *val = priv->current_scales[priv->di_gain][0]; in pac1921_read_raw()
396 *val2 = priv->current_scales[priv->di_gain][1]; in pac1921_read_raw()
406 int *curr_scale = priv->current_scales[priv->di_gain]; in pac1921_read_raw()
411 /* Multiply by max_vbus (V) / dv_gain */ in pac1921_read_raw()
412 tmp *= PAC1921_MAX_VBUS_V >> priv->dv_gain; in pac1921_read_raw()
420 return -EINVAL; in pac1921_read_raw()
424 *val = pac1921_int_num_samples[priv->n_samples]; in pac1921_read_raw()
429 * The sampling frequency (Hz) is read-only and corresponds to in pac1921_read_raw()
438 *val2 = priv->integr_period_usecs; in pac1921_read_raw()
442 return -EINVAL; in pac1921_read_raw()
458 return -EINVAL; in pac1921_read_avail()
474 int ret = regmap_update_bits(priv->regmap, PAC1921_REG_INT_CFG, in pac1921_update_cfg_reg()
480 ret = regmap_update_bits(priv->regmap, reg, mask, val); in pac1921_update_cfg_reg()
484 /* Re-enable integration */ in pac1921_update_cfg_reg()
485 ret = regmap_update_bits(priv->regmap, PAC1921_REG_INT_CFG, in pac1921_update_cfg_reg()
495 priv->integr_started_time_jiffies = jiffies; in pac1921_update_cfg_reg()
496 priv->first_integr_done = false; in pac1921_update_cfg_reg()
517 return -EINVAL; in pac1921_lookup_scale()
557 switch (chan->channel) { in pac1921_update_gain_from_scale()
565 return pac1921_update_gain(priv, &priv->dv_gain, ret, in pac1921_update_gain_from_scale()
574 return pac1921_update_gain(priv, &priv->di_gain, ret, in pac1921_update_gain_from_scale()
577 ret = pac1921_lookup_scale(priv->current_scales, in pac1921_update_gain_from_scale()
578 ARRAY_SIZE(priv->current_scales), in pac1921_update_gain_from_scale()
583 return pac1921_update_gain(priv, &priv->di_gain, ret, in pac1921_update_gain_from_scale()
586 return -EINVAL; in pac1921_update_gain_from_scale()
600 return -EINVAL; in pac1921_lookup_int_num_samples()
621 if (priv->n_samples == n_samples) in pac1921_update_int_num_samples()
631 priv->n_samples = n_samples; in pac1921_update_int_num_samples()
633 priv->integr_period_usecs = pac1921_int_periods_usecs[priv->n_samples]; in pac1921_update_int_num_samples()
648 return -EINVAL; in pac1921_write_raw_get_fmt()
658 guard(mutex)(&priv->lock); in pac1921_write_raw()
666 return -EINVAL; in pac1921_write_raw()
673 switch (chan->channel) { in pac1921_read_label()
683 return -EINVAL; in pac1921_read_label()
694 guard(mutex)(&priv->lock); in pac1921_read_event_config()
696 switch (chan->channel) { in pac1921_read_event_config()
698 return !!(priv->ovf_enabled_events & PAC1921_OVERFLOW_VBOV); in pac1921_read_event_config()
701 return !!(priv->ovf_enabled_events & PAC1921_OVERFLOW_VSOV); in pac1921_read_event_config()
703 return !!(priv->ovf_enabled_events & PAC1921_OVERFLOW_VPOV); in pac1921_read_event_config()
705 return -EINVAL; in pac1921_read_event_config()
718 guard(mutex)(&priv->lock); in pac1921_write_event_config()
720 switch (chan->channel) { in pac1921_write_event_config()
732 return -EINVAL; in pac1921_write_event_config()
736 priv->ovf_enabled_events |= ovf_bit; in pac1921_write_event_config()
738 priv->ovf_enabled_events &= ~ovf_bit; in pac1921_write_event_config()
755 return -EINVAL; in pac1921_read_event_value()
778 if (chan->channel != PAC1921_CHAN_CURRENT) in pac1921_read_shunt_resistor()
779 return -EINVAL; in pac1921_read_shunt_resistor()
781 guard(mutex)(&priv->lock); in pac1921_read_shunt_resistor()
783 vals[0] = priv->rshunt_uohm; in pac1921_read_shunt_resistor()
799 if (chan->channel != PAC1921_CHAN_CURRENT) in pac1921_write_shunt_resistor()
800 return -EINVAL; in pac1921_write_shunt_resistor()
813 return -EINVAL; in pac1921_write_shunt_resistor()
817 guard(mutex)(&priv->lock); in pac1921_write_shunt_resistor()
819 priv->rshunt_uohm = rshunt_uohm; in pac1921_write_shunt_resistor()
844 return -EFBIG; in pac1921_format_scale_avail()
849 return -EFBIG; in pac1921_format_scale_avail()
873 switch (chan->channel) { in pac1921_read_scale_avail()
885 guard(mutex)(&priv->lock); in pac1921_read_scale_avail()
886 scales_tbl = priv->current_scales; in pac1921_read_scale_avail()
887 size = ARRAY_SIZE(priv->current_scales); in pac1921_read_scale_avail()
891 return -EINVAL; in pac1921_read_scale_avail()
1022 struct iio_dev *idev = pf->indio_dev; in pac1921_trigger_handler()
1028 guard(mutex)(&priv->lock); in pac1921_trigger_handler()
1033 ret = pac1921_check_push_overflow(idev, pf->timestamp); in pac1921_trigger_handler()
1040 ret = pac1921_read_res(priv, idev->channels[ch].address, &val); in pac1921_trigger_handler()
1044 priv->scan.chan[ch++] = val; in pac1921_trigger_handler()
1047 iio_push_to_buffers_with_ts(idev, &priv->scan, sizeof(priv->scan), in pac1921_trigger_handler()
1048 pf->timestamp); in pac1921_trigger_handler()
1051 iio_trigger_notify_done(idev->trig); in pac1921_trigger_handler()
1069 ret = regmap_update_bits(priv->regmap, PAC1921_REG_INT_CFG, in pac1921_init()
1074 /* Configure gains, use 14-bits measurement resolution (HW default) */ in pac1921_init()
1075 val = FIELD_PREP(PAC1921_GAIN_DI_GAIN_MASK, priv->di_gain) | in pac1921_init()
1076 FIELD_PREP(PAC1921_GAIN_DV_GAIN_MASK, priv->dv_gain); in pac1921_init()
1077 ret = regmap_write(priv->regmap, PAC1921_REG_GAIN_CFG, val); in pac1921_init()
1083 * - num of integration samples in pac1921_init()
1084 * - filters enabled (HW default) in pac1921_init()
1085 * - set READ/INT pin override (RIOV) to control operation mode via in pac1921_init()
1088 val = FIELD_PREP(PAC1921_INT_CFG_SMPL_MASK, priv->n_samples) | in pac1921_init()
1091 ret = regmap_write(priv->regmap, PAC1921_REG_INT_CFG, val); in pac1921_init()
1097 * - VPower free run integration mode in pac1921_init()
1098 * - OUT pin full scale range: 3V (HW default) in pac1921_init()
1099 * - no timeout, no sleep, no sleep override, no recalc (HW defaults) in pac1921_init()
1103 ret = regmap_write(priv->regmap, PAC1921_REG_CONTROL, val); in pac1921_init()
1108 ret = regmap_update_bits(priv->regmap, PAC1921_REG_INT_CFG, in pac1921_init()
1113 priv->first_integr_started = true; in pac1921_init()
1114 priv->integr_started_time_jiffies = jiffies; in pac1921_init()
1115 priv->integr_period_usecs = pac1921_int_periods_usecs[priv->n_samples]; in pac1921_init()
1126 guard(mutex)(&priv->lock); in pac1921_suspend()
1128 priv->first_integr_started = false; in pac1921_suspend()
1129 priv->first_integr_done = false; in pac1921_suspend()
1131 ret = regmap_update_bits(priv->regmap, PAC1921_REG_INT_CFG, in pac1921_suspend()
1136 ret = regmap_update_bits(priv->regmap, PAC1921_REG_CONTROL, in pac1921_suspend()
1141 return regulator_disable(priv->vdd); in pac1921_suspend()
1151 guard(mutex)(&priv->lock); in pac1921_resume()
1153 ret = regulator_enable(priv->vdd); in pac1921_resume()
1174 …plicationNotes/ApplicationNotes/PAC193X-Integration-Notes-for-Microsoft-Windows-10-and-Windows-11-…
1182 struct device *dev = &priv->client->dev; in pac1921_match_acpi_device()
1189 return dev_err_probe(dev, -EINVAL, in pac1921_match_acpi_device()
1192 priv->rshunt_uohm = status->package.elements[0].integer.value; in pac1921_match_acpi_device()
1198 return dev_err_probe(dev, -EINVAL, in pac1921_match_acpi_device()
1201 label = devm_kstrdup(dev, status->package.elements[0].string.pointer, in pac1921_match_acpi_device()
1205 return -ENOMEM; in pac1921_match_acpi_device()
1207 indio_dev->label = label; in pac1921_match_acpi_device()
1216 struct device *dev = &priv->client->dev; in pac1921_parse_of_fw()
1218 ret = device_property_read_u32(dev, "shunt-resistor-micro-ohms", in pac1921_parse_of_fw()
1219 &priv->rshunt_uohm); in pac1921_parse_of_fw()
1229 struct device *dev = &client->dev; in pac1921_probe()
1236 return -ENOMEM; in pac1921_probe()
1239 priv->client = client; in pac1921_probe()
1242 priv->regmap = devm_regmap_init_i2c(client, &pac1921_regmap_config); in pac1921_probe()
1243 if (IS_ERR(priv->regmap)) in pac1921_probe()
1244 return dev_err_probe(dev, PTR_ERR(priv->regmap), in pac1921_probe()
1247 ret = devm_mutex_init(dev, &priv->lock); in pac1921_probe()
1251 priv->dv_gain = PAC1921_DEFAULT_DV_GAIN; in pac1921_probe()
1252 priv->di_gain = PAC1921_DEFAULT_DI_GAIN; in pac1921_probe()
1253 priv->n_samples = PAC1921_DEFAULT_NUM_SAMPLES; in pac1921_probe()
1255 if (is_acpi_device_node(dev->fwnode)) in pac1921_probe()
1263 if (priv->rshunt_uohm == 0 || priv->rshunt_uohm > INT_MAX) in pac1921_probe()
1264 return dev_err_probe(dev, -EINVAL, in pac1921_probe()
1266 priv->rshunt_uohm); in pac1921_probe()
1270 priv->vdd = devm_regulator_get(dev, "vdd"); in pac1921_probe()
1271 if (IS_ERR(priv->vdd)) in pac1921_probe()
1272 return dev_err_probe(dev, PTR_ERR(priv->vdd), in pac1921_probe()
1275 ret = regulator_enable(priv->vdd); in pac1921_probe()
1280 priv->vdd); in pac1921_probe()
1291 priv->iio_info = pac1921_iio; in pac1921_probe()
1293 indio_dev->name = "pac1921"; in pac1921_probe()
1294 indio_dev->info = &priv->iio_info; in pac1921_probe()
1295 indio_dev->modes = INDIO_DIRECT_MODE; in pac1921_probe()
1296 indio_dev->channels = pac1921_channels; in pac1921_probe()
1297 indio_dev->num_channels = ARRAY_SIZE(pac1921_channels); in pac1921_probe()
1345 MODULE_DESCRIPTION("IIO driver for PAC1921 High-Side Power/Current Monitor");