diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 8a78b4f3ef58..a2c50713b0b6 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -3,6 +3,11 @@
 #
 menu "Analog to digital converters"
 
+config AD_SIGMA_DELTA
+	tristate
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+
 config AD7266
 	tristate "Analog Devices AD7265/AD7266 ADC driver"
 	depends on SPI_MASTER
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 52eec254c38c..5989356c5735 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -2,5 +2,6 @@
 # Makefile for IIO ADC drivers
 #
 
+obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
 obj-$(CONFIG_AD7266) += ad7266.o
 obj-$(CONFIG_AT91_ADC) += at91_adc.o
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
new file mode 100644
index 000000000000..ae847c5a1361
--- /dev/null
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -0,0 +1,558 @@
+/*
+ * Support code for Analog Devices Sigma-Delta ADCs
+ *
+ * Copyright 2012 Analog Devices Inc.
+ *  Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/err.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/adc/ad_sigma_delta.h>
+
+#include <asm/unaligned.h>
+
+
+#define AD_SD_COMM_CHAN_MASK	0x3
+
+#define AD_SD_REG_COMM		0x00
+#define AD_SD_REG_DATA		0x03
+
+/**
+ * ad_sd_set_comm() - Set communications register
+ *
+ * @sigma_delta: The sigma delta device
+ * @comm: New value for the communications register
+ */
+void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm)
+{
+	/* Some variants use the lower two bits of the communications register
+	 * to select the channel */
+	sigma_delta->comm = comm & AD_SD_COMM_CHAN_MASK;
+}
+EXPORT_SYMBOL_GPL(ad_sd_set_comm);
+
+/**
+ * ad_sd_write_reg() - Write a register
+ *
+ * @sigma_delta: The sigma delta device
+ * @reg: Address of the register
+ * @size: Size of the register (0-3)
+ * @val: Value to write to the register
+ *
+ * Returns 0 on success, an error code otherwise.
+ **/
+int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
+	unsigned int size, unsigned int val)
+{
+	uint8_t *data = sigma_delta->data;
+	struct spi_transfer t = {
+		.tx_buf		= data,
+		.len		= size + 1,
+		.cs_change	= sigma_delta->bus_locked,
+	};
+	struct spi_message m;
+	int ret;
+
+	data[0] = (reg << sigma_delta->info->addr_shift) | sigma_delta->comm;
+
+	switch (size) {
+	case 3:
+		data[1] = val >> 16;
+		data[2] = val >> 8;
+		data[3] = val;
+		break;
+	case 2:
+		put_unaligned_be16(val, &data[1]);
+		break;
+	case 1:
+		data[1] = val;
+		break;
+	case 0:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	if (sigma_delta->bus_locked)
+		ret = spi_sync_locked(sigma_delta->spi, &m);
+	else
+		ret = spi_sync(sigma_delta->spi, &m);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ad_sd_write_reg);
+
+static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta,
+	unsigned int reg, unsigned int size, uint8_t *val)
+{
+	uint8_t *data = sigma_delta->data;
+	int ret;
+	struct spi_transfer t[] = {
+		{
+			.tx_buf = data,
+			.len = 1,
+		}, {
+			.rx_buf = val,
+			.len = size,
+			.cs_change = sigma_delta->bus_locked,
+		},
+	};
+	struct spi_message m;
+
+	spi_message_init(&m);
+
+	if (sigma_delta->info->has_registers) {
+		data[0] = reg << sigma_delta->info->addr_shift;
+		data[0] |= sigma_delta->info->read_mask;
+		spi_message_add_tail(&t[0], &m);
+	}
+	spi_message_add_tail(&t[1], &m);
+
+	if (sigma_delta->bus_locked)
+		ret = spi_sync_locked(sigma_delta->spi, &m);
+	else
+		ret = spi_sync(sigma_delta->spi, &m);
+
+	return ret;
+}
+
+/**
+ * ad_sd_read_reg() - Read a register
+ *
+ * @sigma_delta: The sigma delta device
+ * @reg: Address of the register
+ * @size: Size of the register (1-4)
+ * @val: Read value
+ *
+ * Returns 0 on success, an error code otherwise.
+ **/
+int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta,
+	unsigned int reg, unsigned int size, unsigned int *val)
+{
+	int ret;
+
+	ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->data);
+	if (ret < 0)
+		goto out;
+
+	switch (size) {
+	case 4:
+		*val = get_unaligned_be32(sigma_delta->data);
+		break;
+	case 3:
+		*val = (sigma_delta->data[0] << 16) |
+			(sigma_delta->data[1] << 8) |
+			sigma_delta->data[2];
+		break;
+	case 2:
+		*val = get_unaligned_be16(sigma_delta->data);
+		break;
+	case 1:
+		*val = sigma_delta->data[0];
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+out:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ad_sd_read_reg);
+
+static int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
+	unsigned int mode, unsigned int channel)
+{
+	int ret;
+
+	ret = ad_sigma_delta_set_channel(sigma_delta, channel);
+	if (ret)
+		return ret;
+
+	spi_bus_lock(sigma_delta->spi->master);
+	sigma_delta->bus_locked = true;
+	INIT_COMPLETION(sigma_delta->completion);
+
+	ret = ad_sigma_delta_set_mode(sigma_delta, mode);
+	if (ret < 0)
+		goto out;
+
+	sigma_delta->irq_dis = false;
+	enable_irq(sigma_delta->spi->irq);
+	ret = wait_for_completion_timeout(&sigma_delta->completion, 2*HZ);
+	if (ret == 0) {
+		sigma_delta->irq_dis = true;
+		disable_irq_nosync(sigma_delta->spi->irq);
+		ret = -EIO;
+	} else {
+		ret = 0;
+	}
+out:
+	sigma_delta->bus_locked = false;
+	spi_bus_unlock(sigma_delta->spi->master);
+	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
+
+	return ret;
+}
+
+/**
+ * ad_sd_calibrate_all() - Performs channel calibration
+ * @sigma_delta: The sigma delta device
+ * @cb: Array of channels and calibration type to perform
+ * @n: Number of items in cb
+ *
+ * Returns 0 on success, an error code otherwise.
+ **/
+int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta,
+	const struct ad_sd_calib_data *cb, unsigned int n)
+{
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < n; i++) {
+		ret = ad_sd_calibrate(sigma_delta, cb[i].mode, cb[i].channel);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ad_sd_calibrate_all);
+
+/**
+ * ad_sigma_delta_single_conversion() - Performs a single data conversion
+ * @indio_dev: The IIO device
+ * @chan: The conversion is done for this channel
+ * @val: Pointer to the location where to store the read value
+ *
+ * Returns: 0 on success, an error value otherwise.
+ */
+int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, int *val)
+{
+	struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
+	unsigned int sample, raw_sample;
+	int ret = 0;
+
+	if (iio_buffer_enabled(indio_dev))
+		return -EBUSY;
+
+	mutex_lock(&indio_dev->mlock);
+	ad_sigma_delta_set_channel(sigma_delta, chan->address);
+
+	spi_bus_lock(sigma_delta->spi->master);
+	sigma_delta->bus_locked = true;
+	INIT_COMPLETION(sigma_delta->completion);
+
+	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_SINGLE);
+
+	sigma_delta->irq_dis = false;
+	enable_irq(sigma_delta->spi->irq);
+	ret = wait_for_completion_interruptible_timeout(
+			&sigma_delta->completion, HZ);
+
+	sigma_delta->bus_locked = false;
+	spi_bus_unlock(sigma_delta->spi->master);
+
+	if (ret == 0)
+		ret = -EIO;
+	if (ret < 0)
+		goto out;
+
+	ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_DATA,
+		DIV_ROUND_UP(chan->scan_type.realbits + chan->scan_type.shift, 8),
+		&raw_sample);
+
+out:
+	if (!sigma_delta->irq_dis) {
+		disable_irq_nosync(sigma_delta->spi->irq);
+		sigma_delta->irq_dis = true;
+	}
+
+	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
+	mutex_unlock(&indio_dev->mlock);
+
+	if (ret)
+		return ret;
+
+	sample = raw_sample >> chan->scan_type.shift;
+	sample &= (1 << chan->scan_type.realbits) - 1;
+	*val = sample;
+
+	ret = ad_sigma_delta_postprocess_sample(sigma_delta, raw_sample);
+	if (ret)
+		return ret;
+
+	return IIO_VAL_INT;
+}
+EXPORT_SYMBOL_GPL(ad_sigma_delta_single_conversion);
+
+static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
+{
+	struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
+	unsigned int channel;
+	int ret;
+
+	ret = iio_triggered_buffer_postenable(indio_dev);
+	if (ret < 0)
+		return ret;
+
+	channel = find_first_bit(indio_dev->active_scan_mask,
+				 indio_dev->masklength);
+	ret = ad_sigma_delta_set_channel(sigma_delta,
+		indio_dev->channels[channel].address);
+	if (ret)
+		goto err_predisable;
+
+	spi_bus_lock(sigma_delta->spi->master);
+	sigma_delta->bus_locked = true;
+	ret = ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_CONTINUOUS);
+	if (ret)
+		goto err_unlock;
+
+	sigma_delta->irq_dis = false;
+	enable_irq(sigma_delta->spi->irq);
+
+	return 0;
+
+err_unlock:
+	spi_bus_unlock(sigma_delta->spi->master);
+err_predisable:
+
+	return ret;
+}
+
+static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev)
+{
+	struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
+
+	INIT_COMPLETION(sigma_delta->completion);
+	wait_for_completion_timeout(&sigma_delta->completion, HZ);
+
+	if (!sigma_delta->irq_dis) {
+		disable_irq_nosync(sigma_delta->spi->irq);
+		sigma_delta->irq_dis = true;
+	}
+
+	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
+
+	sigma_delta->bus_locked = false;
+	return spi_bus_unlock(sigma_delta->spi->master);
+}
+
+static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
+	unsigned int reg_size;
+	uint8_t data[16];
+	int ret;
+
+	memset(data, 0x00, 16);
+
+	/* Guaranteed to be aligned with 8 byte boundary */
+	if (indio_dev->scan_timestamp)
+		((s64 *)data)[1] = pf->timestamp;
+
+	reg_size = indio_dev->channels[0].scan_type.realbits +
+			indio_dev->channels[0].scan_type.shift;
+	reg_size = DIV_ROUND_UP(reg_size, 8);
+
+	switch (reg_size) {
+	case 4:
+	case 2:
+	case 1:
+		ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA,
+			reg_size, &data[0]);
+		break;
+	case 3:
+		/* We store 24 bit samples in a 32 bit word. Keep the upper
+		 * byte set to zero. */
+		ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA,
+			reg_size, &data[1]);
+		break;
+	}
+
+	iio_push_to_buffer(indio_dev->buffer, (uint8_t *)data, pf->timestamp);
+
+	iio_trigger_notify_done(indio_dev->trig);
+	sigma_delta->irq_dis = false;
+	enable_irq(sigma_delta->spi->irq);
+
+	return IRQ_HANDLED;
+}
+
+static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = {
+	.preenable = &iio_sw_buffer_preenable,
+	.postenable = &ad_sd_buffer_postenable,
+	.predisable = &iio_triggered_buffer_predisable,
+	.postdisable = &ad_sd_buffer_postdisable,
+	.validate_scan_mask = &iio_validate_scan_mask_onehot,
+};
+
+static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private)
+{
+	struct ad_sigma_delta *sigma_delta = private;
+
+	complete(&sigma_delta->completion);
+	disable_irq_nosync(irq);
+	sigma_delta->irq_dis = true;
+	iio_trigger_poll(sigma_delta->trig, iio_get_time_ns());
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * ad_sd_validate_trigger() - validate_trigger callback for ad_sigma_delta devices
+ * @indio_dev: The IIO device
+ * @trig: The new trigger
+ *
+ * Returns: 0 if the 'trig' matches the trigger registered by the ad_sigma_delta
+ * device, -EINVAL otherwise.
+ */
+int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig)
+{
+	struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
+
+	if (sigma_delta->trig != trig)
+		return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ad_sd_validate_trigger);
+
+static const struct iio_trigger_ops ad_sd_trigger_ops = {
+	.owner = THIS_MODULE,
+};
+
+static int ad_sd_probe_trigger(struct iio_dev *indio_dev)
+{
+	struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
+	int ret;
+
+	sigma_delta->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
+						indio_dev->id);
+	if (sigma_delta->trig == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	sigma_delta->trig->ops = &ad_sd_trigger_ops;
+	init_completion(&sigma_delta->completion);
+
+	ret = request_irq(sigma_delta->spi->irq,
+			  ad_sd_data_rdy_trig_poll,
+			  IRQF_TRIGGER_LOW,
+			  indio_dev->name,
+			  sigma_delta);
+	if (ret)
+		goto error_free_trig;
+
+	if (!sigma_delta->irq_dis) {
+		sigma_delta->irq_dis = true;
+		disable_irq_nosync(sigma_delta->spi->irq);
+	}
+	sigma_delta->trig->dev.parent = &sigma_delta->spi->dev;
+	sigma_delta->trig->private_data = sigma_delta;
+
+	ret = iio_trigger_register(sigma_delta->trig);
+	if (ret)
+		goto error_free_irq;
+
+	/* select default trigger */
+	indio_dev->trig = sigma_delta->trig;
+
+	return 0;
+
+error_free_irq:
+	free_irq(sigma_delta->spi->irq, sigma_delta);
+error_free_trig:
+	iio_trigger_free(sigma_delta->trig);
+error_ret:
+	return ret;
+}
+
+static void ad_sd_remove_trigger(struct iio_dev *indio_dev)
+{
+	struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
+
+	iio_trigger_unregister(sigma_delta->trig);
+	free_irq(sigma_delta->spi->irq, sigma_delta);
+	iio_trigger_free(sigma_delta->trig);
+}
+
+/**
+ * ad_sd_setup_buffer_and_trigger() -
+ * @indio_dev: The IIO device
+ */
+int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev)
+{
+	int ret;
+
+	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+			&ad_sd_trigger_handler, &ad_sd_buffer_setup_ops);
+	if (ret)
+		return ret;
+
+	ret = ad_sd_probe_trigger(indio_dev);
+	if (ret) {
+		iio_triggered_buffer_cleanup(indio_dev);
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ad_sd_setup_buffer_and_trigger);
+
+/**
+ * ad_sd_cleanup_buffer_and_trigger() -
+ * @indio_dev: The IIO device
+ */
+void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev)
+{
+	ad_sd_remove_trigger(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
+}
+EXPORT_SYMBOL_GPL(ad_sd_cleanup_buffer_and_trigger);
+
+/**
+ * ad_sd_init() - Initializes a ad_sigma_delta struct
+ * @sigma_delta: The ad_sigma_delta device
+ * @indio_dev: The IIO device which the Sigma Delta device is used for
+ * @spi: The SPI device for the ad_sigma_delta device
+ * @info: Device specific callbacks and options
+ *
+ * This function needs to be called before any other operations are performed on
+ * the ad_sigma_delta struct.
+ */
+int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev,
+	struct spi_device *spi, const struct ad_sigma_delta_info *info)
+{
+	sigma_delta->spi = spi;
+	sigma_delta->info = info;
+	iio_device_set_drvdata(indio_dev, sigma_delta);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ad_sd_init);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices Sigma-Delta ADCs");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h
new file mode 100644
index 000000000000..2e4eab9868a3
--- /dev/null
+++ b/include/linux/iio/adc/ad_sigma_delta.h
@@ -0,0 +1,173 @@
+/*
+ * Support code for Analog Devices Sigma-Delta ADCs
+ *
+ * Copyright 2012 Analog Devices Inc.
+ *  Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ */
+#ifndef __AD_SIGMA_DELTA_H__
+#define __AD_SIGMA_DELTA_H__
+
+enum ad_sigma_delta_mode {
+	AD_SD_MODE_CONTINUOUS = 0,
+	AD_SD_MODE_SINGLE = 1,
+	AD_SD_MODE_IDLE = 2,
+	AD_SD_MODE_POWERDOWN = 3,
+};
+
+/**
+ * struct ad_sigma_delta_calib_data - Calibration data for Sigma Delta devices
+ * @mode: Calibration mode.
+ * @channel: Calibration channel.
+ */
+struct ad_sd_calib_data {
+	unsigned int mode;
+	unsigned int channel;
+};
+
+struct ad_sigma_delta;
+struct iio_dev;
+
+/**
+ * struct ad_sigma_delta_info - Sigma Delta driver specific callbacks and options
+ * @set_channel: Will be called to select the current channel, may be NULL.
+ * @set_mode: Will be called to select the current mode, may be NULL.
+ * @postprocess_sample: Is called for each sampled data word, can be used to
+ *		modify or drop the sample data, it, may be NULL.
+ * @has_registers: true if the device has writable and readable registers, false
+ *		if there is just one read-only sample data shift register.
+ * @addr_shift: Shift of the register address in the communications register.
+ * @read_mask: Mask for the communications register having the read bit set.
+ */
+struct ad_sigma_delta_info {
+	int (*set_channel)(struct ad_sigma_delta *, unsigned int channel);
+	int (*set_mode)(struct ad_sigma_delta *, enum ad_sigma_delta_mode mode);
+	int (*postprocess_sample)(struct ad_sigma_delta *, unsigned int raw_sample);
+	bool has_registers;
+	unsigned int addr_shift;
+	unsigned int read_mask;
+};
+
+/**
+ * struct ad_sigma_delta - Sigma Delta device struct
+ * @spi: The spi device associated with the Sigma Delta device.
+ * @trig: The IIO trigger associated with the Sigma Delta device.
+ *
+ * Most of the fields are private to the sigma delta library code and should not
+ * be accessed by individual drivers.
+ */
+struct ad_sigma_delta {
+	struct spi_device	*spi;
+	struct iio_trigger	*trig;
+
+/* private: */
+	struct completion	completion;
+	bool			irq_dis;
+
+	bool			bus_locked;
+
+	uint8_t			comm;
+
+	const struct ad_sigma_delta_info *info;
+
+	/*
+	 * DMA (thus cache coherency maintenance) requires the
+	 * transfer buffers to live in their own cache lines.
+	 */
+	uint8_t				data[4] ____cacheline_aligned;
+};
+
+static inline int ad_sigma_delta_set_channel(struct ad_sigma_delta *sd,
+	unsigned int channel)
+{
+	if (sd->info->set_channel)
+		return sd->info->set_channel(sd, channel);
+
+	return 0;
+}
+
+static inline int ad_sigma_delta_set_mode(struct ad_sigma_delta *sd,
+	unsigned int mode)
+{
+	if (sd->info->set_mode)
+		return sd->info->set_mode(sd, mode);
+
+	return 0;
+}
+
+static inline int ad_sigma_delta_postprocess_sample(struct ad_sigma_delta *sd,
+	unsigned int raw_sample)
+{
+	if (sd->info->postprocess_sample)
+		return sd->info->postprocess_sample(sd, raw_sample);
+
+	return 0;
+}
+
+void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm);
+int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
+	unsigned int size, unsigned int val);
+int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
+	unsigned int size, unsigned int *val);
+
+int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, int *val);
+int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta,
+	const struct ad_sd_calib_data *cd, unsigned int n);
+int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev,
+	struct spi_device *spi, const struct ad_sigma_delta_info *info);
+
+int ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev);
+void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev);
+
+int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig);
+
+#define __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
+	_storagebits, _shift, _extend_name, _type) \
+	{ \
+		.type = (_type), \
+		.differential = (_channel2 == -1 ? 0 : 1), \
+		.indexed = 1, \
+		.channel = (_channel1), \
+		.channel2 = (_channel2), \
+		.address = (_address), \
+		.extend_name = (_extend_name), \
+		.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+			IIO_CHAN_INFO_SCALE_SHARED_BIT | \
+			IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \
+		.scan_index = (_si), \
+		.scan_type = { \
+			.sign = 'u', \
+			.realbits = (_bits), \
+			.storagebits = (_storagebits), \
+			.shift = (_shift), \
+			.endianness = IIO_BE, \
+		}, \
+	}
+
+#define AD_SD_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
+	_storagebits, _shift) \
+	__AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \
+		_storagebits, _shift, NULL, IIO_VOLTAGE)
+
+#define AD_SD_SHORTED_CHANNEL(_si, _channel, _address, _bits, \
+	_storagebits, _shift) \
+	__AD_SD_CHANNEL(_si, _channel, _channel, _address, _bits, \
+		_storagebits, _shift, "shorted", IIO_VOLTAGE)
+
+#define AD_SD_CHANNEL(_si, _channel, _address, _bits, \
+	_storagebits, _shift) \
+	__AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \
+		_storagebits, _shift, NULL, IIO_VOLTAGE)
+
+#define AD_SD_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \
+	__AD_SD_CHANNEL(_si, 0, -1, _address, _bits, \
+		_storagebits, _shift, NULL, IIO_TEMP)
+
+#define AD_SD_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \
+	_shift) \
+	__AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \
+		_storagebits, _shift, "supply", IIO_VOLTAGE)
+
+#endif