Commit bdc87f98 authored by Nuno Sa's avatar Nuno Sa Committed by Jonathan Cameron
Browse files

iio: adc: ad9467: add new chip_info variables



Add new variables to the per chip info structure:

* test_points: Number of valid test points for calibration;
* has_dco_invert: Supports inverting DCO (Data clock output) polarity;
* dco_en: Specicic mask to enable DCO delays.

This is in preparation for supporting new parts with subtle differences
in how to configure the hardware.

Note that with the new test_points variable, we also add a new
calib_map_size to 'struct ad9467_state' so we know our map size
depending on how many test points we have and if we can run the
calibration in the inverted state or not.

Signed-off-by: default avatarNuno Sa <nuno.sa@analog.com>
Link: https://patch.msgid.link/20240704-dev-iio-ad9467-new-devs-v1-2-f1adfee921f7@analog.com


Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 7394a155
Loading
Loading
Loading
Loading
+29 −9
Original line number Diff line number Diff line
@@ -105,6 +105,8 @@
#define AD9467_REG_VREF_MASK		0x0F

#define AD9647_MAX_TEST_POINTS		32
#define AD9467_CAN_INVERT(st)	\
	(!(st)->info->has_dco || (st)->info->has_dco_invert)

struct ad9467_chip_info {
	const char *name;
@@ -117,8 +119,11 @@ struct ad9467_chip_info {
	unsigned int default_output_mode;
	unsigned int vref_mask;
	unsigned int num_lanes;
	unsigned int dco_en;
	unsigned int test_points;
	/* data clock output */
	bool has_dco;
	bool has_dco_invert;
};

struct ad9467_state {
@@ -138,6 +143,8 @@ struct ad9467_state {
	 * at the io delay control section.
	 */
	DECLARE_BITMAP(calib_map, AD9647_MAX_TEST_POINTS * 2);
	/* number of bits of the map */
	unsigned int calib_map_size;
	struct gpio_desc *pwrdown_gpio;
	/* ensure consistent state obtained on multiple related accesses */
	struct mutex lock;
@@ -256,6 +263,7 @@ static const struct ad9467_chip_info ad9467_chip_tbl = {
	.num_scales = ARRAY_SIZE(ad9467_scale_table),
	.channels = ad9467_channels,
	.num_channels = ARRAY_SIZE(ad9467_channels),
	.test_points = AD9647_MAX_TEST_POINTS,
	.default_output_mode = AD9467_DEF_OUTPUT_MODE,
	.vref_mask = AD9467_REG_VREF_MASK,
	.num_lanes = 8,
@@ -269,6 +277,7 @@ static const struct ad9467_chip_info ad9434_chip_tbl = {
	.num_scales = ARRAY_SIZE(ad9434_scale_table),
	.channels = ad9434_channels,
	.num_channels = ARRAY_SIZE(ad9434_channels),
	.test_points = AD9647_MAX_TEST_POINTS,
	.default_output_mode = AD9434_DEF_OUTPUT_MODE,
	.vref_mask = AD9434_REG_VREF_MASK,
	.num_lanes = 6,
@@ -282,9 +291,11 @@ static const struct ad9467_chip_info ad9265_chip_tbl = {
	.num_scales = ARRAY_SIZE(ad9265_scale_table),
	.channels = ad9467_channels,
	.num_channels = ARRAY_SIZE(ad9467_channels),
	.test_points = AD9647_MAX_TEST_POINTS,
	.default_output_mode = AD9265_DEF_OUTPUT_MODE,
	.vref_mask = AD9265_REG_VREF_MASK,
	.has_dco = true,
	.has_dco_invert = true,
};

static int ad9467_get_scale(struct ad9467_state *st, int *val, int *val2)
@@ -468,7 +479,7 @@ static int ad9467_calibrate_apply(struct ad9467_state *st, unsigned int val)

	if (st->info->has_dco) {
		ret = ad9467_spi_write(st, AN877_ADC_REG_OUTPUT_DELAY,
				       val);
				       val | st->info->dco_en);
		if (ret)
			return ret;

@@ -524,14 +535,14 @@ static int ad9467_calibrate(struct ad9467_state *st)
	 * Half of the bitmap is for the inverted signal. The number of test
	 * points is the same though...
	 */
	unsigned int test_points = AD9647_MAX_TEST_POINTS;
	unsigned int test_points = st->info->test_points;
	unsigned long sample_rate = clk_get_rate(st->clk);
	struct device *dev = &st->spi->dev;
	bool invert = false, stat;
	int ret;

	/* all points invalid */
	bitmap_fill(st->calib_map, BITS_PER_TYPE(st->calib_map));
	bitmap_fill(st->calib_map, st->calib_map_size);

	ret = ad9647_calibrate_prepare(st);
	if (ret)
@@ -541,7 +552,7 @@ static int ad9467_calibrate(struct ad9467_state *st)
	if (ret)
		return ret;

	for (point = 0; point < test_points; point++) {
	for (point = 0; point < st->info->test_points; point++) {
		ret = ad9467_calibrate_apply(st, point);
		if (ret)
			return ret;
@@ -576,9 +587,14 @@ static int ad9467_calibrate(struct ad9467_state *st)
		 * a row.
		 */
		if (cnt < 3) {
			if (AD9467_CAN_INVERT(st)) {
				invert = true;
				goto retune;
			}

			if (!cnt)
				return -EIO;
		}
	} else {
		inv_cnt = ad9467_find_optimal_point(st->calib_map, test_points,
						    test_points, &inv_val);
@@ -802,7 +818,7 @@ static ssize_t ad9467_dump_calib_table(struct file *file,
				       size_t count, loff_t *ppos)
{
	struct ad9467_state *st = file->private_data;
	unsigned int bit, size = BITS_PER_TYPE(st->calib_map);
	unsigned int bit;
	/* +2 for the newline and +1 for the string termination */
	unsigned char map[AD9647_MAX_TEST_POINTS * 2 + 3];
	ssize_t len = 0;
@@ -811,8 +827,8 @@ static ssize_t ad9467_dump_calib_table(struct file *file,
	if (*ppos)
		goto out_read;

	for (bit = 0; bit < size; bit++) {
		if (bit == size / 2)
	for (bit = 0; bit < st->calib_map_size; bit++) {
		if (AD9467_CAN_INVERT(st) && bit == st->calib_map_size / 2)
			len += scnprintf(map + len, sizeof(map) - len, "\n");

		len += scnprintf(map + len, sizeof(map) - len, "%c",
@@ -861,6 +877,10 @@ static int ad9467_probe(struct spi_device *spi)
	if (!st->info)
		return -ENODEV;

	st->calib_map_size = st->info->test_points;
	if (AD9467_CAN_INVERT(st))
		st->calib_map_size *= 2;

	st->clk = devm_clk_get_enabled(&spi->dev, "adc-clk");
	if (IS_ERR(st->clk))
		return PTR_ERR(st->clk);