static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev) { struct vf610_adc *info = iio_priv(indio_dev); unsigned int channel; int ret; int val; ret = iio_triggered_buffer_postenable(indio_dev); if (ret) return ret; val = readl(info->regs + VF610_REG_ADC_GC); val |= VF610_ADC_ADCON; writel(val, info->regs + VF610_REG_ADC_GC); channel = find_first_bit(indio_dev->active_scan_mask, indio_dev->masklength); val = VF610_ADC_ADCHC(channel); val |= VF610_ADC_AIEN; writel(val, info->regs + VF610_REG_ADC_HC0); return 0; }
static int vf610_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { struct vf610_adc *info = iio_priv(indio_dev); unsigned int hc_cfg; unsigned long ret; switch (mask) { case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); reinit_completion(&info->completion); hc_cfg = VF610_ADC_ADCHC(chan->channel); hc_cfg |= VF610_ADC_AIEN; writel(hc_cfg, info->regs + VF610_REG_ADC_HC0); ret = wait_for_completion_interruptible_timeout (&info->completion, VF610_ADC_TIMEOUT); if (ret == 0) { mutex_unlock(&indio_dev->mlock); return -ETIMEDOUT; } if (ret < 0) { mutex_unlock(&indio_dev->mlock); return ret; } *val = info->value; mutex_unlock(&indio_dev->mlock); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: *val = info->vref_uv / 1000; *val2 = info->adc_feature.res_mode; return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_SAMP_FREQ: *val = vf610_sample_freq_avail[info->adc_feature.sample_rate]; *val2 = 0; return IIO_VAL_INT; default: break; } return -EINVAL; }
static int vf610_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { struct vf610_adc *info = iio_priv(indio_dev); unsigned int hc_cfg; long ret; switch (mask) { case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_PROCESSED: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) { mutex_unlock(&indio_dev->mlock); return -EBUSY; } reinit_completion(&info->completion); hc_cfg = VF610_ADC_ADCHC(chan->channel); hc_cfg |= VF610_ADC_AIEN; writel(hc_cfg, info->regs + VF610_REG_ADC_HC0); ret = wait_for_completion_interruptible_timeout (&info->completion, VF610_ADC_TIMEOUT); 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: /* * Calculate in degree Celsius times 1000 * Using the typical sensor slope of 1.84 mV/°C * and VREFH_ADC at 3.3V, V at 25°C of 699 mV */ *val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) * 1000000 / VF610_TEMP_SLOPE_COEFF; break; default: mutex_unlock(&indio_dev->mlock); return -EINVAL; } mutex_unlock(&indio_dev->mlock); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: *val = info->vref_uv / 1000; *val2 = info->adc_feature.res_mode; return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_SAMP_FREQ: *val = info->sample_freq_avail[info->adc_feature.sample_rate]; *val2 = 0; return IIO_VAL_INT; default: break; } return -EINVAL; }