[PATCH v3 06/14] iio: adc: ad7768: Add configurable sampling modes
From: Janani Sunil
Date: Thu Aug 13 2026 - 10:02:29 EST
Derive the available output data rates from MCLK and expose per-channel
sampling frequency and filter controls.
Select the fastest compatible power mode for the enabled channels and
map matching sampling frequency and filter combinations onto the two
hardware channel profiles. Configure the data clock divider and wait for
the selected filters to settle before capture.
Signed-off-by: Janani Sunil <janani.sunil@xxxxxxxxxx>
---
drivers/iio/adc/ad7768.c | 507 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 477 insertions(+), 30 deletions(-)
diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c
index 9b908ce0a1c3..3849f544a1e5 100644
--- a/drivers/iio/adc/ad7768.c
+++ b/drivers/iio/adc/ad7768.c
@@ -13,6 +13,7 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
+#include <linux/log2.h>
#include <linux/math.h>
#include <linux/minmax.h>
#include <linux/module.h>
@@ -94,8 +95,17 @@
#define AD7768_SPI_REG_MASK GENMASK(14, 8)
#define AD7768_SPI_DATA_MASK GENMASK(7, 0)
#define AD7768_SAMPLE_SIZE 32
+#define MAX_FREQ_PER_MODE 6
#define AD7768_MAX_CHANNEL 8
+#define AD7768_NUM_CHANNEL_MODES 2
#define AD7768_REV_ID_VAL 0x06
+#define AD7768_WIDEBAND_SETTLING_SAMPLES 68
+#define AD7768_SINC5_SETTLING_SAMPLES 7
+
+enum ad7768_filter_type {
+ AD7768_FILTER_TYPE_WIDEBAND,
+ AD7768_FILTER_TYPE_SINC5,
+};
enum ad7768_power_modes {
AD7768_LOW_POWER_MODE,
@@ -104,6 +114,8 @@ enum ad7768_power_modes {
AD7768_NUM_POWER_MODES
};
+#define AD7768_MAX_FREQS (MAX_FREQ_PER_MODE + AD7768_NUM_POWER_MODES)
+
struct ad7768_precharge_config {
bool prebufp_en;
bool prebufn_en;
@@ -111,6 +123,17 @@ struct ad7768_precharge_config {
bool refbufn;
};
+struct ad7768_freq_config {
+ unsigned int freq_hz;
+ unsigned int dec_rate;
+};
+
+struct ad7768_avail_freq {
+ unsigned int n_freqs;
+ unsigned int freqs[MAX_FREQ_PER_MODE];
+ struct ad7768_freq_config freq_cfg[MAX_FREQ_PER_MODE];
+};
+
struct ad7768_chip_info {
const char *name;
unsigned int num_channels;
@@ -126,12 +149,26 @@ struct ad7768_state {
struct mutex lock; /* Protects device register access and configuration */
struct clk *mclk;
unsigned int datalines;
+ enum ad7768_power_modes power_mode;
const struct ad7768_chip_info *chip_info;
+ struct ad7768_avail_freq avail_freq[AD7768_NUM_POWER_MODES];
+ unsigned int n_freqs;
+ int freqs[AD7768_MAX_FREQS];
+ unsigned int ch_freq[AD7768_MAX_CHANNEL];
+ enum ad7768_filter_type ch_filter[AD7768_MAX_CHANNEL];
struct iio_backend *back;
__be16 d16 __aligned(IIO_DMA_MINALIGN);
};
+static const int ad7768_dec_rate[MAX_FREQ_PER_MODE] = {
+ 32, 64, 128, 256, 512, 1024,
+};
+
+static const int ad7768_mclk_div[3] = {
+ 32, 8, 4,
+};
+
static const unsigned int ad7768_available_datalines[] = {
1, 2, 8,
};
@@ -323,61 +360,253 @@ static int ad7768_sync(struct ad7768_state *st)
FIELD_PREP(AD7768_DATA_CONTROL_SPI_SYNC_MSK, 1));
}
-static int ad7768_configure_capture(struct ad7768_state *st)
+static int ad7768_set_power_mode(struct ad7768_state *st, unsigned int mode)
{
- unsigned int dclk_div;
unsigned int regval;
int ret;
- regval = ad7768_map_power_mode_to_regval(AD7768_FAST_MODE);
+ if (mode >= AD7768_NUM_POWER_MODES)
+ return -EINVAL;
+
+ regval = ad7768_map_power_mode_to_regval(mode);
ret = regmap_update_bits(st->regmap, AD7768_REG_POWER_MODE,
- AD7768_POWER_MODE_POWER_MODE_MSK |
- AD7768_POWER_MODE_MCLK_DIV_MSK,
- AD7768_POWER_MODE_POWER_MODE(regval) |
- FIELD_PREP(AD7768_POWER_MODE_MCLK_DIV_MSK, regval));
+ AD7768_POWER_MODE_POWER_MODE_MSK,
+ AD7768_POWER_MODE_POWER_MODE(regval));
if (ret)
return ret;
- /*
- * Start with the wideband filter and a decimation rate of 64. This
- * supports every valid data-line configuration at the maximum MCLK.
- */
- ret = regmap_update_bits(st->regmap, AD7768_REG_CH_MODE(0),
- AD7768_CH_MODE_FILTER_TYPE_MSK |
- AD7768_CH_MODE_DEC_RATE_MSK,
- AD7768_CH_MODE_FILTER_TYPE_MODE(0) |
- AD7768_CH_MODE_DEC_RATE_MODE(1));
+ ret = regmap_update_bits(st->regmap, AD7768_REG_POWER_MODE,
+ AD7768_POWER_MODE_MCLK_DIV_MSK,
+ FIELD_PREP(AD7768_POWER_MODE_MCLK_DIV_MSK, regval));
if (ret)
return ret;
- ret = regmap_write(st->regmap, AD7768_REG_CH_MODE_SEL, 0);
+ ret = ad7768_sync(st);
if (ret)
return ret;
- dclk_div = 8 * st->datalines / st->chip_info->num_channels;
- ret = regmap_update_bits(st->regmap, AD7768_REG_INTERFACE_CFG,
- AD7768_INTERFACE_CFG_DCLK_DIV_MSK,
- AD7768_INTERFACE_CFG_DCLK_DIV_MODE(dclk_div));
- if (ret)
- return ret;
+ st->power_mode = mode;
- return ad7768_sync(st);
+ return 0;
}
-static int ad7768_update_scan_mode(struct iio_dev *indio_dev,
- const unsigned long *scan_mask)
+static int ad7768_set_clk_divs(struct ad7768_state *st,
+ unsigned int freq)
+{
+ unsigned int mclk, dclk, dclk_div, i;
+ struct ad7768_freq_config f_cfg = {};
+ unsigned int chan_per_doutx;
+
+ mclk = clk_get_rate(st->mclk);
+
+ chan_per_doutx = st->chip_info->num_channels / st->datalines;
+ if (!chan_per_doutx)
+ return -EINVAL;
+
+ for (i = 0; i < st->avail_freq[st->power_mode].n_freqs; i++) {
+ f_cfg = st->avail_freq[st->power_mode].freq_cfg[i];
+ if (freq == f_cfg.freq_hz)
+ break;
+ }
+
+ if (i == st->avail_freq[st->power_mode].n_freqs)
+ return -EINVAL;
+
+ dclk = f_cfg.freq_hz * AD7768_SAMPLE_SIZE * chan_per_doutx;
+ if (!dclk || dclk > mclk)
+ return -EINVAL;
+
+ /* Set dclk_div to the nearest power of 2 less than the original value */
+ dclk_div = DIV_ROUND_CLOSEST(mclk, dclk);
+ if (dclk_div > AD7768_MAX_DCLK_DIV)
+ dclk_div = AD7768_MAX_DCLK_DIV;
+ else
+ dclk_div = rounddown_pow_of_two(dclk_div);
+
+ return regmap_update_bits(st->regmap, AD7768_REG_INTERFACE_CFG,
+ AD7768_INTERFACE_CFG_DCLK_DIV_MSK,
+ AD7768_INTERFACE_CFG_DCLK_DIV_MODE(dclk_div));
+}
+
+static bool ad7768_freq_supported(const struct ad7768_state *st,
+ unsigned int mode, unsigned int freq)
+{
+ for (unsigned int i = 0; i < st->avail_freq[mode].n_freqs; i++) {
+ if (freq == st->avail_freq[mode].freq_cfg[i].freq_hz)
+ return true;
+ }
+
+ return false;
+}
+
+static bool ad7768_freq_supported_in_any_mode(const struct ad7768_state *st,
+ unsigned int freq)
+{
+ for (unsigned int mode = 0; mode < AD7768_NUM_POWER_MODES; mode++) {
+ if (ad7768_freq_supported(st, mode, freq))
+ return true;
+ }
+
+ return false;
+}
+
+static int ad7768_set_lowest_noise_mode(struct ad7768_state *st,
+ const unsigned long *scan_mask)
+{
+ unsigned int channel;
+ unsigned int mode = AD7768_NUM_POWER_MODES;
+
+ /*
+ * The output data rate ranges overlap between the power modes. At a
+ * common ODR, the faster mode has lower noise, so prefer the fastest
+ * mode that supports every enabled channel.
+ */
+ while (mode--) {
+ for (channel = 0; channel < st->chip_info->num_channels; channel++) {
+ if (test_bit(channel, scan_mask) &&
+ !ad7768_freq_supported(st, mode, st->ch_freq[channel]))
+ break;
+ }
+
+ if (channel == st->chip_info->num_channels)
+ return ad7768_set_power_mode(st, mode);
+ }
+
+ return -EINVAL;
+}
+
+static int ad7768_set_mode_decimation(struct ad7768_state *st,
+ unsigned int freq, unsigned int mode)
+{
+ struct ad7768_freq_config f_cfg = {};
+ unsigned int i;
+
+ for (i = 0; i < st->avail_freq[st->power_mode].n_freqs; i++) {
+ f_cfg = st->avail_freq[st->power_mode].freq_cfg[i];
+ if (freq == f_cfg.freq_hz)
+ break;
+ }
+
+ if (i == st->avail_freq[st->power_mode].n_freqs)
+ return -EINVAL;
+
+ return regmap_update_bits(st->regmap, AD7768_REG_CH_MODE(mode),
+ AD7768_CH_MODE_DEC_RATE_MSK,
+ AD7768_CH_MODE_DEC_RATE_MODE(f_cfg.dec_rate));
+}
+
+static int ad7768_set_sampling_freq(struct iio_dev *indio_dev,
+ unsigned int freq, unsigned int ch)
+{
+ struct ad7768_state *st = iio_priv(indio_dev);
+
+ if (!freq)
+ return -EINVAL;
+
+ if (!ad7768_freq_supported_in_any_mode(st, freq))
+ return -EINVAL;
+
+ guard(mutex)(&st->lock);
+
+ st->ch_freq[ch] = freq;
+
+ return 0;
+}
+
+static void ad7768_filter_wait(const unsigned int *mode_freq,
+ const enum ad7768_filter_type *mode_filter,
+ const bool *mode_used)
+{
+ unsigned int t_settle_us = 0;
+
+ for (unsigned int mode = 0; mode < AD7768_NUM_CHANNEL_MODES; mode++) {
+ unsigned int t_mode_us;
+ unsigned int settling_samples;
+
+ if (!mode_used[mode] || !mode_freq[mode])
+ continue;
+
+ if (mode_filter[mode] == AD7768_FILTER_TYPE_SINC5)
+ settling_samples = AD7768_SINC5_SETTLING_SAMPLES;
+ else
+ settling_samples = AD7768_WIDEBAND_SETTLING_SAMPLES;
+
+ t_mode_us = DIV_ROUND_UP(settling_samples * USEC_PER_SEC,
+ mode_freq[mode]);
+ t_settle_us = max(t_settle_us, t_mode_us);
+ }
+
+ if (t_settle_us)
+ fsleep(t_settle_us);
+}
+
+static int ad7768_find_matching_mode(const bool *mode_used,
+ const unsigned int *mode_freq,
+ const enum ad7768_filter_type *mode_filter,
+ unsigned int freq,
+ enum ad7768_filter_type filter)
+{
+ unsigned int mode;
+
+ for (mode = 0; mode < AD7768_NUM_CHANNEL_MODES; mode++) {
+ if (!mode_used[mode] ||
+ (mode_freq[mode] == freq && mode_filter[mode] == filter))
+ return mode;
+ }
+
+ return -EINVAL;
+}
+
+static int ad7768_apply_channel_modes(struct iio_dev *indio_dev,
+ const unsigned long *scan_mask)
{
struct ad7768_state *st = iio_priv(indio_dev);
+ unsigned int mode_freq[AD7768_NUM_CHANNEL_MODES];
+ enum ad7768_filter_type mode_filter[AD7768_NUM_CHANNEL_MODES];
+ bool mode_used[AD7768_NUM_CHANNEL_MODES] = { };
unsigned int channel_mask;
unsigned int standby_mask;
+ unsigned int max_freq = 0;
unsigned int c;
- int ret;
+ int mode, ret;
+
+ guard(mutex)(&st->lock);
+
+ ret = ad7768_set_lowest_noise_mode(st, scan_mask);
+ if (ret == -EINVAL)
+ return dev_err_probe(regmap_get_device(st->regmap), ret,
+ "No power mode supports all enabled channel frequencies\n");
+ if (ret)
+ return ret;
channel_mask = ad7768_all_channels_mask(st);
standby_mask = channel_mask;
+
for (c = 0; c < st->chip_info->num_channels; c++) {
- if (test_bit(c, scan_mask))
- standby_mask &= ~ad7768_channel_mask(st, c);
+ unsigned int mask;
+
+ if (!test_bit(c, scan_mask))
+ continue;
+
+ standby_mask &= ~ad7768_channel_mask(st, c);
+
+ mode = ad7768_find_matching_mode(mode_used, mode_freq,
+ mode_filter, st->ch_freq[c],
+ st->ch_filter[c]);
+ if (mode < 0)
+ return dev_err_probe(regmap_get_device(st->regmap), -EINVAL,
+ "Enabled channels require more than %d mode profiles\n",
+ AD7768_NUM_CHANNEL_MODES);
+
+ mode_freq[mode] = st->ch_freq[c];
+ mode_filter[mode] = st->ch_filter[c];
+ mode_used[mode] = true;
+
+ mask = ad7768_channel_mask(st, c);
+ ret = regmap_update_bits(st->regmap, AD7768_REG_CH_MODE_SEL,
+ mask, mode ? mask : 0);
+ if (ret)
+ return ret;
}
ret = regmap_update_bits(st->regmap, AD7768_REG_CH_STANDBY,
@@ -385,6 +614,117 @@ static int ad7768_update_scan_mode(struct iio_dev *indio_dev,
if (ret)
return ret;
+ for (mode = 0; mode < AD7768_NUM_CHANNEL_MODES; mode++) {
+ if (!mode_used[mode])
+ continue;
+
+ ret = ad7768_set_mode_decimation(st, mode_freq[mode], mode);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(st->regmap, AD7768_REG_CH_MODE(mode),
+ AD7768_CH_MODE_FILTER_TYPE_MSK,
+ AD7768_CH_MODE_FILTER_TYPE_MODE(mode_filter[mode]));
+ if (ret)
+ return ret;
+
+ max_freq = max(max_freq, mode_freq[mode]);
+ }
+
+ ret = ad7768_set_clk_divs(st, max_freq);
+ if (ret)
+ return ret;
+
+ ret = ad7768_sync(st);
+ if (ret)
+ return ret;
+
+ /* Apply a filter settling time (Datasheet table 35 and 36) */
+ ad7768_filter_wait(mode_freq, mode_filter, mode_used);
+
+ return 0;
+}
+
+static int ad7768_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long info)
+{
+ struct ad7768_state *st = iio_priv(indio_dev);
+ int ret;
+
+ PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(regmap_get_device(st->regmap), pm);
+ ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+ if (ret)
+ return ret;
+
+ if (info != IIO_CHAN_INFO_SAMP_FREQ)
+ return -EINVAL;
+
+ guard(mutex)(&st->lock);
+ *val = st->ch_freq[chan->channel];
+
+ return IIO_VAL_INT;
+}
+
+static int ad7768_write_raw_get_fmt(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, long info)
+{
+ if (info == IIO_CHAN_INFO_SAMP_FREQ)
+ return IIO_VAL_INT;
+
+ return -EINVAL;
+}
+
+static int ad7768_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long info)
+{
+ struct ad7768_state *st = iio_priv(indio_dev);
+ int ret;
+
+ IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
+ if (IIO_DEV_ACQUIRE_FAILED(claim))
+ return -EBUSY;
+
+ PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(regmap_get_device(st->regmap), pm);
+ ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+ if (ret)
+ return ret;
+
+ if (info == IIO_CHAN_INFO_SAMP_FREQ)
+ return ad7768_set_sampling_freq(indio_dev, val, chan->channel);
+
+ return -EINVAL;
+}
+
+static int ad7768_read_avail(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ const int **vals, int *type, int *length,
+ long info)
+{
+ struct ad7768_state *st = iio_priv(indio_dev);
+
+ if (info != IIO_CHAN_INFO_SAMP_FREQ)
+ return -EINVAL;
+
+ *vals = st->freqs;
+ *type = IIO_VAL_INT;
+ *length = st->n_freqs;
+
+ return IIO_AVAIL_LIST;
+}
+
+static int ad7768_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *scan_mask)
+{
+ struct ad7768_state *st = iio_priv(indio_dev);
+ unsigned int c;
+ int ret;
+
+ ret = ad7768_apply_channel_modes(indio_dev, scan_mask);
+ if (ret)
+ return ret;
+
for (c = 0; c < st->chip_info->num_channels; c++) {
if (test_bit(c, scan_mask))
ret = iio_backend_chan_enable(st->back, c);
@@ -439,9 +779,73 @@ static const struct iio_buffer_setup_ops ad7768_buffer_ops = {
static const struct iio_info ad7768_info = {
.debugfs_reg_access = ad7768_reg_access,
+ .read_raw = ad7768_read_raw,
+ .write_raw_get_fmt = ad7768_write_raw_get_fmt,
+ .write_raw = ad7768_write_raw,
+ .read_avail = ad7768_read_avail,
.update_scan_mode = ad7768_update_scan_mode,
};
+static void ad7768_set_available_sampl_freq(struct ad7768_state *st)
+{
+ struct ad7768_avail_freq *avail_freq;
+ unsigned int mclk = clk_get_rate(st->mclk);
+ unsigned int mode;
+
+ for (mode = 0; mode < AD7768_NUM_POWER_MODES; mode++) {
+ avail_freq = &st->avail_freq[mode];
+ for (unsigned int dec = ARRAY_SIZE(ad7768_dec_rate); dec > 0; dec--) {
+ struct ad7768_freq_config freq_cfg;
+
+ freq_cfg.dec_rate = dec - 1;
+ freq_cfg.freq_hz = mclk / (ad7768_dec_rate[dec - 1] *
+ ad7768_mclk_div[mode]);
+ avail_freq->freqs[avail_freq->n_freqs] = freq_cfg.freq_hz;
+ avail_freq->freq_cfg[avail_freq->n_freqs++] = freq_cfg;
+ }
+ }
+
+ if (st->datalines == 1 &&
+ st->chip_info->num_channels == AD7768_MAX_CHANNEL)
+ st->avail_freq[AD7768_FAST_MODE].n_freqs--;
+
+ for (mode = 0; mode < AD7768_NUM_POWER_MODES; mode++) {
+ avail_freq = &st->avail_freq[mode];
+ for (unsigned int i = 0; i < avail_freq->n_freqs; i++) {
+ unsigned int freq = avail_freq->freqs[i];
+
+ if (st->n_freqs && st->freqs[st->n_freqs - 1] >= freq)
+ continue;
+
+ st->freqs[st->n_freqs++] = freq;
+ }
+ }
+}
+
+static int ad7768_set_filter_mode(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ unsigned int mode)
+{
+ struct ad7768_state *st = iio_priv(indio_dev);
+
+ IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
+ if (IIO_DEV_ACQUIRE_FAILED(claim))
+ return -EBUSY;
+
+ guard(mutex)(&st->lock);
+ st->ch_filter[chan->channel] = mode;
+ return 0;
+}
+
+static int ad7768_get_filter_mode(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+{
+ struct ad7768_state *st = iio_priv(indio_dev);
+
+ guard(mutex)(&st->lock);
+ return st->ch_filter[chan->channel];
+}
+
static int ad7768_configure_precharge_buffers(struct iio_dev *indio_dev,
struct ad7768_precharge_config *precharge_cfg)
{
@@ -487,16 +891,37 @@ static int ad7768_configure_precharge_buffers(struct iio_dev *indio_dev,
return regmap_write(st->regmap, AD7768_REG_REFN_BUF, refbufn_val);
}
+static const char *const ad7768_filter_types[] = {
+ [AD7768_FILTER_TYPE_WIDEBAND] = "wideband",
+ [AD7768_FILTER_TYPE_SINC5] = "sinc5",
+};
+
+static const struct iio_enum ad7768_filter_types_enum = {
+ .items = ad7768_filter_types,
+ .num_items = ARRAY_SIZE(ad7768_filter_types),
+ .set = ad7768_set_filter_mode,
+ .get = ad7768_get_filter_mode,
+};
+
+static struct iio_chan_spec_ext_info ad7768_ext_info[] = {
+ IIO_ENUM("filter_type", IIO_SEPARATE,
+ &ad7768_filter_types_enum),
+ IIO_ENUM_AVAILABLE("filter_type", IIO_SEPARATE, &ad7768_filter_types_enum),
+ {}
+};
+
static int ad7768_parse_config(struct iio_dev *indio_dev,
struct device *dev)
{
struct ad7768_state *st = iio_priv(indio_dev);
+ const struct ad7768_avail_freq *avail_freq;
const unsigned int *available_datalines;
struct ad7768_precharge_config precharge_cfg[AD7768_MAX_CHANNEL] = { };
struct iio_chan_spec *chan;
unsigned int num_channels;
unsigned int channel;
unsigned int i, len;
+ unsigned int default_freq;
int chan_idx = 0;
int ret;
@@ -558,6 +983,9 @@ static int ad7768_parse_config(struct iio_dev *indio_dev,
chan[chan_idx] = (struct iio_chan_spec) {
.type = IIO_VOLTAGE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ .info_mask_separate_available =
+ BIT(IIO_CHAN_INFO_SAMP_FREQ),
.indexed = 1,
.address = channel,
.channel = channel,
@@ -567,6 +995,7 @@ static int ad7768_parse_config(struct iio_dev *indio_dev,
.realbits = 24,
.storagebits = 32,
},
+ .ext_info = ad7768_ext_info,
};
chan_idx++;
}
@@ -582,6 +1011,22 @@ static int ad7768_parse_config(struct iio_dev *indio_dev,
return dev_err_probe(dev, ret,
"Invalid \"adi,data-lines-number\" property\n");
+ ad7768_set_available_sampl_freq(st);
+
+ /* Start in fast mode; capture setup may select another compatible mode. */
+ scoped_guard(mutex, &st->lock) {
+ ret = ad7768_set_power_mode(st, AD7768_FAST_MODE);
+ }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to set power mode\n");
+
+ avail_freq = &st->avail_freq[AD7768_FAST_MODE];
+ default_freq = avail_freq->freq_cfg[avail_freq->n_freqs - 1].freq_hz;
+ for (i = 0; i < st->chip_info->num_channels; i++) {
+ st->ch_freq[i] = default_freq;
+ st->ch_filter[i] = AD7768_FILTER_TYPE_WIDEBAND;
+ }
+
available_datalines = st->chip_info->available_datalines;
len = st->chip_info->num_datalines;
@@ -595,7 +1040,7 @@ static int ad7768_parse_config(struct iio_dev *indio_dev,
"Invalid data-lines-number %d for %s\n",
st->datalines, st->chip_info->name);
- return ad7768_configure_capture(st);
+ return 0;
}
static int ad7768_reset(struct ad7768_state *st)
@@ -679,6 +1124,8 @@ static int ad7768_probe(struct spi_device *spi)
st->mclk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(st->mclk))
return PTR_ERR(st->mclk);
+ if (!clk_get_rate(st->mclk))
+ return dev_err_probe(dev, -EINVAL, "MCLK rate must be non-zero\n");
st->regmap = devm_regmap_init(dev, &ad7768_regmap_bus, spi,
st->chip_info->regmap_config);
--
2.43.0