diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2017-04-12 17:12:17 -0700 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2017-12-21 14:27:45 +0100 |
commit | eae4f0271151b1b6fd73c26df82e67a2717e3d98 (patch) | |
tree | e93f864b76ffffec0134ff7db3291014aeec3364 /drivers | |
parent | fb772326e612648c5314458fb3016bd00f4a70bd (diff) |
iio: adc: support IIO_CHAN_INFO_SCALE
Add support to read back raw value scale. This allows to calculate
actual voltages from the raw values.
Also combine the value acquisition and implement error handling
closer the way used in other IIO ADC drivers.
Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
Acked-by: Max Krummenacher <max.krummenacher@toradex.com>
(cherry picked from commit 7a751b2238383593fef0b3549fcf5a04558a0d3e)
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/iio/adc/stmpe-adc.c | 97 |
1 files changed, 61 insertions, 36 deletions
diff --git a/drivers/staging/iio/adc/stmpe-adc.c b/drivers/staging/iio/adc/stmpe-adc.c index 038d3c30d0e7..f23c1e92d5bb 100644 --- a/drivers/staging/iio/adc/stmpe-adc.c +++ b/drivers/staging/iio/adc/stmpe-adc.c @@ -78,54 +78,79 @@ static int stmpe_read_raw(struct iio_dev *indio_dev, long mask) { struct stmpe_adc *info = iio_priv(indio_dev); - unsigned long timeout; + long ret; - if (mask > 0) - return -EINVAL; + switch (mask) { + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: - mutex_lock(&indio_dev->mlock); + mutex_lock(&indio_dev->mlock); - info->channel = (u8)chan->channel; - switch (chan->type) - { - case IIO_VOLTAGE: - BUG_ON(info->channel > 7); - stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_EN, - STMPE_ADC_CH(info->channel)); + info->channel = (u8)chan->channel; - stmpe_reg_write(info->stmpe, STMPE_REG_ADC_CAPT, - STMPE_ADC_CH(info->channel)); + switch (chan->type) + { + case IIO_VOLTAGE: + BUG_ON(info->channel > 7); + stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_EN, + STMPE_ADC_CH(info->channel)); - timeout = wait_for_completion_interruptible_timeout - (&info->completion, STMPE_ADC_TIMEOUT); + stmpe_reg_write(info->stmpe, STMPE_REG_ADC_CAPT, + STMPE_ADC_CH(info->channel)); - *val = info->value; - break; - case IIO_TEMP: - BUG_ON(info->channel != 8); - stmpe_reg_write(info->stmpe, STMPE_REG_TEMP_CTRL, - STMPE_START_ONE_TEMP_CONV); + *val = info->value; + break; - timeout = wait_for_completion_interruptible_timeout + case IIO_TEMP: + BUG_ON(info->channel != 8); + stmpe_reg_write(info->stmpe, STMPE_REG_TEMP_CTRL, + STMPE_START_ONE_TEMP_CONV); + break; + default: + mutex_unlock(&indio_dev->mlock); + return -EINVAL; + } + + ret = wait_for_completion_interruptible_timeout (&info->completion, STMPE_ADC_TIMEOUT); - /* absolute temp = +V3.3 * value /7.51 [K] */ - /* scale to [milli °C] */ - *val = ((449960l * info->value) / 1024l) - 273150; - break; + + if (ret == 0) { + mutex_unlock(&indio_dev->mlock); + return -ETIMEDOUT; + } + if (ret < 0) { + mutex_unlock(&indio_dev->mlock); + return ret; + } + + switch (chan->type) + { + case IIO_VOLTAGE: + *val = info->value; + break; + + case IIO_TEMP: + /* absolute temp = +V3.3 * value /7.51 [K] */ + /* scale to [milli °C] */ + *val = ((449960l * info->value) / 1024l) - 273150; + break; + default: + break; + } + + mutex_unlock(&indio_dev->mlock); + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = 3300; + *val2 = info->mod_12b ? 12 : 10; + return IIO_VAL_FRACTIONAL_LOG2; + default: - BUG(); break; } - mutex_unlock(&indio_dev->mlock); - - if (timeout == -ERESTARTSYS) - return -EINTR; - - if (timeout == 0) - return -ETIMEDOUT; - - return IIO_VAL_INT; + return -EINVAL; } static irqreturn_t stmpe_adc_isr(int irq, void *dev_id) |