]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iio: adc: ad9467: add new chip_info variables
authorNuno Sa <nuno.sa@analog.com>
Thu, 4 Jul 2024 09:25:22 +0000 (11:25 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Mon, 29 Jul 2024 19:31:11 +0000 (20:31 +0100)
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: Nuno Sa <nuno.sa@analog.com>
Link: https://patch.msgid.link/20240704-dev-iio-ad9467-new-devs-v1-2-f1adfee921f7@analog.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/ad9467.c

index 1d8270a5bccbf88027b1afbfa22a1ce38d782221..077c3a594bfc4a017895ffcfd4bf1442470cf36f 100644 (file)
 #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 @@ retune:
        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,8 +587,13 @@ retune:
                 * a row.
                 */
                if (cnt < 3) {
-                       invert = true;
-                       goto retune;
+                       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,
@@ -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);