Commit f5657c77 authored by Ramona Gradinariu's avatar Ramona Gradinariu Committed by Jonathan Cameron

drivers: iio: imu: adis16475: generic computation for sample rate

Currently adis16475 supports a sample rate between 1900 and 2100 Hz.
This patch changes the setting of sample rate from hardcoded values to
a generic computation based on the internal clock frequency.
This is a preparatory patch for adding support for adis1657x family
devices which allow sample rates between 3900 and 4100 Hz.
Reviewed-by: default avatarNuno Sa <nuno.sa@analog.com>
Signed-off-by: default avatarRamona Gradinariu <ramona.bolboaca13@gmail.com>
Link: https://lore.kernel.org/r/20240527142618.275897-6-ramona.bolboaca13@gmail.comSigned-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 880b1b1f
...@@ -310,6 +310,9 @@ static int adis16475_set_freq(struct adis16475 *st, const u32 freq) ...@@ -310,6 +310,9 @@ static int adis16475_set_freq(struct adis16475 *st, const u32 freq)
u16 dec; u16 dec;
int ret; int ret;
u32 sample_rate = st->clk_freq; u32 sample_rate = st->clk_freq;
/* The optimal sample rate for the supported IMUs is between int_clk - 100 and int_clk + 100. */
u32 max_sample_rate = st->info->int_clk * 1000 + 100000;
u32 min_sample_rate = st->info->int_clk * 1000 - 100000;
if (!freq) if (!freq)
return -EINVAL; return -EINVAL;
...@@ -317,8 +320,9 @@ static int adis16475_set_freq(struct adis16475 *st, const u32 freq) ...@@ -317,8 +320,9 @@ static int adis16475_set_freq(struct adis16475 *st, const u32 freq)
adis_dev_lock(&st->adis); adis_dev_lock(&st->adis);
/* /*
* When using sync scaled mode, the input clock needs to be scaled so that we have * When using sync scaled mode, the input clock needs to be scaled so that we have
* an IMU sample rate between (optimally) 1900 and 2100. After this, we can use the * an IMU sample rate between (optimally) int_clk - 100 and int_clk + 100.
* decimation filter to lower the sampling rate in order to get what the user wants. * After this, we can use the decimation filter to lower the sampling rate in order
* to get what the user wants.
* Optimally, the user sample rate is a multiple of both the IMU sample rate and * Optimally, the user sample rate is a multiple of both the IMU sample rate and
* the input clock. Hence, calculating the sync_scale dynamically gives us better * the input clock. Hence, calculating the sync_scale dynamically gives us better
* chances of achieving a perfect/integer value for DEC_RATE. The math here is: * chances of achieving a perfect/integer value for DEC_RATE. The math here is:
...@@ -336,23 +340,24 @@ static int adis16475_set_freq(struct adis16475 *st, const u32 freq) ...@@ -336,23 +340,24 @@ static int adis16475_set_freq(struct adis16475 *st, const u32 freq)
* solution. In this case, we get the highest multiple of the input clock * solution. In this case, we get the highest multiple of the input clock
* lower than the IMU max sample rate. * lower than the IMU max sample rate.
*/ */
if (scaled_rate > 2100000) if (scaled_rate > max_sample_rate)
scaled_rate = 2100000 / st->clk_freq * st->clk_freq; scaled_rate = max_sample_rate / st->clk_freq * st->clk_freq;
else else
scaled_rate = 2100000 / scaled_rate * scaled_rate; scaled_rate = max_sample_rate / scaled_rate * scaled_rate;
/* /*
* This is not an hard requirement but it's not advised to run the IMU * This is not an hard requirement but it's not advised to run the IMU
* with a sample rate lower than 1900Hz due to possible undersampling * with a sample rate lower than internal clock frequency, due to possible
* issues. However, there are users that might really want to take the risk. * undersampling issues. However, there are users that might really want
* Hence, we provide a module parameter for them. If set, we allow sample * to take the risk. Hence, we provide a module parameter for them. If set,
* rates lower than 1.9KHz. By default, we won't allow this and we just roundup * we allow sample rates lower than internal clock frequency.
* the rate to the next multiple of the input clock bigger than 1.9KHz. This * By default, we won't allow this and we just roundup the rate to the next
* is done like this as in some cases (when DEC_RATE is 0) might give * multiple of the input clock. This is done like this as in some cases
* us the closest value to the one desired by the user... * (when DEC_RATE is 0) might give us the closest value to the one desired
* by the user...
*/ */
if (scaled_rate < 1900000 && !low_rate_allow) if (scaled_rate < min_sample_rate && !low_rate_allow)
scaled_rate = roundup(1900000, st->clk_freq); scaled_rate = roundup(min_sample_rate, st->clk_freq);
sync_scale = scaled_rate / st->clk_freq; sync_scale = scaled_rate / st->clk_freq;
ret = __adis_write_reg_16(&st->adis, ADIS16475_REG_UP_SCALE, sync_scale); ret = __adis_write_reg_16(&st->adis, ADIS16475_REG_UP_SCALE, sync_scale);
...@@ -1317,6 +1322,7 @@ static int adis16475_config_sync_mode(struct adis16475 *st) ...@@ -1317,6 +1322,7 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
struct device *dev = &st->adis.spi->dev; struct device *dev = &st->adis.spi->dev;
const struct adis16475_sync *sync; const struct adis16475_sync *sync;
u32 sync_mode; u32 sync_mode;
u16 max_sample_rate = st->info->int_clk + 100;
u16 val; u16 val;
/* default to internal clk */ /* default to internal clk */
...@@ -1357,10 +1363,9 @@ static int adis16475_config_sync_mode(struct adis16475 *st) ...@@ -1357,10 +1363,9 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
/* /*
* In sync scaled mode, the IMU sample rate is the clk_freq * sync_scale. * In sync scaled mode, the IMU sample rate is the clk_freq * sync_scale.
* Hence, default the IMU sample rate to the highest multiple of the input * Hence, default the IMU sample rate to the highest multiple of the input
* clock lower than the IMU max sample rate. The optimal range is * clock lower than the IMU max sample rate.
* 1900-2100 sps...
*/ */
up_scale = 2100 / st->clk_freq; up_scale = max_sample_rate / st->clk_freq;
ret = __adis_write_reg_16(&st->adis, ret = __adis_write_reg_16(&st->adis,
ADIS16475_REG_UP_SCALE, ADIS16475_REG_UP_SCALE,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment