Message ID | 1551862524-25098-2-git-send-email-fabrice.gasnier@st.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | iio: adc: stm32-dfsdm: add buffer modes | expand |
On Wed, 6 Mar 2019 09:55:17 +0100 Fabrice Gasnier <fabrice.gasnier@st.com> wrote: > When SPI clock isn't accurate, 'spi_master_freq' is filled in with > expected frequency. Use computed value instead: > - e.g. source clock / (CKOUTDIV + 1) > Also, current divider may be set to value that makes CKOUT to exceed > spi-max-frequency. Rather use lower value (e.g. round up divider when > ckout isn't accurate). > > Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com> > --- > drivers/iio/adc/stm32-dfsdm-core.c | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c > index bf089f5..65b7556 100644 > --- a/drivers/iio/adc/stm32-dfsdm-core.c > +++ b/drivers/iio/adc/stm32-dfsdm-core.c > @@ -243,13 +243,18 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, > return 0; > } > > - priv->spi_clk_out_div = div_u64_rem(clk_freq, spi_freq, &rem) - 1; > + priv->spi_clk_out_div = div_u64_rem(clk_freq, spi_freq, &rem); > + > + /* round up divider when clkout isn't accurate (e.g. !rem) */ > + if (priv->spi_clk_out_div && !rem) > + priv->spi_clk_out_div--; > + This comment perhaps needs adjusting because at the moment it looks like it decrements when it is accurate. With the old code in place in the patch it's obvious that's because you actually want one less. Might even be worth the dance of /* round up if not precise */ if (priv->spi_clk_out_div && rem) priv->spi_clk_out_div++; /* subtract one because.... */ priv->spi_clk_out_div--; > if (!priv->spi_clk_out_div) { > /* spi_clk_out_div == 0 means ckout is OFF */ > dev_err(&pdev->dev, "spi-max-frequency not achievable\n"); > return -EINVAL; > } > - priv->dfsdm.spi_master_freq = spi_freq; > + priv->dfsdm.spi_master_freq = clk_freq / (priv->spi_clk_out_div + 1); And we increment it again here? That needs an explanation as well. > > if (rem) { > dev_warn(&pdev->dev, "SPI clock not accurate\n");
On 3/10/19 11:09 AM, Jonathan Cameron wrote: > On Wed, 6 Mar 2019 09:55:17 +0100 > Fabrice Gasnier <fabrice.gasnier@st.com> wrote: > >> When SPI clock isn't accurate, 'spi_master_freq' is filled in with >> expected frequency. Use computed value instead: >> - e.g. source clock / (CKOUTDIV + 1) >> Also, current divider may be set to value that makes CKOUT to exceed >> spi-max-frequency. Rather use lower value (e.g. round up divider when >> ckout isn't accurate). >> >> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com> >> --- >> drivers/iio/adc/stm32-dfsdm-core.c | 9 +++++++-- >> 1 file changed, 7 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c >> index bf089f5..65b7556 100644 >> --- a/drivers/iio/adc/stm32-dfsdm-core.c >> +++ b/drivers/iio/adc/stm32-dfsdm-core.c >> @@ -243,13 +243,18 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, >> return 0; >> } >> >> - priv->spi_clk_out_div = div_u64_rem(clk_freq, spi_freq, &rem) - 1; >> + priv->spi_clk_out_div = div_u64_rem(clk_freq, spi_freq, &rem); >> + >> + /* round up divider when clkout isn't accurate (e.g. !rem) */ >> + if (priv->spi_clk_out_div && !rem) >> + priv->spi_clk_out_div--; >> + > This comment perhaps needs adjusting because at the moment it looks > like it decrements when it is accurate. With the old code in place > in the patch it's obvious that's because you actually want one less. > > Might even be worth the dance of > > /* round up if not precise */ > if (priv->spi_clk_out_div && rem) > priv->spi_clk_out_div++; > > /* subtract one because.... */ > priv->spi_clk_out_div--; Hi Jonathan, I'll rework this patch in v2, make it easier to understand & read. In a few words: the clock output is divider = ckoutdiv + 1. ckoutdiv range can be from 1-255 to provide divider of 2-256. So I'll introduce this divider as a variable, and use it to setup spi_clk_out_div. This should address all your remarks here. Thanks for reviewing, Best Regards, Fabrice > >> if (!priv->spi_clk_out_div) { >> /* spi_clk_out_div == 0 means ckout is OFF */ >> dev_err(&pdev->dev, "spi-max-frequency not achievable\n"); >> return -EINVAL; >> } >> - priv->dfsdm.spi_master_freq = spi_freq; >> + priv->dfsdm.spi_master_freq = clk_freq / (priv->spi_clk_out_div + 1); > And we increment it again here? That needs an explanation as well. >> >> if (rem) { >> dev_warn(&pdev->dev, "SPI clock not accurate\n"); >
diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c index bf089f5..65b7556 100644 --- a/drivers/iio/adc/stm32-dfsdm-core.c +++ b/drivers/iio/adc/stm32-dfsdm-core.c @@ -243,13 +243,18 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, return 0; } - priv->spi_clk_out_div = div_u64_rem(clk_freq, spi_freq, &rem) - 1; + priv->spi_clk_out_div = div_u64_rem(clk_freq, spi_freq, &rem); + + /* round up divider when clkout isn't accurate (e.g. !rem) */ + if (priv->spi_clk_out_div && !rem) + priv->spi_clk_out_div--; + if (!priv->spi_clk_out_div) { /* spi_clk_out_div == 0 means ckout is OFF */ dev_err(&pdev->dev, "spi-max-frequency not achievable\n"); return -EINVAL; } - priv->dfsdm.spi_master_freq = spi_freq; + priv->dfsdm.spi_master_freq = clk_freq / (priv->spi_clk_out_div + 1); if (rem) { dev_warn(&pdev->dev, "SPI clock not accurate\n");
When SPI clock isn't accurate, 'spi_master_freq' is filled in with expected frequency. Use computed value instead: - e.g. source clock / (CKOUTDIV + 1) Also, current divider may be set to value that makes CKOUT to exceed spi-max-frequency. Rather use lower value (e.g. round up divider when ckout isn't accurate). Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com> --- drivers/iio/adc/stm32-dfsdm-core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)