]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iio: adc: ad7768-1: add low pass -3dB cutoff attribute
authorJonathan Santos <Jonathan.Santos@analog.com>
Wed, 11 Jun 2025 11:52:03 +0000 (08:52 -0300)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sun, 13 Jul 2025 14:36:24 +0000 (15:36 +0100)
Ad7768-1 has a different -3db frequency multiplier depending on
the filter type configured. The cutoff frequency also varies according
to the current ODR.

Add a readonly low pass -3dB frequency cutoff attribute to clarify to
the user which bandwidth is being allowed depending on the filter
configurations.

Reviewed-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
Reviewed-by: David Lechner <dlechner@baylibre.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
Link: https://patch.msgid.link/804d66f1858014d7278aec3344d81c223661e878.1749569957.git.Jonathan.Santos@analog.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/ad7768-1.c

index 72a960c7fb4e8095097e1994547ac061cd48c7ef..a2e061f0cb08ae3eeba4ce2b9a253d2816cadca4 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/sysfs.h>
 #include <linux/spi/spi.h>
 #include <linux/unaligned.h>
+#include <linux/units.h>
 #include <linux/util_macros.h>
 
 #include <linux/iio/buffer.h>
@@ -152,6 +153,14 @@ enum ad7768_scan_type {
        AD7768_SCAN_TYPE_HIGH_SPEED,
 };
 
+/* -3dB cutoff frequency multipliers (relative to ODR) for each filter type. */
+static const int ad7768_filter_3db_odr_multiplier[] = {
+       [AD7768_FILTER_SINC5] = 204,            /* 0.204 */
+       [AD7768_FILTER_SINC3] = 262,            /* 0.2617 */
+       [AD7768_FILTER_SINC3_REJ60] = 262,      /* 0.2617 */
+       [AD7768_FILTER_WIDEBAND] = 433,         /* 0.433 */
+};
+
 static const int ad7768_mclk_div_rates[] = {
        16, 8, 4, 2,
 };
@@ -746,6 +755,7 @@ static const struct iio_chan_spec ad7768_channels[] = {
                .type = IIO_VOLTAGE,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
+                                           BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) |
                                            BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
                .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
@@ -766,7 +776,7 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
 {
        struct ad7768_state *st = iio_priv(indio_dev);
        const struct iio_scan_type *scan_type;
-       int scale_uv, ret;
+       int scale_uv, ret, temp;
 
        scan_type = iio_get_current_scan_type(indio_dev, chan);
        if (IS_ERR(scan_type))
@@ -804,6 +814,12 @@ static int ad7768_read_raw(struct iio_dev *indio_dev,
        case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
                *val = st->oversampling_ratio;
 
+               return IIO_VAL_INT;
+
+       case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+               temp = st->samp_freq * ad7768_filter_3db_odr_multiplier[st->filter_type];
+               *val = DIV_ROUND_CLOSEST(temp, MILLI);
+
                return IIO_VAL_INT;
        }