// SPDX-License-Identifier: GPL-2.0-only /* * Driver for ADC module on the Cirrus Logic EP93xx series of SoCs * * Copyright (C) 2015 Alexander Sverdlin * * The driver uses polling to get the conversion status. According to EP93xx * datasheets, reading ADCResult register starts the conversion, but user is also * responsible for ensuring that delay between adjacent conversion triggers is * long enough so that maximum allowed conversion rate is not exceeded. This * basically renders IRQ mode unusable.
*/
/* * This code could benefit from real HR Timers, but jiffy granularity would * lower ADC conversion rate down to CONFIG_HZ, so we fallback to busy wait * in such case. * * HR Timers-based version loads CPU only up to 10% during back to back ADC * conversion, while busy wait-based version consumes whole CPU power.
*/ #ifdef CONFIG_HIGH_RES_TIMERS #define ep93xx_adc_delay(usmin, usmax) usleep_range(usmin, usmax) #else #define ep93xx_adc_delay(usmin, usmax) udelay(usmin) #endif
/* * Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets. * EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is * not defined. So the last three are numbered randomly, let's say.
*/ staticconststruct iio_chan_spec ep93xx_adc_channels[8] = {
EP93XX_ADC_CH(0, "YM", 0x608),
EP93XX_ADC_CH(1, "SXP", 0x680),
EP93XX_ADC_CH(2, "SXM", 0x640),
EP93XX_ADC_CH(3, "SYP", 0x620),
EP93XX_ADC_CH(4, "SYM", 0x610),
EP93XX_ADC_CH(5, "XP", 0x601),
EP93XX_ADC_CH(6, "XM", 0x602),
EP93XX_ADC_CH(7, "YP", 0x604),
};
staticint ep93xx_read_raw(struct iio_dev *iiodev, struct iio_chan_spec const *channel, int *value, int *shift, long mask)
{ struct ep93xx_adc_priv *priv = iio_priv(iiodev); unsignedlong timeout; int ret;
switch (mask) { case IIO_CHAN_INFO_RAW:
mutex_lock(&priv->lock); if (priv->lastch != channel->channel) {
priv->lastch = channel->channel; /* * Switch register is software-locked, unlocking must be * immediately followed by write
*/
local_irq_disable();
writel_relaxed(0xAA, priv->base + EP93XX_ADC_SW_LOCK);
writel_relaxed(channel->address,
priv->base + EP93XX_ADC_SWITCH);
local_irq_enable(); /* * Settling delay depends on module clock and could be * 2ms or 500us
*/
ep93xx_adc_delay(2000, 2000);
} /* Start the conversion, eventually discarding old result */
readl_relaxed(priv->base + EP93XX_ADC_RESULT); /* Ensure maximum conversion rate is not exceeded */
ep93xx_adc_delay(DIV_ROUND_UP(1000000, 925),
DIV_ROUND_UP(1000000, 925)); /* At this point conversion must be completed, but anyway... */
ret = IIO_VAL_INT;
timeout = jiffies + msecs_to_jiffies(1) + 1; while (1) {
u32 t;
t = readl_relaxed(priv->base + EP93XX_ADC_RESULT); if (t & EP93XX_ADC_SDR) {
*value = sign_extend32(t, 15); break;
}
if (time_after(jiffies, timeout)) {
dev_err(&iiodev->dev, "Conversion timeout\n");
ret = -ETIMEDOUT; break;
}
pclk = clk_get_parent(priv->clk); if (!pclk) {
dev_warn(&pdev->dev, "Cannot obtain parent clock\n");
} else { /* * This is actually a place for improvement: * EP93xx ADC supports two clock divisors -- 4 and 16, * resulting in conversion rates 3750 and 925 samples per second * with 500us or 2ms settling time respectively. * One might find this interesting enough to be configurable.
*/
ret = clk_set_rate(priv->clk, clk_get_rate(pclk) / 16); if (ret)
dev_warn(&pdev->dev, "Cannot set clock rate\n"); /* * We can tolerate rate setting failure because the module should * work in any case.
*/
}
ret = clk_prepare_enable(priv->clk); if (ret) {
dev_err(&pdev->dev, "Cannot enable clock\n"); return ret;
}
ret = iio_device_register(iiodev); if (ret)
clk_disable_unprepare(priv->clk);
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.