regmap_read(priv->reg, STM32_LPTIM_CR, &val); if (!FIELD_GET(STM32_LPTIM_ENABLE, val)) { /* Enable LPTIMER to be able to write into IER and ARR registers */
regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE); /* * After setting the ENABLE bit, a delay of two counter clock cycles is needed * before the LPTIM is actually enabled. For 32KHz rate, this makes approximately * 62.5 micro-seconds, round it up.
*/
udelay(63);
} /* set next event counter */
regmap_write(priv->reg, STM32_LPTIM_ARR, evt); /* enable ARR interrupt */
regmap_write(priv->reg, STM32_LPTIM_IER, STM32_LPTIM_ARRMIE);
/* Poll DIEROK and ARROK to ensure register access has completed */
ret = regmap_read_poll_timeout_atomic(priv->reg, STM32_LPTIM_ISR, val,
(val & STM32_LPTIM_DIEROK_ARROK) ==
STM32_LPTIM_DIEROK_ARROK,
10, 500); if (ret) {
dev_err(priv->dev, "access to LPTIM timed out\n"); /* Disable LPTIMER */
regmap_write(priv->reg, STM32_LPTIM_CR, 0); return ret;
} /* Clear DIEROK and ARROK flags */
regmap_write(priv->reg, STM32_LPTIM_ICR, STM32_LPTIM_DIEROKCF_ARROKCF);
return 0;
}
staticvoid stm32_clkevent_lp_set_evt(struct stm32_lp_private *priv, unsignedlong evt)
{ /* disable LPTIMER to be able to write into IER register*/
regmap_write(priv->reg, STM32_LPTIM_CR, 0); /* enable ARR interrupt */
regmap_write(priv->reg, STM32_LPTIM_IER, STM32_LPTIM_ARRMIE); /* enable LPTIMER to be able to write into ARR register */
regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE); /* set next event counter */
regmap_write(priv->reg, STM32_LPTIM_ARR, evt);
}
staticint stm32_clkevent_lp_set_timer(unsignedlong evt, struct clock_event_device *clkevt, int is_periodic)
{ struct stm32_lp_private *priv = to_priv(clkevt); int ret;
if (priv->version == STM32_LPTIM_VERR_23) {
ret = stm32mp25_clkevent_lp_set_evt(priv, evt); if (ret) return ret;
} else {
stm32_clkevent_lp_set_evt(priv, evt);
}
if (clkevt->event_handler)
clkevt->event_handler(clkevt);
return IRQ_HANDLED;
}
staticvoid stm32_clkevent_lp_set_prescaler(struct stm32_lp_private *priv, unsignedlong *rate)
{ int i;
for (i = 0; i <= STM32_LP_MAX_PSC; i++) { if (DIV_ROUND_CLOSEST(*rate, 1 << i) < STM32_TARGET_CLKRATE) break;
}
regmap_write(priv->reg, STM32_LPTIM_CFGR, i << CFGR_PSC_OFFSET);
/* Adjust rate and period given the prescaler value */
*rate = DIV_ROUND_CLOSEST(*rate, (1 << i));
priv->period = DIV_ROUND_UP(*rate, HZ);
priv->psc = i;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.