diff options
-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) |