Lines Matching +full:output +full:- +full:polarity +full:- +full:invert
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright 2012-2020 Analog Devices Inc.
32 * ADI High-Speed ADC common spi interface registers
33 * See Application-Note AN-877:
34 * https://www.analog.com/media/en/technical-documentation/application-notes/AN-877.pdf
85 * Analog Devices AD9265 16-Bit, 125/105/80 MSPS ADC
93 * Analog Devices AD9434 12-Bit, 370/500 MSPS ADC
101 * Analog Devices AD9467 16-Bit, 200/250 MSPS ADC
109 * Analog Devices AD9643 14-Bit, 170/210/250 MSPS ADC
116 * Analog Devices AD9652 16-bit 310 MSPS ADC
123 * Analog Devices AD9649 14-bit 20/40/65/80 MSPS ADC
131 (!(st)->info->has_dco || (st)->info->has_dco_invert)
148 /* data clock output */
169 * Times 2 because we may also invert the signal polarity and run the
171 * https://www.analog.com/media/en/technical-documentation/data-sheets/ad9265.pdf
172 * at page 38 for the dco output delay. On devices as ad9467, the
173 * calibration is done at the backend level. For the ADI axi-adc:
194 ret = spi_write_then_read(st->spi, in ad9467_spi_read()
207 st->buf[0] = reg >> 8; in ad9467_spi_write()
208 st->buf[1] = reg & 0xFF; in ad9467_spi_write()
209 st->buf[2] = val; in ad9467_spi_write()
211 return spi_write(st->spi, st->buf, ARRAY_SIZE(st->buf)); in ad9467_spi_write()
221 guard(mutex)(&st->lock); in ad9467_reg_access()
274 const struct ad9467_chip_info *info = st->info; in __ad9467_get_scale()
275 const struct iio_chan_spec *chan = &info->channels[0]; in __ad9467_get_scale()
278 tmp = (info->scale_table[index][0] * 1000000ULL) >> in __ad9467_get_scale()
279 chan->scan_type.realbits; in __ad9467_get_scale()
443 const struct ad9467_chip_info *info = st->info; in ad9467_get_scale()
449 if (info->num_scales == 1) in ad9467_get_scale()
456 vref_val = ret & info->vref_mask; in ad9467_get_scale()
458 for (i = 0; i < info->num_scales; i++) { in ad9467_get_scale()
459 if (vref_val == info->scale_table[i][1]) in ad9467_get_scale()
463 if (i == info->num_scales) in ad9467_get_scale()
464 return -ERANGE; in ad9467_get_scale()
474 const struct ad9467_chip_info *info = st->info; in ad9467_set_scale()
480 return -EINVAL; in ad9467_set_scale()
481 if (info->num_scales == 1) in ad9467_set_scale()
482 return -EOPNOTSUPP; in ad9467_set_scale()
484 for (i = 0; i < info->num_scales; i++) { in ad9467_set_scale()
489 guard(mutex)(&st->lock); in ad9467_set_scale()
491 info->scale_table[i][1]); in ad9467_set_scale()
499 return -EINVAL; in ad9467_set_scale()
519 if (st->info->num_channels > 1) { in ad9467_testmode_set()
530 if (st->info->num_channels > 1) { in ad9467_testmode_set()
533 GENMASK(st->info->num_channels - 1, 0)); in ad9467_testmode_set()
551 ret = iio_backend_data_format_set(st->back, chan, &data); in ad9467_backend_testmode_on()
555 ret = iio_backend_test_pattern_set(st->back, chan, pattern); in ad9467_backend_testmode_on()
559 return iio_backend_chan_enable(st->back, chan); in ad9467_backend_testmode_on()
571 ret = iio_backend_chan_disable(st->back, chan); in ad9467_backend_testmode_off()
575 ret = iio_backend_test_pattern_set(st->back, chan, in ad9467_backend_testmode_off()
580 return iio_backend_data_format_set(st->back, chan, &data); in ad9467_backend_testmode_off()
588 ret = ad9467_outputmode_set(st, st->info->default_output_mode); in ad9647_calibrate_prepare()
592 for (c = 0; c < st->info->num_channels; c++) { in ad9647_calibrate_prepare()
607 bool invert) in ad9647_calibrate_polarity_set() argument
611 if (st->info->has_dco) { in ad9647_calibrate_polarity_set()
614 if (invert) in ad9647_calibrate_polarity_set()
621 if (invert) in ad9647_calibrate_polarity_set()
626 return iio_backend_data_sample_trigger(st->back, trigger); in ad9647_calibrate_polarity_set()
641 if (end - bit > cnt) { in ad9467_find_optimal_point()
642 cnt = end - bit; in ad9467_find_optimal_point()
658 if (st->info->has_dco) { in ad9467_calibrate_apply()
660 val | st->info->dco_en); in ad9467_calibrate_apply()
668 for (lane = 0; lane < st->info->num_lanes; lane++) { in ad9467_calibrate_apply()
669 ret = iio_backend_iodelay_set(st->back, lane, val); in ad9467_calibrate_apply()
682 for (c = 0; c < st->info->num_channels; c++) { in ad9647_calibrate_stop()
692 mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; in ad9647_calibrate_stop()
703 unsigned int test_points = st->info->test_points; in ad9467_calibrate()
704 unsigned long sample_rate = clk_get_rate(st->clk); in ad9467_calibrate()
705 struct device *dev = &st->spi->dev; in ad9467_calibrate()
706 bool invert = false, stat; in ad9467_calibrate() local
710 bitmap_fill(st->calib_map, st->calib_map_size); in ad9467_calibrate()
716 ret = ad9647_calibrate_polarity_set(st, invert); in ad9467_calibrate()
720 for (point = 0; point < st->info->test_points; point++) { in ad9467_calibrate()
725 for (c = 0; c < st->info->num_channels; c++) { in ad9467_calibrate()
726 ret = iio_backend_chan_status(st->back, c, &stat); in ad9467_calibrate()
737 point, invert, c); in ad9467_calibrate()
741 if (c == st->info->num_channels - 1) in ad9467_calibrate()
742 __clear_bit(point + invert * test_points, in ad9467_calibrate()
743 st->calib_map); in ad9467_calibrate()
747 if (!invert) { in ad9467_calibrate()
748 cnt = ad9467_find_optimal_point(st->calib_map, 0, test_points, in ad9467_calibrate()
756 invert = true; in ad9467_calibrate()
761 return -EIO; in ad9467_calibrate()
764 inv_cnt = ad9467_find_optimal_point(st->calib_map, test_points, in ad9467_calibrate()
767 return -EIO; in ad9467_calibrate()
776 * polarity inverted is the last test to run. Hence, there's no in ad9467_calibrate()
777 * need to re-do any configuration. We just need to "normalize" in ad9467_calibrate()
780 val = inv_val - test_points; in ad9467_calibrate()
783 if (st->info->has_dco) in ad9467_calibrate()
784 dev_dbg(dev, "%sDCO 0x%X CLK %lu Hz\n", inv_cnt >= cnt ? "INVERT " : "", in ad9467_calibrate()
787 dev_dbg(dev, "%sIDELAY 0x%x\n", inv_cnt >= cnt ? "INVERT " : "", in ad9467_calibrate()
808 *val = clk_get_rate(st->clk); in ad9467_read_raw()
812 return -EINVAL; in ad9467_read_raw()
821 const struct ad9467_chip_info *info = st->info; in ad9467_write_raw()
830 r_clk = clk_round_rate(st->clk, val); in ad9467_write_raw()
831 if (r_clk < 0 || r_clk > info->max_rate) { in ad9467_write_raw()
832 dev_warn(&st->spi->dev, in ad9467_write_raw()
834 return -EINVAL; in ad9467_write_raw()
837 sample_rate = clk_get_rate(st->clk); in ad9467_write_raw()
845 iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { in ad9467_write_raw()
846 ret = clk_set_rate(st->clk, r_clk); in ad9467_write_raw()
850 guard(mutex)(&st->lock); in ad9467_write_raw()
855 return -EINVAL; in ad9467_write_raw()
865 const struct ad9467_chip_info *info = st->info; in ad9467_read_avail()
869 *vals = (const int *)st->scales; in ad9467_read_avail()
872 *length = info->num_scales * 2; in ad9467_read_avail()
875 return -EINVAL; in ad9467_read_avail()
886 for (c = 0; c < st->info->num_channels; c++) { in ad9467_update_scan_mode()
888 ret = iio_backend_chan_enable(st->back, c); in ad9467_update_scan_mode()
890 ret = iio_backend_chan_disable(st->back, c); in ad9467_update_scan_mode()
908 const struct ad9467_chip_info *info = st->info; in ad9467_scale_fill()
911 st->scales = devm_kmalloc_array(&st->spi->dev, info->num_scales, in ad9467_scale_fill()
912 sizeof(*st->scales), GFP_KERNEL); in ad9467_scale_fill()
913 if (!st->scales) in ad9467_scale_fill()
914 return -ENOMEM; in ad9467_scale_fill()
916 for (i = 0; i < info->num_scales; i++) { in ad9467_scale_fill()
918 st->scales[i][0] = val1; in ad9467_scale_fill()
919 st->scales[i][1] = val2; in ad9467_scale_fill()
942 struct device *dev = &st->spi->dev; in ad9467_iio_backend_get()
945 st->back = devm_iio_backend_get(dev, NULL); in ad9467_iio_backend_get()
946 if (!IS_ERR(st->back)) in ad9467_iio_backend_get()
949 if (PTR_ERR(st->back) != -ENOENT) in ad9467_iio_backend_get()
950 return PTR_ERR(st->back); in ad9467_iio_backend_get()
954 * 'adi,adc-dev' property. So we get all nodes with that property, and in ad9467_iio_backend_get()
957 * make io-backends mandatory which would break DT ABI. in ad9467_iio_backend_get()
959 for_each_node_with_property(__back, "adi,adc-dev") { in ad9467_iio_backend_get()
962 __me = of_parse_phandle(__back, "adi,adc-dev", 0); in ad9467_iio_backend_get()
972 st->back = __devm_iio_backend_get_from_fwnode_lookup(dev, in ad9467_iio_backend_get()
975 return PTR_ERR_OR_ZERO(st->back); in ad9467_iio_backend_get()
978 return -ENODEV; in ad9467_iio_backend_get()
983 struct ad9467_state *st = s->private; in ad9467_test_mode_available_show()
986 for_each_set_bit(bit, &st->info->test_mask, st->info->test_mask_len) in ad9467_test_mode_available_show()
997 struct ad9467_chan_test_mode *chan = file->private_data; in ad9467_chan_test_mode_read()
998 struct ad9467_state *st = chan->st; in ad9467_chan_test_mode_read()
1003 if (chan->mode == AN877_ADC_TESTMODE_PN9_SEQ || in ad9467_chan_test_mode_read()
1004 chan->mode == AN877_ADC_TESTMODE_PN23_SEQ) { in ad9467_chan_test_mode_read()
1006 ad9467_test_modes[chan->mode]); in ad9467_chan_test_mode_read()
1008 ret = iio_backend_debugfs_print_chan_status(st->back, chan->idx, in ad9467_chan_test_mode_read()
1010 sizeof(buf) - len); in ad9467_chan_test_mode_read()
1014 } else if (chan->mode == AN877_ADC_TESTMODE_OFF) { in ad9467_chan_test_mode_read()
1018 ad9467_test_modes[chan->mode], chan->idx); in ad9467_chan_test_mode_read()
1028 struct ad9467_chan_test_mode *chan = file->private_data; in ad9467_chan_test_mode_write()
1029 struct ad9467_state *st = chan->st; in ad9467_chan_test_mode_write()
1034 ret = simple_write_to_buffer(test_mode, sizeof(test_mode) - 1, ppos, in ad9467_chan_test_mode_write()
1039 for_each_set_bit(mode, &st->info->test_mask, st->info->test_mask_len) { in ad9467_chan_test_mode_write()
1044 if (mode == st->info->test_mask_len) in ad9467_chan_test_mode_write()
1045 return -EINVAL; in ad9467_chan_test_mode_write()
1047 guard(mutex)(&st->lock); in ad9467_chan_test_mode_write()
1052 if (chan->mode == AN877_ADC_TESTMODE_PN9_SEQ || in ad9467_chan_test_mode_write()
1053 chan->mode == AN877_ADC_TESTMODE_PN23_SEQ) { in ad9467_chan_test_mode_write()
1054 ret = ad9467_backend_testmode_off(st, chan->idx); in ad9467_chan_test_mode_write()
1059 ret = ad9467_testmode_set(st, chan->idx, mode); in ad9467_chan_test_mode_write()
1063 out_mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; in ad9467_chan_test_mode_write()
1068 ret = ad9467_outputmode_set(st, st->info->default_output_mode); in ad9467_chan_test_mode_write()
1072 ret = ad9467_testmode_set(st, chan->idx, mode); in ad9467_chan_test_mode_write()
1078 ret = ad9467_backend_testmode_on(st, chan->idx, in ad9467_chan_test_mode_write()
1083 ret = ad9467_backend_testmode_on(st, chan->idx, in ad9467_chan_test_mode_write()
1090 chan->mode = mode; in ad9467_chan_test_mode_write()
1107 struct ad9467_state *st = file->private_data; in ad9467_dump_calib_table()
1113 guard(mutex)(&st->lock); in ad9467_dump_calib_table()
1117 for (bit = 0; bit < st->calib_map_size; bit++) { in ad9467_dump_calib_table()
1118 if (AD9467_CAN_INVERT(st) && bit == st->calib_map_size / 2) in ad9467_dump_calib_table()
1119 len += scnprintf(map + len, sizeof(map) - len, "\n"); in ad9467_dump_calib_table()
1121 len += scnprintf(map + len, sizeof(map) - len, "%c", in ad9467_dump_calib_table()
1122 test_bit(bit, st->calib_map) ? 'x' : 'o'); in ad9467_dump_calib_table()
1125 len += scnprintf(map + len, sizeof(map) - len, "\n"); in ad9467_dump_calib_table()
1147 st->chan_test = devm_kcalloc(&st->spi->dev, st->info->num_channels, in ad9467_debugfs_init()
1148 sizeof(*st->chan_test), GFP_KERNEL); in ad9467_debugfs_init()
1149 if (!st->chan_test) in ad9467_debugfs_init()
1155 for (chan = 0; chan < st->info->num_channels; chan++) { in ad9467_debugfs_init()
1158 st->chan_test[chan].idx = chan; in ad9467_debugfs_init()
1159 st->chan_test[chan].st = st; in ad9467_debugfs_init()
1160 debugfs_create_file(attr_name, 0600, d, &st->chan_test[chan], in ad9467_debugfs_init()
1167 iio_backend_debugfs_add(st->back, indio_dev); in ad9467_debugfs_init()
1177 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); in ad9467_probe()
1179 return -ENOMEM; in ad9467_probe()
1182 st->spi = spi; in ad9467_probe()
1184 st->info = spi_get_device_match_data(spi); in ad9467_probe()
1185 if (!st->info) in ad9467_probe()
1186 return -ENODEV; in ad9467_probe()
1188 st->calib_map_size = st->info->test_points; in ad9467_probe()
1190 st->calib_map_size *= 2; in ad9467_probe()
1192 st->clk = devm_clk_get_enabled(&spi->dev, "adc-clk"); in ad9467_probe()
1193 if (IS_ERR(st->clk)) in ad9467_probe()
1194 return PTR_ERR(st->clk); in ad9467_probe()
1196 st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown", in ad9467_probe()
1198 if (IS_ERR(st->pwrdown_gpio)) in ad9467_probe()
1199 return PTR_ERR(st->pwrdown_gpio); in ad9467_probe()
1201 ret = ad9467_reset(&spi->dev); in ad9467_probe()
1210 if (id != st->info->id) { in ad9467_probe()
1211 dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n", in ad9467_probe()
1212 id, st->info->id); in ad9467_probe()
1213 return -ENODEV; in ad9467_probe()
1216 if (st->info->num_scales > 1) in ad9467_probe()
1218 indio_dev->name = st->info->name; in ad9467_probe()
1219 indio_dev->channels = st->info->channels; in ad9467_probe()
1220 indio_dev->num_channels = st->info->num_channels; in ad9467_probe()
1221 indio_dev->info = &ad9467_info; in ad9467_probe()
1227 ret = devm_iio_backend_request_buffer(&spi->dev, st->back, indio_dev); in ad9467_probe()
1231 ret = devm_iio_backend_enable(&spi->dev, st->back); in ad9467_probe()
1239 ret = devm_iio_device_register(&spi->dev, indio_dev); in ad9467_probe()