Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: adc: ad7124: fix sample rate for multi-channel use

Change how the FS[10:0] field of the FILTER register is calculated to
get consistent sample rates when only one channel is enabled vs when
multiple channels are enabled in a buffered read.

By default, the AD7124 allows larger sampling frequencies when only one
channel is enabled. It assumes that you will discard the first sample or
so to allow for settling time and then no additional settling time is
needed between samples because there is no multiplexing due to only one
channel being enabled. The conversion formula to convert between the
sampling frequency and the FS[10:0] field is:

fADC = fCLK / (FS[10:0] x 32)

which is what the driver has been using.

On the other hand, when multiple channels are enabled, there is
additional settling time needed when switching between channels so the
calculation to convert between becomes:

fADC = fCLK / (FS[10:0] x 32 x N)

where N depends on if SINGLE_CYCLE is set, the selected filter type and,
in some cases, the power mode.

The FILTER register has a SINGLE_CYCLE bit that can be set to force the
single channel case to use the same timing as the multi-channel case.

Before this change, the first formula was always used, so if all of the
in_voltageY_sampling_frequency attributes were set to 10 Hz, then doing
a buffered read with 1 channel enabled would result in the requested
sampling frequency of 10 Hz. But when more than one channel was
enabled, the actual sampling frequency would be 2.5 Hz per channel,
which is 1/4 of the requested frequency.

After this change, the SINGLE_CYCLE flag is now always enabled and the
multi-channel formula is now always used. This causes the sampling
frequency to be consistent regardless of the number of channels enabled.

For now, we are hard-coding N = 4 since the driver doesn't yet support
other filter types other than the default sinc4 filter.

The AD7124_FILTER_FS define is moved while we are touching this to
keep the bit fields in descending order to be consistent with the rest
of the file.

Signed-off-by: David Lechner <dlechner@baylibre.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

David Lechner and committed by
Jonathan Cameron
08a9e5f8 ee905c92

+20 -6
+20 -6
drivers/iio/adc/ad7124.c
··· 93 93 #define AD7124_CONFIG_PGA GENMASK(2, 0) 94 94 95 95 /* AD7124_FILTER_X */ 96 - #define AD7124_FILTER_FS GENMASK(10, 0) 97 96 #define AD7124_FILTER_FILTER GENMASK(23, 21) 98 97 #define AD7124_FILTER_FILTER_SINC4 0 99 98 #define AD7124_FILTER_FILTER_SINC3 2 99 + #define AD7124_FILTER_SINGLE_CYCLE BIT(16) 100 + #define AD7124_FILTER_FS GENMASK(10, 0) 100 101 101 102 #define AD7124_MAX_CONFIGS 8 102 103 #define AD7124_MAX_CHANNELS 16 ··· 286 285 287 286 static void ad7124_set_channel_odr(struct ad7124_state *st, unsigned int channel, unsigned int odr) 288 287 { 289 - unsigned int fclk, odr_sel_bits; 288 + unsigned int fclk, factor, odr_sel_bits; 290 289 291 290 fclk = ad7124_get_fclk_hz(st); 292 291 293 292 /* 294 - * FS[10:0] = fCLK / (fADC x 32) where: 293 + * FS[10:0] = fCLK / (fADC x 32 * N) where: 295 294 * fADC is the output data rate 296 295 * fCLK is the master clock frequency 296 + * N is number of conversions per sample (depends on filter type) 297 297 * FS[10:0] are the bits in the filter register 298 298 * FS[10:0] can have a value from 1 to 2047 299 299 */ 300 - odr_sel_bits = DIV_ROUND_CLOSEST(fclk, odr * 32); 300 + factor = 32 * 4; /* N = 4 for default sinc4 filter. */ 301 + odr_sel_bits = DIV_ROUND_CLOSEST(fclk, odr * factor); 301 302 if (odr_sel_bits < 1) 302 303 odr_sel_bits = 1; 303 304 else if (odr_sel_bits > 2047) ··· 309 306 st->channels[channel].cfg.live = false; 310 307 311 308 /* fADC = fCLK / (FS[10:0] x 32) */ 312 - st->channels[channel].cfg.odr = DIV_ROUND_CLOSEST(fclk, odr_sel_bits * 32); 309 + st->channels[channel].cfg.odr = DIV_ROUND_CLOSEST(fclk, odr_sel_bits * 310 + factor); 313 311 st->channels[channel].cfg.odr_sel_bits = odr_sel_bits; 314 312 } 315 313 ··· 443 439 if (ret < 0) 444 440 return ret; 445 441 442 + /* 443 + * NB: AD7124_FILTER_SINGLE_CYCLE is always set so that we get the same 444 + * sampling frequency even when only one channel is enabled in a 445 + * buffered read. If it was not set, the N in ad7124_set_channel_odr() 446 + * would be 1 and we would get a faster sampling frequency than what 447 + * was requested. 448 + */ 446 449 tmp = FIELD_PREP(AD7124_FILTER_FILTER, cfg->filter_type) | 450 + AD7124_FILTER_SINGLE_CYCLE | 447 451 FIELD_PREP(AD7124_FILTER_FS, cfg->odr_sel_bits); 448 452 return ad7124_spi_write_mask(st, AD7124_FILTER(cfg->cfg_slot), 449 - AD7124_FILTER_FILTER | AD7124_FILTER_FS, 453 + AD7124_FILTER_FILTER | 454 + AD7124_FILTER_SINGLE_CYCLE | 455 + AD7124_FILTER_FS, 450 456 tmp, 3); 451 457 } 452 458