summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2017-04-12 17:12:17 -0700
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2017-12-21 14:27:45 +0100
commiteae4f0271151b1b6fd73c26df82e67a2717e3d98 (patch)
treee93f864b76ffffec0134ff7db3291014aeec3364 /drivers
parentfb772326e612648c5314458fb3016bd00f4a70bd (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.c97
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)