Commit 8508317c authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'iio-for-v3.7d' of...

Merge tag 'iio-for-v3.7d' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

IIO new drivers, features and rework for the 3.7 cycle, 4th set.

Here we have

1) a set cleaning up and moving the ad7476 driver out of staging.
Support for a number of additional parts is also added to that driver.

2) cleanups from various people for the in kernel interface code as that
is getting more an more real use and hence people are picking up on
minor issues that made it through review.  Also a related useful set
of utility functions to avoid duplicate code for converting IIO
representations to other forms.

3) a new fractional type for our read_raw / write_raw functions.
  This allows avoiding loss of accuracy via the in kernel interfaces in some
  cases as well as being rather convenient for a lot of range -> scale
  conversions.

4) New AD5755 DAC driver.

5) Some Blackfin timer trigger improvements including hardware pulse control
for device triggering.

6) Support for the ad7091r in the ad7476 driver.
parents 3afcb91c 87c5b10f
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -30,6 +30,21 @@ config AD7791
	  To compile this driver as a module, choose M here: the module will be
	  called ad7791.

config AD7476
	tristate "Analog Devices AD7476 and similar 1-channel ADCs driver"
	depends on SPI
	select IIO_BUFFER
	select IIO_TRIGGERED_BUFFER
	help
	  Say yes here to build support for Analog Devices AD7273, AD7274, AD7276,
	  AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
	  AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC).

	  If unsure, say N (but it's safe to say "Y").

	  To compile this driver as a module, choose M here: the
	  module will be called ad7476.

config AT91_ADC
	tristate "Atmel AT91 ADC"
	depends on ARCH_AT91
+1 −0
Original line number Diff line number Diff line
@@ -4,5 +4,6 @@

obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
obj-$(CONFIG_AD7266) += ad7266.o
obj-$(CONFIG_AD7476) += ad7476.o
obj-$(CONFIG_AD7791) += ad7791.o
obj-$(CONFIG_AT91_ADC) += at91_adc.o
+148 −60
Original line number Diff line number Diff line
@@ -18,8 +18,76 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>

#include "ad7476.h"
#define RES_MASK(bits)	((1 << (bits)) - 1)

struct ad7476_state;

struct ad7476_chip_info {
	unsigned int			int_vref_uv;
	struct iio_chan_spec		channel[2];
	void (*reset)(struct ad7476_state *);
};

struct ad7476_state {
	struct spi_device		*spi;
	const struct ad7476_chip_info	*chip_info;
	struct regulator		*reg;
	struct spi_transfer		xfer;
	struct spi_message		msg;
	/*
	 * DMA (thus cache coherency maintenance) requires the
	 * transfer buffers to live in their own cache lines.
	 * Make the buffer large enough for one 16 bit sample and one 64 bit
	 * aligned 64 bit timestamp.
	 */
	unsigned char data[ALIGN(2, sizeof(s64)) + sizeof(s64)]
			____cacheline_aligned;
};

enum ad7476_supported_device_ids {
	ID_AD7091R,
	ID_AD7276,
	ID_AD7277,
	ID_AD7278,
	ID_AD7466,
	ID_AD7467,
	ID_AD7468,
	ID_AD7495,
	ID_AD7940,
};

static irqreturn_t ad7476_trigger_handler(int irq, void  *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct ad7476_state *st = iio_priv(indio_dev);
	s64 time_ns;
	int b_sent;

	b_sent = spi_sync(st->spi, &st->msg);
	if (b_sent < 0)
		goto done;

	time_ns = iio_get_time_ns();

	if (indio_dev->scan_timestamp)
		((s64 *)st->data)[1] = time_ns;

	iio_push_to_buffer(indio_dev->buffer, st->data);
done:
	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

static void ad7091_reset(struct ad7476_state *st)
{
	/* Any transfers with 8 scl cycles will reset the device */
	spi_read(st->spi, st->data, 1);
}

static int ad7476_scan_direct(struct ad7476_state *st)
{
@@ -29,7 +97,7 @@ static int ad7476_scan_direct(struct ad7476_state *st)
	if (ret)
		return ret;

	return (st->data[0] << 8) | st->data[1];
	return be16_to_cpup((__be16 *)st->data);
}

static int ad7476_read_raw(struct iio_dev *indio_dev,
@@ -40,7 +108,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
{
	int ret;
	struct ad7476_state *st = iio_priv(indio_dev);
	unsigned int scale_uv;
	int scale_uv;

	switch (m) {
	case IIO_CHAN_INFO_RAW:
@@ -57,8 +125,14 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
			RES_MASK(st->chip_info->channel[0].scan_type.realbits);
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		scale_uv = (st->int_vref_mv * 1000)
			>> st->chip_info->channel[0].scan_type.realbits;
		if (!st->chip_info->int_vref_uv) {
			scale_uv = regulator_get_voltage(st->reg);
			if (scale_uv < 0)
				return scale_uv;
		} else {
			scale_uv = st->chip_info->int_vref_uv;
		}
		scale_uv >>= chan->scan_type.realbits;
		*val =  scale_uv / 1000;
		*val2 = (scale_uv % 1000) * 1000;
		return IIO_VAL_INT_PLUS_MICRO;
@@ -66,53 +140,65 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
	return -EINVAL;
}

#define AD7476_CHAN(bits)					\
#define _AD7476_CHAN(bits, _shift, _info_mask)			\
	{							\
	.type = IIO_VOLTAGE,					\
	.indexed = 1,						\
	.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |		\
	.info_mask = _info_mask |				\
	IIO_CHAN_INFO_SCALE_SHARED_BIT,				\
	.scan_type = {						\
		.sign = 'u',					\
		.realbits = bits,				\
		.realbits = (bits),				\
		.storagebits = 16,				\
		.shift = 12 - bits,				\
		.shift = (_shift),				\
		.endianness = IIO_BE,				\
	},							\
}

#define AD7476_CHAN(bits) _AD7476_CHAN((bits), 13 - (bits), \
		IIO_CHAN_INFO_RAW_SEPARATE_BIT)
#define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \
		IIO_CHAN_INFO_RAW_SEPARATE_BIT)
#define AD7091R_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), 0)

static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
	[ID_AD7466] = {
		.channel[0] = AD7476_CHAN(12),
	[ID_AD7091R] = {
		.channel[0] = AD7091R_CHAN(12),
		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
		.reset = ad7091_reset,
	},
	[ID_AD7467] = {
		.channel[0] = AD7476_CHAN(10),
	[ID_AD7276] = {
		.channel[0] = AD7940_CHAN(12),
		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
	},
	[ID_AD7468] = {
		.channel[0] = AD7476_CHAN(8),
	[ID_AD7277] = {
		.channel[0] = AD7940_CHAN(10),
		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
	},
	[ID_AD7475] = {
		.channel[0] = AD7476_CHAN(12),
	[ID_AD7278] = {
		.channel[0] = AD7940_CHAN(8),
		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
	},
	[ID_AD7476] = {
	[ID_AD7466] = {
		.channel[0] = AD7476_CHAN(12),
		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
	},
	[ID_AD7477] = {
	[ID_AD7467] = {
		.channel[0] = AD7476_CHAN(10),
		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
	},
	[ID_AD7478] = {
	[ID_AD7468] = {
		.channel[0] = AD7476_CHAN(8),
		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
	},
	[ID_AD7495] = {
		.channel[0] = AD7476_CHAN(12),
		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
		.int_vref_mv = 2500,
		.int_vref_uv = 2500000,
	},
	[ID_AD7940] = {
		.channel[0] = AD7940_CHAN(14),
		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
	},
};

@@ -123,10 +209,9 @@ static const struct iio_info ad7476_info = {

static int __devinit ad7476_probe(struct spi_device *spi)
{
	struct ad7476_platform_data *pdata = spi->dev.platform_data;
	struct ad7476_state *st;
	struct iio_dev *indio_dev;
	int ret, voltage_uv = 0;
	int ret;

	indio_dev = iio_device_alloc(sizeof(*st));
	if (indio_dev == NULL) {
@@ -134,26 +219,19 @@ static int __devinit ad7476_probe(struct spi_device *spi)
		goto error_ret;
	}
	st = iio_priv(indio_dev);
	st->chip_info =
		&ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];

	st->reg = regulator_get(&spi->dev, "vcc");
	if (!IS_ERR(st->reg)) {
	if (IS_ERR(st->reg)) {
		ret = PTR_ERR(st->reg);
		goto error_free_dev;
	}

	ret = regulator_enable(st->reg);
	if (ret)
		goto error_put_reg;

		voltage_uv = regulator_get_voltage(st->reg);
	}
	st->chip_info =
		&ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];

	if (st->chip_info->int_vref_mv)
		st->int_vref_mv = st->chip_info->int_vref_mv;
	else if (pdata && pdata->vref_mv)
		st->int_vref_mv = pdata->vref_mv;
	else if (voltage_uv)
		st->int_vref_mv = voltage_uv / 1000;
	else
		dev_warn(&spi->dev, "reference voltage unspecified\n");

	spi_set_drvdata(spi, indio_dev);

	st->spi = spi;
@@ -173,23 +251,26 @@ static int __devinit ad7476_probe(struct spi_device *spi)
	spi_message_init(&st->msg);
	spi_message_add_tail(&st->xfer, &st->msg);

	ret = ad7476_register_ring_funcs_and_init(indio_dev);
	ret = iio_triggered_buffer_setup(indio_dev, NULL,
			&ad7476_trigger_handler, NULL);
	if (ret)
		goto error_disable_reg;

	if (st->chip_info->reset)
		st->chip_info->reset(st);

	ret = iio_device_register(indio_dev);
	if (ret)
		goto error_ring_unregister;
	return 0;

error_ring_unregister:
	ad7476_ring_cleanup(indio_dev);
	iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
	if (!IS_ERR(st->reg))
	regulator_disable(st->reg);
error_put_reg:
	if (!IS_ERR(st->reg))
	regulator_put(st->reg);
error_free_dev:
	iio_device_free(indio_dev);

error_ret:
@@ -202,28 +283,35 @@ static int __devexit ad7476_remove(struct spi_device *spi)
	struct ad7476_state *st = iio_priv(indio_dev);

	iio_device_unregister(indio_dev);
	ad7476_ring_cleanup(indio_dev);
	if (!IS_ERR(st->reg)) {
	iio_triggered_buffer_cleanup(indio_dev);
	regulator_disable(st->reg);
	regulator_put(st->reg);
	}
	iio_device_free(indio_dev);

	return 0;
}

static const struct spi_device_id ad7476_id[] = {
	{"ad7091r", ID_AD7091R},
	{"ad7273", ID_AD7277},
	{"ad7274", ID_AD7276},
	{"ad7276", ID_AD7276},
	{"ad7277", ID_AD7277},
	{"ad7278", ID_AD7278},
	{"ad7466", ID_AD7466},
	{"ad7467", ID_AD7467},
	{"ad7468", ID_AD7468},
	{"ad7475", ID_AD7475},
	{"ad7476", ID_AD7476},
	{"ad7476a", ID_AD7476},
	{"ad7477", ID_AD7477},
	{"ad7477a", ID_AD7477},
	{"ad7478", ID_AD7478},
	{"ad7478a", ID_AD7478},
	{"ad7475", ID_AD7466},
	{"ad7476", ID_AD7466},
	{"ad7476a", ID_AD7466},
	{"ad7477", ID_AD7467},
	{"ad7477a", ID_AD7467},
	{"ad7478", ID_AD7468},
	{"ad7478a", ID_AD7468},
	{"ad7495", ID_AD7495},
	{"ad7910", ID_AD7467},
	{"ad7920", ID_AD7466},
	{"ad7940", ID_AD7940},
	{}
};
MODULE_DEVICE_TABLE(spi, ad7476_id);
@@ -240,5 +328,5 @@ static struct spi_driver ad7476_driver = {
module_spi_driver(ad7476_driver);

MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
MODULE_DESCRIPTION("Analog Devices AD7475/6/7/8(A) AD7466/7/8 ADC");
MODULE_DESCRIPTION("Analog Devices AD7476 and similar 1-channel ADCs");
MODULE_LICENSE("GPL v2");
+11 −0
Original line number Diff line number Diff line
@@ -77,6 +77,17 @@ config AD5504
	  To compile this driver as a module, choose M here: the
	  module will be called ad5504.

config AD5755
	tristate "Analog Devices AD5755/AD5755-1/AD5757/AD5735/AD5737 DAC driver"
	depends on SPI_MASTER
	help
	  Say yes here to build support for Analog Devices AD5755, AD5755-1,
	  AD5757, AD5735, AD5737 quad channel Digital to
	  Analog Converter.

	  To compile this driver as a module, choose M here: the
	  module will be called ad5755.

config AD5764
	tristate "Analog Devices AD5764/64R/44/44R DAC driver"
	depends on SPI_MASTER
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o
obj-$(CONFIG_AD5064) += ad5064.o
obj-$(CONFIG_AD5504) += ad5504.o
obj-$(CONFIG_AD5446) += ad5446.o
obj-$(CONFIG_AD5755) += ad5755.o
obj-$(CONFIG_AD5764) += ad5764.o
obj-$(CONFIG_AD5791) += ad5791.o
obj-$(CONFIG_AD5686) += ad5686.o
Loading