|
@@ -333,6 +333,27 @@ static const struct iio_chan_spec at91_adc_channels[] = {
|
|
|
+ AT91_SAMA5D2_DIFF_CHAN_CNT + 1),
|
|
|
};
|
|
|
|
|
|
+static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < indio_dev->num_channels; i++) {
|
|
|
+ if (indio_dev->channels[i].scan_index == chan)
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+ return -EINVAL;
|
|
|
+}
|
|
|
+
|
|
|
+static inline struct iio_chan_spec const *
|
|
|
+at91_adc_chan_get(struct iio_dev *indio_dev, int chan)
|
|
|
+{
|
|
|
+ int index = at91_adc_chan_xlate(indio_dev, chan);
|
|
|
+
|
|
|
+ if (index < 0)
|
|
|
+ return NULL;
|
|
|
+ return indio_dev->channels + index;
|
|
|
+}
|
|
|
+
|
|
|
static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
|
|
|
{
|
|
|
struct iio_dev *indio = iio_trigger_get_drvdata(trig);
|
|
@@ -350,8 +371,10 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
|
|
|
at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
|
|
|
|
|
|
for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) {
|
|
|
- struct iio_chan_spec const *chan = indio->channels + bit;
|
|
|
+ struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit);
|
|
|
|
|
|
+ if (!chan)
|
|
|
+ continue;
|
|
|
if (state) {
|
|
|
at91_adc_writel(st, AT91_SAMA5D2_CHER,
|
|
|
BIT(chan->channel));
|
|
@@ -448,7 +471,11 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
|
|
|
|
|
|
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
|
|
indio_dev->num_channels) {
|
|
|
- struct iio_chan_spec const *chan = indio_dev->channels + bit;
|
|
|
+ struct iio_chan_spec const *chan =
|
|
|
+ at91_adc_chan_get(indio_dev, bit);
|
|
|
+
|
|
|
+ if (!chan)
|
|
|
+ continue;
|
|
|
|
|
|
st->dma_st.rx_buf_sz += chan->scan_type.storagebits / 8;
|
|
|
}
|
|
@@ -526,8 +553,11 @@ static int at91_adc_buffer_predisable(struct iio_dev *indio_dev)
|
|
|
*/
|
|
|
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
|
|
indio_dev->num_channels) {
|
|
|
- struct iio_chan_spec const *chan = indio_dev->channels + bit;
|
|
|
+ struct iio_chan_spec const *chan =
|
|
|
+ at91_adc_chan_get(indio_dev, bit);
|
|
|
|
|
|
+ if (!chan)
|
|
|
+ continue;
|
|
|
if (st->dma_st.dma_chan)
|
|
|
at91_adc_readl(st, chan->address);
|
|
|
}
|
|
@@ -587,8 +617,11 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
|
|
|
|
|
|
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
|
|
indio_dev->num_channels) {
|
|
|
- struct iio_chan_spec const *chan = indio_dev->channels + bit;
|
|
|
+ struct iio_chan_spec const *chan =
|
|
|
+ at91_adc_chan_get(indio_dev, bit);
|
|
|
|
|
|
+ if (!chan)
|
|
|
+ continue;
|
|
|
st->buffer[i] = at91_adc_readl(st, chan->address);
|
|
|
i++;
|
|
|
}
|