lkml.org 
[lkml]   [2020]   [Feb]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH] iio: adc: ad7124: add 3db filter
    On Wed, 22 Jan 2020 10:54:14 +0200
    Alexandru Tachici <alexandru.tachici@analog.com> wrote:

    > This patch adds the LOW_PASS_FILTER_3DB_FREQUENCY attribute
    > in iio_chan_spec for each channel. The used filters are sinc3
    > or sinc4. The filter type with the highest output data rate
    > is used when setting a low pass frequency in the channel's sysfs.
    >
    > Signed-off-by: Alexandru Tachici <alexandru.tachici@analog.com>

    Applied to the togreg branch of iio.git and pushed out as testing for
    the autobuilders to play with it.

    thanks,

    Jonathan

    > ---
    > drivers/iio/adc/ad7124.c | 69 +++++++++++++++++++++++++++++++++++++++-
    > 1 file changed, 68 insertions(+), 1 deletion(-)
    >
    > diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c
    > index 52f45b13da4a..8f48c0581f02 100644
    > --- a/drivers/iio/adc/ad7124.c
    > +++ b/drivers/iio/adc/ad7124.c
    > @@ -70,6 +70,11 @@
    > /* AD7124_FILTER_X */
    > #define AD7124_FILTER_FS_MSK GENMASK(10, 0)
    > #define AD7124_FILTER_FS(x) FIELD_PREP(AD7124_FILTER_FS_MSK, x)
    > +#define AD7124_FILTER_TYPE_MSK GENMASK(23, 21)
    > +#define AD7124_FILTER_TYPE_SEL(x) FIELD_PREP(AD7124_FILTER_TYPE_MSK, x)
    > +
    > +#define AD7124_SINC3_FILTER 2
    > +#define AD7124_SINC4_FILTER 0
    >
    > enum ad7124_ids {
    > ID_AD7124_4,
    > @@ -119,6 +124,7 @@ struct ad7124_channel_config {
    > unsigned int vref_mv;
    > unsigned int pga_bits;
    > unsigned int odr;
    > + unsigned int filter_type;
    > };
    >
    > struct ad7124_state {
    > @@ -138,7 +144,8 @@ static const struct iio_chan_spec ad7124_channel_template = {
    > .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    > BIT(IIO_CHAN_INFO_SCALE) |
    > BIT(IIO_CHAN_INFO_OFFSET) |
    > - BIT(IIO_CHAN_INFO_SAMP_FREQ),
    > + BIT(IIO_CHAN_INFO_SAMP_FREQ) |
    > + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
    > .scan_type = {
    > .sign = 'u',
    > .realbits = 24,
    > @@ -281,6 +288,58 @@ static int ad7124_set_channel_gain(struct ad7124_state *st,
    > return 0;
    > }
    >
    > +static int ad7124_get_3db_filter_freq(struct ad7124_state *st,
    > + unsigned int channel)
    > +{
    > + unsigned int fadc;
    > +
    > + fadc = st->channel_config[channel].odr;
    > +
    > + switch (st->channel_config[channel].filter_type) {
    > + case AD7124_SINC3_FILTER:
    > + return DIV_ROUND_CLOSEST(fadc * 230, 1000);
    > + case AD7124_SINC4_FILTER:
    > + return DIV_ROUND_CLOSEST(fadc * 262, 1000);
    > + default:
    > + return -EINVAL;
    > + }
    > +}
    > +
    > +static int ad7124_set_3db_filter_freq(struct ad7124_state *st,
    > + unsigned int channel,
    > + unsigned int freq)
    > +{
    > + unsigned int sinc4_3db_odr;
    > + unsigned int sinc3_3db_odr;
    > + unsigned int new_filter;
    > + unsigned int new_odr;
    > +
    > + sinc4_3db_odr = DIV_ROUND_CLOSEST(freq * 1000, 230);
    > + sinc3_3db_odr = DIV_ROUND_CLOSEST(freq * 1000, 262);
    > +
    > + if (sinc4_3db_odr > sinc3_3db_odr) {
    > + new_filter = AD7124_SINC3_FILTER;
    > + new_odr = sinc4_3db_odr;
    > + } else {
    > + new_filter = AD7124_SINC4_FILTER;
    > + new_odr = sinc3_3db_odr;
    > + }
    > +
    > + if (st->channel_config[channel].filter_type != new_filter) {
    > + int ret;
    > +
    > + st->channel_config[channel].filter_type = new_filter;
    > + ret = ad7124_spi_write_mask(st, AD7124_FILTER(channel),
    > + AD7124_FILTER_TYPE_MSK,
    > + AD7124_FILTER_TYPE_SEL(new_filter),
    > + 3);
    > + if (ret < 0)
    > + return ret;
    > + }
    > +
    > + return ad7124_set_channel_odr(st, channel, new_odr);
    > +}
    > +
    > static int ad7124_read_raw(struct iio_dev *indio_dev,
    > struct iio_chan_spec const *chan,
    > int *val, int *val2, long info)
    > @@ -322,6 +381,9 @@ static int ad7124_read_raw(struct iio_dev *indio_dev,
    > case IIO_CHAN_INFO_SAMP_FREQ:
    > *val = st->channel_config[chan->address].odr;
    >
    > + return IIO_VAL_INT;
    > + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
    > + *val = ad7124_get_3db_filter_freq(st, chan->scan_index);
    > return IIO_VAL_INT;
    > default:
    > return -EINVAL;
    > @@ -355,6 +417,11 @@ static int ad7124_write_raw(struct iio_dev *indio_dev,
    > gain = DIV_ROUND_CLOSEST(res, val2);
    >
    > return ad7124_set_channel_gain(st, chan->address, gain);
    > + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
    > + if (val2 != 0)
    > + return -EINVAL;
    > +
    > + return ad7124_set_3db_filter_freq(st, chan->address, val);
    > default:
    > return -EINVAL;
    > }

    \
     
     \ /
      Last update: 2020-02-02 17:23    [W:4.951 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site