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: stm32-adc: adapt clock duty cycle for proper operation

For proper operation, STM32 ADC should be used with a clock duty cycle
of 50%, in the range of 49% to 51%. Depending on the clock tree, divider
can be used in case clock duty cycle is out of this range.
In case clk_get_scaled_duty_cycle() returns an error, kindly apply a
divider by default (don't make the probe fail).

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Link: https://lore.kernel.org/r/1604681846-31234-1-git-send-email-fabrice.gasnier@st.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Fabrice Gasnier and committed by
Jonathan Cameron
89d1f725 8dedcc3e

+20 -1
+20 -1
drivers/iio/adc/stm32-adc-core.c
··· 202 202 { 203 203 u32 ckmode, presc, val; 204 204 unsigned long rate; 205 - int i, div; 205 + int i, div, duty; 206 206 207 207 /* stm32h7 bus clock is common for all ADC instances (mandatory) */ 208 208 if (!priv->bclk) { ··· 226 226 return -EINVAL; 227 227 } 228 228 229 + /* If duty is an error, kindly use at least /2 divider */ 230 + duty = clk_get_scaled_duty_cycle(priv->aclk, 100); 231 + if (duty < 0) 232 + dev_warn(&pdev->dev, "adc clock duty: %d\n", duty); 233 + 229 234 for (i = 0; i < ARRAY_SIZE(stm32h7_adc_ckmodes_spec); i++) { 230 235 ckmode = stm32h7_adc_ckmodes_spec[i].ckmode; 231 236 presc = stm32h7_adc_ckmodes_spec[i].presc; 232 237 div = stm32h7_adc_ckmodes_spec[i].div; 233 238 234 239 if (ckmode) 240 + continue; 241 + 242 + /* 243 + * For proper operation, clock duty cycle range is 49% 244 + * to 51%. Apply at least /2 prescaler otherwise. 245 + */ 246 + if (div == 1 && (duty < 49 || duty > 51)) 235 247 continue; 236 248 237 249 if ((rate / div) <= priv->max_clk_rate) ··· 258 246 return -EINVAL; 259 247 } 260 248 249 + duty = clk_get_scaled_duty_cycle(priv->bclk, 100); 250 + if (duty < 0) 251 + dev_warn(&pdev->dev, "bus clock duty: %d\n", duty); 252 + 261 253 for (i = 0; i < ARRAY_SIZE(stm32h7_adc_ckmodes_spec); i++) { 262 254 ckmode = stm32h7_adc_ckmodes_spec[i].ckmode; 263 255 presc = stm32h7_adc_ckmodes_spec[i].presc; 264 256 div = stm32h7_adc_ckmodes_spec[i].div; 265 257 266 258 if (!ckmode) 259 + continue; 260 + 261 + if (div == 1 && (duty < 49 || duty > 51)) 267 262 continue; 268 263 269 264 if ((rate / div) <= priv->max_clk_rate)