Lines Matching +full:output +full:- +full:range +full:- +full:microamp
1 // SPDX-License-Identifier: GPL-2.0
29 #include <dt-bindings/iio/addac/adi,ad74413r.h>
67 * Synchronize consecutive operations when doing a one-shot
177 ad74413r_format_reg_write(reg, val, st->reg_tx_buf); in ad74413r_reg_write()
179 return spi_write(st->spi, st->reg_tx_buf, AD74413R_FRAME_SIZE); in ad74413r_reg_write()
187 dev_err(st->dev, "Bad CRC %02x for %02x%02x%02x\n", in ad74413r_crc_check()
189 return -EINVAL; in ad74413r_crc_check()
200 .tx_buf = st->reg_tx_buf, in ad74413r_reg_read()
205 .rx_buf = st->reg_rx_buf, in ad74413r_reg_read()
212 st->reg_tx_buf); in ad74413r_reg_read()
214 ret = spi_sync_transfer(st->spi, reg_read_xfer, in ad74413r_reg_read()
219 ret = ad74413r_crc_check(st, st->reg_rx_buf); in ad74413r_reg_read()
223 *val = get_unaligned_be16(&st->reg_rx_buf[1]); in ad74413r_reg_read()
238 return regmap_update_bits(st->regmap, AD74413R_REG_GPO_CONFIG_X(offset), in ad74413r_set_gpo_config()
253 unsigned int val = AD74413R_DIN_DEBOUNCE_LEN - 1; in ad74413r_set_comp_debounce()
262 return regmap_update_bits(st->regmap, in ad74413r_set_comp_debounce()
274 return regmap_update_bits(st->regmap, AD74413R_REG_DIN_CONFIG_X(offset), in ad74413r_set_comp_drive_strength()
284 unsigned int real_offset = st->gpo_gpio_offsets[offset]; in ad74413r_gpio_set()
292 return regmap_update_bits(st->regmap, in ad74413r_gpio_set()
307 for_each_set_bit(offset, mask, chip->ngpio) { in ad74413r_gpio_set_multiple()
308 unsigned int real_offset = st->gpo_gpio_offsets[offset]; in ad74413r_gpio_set_multiple()
320 return regmap_update_bits(st->regmap, AD74413R_REG_GPO_PAR_DATA, in ad74413r_gpio_set_multiple()
327 unsigned int real_offset = st->comp_gpio_offsets[offset]; in ad74413r_gpio_get()
331 ret = regmap_read(st->regmap, AD74413R_REG_DIN_COMP_OUT, &status); in ad74413r_gpio_get()
349 ret = regmap_read(st->regmap, AD74413R_REG_DIN_COMP_OUT, &val); in ad74413r_gpio_get_multiple()
353 for_each_set_bit(offset, mask, chip->ngpio) { in ad74413r_gpio_get_multiple()
354 unsigned int real_offset = st->comp_gpio_offsets[offset]; in ad74413r_gpio_get_multiple()
379 unsigned int real_offset = st->gpo_gpio_offsets[offset]; in ad74413r_gpio_set_gpo_config()
389 return -ENOTSUPP; in ad74413r_gpio_set_gpo_config()
398 unsigned int real_offset = st->comp_gpio_offsets[offset]; in ad74413r_gpio_set_comp_config()
405 return -ENOTSUPP; in ad74413r_gpio_set_comp_config()
414 reset_gpio = devm_gpiod_get_optional(st->dev, "reset", GPIOD_OUT_HIGH); in ad74413r_reset()
424 ret = regmap_write(st->regmap, AD74413R_REG_CMD_KEY, in ad74413r_reset()
429 return regmap_write(st->regmap, AD74413R_REG_CMD_KEY, in ad74413r_reset()
441 return regmap_multi_reg_write(st->regmap, reg_seq, 2); in ad74413r_set_channel_dac_code()
449 ret = regmap_update_bits(st->regmap, in ad74413r_set_channel_function()
464 ret = regmap_update_bits(st->regmap, in ad74413r_set_channel_function()
474 ret = regmap_set_bits(st->regmap, in ad74413r_set_channel_function()
490 ret = regmap_write_bits(st->regmap, AD74413R_REG_ADC_CONV_CTRL, in ad74413r_set_adc_conv_seq()
508 return regmap_update_bits(st->regmap, AD74413R_REG_ADC_CONV_CTRL, in ad74413r_set_adc_channel_enable()
519 ret = regmap_read(st->regmap, AD74413R_REG_ADC_CONFIG_X(channel), val); in ad74413r_get_adc_range()
534 ret = regmap_read(st->regmap, AD74413R_REG_ADC_CONFIG_X(channel), val); in ad74413r_get_adc_rejection()
547 return regmap_update_bits(st->regmap, in ad74413r_set_adc_rejection()
571 dev_err(st->dev, "ADC rejection invalid\n"); in ad74413r_rejection_to_rate()
572 return -EINVAL; in ad74413r_rejection_to_rate()
593 dev_err(st->dev, "ADC rate invalid\n"); in ad74413r_rate_to_rejection()
594 return -EINVAL; in ad74413r_rate_to_rejection()
599 unsigned int range, int *val) in ad74413r_range_to_voltage_range() argument
601 switch (range) { in ad74413r_range_to_voltage_range()
613 dev_err(st->dev, "ADC range invalid\n"); in ad74413r_range_to_voltage_range()
614 return -EINVAL; in ad74413r_range_to_voltage_range()
619 unsigned int range, int *val) in ad74413r_range_to_voltage_offset() argument
621 switch (range) { in ad74413r_range_to_voltage_offset()
628 *val = -2500; in ad74413r_range_to_voltage_offset()
631 dev_err(st->dev, "ADC range invalid\n"); in ad74413r_range_to_voltage_offset()
632 return -EINVAL; in ad74413r_range_to_voltage_offset()
637 unsigned int range, int *val) in ad74413r_range_to_voltage_offset_raw() argument
639 switch (range) { in ad74413r_range_to_voltage_offset_raw()
645 *val = -((int)AD74413R_ADC_RESULT_MAX); in ad74413r_range_to_voltage_offset_raw()
648 *val = -((int)AD74413R_ADC_RESULT_MAX / 2); in ad74413r_range_to_voltage_offset_raw()
651 dev_err(st->dev, "ADC range invalid\n"); in ad74413r_range_to_voltage_offset_raw()
652 return -EINVAL; in ad74413r_range_to_voltage_offset_raw()
668 *val = st->refin_reg_uv; in ad74413r_get_output_current_scale()
669 *val2 = st->sense_resistor_ohms * AD74413R_DAC_CODE_MAX * 1000; in ad74413r_get_output_current_scale()
678 unsigned int range; in ad74413r_get_input_voltage_scale() local
681 ret = ad74413r_get_adc_range(st, channel, &range); in ad74413r_get_input_voltage_scale()
685 ret = ad74413r_range_to_voltage_range(st, range, val); in ad74413r_get_input_voltage_scale()
697 unsigned int range; in ad74413r_get_input_voltage_offset() local
700 ret = ad74413r_get_adc_range(st, channel, &range); in ad74413r_get_input_voltage_offset()
704 ret = ad74413r_range_to_voltage_offset_raw(st, range, val); in ad74413r_get_input_voltage_offset()
715 unsigned int range; in ad74413r_get_input_current_scale() local
718 ret = ad74413r_get_adc_range(st, channel, &range); in ad74413r_get_input_current_scale()
722 ret = ad74413r_range_to_voltage_range(st, range, val); in ad74413r_get_input_current_scale()
726 *val2 = AD74413R_ADC_RESULT_MAX * st->sense_resistor_ohms; in ad74413r_get_input_current_scale()
734 unsigned int range; in ad74413r_get_input_current_offset() local
739 ret = ad74413r_get_adc_range(st, channel, &range); in ad74413r_get_input_current_offset()
743 ret = ad74413r_range_to_voltage_range(st, range, &voltage_range); in ad74413r_get_input_current_offset()
747 ret = ad74413r_range_to_voltage_offset(st, range, &voltage_offset); in ad74413r_get_input_current_offset()
789 struct iio_dev *indio_dev = pf->indio_dev; in ad74413r_trigger_handler()
791 u8 *rx_buf = st->adc_samples_buf.rx_buf; in ad74413r_trigger_handler()
795 ret = spi_sync(st->spi, &st->adc_samples_msg); in ad74413r_trigger_handler()
799 for (i = 0; i < st->adc_active_channels; i++) in ad74413r_trigger_handler()
802 iio_push_to_buffers_with_timestamp(indio_dev, &st->adc_samples_buf, in ad74413r_trigger_handler()
806 iio_trigger_notify_done(indio_dev->trig); in ad74413r_trigger_handler()
817 iio_trigger_poll(st->trig); in ad74413r_adc_data_interrupt()
819 complete(&st->adc_data_completion); in ad74413r_adc_data_interrupt()
830 guard(mutex)(&st->lock); in _ad74413r_get_single_adc_result()
832 reinit_completion(&st->adc_data_completion); in _ad74413r_get_single_adc_result()
842 ret = wait_for_completion_timeout(&st->adc_data_completion, in _ad74413r_get_single_adc_result()
845 ret = -ETIMEDOUT; in _ad74413r_get_single_adc_result()
849 ret = regmap_read(st->regmap, AD74413R_REG_ADC_RESULT_X(channel), in _ad74413r_get_single_adc_result()
874 return -EBUSY; in ad74413r_get_single_adc_result()
884 adc_result = AD74413R_ADC_RESULT_MAX - 1; in ad74413r_adc_to_resistance_result()
887 AD74413R_ADC_RESULT_MAX - adc_result); in ad74413r_adc_to_resistance_result()
894 struct spi_transfer *xfer = st->adc_samples_xfer; in ad74413r_update_scan_mode()
895 u8 *rx_buf = st->adc_samples_buf.rx_buf; in ad74413r_update_scan_mode()
896 u8 *tx_buf = st->adc_samples_tx_buf; in ad74413r_update_scan_mode()
898 int ret = -EINVAL; in ad74413r_update_scan_mode()
900 guard(mutex)(&st->lock); in ad74413r_update_scan_mode()
902 spi_message_init(&st->adc_samples_msg); in ad74413r_update_scan_mode()
903 st->adc_active_channels = 0; in ad74413r_update_scan_mode()
932 st->adc_active_channels++; in ad74413r_update_scan_mode()
934 if (xfer == st->adc_samples_xfer) in ad74413r_update_scan_mode()
935 xfer->rx_buf = NULL; in ad74413r_update_scan_mode()
937 xfer->rx_buf = rx_buf; in ad74413r_update_scan_mode()
939 xfer->tx_buf = tx_buf; in ad74413r_update_scan_mode()
940 xfer->len = AD74413R_FRAME_SIZE; in ad74413r_update_scan_mode()
941 xfer->cs_change = 1; in ad74413r_update_scan_mode()
947 spi_message_add_tail(xfer, &st->adc_samples_msg); in ad74413r_update_scan_mode()
950 if (xfer != st->adc_samples_xfer) in ad74413r_update_scan_mode()
955 xfer->rx_buf = rx_buf; in ad74413r_update_scan_mode()
956 xfer->tx_buf = NULL; in ad74413r_update_scan_mode()
957 xfer->len = AD74413R_FRAME_SIZE; in ad74413r_update_scan_mode()
958 xfer->cs_change = 0; in ad74413r_update_scan_mode()
960 spi_message_add_tail(xfer, &st->adc_samples_msg); in ad74413r_update_scan_mode()
986 switch (chan->type) { in ad74413r_read_raw()
988 if (chan->output) in ad74413r_read_raw()
993 chan->channel, val, val2); in ad74413r_read_raw()
995 if (chan->output) in ad74413r_read_raw()
1000 chan->channel, val, val2); in ad74413r_read_raw()
1002 return -EINVAL; in ad74413r_read_raw()
1005 switch (chan->type) { in ad74413r_read_raw()
1008 chan->channel, val); in ad74413r_read_raw()
1011 chan->channel, val); in ad74413r_read_raw()
1013 return -EINVAL; in ad74413r_read_raw()
1016 if (chan->output) in ad74413r_read_raw()
1017 return -EINVAL; in ad74413r_read_raw()
1019 return ad74413r_get_single_adc_result(indio_dev, chan->channel, in ad74413r_read_raw()
1024 ret = ad74413r_get_single_adc_result(indio_dev, chan->channel, in ad74413r_read_raw()
1034 return ad74413r_get_adc_rate(st, chan->channel, val); in ad74413r_read_raw()
1036 return -EINVAL; in ad74413r_read_raw()
1048 if (!chan->output) in ad74413r_write_raw()
1049 return -EINVAL; in ad74413r_write_raw()
1052 dev_err(st->dev, "Invalid DAC code\n"); in ad74413r_write_raw()
1053 return -EINVAL; in ad74413r_write_raw()
1056 return ad74413r_set_channel_dac_code(st, chan->channel, val); in ad74413r_write_raw()
1058 return ad74413r_set_adc_rate(st, chan->channel, val); in ad74413r_write_raw()
1060 return -EINVAL; in ad74413r_write_raw()
1073 if (st->chip_info->hart_support) { in ad74413r_read_avail()
1083 return -EINVAL; in ad74413r_read_avail()
1107 .output = 1, \
1116 .output = 0, \
1203 dev_err(st->dev, "Failed to read channel reg: %d\n", ret); in ad74413r_parse_channel_config()
1208 dev_err(st->dev, "Channel index %u is too large\n", index); in ad74413r_parse_channel_config()
1209 return -EINVAL; in ad74413r_parse_channel_config()
1212 config = &st->channel_configs[index]; in ad74413r_parse_channel_config()
1213 if (config->initialized) { in ad74413r_parse_channel_config()
1214 dev_err(st->dev, "Channel %u already initialized\n", index); in ad74413r_parse_channel_config()
1215 return -EINVAL; in ad74413r_parse_channel_config()
1218 config->func = CH_FUNC_HIGH_IMPEDANCE; in ad74413r_parse_channel_config()
1219 fwnode_property_read_u32(channel_node, "adi,ch-func", &config->func); in ad74413r_parse_channel_config()
1221 if (config->func < CH_FUNC_MIN || config->func > CH_FUNC_MAX) { in ad74413r_parse_channel_config()
1222 dev_err(st->dev, "Invalid channel function %u\n", config->func); in ad74413r_parse_channel_config()
1223 return -EINVAL; in ad74413r_parse_channel_config()
1226 if (!st->chip_info->hart_support && in ad74413r_parse_channel_config()
1227 (config->func == CH_FUNC_CURRENT_INPUT_EXT_POWER_HART || in ad74413r_parse_channel_config()
1228 config->func == CH_FUNC_CURRENT_INPUT_LOOP_POWER_HART)) { in ad74413r_parse_channel_config()
1229 dev_err(st->dev, "Unsupported HART function %u\n", config->func); in ad74413r_parse_channel_config()
1230 return -EINVAL; in ad74413r_parse_channel_config()
1233 if (config->func == CH_FUNC_DIGITAL_INPUT_LOGIC || in ad74413r_parse_channel_config()
1234 config->func == CH_FUNC_DIGITAL_INPUT_LOOP_POWER) in ad74413r_parse_channel_config()
1235 st->num_comparator_gpios++; in ad74413r_parse_channel_config()
1237 config->gpo_comparator = fwnode_property_read_bool(channel_node, in ad74413r_parse_channel_config()
1238 "adi,gpo-comparator"); in ad74413r_parse_channel_config()
1240 fwnode_property_read_u32(channel_node, "drive-strength-microamp", in ad74413r_parse_channel_config()
1241 &config->drive_strength); in ad74413r_parse_channel_config()
1243 if (!config->gpo_comparator) in ad74413r_parse_channel_config()
1244 st->num_gpo_gpios++; in ad74413r_parse_channel_config()
1246 indio_dev->num_channels += ad74413r_channels_map[config->func].num_channels; in ad74413r_parse_channel_config()
1248 config->initialized = true; in ad74413r_parse_channel_config()
1258 device_for_each_child_node_scoped(st->dev, channel_node) { in ad74413r_parse_channel_configs()
1276 channels = devm_kcalloc(st->dev, sizeof(*channels), in ad74413r_setup_channels()
1277 indio_dev->num_channels, GFP_KERNEL); in ad74413r_setup_channels()
1279 return -ENOMEM; in ad74413r_setup_channels()
1281 indio_dev->channels = channels; in ad74413r_setup_channels()
1284 config = &st->channel_configs[i]; in ad74413r_setup_channels()
1285 chans = ad74413r_channels_map[config->func].channels; in ad74413r_setup_channels()
1286 num_chans = ad74413r_channels_map[config->func].num_channels; in ad74413r_setup_channels()
1293 chan->channel = i; in ad74413r_setup_channels()
1294 if (chan->output) in ad74413r_setup_channels()
1295 chan->scan_index = -1; in ad74413r_setup_channels()
1297 chan->scan_index = i; in ad74413r_setup_channels()
1300 ret = ad74413r_set_channel_function(st, i, config->func); in ad74413r_setup_channels()
1321 config = &st->channel_configs[i]; in ad74413r_setup_gpios()
1323 if (config->gpo_comparator) { in ad74413r_setup_gpios()
1327 st->gpo_gpio_offsets[gpo_gpio_i++] = i; in ad74413r_setup_gpios()
1330 if (config->func == CH_FUNC_DIGITAL_INPUT_LOGIC || in ad74413r_setup_gpios()
1331 config->func == CH_FUNC_DIGITAL_INPUT_LOOP_POWER) { in ad74413r_setup_gpios()
1332 st->comp_gpio_offsets[comp_gpio_i++] = i; in ad74413r_setup_gpios()
1334 strength = config->drive_strength; in ad74413r_setup_gpios()
1354 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); in ad74413r_probe()
1356 return -ENOMEM; in ad74413r_probe()
1360 st->spi = spi; in ad74413r_probe()
1361 st->dev = &spi->dev; in ad74413r_probe()
1362 st->chip_info = spi_get_device_match_data(spi); in ad74413r_probe()
1363 if (!st->chip_info) in ad74413r_probe()
1364 return -EINVAL; in ad74413r_probe()
1366 ret = devm_mutex_init(st->dev, &st->lock); in ad74413r_probe()
1370 init_completion(&st->adc_data_completion); in ad74413r_probe()
1372 st->regmap = devm_regmap_init(st->dev, NULL, st, in ad74413r_probe()
1374 if (IS_ERR(st->regmap)) in ad74413r_probe()
1375 return PTR_ERR(st->regmap); in ad74413r_probe()
1377 ret = devm_regulator_get_enable_read_voltage(st->dev, "refin"); in ad74413r_probe()
1379 return dev_err_probe(st->dev, ret, in ad74413r_probe()
1381 st->refin_reg_uv = ret; in ad74413r_probe()
1383 st->sense_resistor_ohms = 100000000; in ad74413r_probe()
1384 device_property_read_u32(st->dev, "shunt-resistor-micro-ohms", in ad74413r_probe()
1385 &st->sense_resistor_ohms); in ad74413r_probe()
1386 st->sense_resistor_ohms /= 1000000; in ad74413r_probe()
1388 st->trig = devm_iio_trigger_alloc(st->dev, "%s-dev%d", in ad74413r_probe()
1389 st->chip_info->name, iio_device_id(indio_dev)); in ad74413r_probe()
1390 if (!st->trig) in ad74413r_probe()
1391 return -ENOMEM; in ad74413r_probe()
1393 st->trig->ops = &ad74413r_trigger_ops; in ad74413r_probe()
1394 iio_trigger_set_drvdata(st->trig, st); in ad74413r_probe()
1396 ret = devm_iio_trigger_register(st->dev, st->trig); in ad74413r_probe()
1400 indio_dev->name = st->chip_info->name; in ad74413r_probe()
1401 indio_dev->modes = INDIO_DIRECT_MODE; in ad74413r_probe()
1402 indio_dev->info = &ad74413r_info; in ad74413r_probe()
1403 indio_dev->trig = iio_trigger_get(st->trig); in ad74413r_probe()
1421 if (st->num_gpo_gpios) { in ad74413r_probe()
1422 st->gpo_gpiochip.owner = THIS_MODULE; in ad74413r_probe()
1423 st->gpo_gpiochip.label = st->chip_info->name; in ad74413r_probe()
1424 st->gpo_gpiochip.base = -1; in ad74413r_probe()
1425 st->gpo_gpiochip.ngpio = st->num_gpo_gpios; in ad74413r_probe()
1426 st->gpo_gpiochip.parent = st->dev; in ad74413r_probe()
1427 st->gpo_gpiochip.can_sleep = true; in ad74413r_probe()
1428 st->gpo_gpiochip.set_rv = ad74413r_gpio_set; in ad74413r_probe()
1429 st->gpo_gpiochip.set_multiple_rv = ad74413r_gpio_set_multiple; in ad74413r_probe()
1430 st->gpo_gpiochip.set_config = ad74413r_gpio_set_gpo_config; in ad74413r_probe()
1431 st->gpo_gpiochip.get_direction = in ad74413r_probe()
1434 ret = devm_gpiochip_add_data(st->dev, &st->gpo_gpiochip, st); in ad74413r_probe()
1439 if (st->num_comparator_gpios) { in ad74413r_probe()
1440 st->comp_gpiochip.owner = THIS_MODULE; in ad74413r_probe()
1441 st->comp_gpiochip.label = st->chip_info->name; in ad74413r_probe()
1442 st->comp_gpiochip.base = -1; in ad74413r_probe()
1443 st->comp_gpiochip.ngpio = st->num_comparator_gpios; in ad74413r_probe()
1444 st->comp_gpiochip.parent = st->dev; in ad74413r_probe()
1445 st->comp_gpiochip.can_sleep = true; in ad74413r_probe()
1446 st->comp_gpiochip.get = ad74413r_gpio_get; in ad74413r_probe()
1447 st->comp_gpiochip.get_multiple = ad74413r_gpio_get_multiple; in ad74413r_probe()
1448 st->comp_gpiochip.set_config = ad74413r_gpio_set_comp_config; in ad74413r_probe()
1449 st->comp_gpiochip.get_direction = in ad74413r_probe()
1452 ret = devm_gpiochip_add_data(st->dev, &st->comp_gpiochip, st); in ad74413r_probe()
1461 ret = devm_request_irq(st->dev, spi->irq, ad74413r_adc_data_interrupt, in ad74413r_probe()
1462 0, st->chip_info->name, indio_dev); in ad74413r_probe()
1464 return dev_err_probe(st->dev, ret, "Failed to request irq\n"); in ad74413r_probe()
1466 ret = devm_iio_triggered_buffer_setup(st->dev, indio_dev, in ad74413r_probe()
1473 return devm_iio_device_register(st->dev, indio_dev); in ad74413r_probe()