// SPDX-License-Identifier: GPL-2.0-only /* * TI ADC108S102 SPI ADC driver * * Copyright (c) 2013-2015 Intel Corporation. * Copyright (c) 2017 Siemens AG * * This IIO device driver is designed to work with the following * analog to digital converters from Texas Instruments: * ADC108S102 * ADC128S102 * The communication with ADC chip is via the SPI bus (mode 3).
*/
/* * In case of ACPI, we use the hard-wired 5000 mV of the Galileo and IOT2000 * boards as default for the reference pin VA. Device tree users encode that * via the vref-supply regulator.
*/ #define ADC108S102_VA_MV_ACPI_DEFAULT 5000
/* * Defining the ADC resolution being 12 bits, we can use the same driver for * both ADC108S102 (10 bits resolution) and ADC128S102 (12 bits resolution) * chips. The ADC108S102 effectively returns a 12-bit result with the 2 * least-significant bits unset.
*/ #define ADC108S102_BITS 12 #define ADC108S102_MAX_CHANNELS 8
struct adc108s102_state { struct spi_device *spi;
u32 va_millivolt; /* SPI transfer used by triggered buffer handler*/ struct spi_transfer ring_xfer; /* SPI transfer used by direct scan */ struct spi_transfer scan_single_xfer; /* SPI message used by ring_xfer SPI transfer */ struct spi_message ring_msg; /* SPI message used by scan_single_xfer SPI transfer */ struct spi_message scan_single_msg;
/* * Fill in the first x shorts of tx_buf with the number of channels * enabled for sampling by the triggered buffer.
*/
cmds = 0;
for_each_set_bit(bit, active_scan_mask, ADC108S102_MAX_CHANNELS)
st->tx_buf[cmds++] = cpu_to_be16(ADC108S102_CMD(bit));
/* One dummy command added, to clock in the last response */
st->tx_buf[cmds++] = 0x00;
ret = spi_sync(st->spi, &st->ring_msg); if (ret < 0) goto out_notify;
/* Skip the dummy response in the first slot */
iio_push_to_buffers_with_ts_unaligned(indio_dev,
&st->rx_buf[1],
st->ring_xfer.len - sizeof(st->rx_buf[1]),
iio_get_time_ns(indio_dev));
staticint adc108s102_scan_direct(struct adc108s102_state *st, unsignedint ch)
{ int ret;
st->tx_buf[0] = cpu_to_be16(ADC108S102_CMD(ch));
ret = spi_sync(st->spi, &st->scan_single_msg); if (ret) return ret;
/* Skip the dummy response in the first slot */ return be16_to_cpu(st->rx_buf[1]);
}
staticint adc108s102_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long m)
{ struct adc108s102_state *st = iio_priv(indio_dev); int ret;
switch (m) { case IIO_CHAN_INFO_RAW: if (!iio_device_claim_direct(indio_dev)) return -EBUSY;
ret = adc108s102_scan_direct(st, chan->address);
iio_device_release_direct(indio_dev);
if (ret < 0) return ret;
*val = ADC108S102_RES_DATA(ret);
return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: if (chan->type != IIO_VOLTAGE) break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.