Commit 7989b4bb authored by Beniamin Bia's avatar Beniamin Bia Committed by Jonathan Cameron

iio: adc: ad7616: Add support for AD7616 ADC

The AD7616 is a 12-bit ADC with 16 channels.

The AD7616 can be configured to work in hardware mode by controlling it via
gpio pins and read data via spi. No support for software mode yet, but it
is a work in progress.

This device requires a reset in order to update oversampling, so chip info
has got a new attribute to mark this.

The current assumption that this driver makes for AD7616, is that it's
working in Hardware Mode with Serial, Burst and Sequencer modes activated.
To activate them, following pins must be pulled high:
	-SER/PAR
	-SEQEN
And following must be pulled low:
	-WR/BURST
	-DB4/SEQEN

Datasheets:
Link: https://www.analog.com/media/en/technical-documentation/data-sheets/ad7616.pdfSigned-off-by: default avatarBeniamin Bia <beniamin.bia@analog.com>
Signed-off-by: default avatarAlexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 6bf229ab
...@@ -39,6 +39,10 @@ static const unsigned int ad7606_oversampling_avail[7] = { ...@@ -39,6 +39,10 @@ static const unsigned int ad7606_oversampling_avail[7] = {
1, 2, 4, 8, 16, 32, 64, 1, 2, 4, 8, 16, 32, 64,
}; };
static const unsigned int ad7616_oversampling_avail[8] = {
1, 2, 4, 8, 16, 32, 64, 128,
};
static int ad7606_reset(struct ad7606_state *st) static int ad7606_reset(struct ad7606_state *st)
{ {
if (st->gpio_reset) { if (st->gpio_reset) {
...@@ -220,6 +224,11 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, ...@@ -220,6 +224,11 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
mutex_lock(&st->lock); mutex_lock(&st->lock);
gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc, gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc,
st->gpio_os->info, values); st->gpio_os->info, values);
/* AD7616 requires a reset to update value */
if (st->chip_info->os_req_reset)
ad7606_reset(st);
st->oversampling = st->oversampling_avail[i]; st->oversampling = st->oversampling_avail[i];
mutex_unlock(&st->lock); mutex_unlock(&st->lock);
...@@ -314,6 +323,36 @@ static const struct iio_chan_spec ad7606_channels[] = { ...@@ -314,6 +323,36 @@ static const struct iio_chan_spec ad7606_channels[] = {
AD7606_CHANNEL(7), AD7606_CHANNEL(7),
}; };
/*
* The current assumption that this driver makes for AD7616, is that it's
* working in Hardware Mode with Serial, Burst and Sequencer modes activated.
* To activate them, following pins must be pulled high:
* -SER/PAR
* -SEQEN
* And following pins must be pulled low:
* -WR/BURST
* -DB4/SER1W
*/
static const struct iio_chan_spec ad7616_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(16),
AD7606_CHANNEL(0),
AD7606_CHANNEL(1),
AD7606_CHANNEL(2),
AD7606_CHANNEL(3),
AD7606_CHANNEL(4),
AD7606_CHANNEL(5),
AD7606_CHANNEL(6),
AD7606_CHANNEL(7),
AD7606_CHANNEL(8),
AD7606_CHANNEL(9),
AD7606_CHANNEL(10),
AD7606_CHANNEL(11),
AD7606_CHANNEL(12),
AD7606_CHANNEL(13),
AD7606_CHANNEL(14),
AD7606_CHANNEL(15),
};
static const struct ad7606_chip_info ad7606_chip_info_tbl[] = { static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
/* More devices added in future */ /* More devices added in future */
[ID_AD7605_4] = { [ID_AD7605_4] = {
...@@ -338,6 +377,13 @@ static const struct ad7606_chip_info ad7606_chip_info_tbl[] = { ...@@ -338,6 +377,13 @@ static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
.oversampling_avail = ad7606_oversampling_avail, .oversampling_avail = ad7606_oversampling_avail,
.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
}, },
[ID_AD7616] = {
.channels = ad7616_channels,
.num_channels = 17,
.oversampling_avail = ad7616_oversampling_avail,
.oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail),
.os_req_reset = true,
},
}; };
static int ad7606_request_gpios(struct ad7606_state *st) static int ad7606_request_gpios(struct ad7606_state *st)
......
...@@ -15,12 +15,14 @@ ...@@ -15,12 +15,14 @@
* @oversampling_avail pointer to the array which stores the available * @oversampling_avail pointer to the array which stores the available
* oversampling ratios. * oversampling ratios.
* @oversampling_num number of elements stored in oversampling_avail array * @oversampling_num number of elements stored in oversampling_avail array
* @os_req_reset some devices require a reset to update oversampling
*/ */
struct ad7606_chip_info { struct ad7606_chip_info {
const struct iio_chan_spec *channels; const struct iio_chan_spec *channels;
unsigned int num_channels; unsigned int num_channels;
const unsigned int *oversampling_avail; const unsigned int *oversampling_avail;
unsigned int oversampling_num; unsigned int oversampling_num;
bool os_req_reset;
}; };
/** /**
...@@ -76,9 +78,9 @@ struct ad7606_state { ...@@ -76,9 +78,9 @@ struct ad7606_state {
/* /*
* DMA (thus cache coherency maintenance) requires the * DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines. * transfer buffers to live in their own cache lines.
* 8 * 16-bit samples + 64-bit timestamp * 16 * 16-bit samples + 64-bit timestamp
*/ */
unsigned short data[12] ____cacheline_aligned; unsigned short data[20] ____cacheline_aligned;
}; };
/** /**
...@@ -98,7 +100,8 @@ enum ad7606_supported_device_ids { ...@@ -98,7 +100,8 @@ enum ad7606_supported_device_ids {
ID_AD7605_4, ID_AD7605_4,
ID_AD7606_8, ID_AD7606_8,
ID_AD7606_6, ID_AD7606_6,
ID_AD7606_4 ID_AD7606_4,
ID_AD7616,
}; };
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
......
...@@ -53,6 +53,7 @@ static const struct spi_device_id ad7606_id_table[] = { ...@@ -53,6 +53,7 @@ static const struct spi_device_id ad7606_id_table[] = {
{ "ad7606-4", ID_AD7606_4 }, { "ad7606-4", ID_AD7606_4 },
{ "ad7606-6", ID_AD7606_6 }, { "ad7606-6", ID_AD7606_6 },
{ "ad7606-8", ID_AD7606_8 }, { "ad7606-8", ID_AD7606_8 },
{ "ad7616", ID_AD7616 },
{} {}
}; };
MODULE_DEVICE_TABLE(spi, ad7606_id_table); MODULE_DEVICE_TABLE(spi, ad7606_id_table);
...@@ -62,6 +63,7 @@ static const struct of_device_id ad7606_of_match[] = { ...@@ -62,6 +63,7 @@ static const struct of_device_id ad7606_of_match[] = {
{ .compatible = "adi,ad7606-4" }, { .compatible = "adi,ad7606-4" },
{ .compatible = "adi,ad7606-6" }, { .compatible = "adi,ad7606-6" },
{ .compatible = "adi,ad7606-8" }, { .compatible = "adi,ad7606-8" },
{ .compatible = "adi,ad7616" },
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, ad7606_of_match); MODULE_DEVICE_TABLE(of, ad7606_of_match);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment