Commit 7cb2303d authored by Olivier Moysan's avatar Olivier Moysan Committed by Jonathan Cameron

iio: adc: stm32: manage min sampling time on all internal channels

Force minimum sampling time for all internal channels according
to datasheet requirement. This value can be increased through
DT st,min-sample-time-ns property.
Signed-off-by: default avatarOlivier Moysan <olivier.moysan@foss.st.com>
Reviewed-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: default avatarFabrice Gasnier <fabrice.gasnier@foss.st.com>
Link: https://lore.kernel.org/r/20221012142205.13041-5-olivier.moysan@foss.st.comSigned-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent cf0fb80a
......@@ -215,7 +215,7 @@ struct stm32_adc;
* @unprepare: optional unprepare routine (disable, power-down)
* @irq_clear: routine to clear irqs
* @smp_cycles: programmable sampling time (ADC clock cycles)
* @ts_vrefint_ns: vrefint minimum sampling time in ns
* @ts_int_ch: pointer to array of internal channels minimum sampling time in ns
*/
struct stm32_adc_cfg {
const struct stm32_adc_regspec *regs;
......@@ -232,7 +232,7 @@ struct stm32_adc_cfg {
void (*unprepare)(struct iio_dev *);
void (*irq_clear)(struct iio_dev *indio_dev, u32 msk);
const unsigned int *smp_cycles;
const unsigned int ts_vrefint_ns;
const unsigned int *ts_int_ch;
};
/**
......@@ -1910,14 +1910,15 @@ static void stm32_adc_smpr_init(struct stm32_adc *adc, int channel, u32 smp_ns)
{
const struct stm32_adc_regs *smpr = &adc->cfg->regs->smp_bits[channel];
u32 period_ns, shift = smpr->shift, mask = smpr->mask;
unsigned int smp, r = smpr->reg;
unsigned int i, smp, r = smpr->reg;
/*
* For vrefint channel, ensure that the sampling time cannot
* For internal channels, ensure that the sampling time cannot
* be lower than the one specified in the datasheet
*/
if (channel == adc->int_ch[STM32_ADC_INT_CH_VREFINT])
smp_ns = max(smp_ns, adc->cfg->ts_vrefint_ns);
for (i = 0; i < STM32_ADC_INT_CH_NB; i++)
if (channel == adc->int_ch[i] && adc->int_ch[i] != STM32_ADC_INT_CH_NONE)
smp_ns = max(smp_ns, adc->cfg->ts_int_ch[i]);
/* Determine sampling time (ADC clock cycles) */
period_ns = NSEC_PER_SEC / adc->common->rate;
......@@ -2568,6 +2569,9 @@ static const struct stm32_adc_cfg stm32f4_adc_cfg = {
.irq_clear = stm32f4_adc_irq_clear,
};
const unsigned int stm32_adc_min_ts_h7[] = { 0, 0, 0, 4300, 9000 };
static_assert(ARRAY_SIZE(stm32_adc_min_ts_h7) == STM32_ADC_INT_CH_NB);
static const struct stm32_adc_cfg stm32h7_adc_cfg = {
.regs = &stm32h7_adc_regspec,
.adc_info = &stm32h7_adc_info,
......@@ -2581,8 +2585,12 @@ static const struct stm32_adc_cfg stm32h7_adc_cfg = {
.unprepare = stm32h7_adc_unprepare,
.smp_cycles = stm32h7_adc_smp_cycles,
.irq_clear = stm32h7_adc_irq_clear,
.ts_int_ch = stm32_adc_min_ts_h7,
};
const unsigned int stm32_adc_min_ts_mp1[] = { 100, 100, 100, 4300, 9800 };
static_assert(ARRAY_SIZE(stm32_adc_min_ts_mp1) == STM32_ADC_INT_CH_NB);
static const struct stm32_adc_cfg stm32mp1_adc_cfg = {
.regs = &stm32mp1_adc_regspec,
.adc_info = &stm32h7_adc_info,
......@@ -2597,9 +2605,12 @@ static const struct stm32_adc_cfg stm32mp1_adc_cfg = {
.unprepare = stm32h7_adc_unprepare,
.smp_cycles = stm32h7_adc_smp_cycles,
.irq_clear = stm32h7_adc_irq_clear,
.ts_vrefint_ns = 4300,
.ts_int_ch = stm32_adc_min_ts_mp1,
};
const unsigned int stm32_adc_min_ts_mp13[] = { 100, 0, 0, 4300, 9800 };
static_assert(ARRAY_SIZE(stm32_adc_min_ts_mp13) == STM32_ADC_INT_CH_NB);
static const struct stm32_adc_cfg stm32mp13_adc_cfg = {
.regs = &stm32mp13_adc_regspec,
.adc_info = &stm32mp13_adc_info,
......@@ -2610,6 +2621,7 @@ static const struct stm32_adc_cfg stm32mp13_adc_cfg = {
.unprepare = stm32h7_adc_unprepare,
.smp_cycles = stm32mp13_adc_smp_cycles,
.irq_clear = stm32h7_adc_irq_clear,
.ts_int_ch = stm32_adc_min_ts_mp13,
};
static const struct of_device_id stm32_adc_of_match[] = {
......
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