staging:iio: Move DAC drivers out of staging
authorLars-Peter Clausen <lars@metafoo.de>
Mon, 4 Jun 2012 09:36:28 +0000 (11:36 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 5 Jun 2012 05:02:25 +0000 (14:02 +0900)
The IIO DAC drivers are in a reasonably good shape. They all make use of channel
spec and non of them provides non-documented sysfs attributes. Code style should
be OK as well, both checkpatch and coccicheck only report trivial issues.

So lets move the whole folder out of staging.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
42 files changed:
drivers/iio/Kconfig
drivers/iio/Makefile
drivers/iio/dac/Kconfig [new file with mode: 0644]
drivers/iio/dac/Makefile [new file with mode: 0644]
drivers/iio/dac/ad5064.c [new file with mode: 0644]
drivers/iio/dac/ad5360.c [new file with mode: 0644]
drivers/iio/dac/ad5380.c [new file with mode: 0644]
drivers/iio/dac/ad5421.c [new file with mode: 0644]
drivers/iio/dac/ad5446.c [new file with mode: 0644]
drivers/iio/dac/ad5446.h [new file with mode: 0644]
drivers/iio/dac/ad5504.c [new file with mode: 0644]
drivers/iio/dac/ad5624r.h [new file with mode: 0644]
drivers/iio/dac/ad5624r_spi.c [new file with mode: 0644]
drivers/iio/dac/ad5686.c [new file with mode: 0644]
drivers/iio/dac/ad5764.c [new file with mode: 0644]
drivers/iio/dac/ad5791.c [new file with mode: 0644]
drivers/iio/dac/max517.c [new file with mode: 0644]
drivers/staging/iio/Kconfig
drivers/staging/iio/Makefile
drivers/staging/iio/dac/Kconfig [deleted file]
drivers/staging/iio/dac/Makefile [deleted file]
drivers/staging/iio/dac/ad5064.c [deleted file]
drivers/staging/iio/dac/ad5360.c [deleted file]
drivers/staging/iio/dac/ad5380.c [deleted file]
drivers/staging/iio/dac/ad5421.c [deleted file]
drivers/staging/iio/dac/ad5421.h [deleted file]
drivers/staging/iio/dac/ad5446.c [deleted file]
drivers/staging/iio/dac/ad5446.h [deleted file]
drivers/staging/iio/dac/ad5504.c [deleted file]
drivers/staging/iio/dac/ad5504.h [deleted file]
drivers/staging/iio/dac/ad5624r.h [deleted file]
drivers/staging/iio/dac/ad5624r_spi.c [deleted file]
drivers/staging/iio/dac/ad5686.c [deleted file]
drivers/staging/iio/dac/ad5764.c [deleted file]
drivers/staging/iio/dac/ad5791.c [deleted file]
drivers/staging/iio/dac/ad5791.h [deleted file]
drivers/staging/iio/dac/max517.c [deleted file]
drivers/staging/iio/dac/max517.h [deleted file]
include/linux/iio/dac/ad5421.h [new file with mode: 0644]
include/linux/iio/dac/ad5504.h [new file with mode: 0644]
include/linux/iio/dac/ad5791.h [new file with mode: 0644]
include/linux/iio/dac/max517.h [new file with mode: 0644]

index 64c88e5cda4d95ded7b0572752adbe257eec4af3..103349f2b3b5be0657c2d8138b55ad7a6af41c57 100644 (file)
@@ -52,5 +52,6 @@ source "drivers/iio/adc/Kconfig"
 source "drivers/iio/amplifiers/Kconfig"
 source "drivers/iio/light/Kconfig"
 source "drivers/iio/frequency/Kconfig"
+source "drivers/iio/dac/Kconfig"
 
 endif # IIO
index bd801c0bbc2f9b2967c05143a5999c3d4fdf760f..c38fa2a40af27630b94783d7bdb34ff60d0e8213 100644 (file)
@@ -13,3 +13,4 @@ obj-y += adc/
 obj-y += amplifiers/
 obj-y += light/
 obj-y += frequency/
+obj-y += dac/
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
new file mode 100644 (file)
index 0000000..a626f03
--- /dev/null
@@ -0,0 +1,121 @@
+#
+# DAC drivers
+#
+menu "Digital to analog converters"
+
+config AD5064
+       tristate "Analog Devices AD5064/64-1/65/44/45/24/25, AD5628/48/66/68 DAC driver"
+       depends on SPI
+       help
+         Say yes here to build support for Analog Devices AD5024, AD5025, AD5044,
+         AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5648, AD5666, AD5668 Digital
+         to Analog Converter.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ad5064.
+
+config AD5360
+       tristate "Analog Devices Analog Devices AD5360/61/62/63/70/71/73 DAC driver"
+       depends on SPI
+       help
+         Say yes here to build support for Analog Devices AD5360, AD5361,
+         AD5362, AD5363, AD5370, AD5371, AD5373 multi-channel
+         Digital to Analog Converters (DAC).
+
+         To compile this driver as module choose M here: the module will be called
+         ad5360.
+
+config AD5380
+       tristate "Analog Devices AD5380/81/82/83/84/90/91/92 DAC driver"
+       depends on (SPI_MASTER || I2C)
+       select REGMAP_I2C if I2C
+       select REGMAP_SPI if SPI_MASTER
+       help
+         Say yes here to build support for Analog Devices AD5380, AD5381,
+         AD5382, AD5383, AD5384, AD5390, AD5391, AD5392 multi-channel
+         Digital to Analog Converters (DAC).
+
+         To compile this driver as module choose M here: the module will be called
+         ad5380.
+
+config AD5421
+       tristate "Analog Devices AD5421 DAC driver"
+       depends on SPI
+       help
+         Say yes here to build support for Analog Devices AD5421 loop-powered
+         digital-to-analog convertors (DAC).
+
+         To compile this driver as module choose M here: the module will be called
+         ad5421.
+
+config AD5624R_SPI
+       tristate "Analog Devices AD5624/44/64R DAC spi driver"
+       depends on SPI
+       help
+         Say yes here to build support for Analog Devices AD5624R, AD5644R and
+         AD5664R converters (DAC). This driver uses the common SPI interface.
+
+config AD5446
+       tristate "Analog Devices AD5446 and similar single channel DACs driver"
+       depends on SPI
+       help
+         Say yes here to build support for Analog Devices AD5444, AD5446,
+         AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5611, AD5620,
+         AD5621, AD5640, AD5660, AD5662 DACs.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ad5446.
+
+config AD5504
+       tristate "Analog Devices AD5504/AD5501 DAC SPI driver"
+       depends on SPI
+       help
+         Say yes here to build support for Analog Devices AD5504, AD5501,
+         High Voltage Digital to Analog Converter.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ad5504.
+
+config AD5764
+       tristate "Analog Devices AD5764/64R/44/44R DAC driver"
+       depends on SPI_MASTER
+       help
+         Say yes here to build support for Analog Devices AD5764, AD5764R, AD5744,
+         AD5744R Digital to Analog Converter.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ad5764.
+
+config AD5791
+       tristate "Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC SPI driver"
+       depends on SPI
+       help
+         Say yes here to build support for Analog Devices AD5760, AD5780,
+         AD5781, AD5790, AD5791 High Resolution Voltage Output Digital to
+         Analog Converter.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ad5791.
+
+config AD5686
+       tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver"
+       depends on SPI
+       help
+         Say yes here to build support for Analog Devices AD5686R, AD5685R,
+         AD5684R, AD5791 Voltage Output Digital to
+         Analog Converter.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ad5686.
+
+config MAX517
+       tristate "Maxim MAX517/518/519 DAC driver"
+       depends on I2C && EXPERIMENTAL
+       help
+         If you say yes here you get support for the Maxim chips MAX517,
+         MAX518 and MAX519 (I2C 8-Bit DACs with rail-to-rail outputs).
+
+         This driver can also be built as a module.  If so, the module
+         will be called max517.
+
+endmenu
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
new file mode 100644 (file)
index 0000000..8ab1d26
--- /dev/null
@@ -0,0 +1,15 @@
+#
+# Makefile for industrial I/O DAC drivers
+#
+
+obj-$(CONFIG_AD5360) += ad5360.o
+obj-$(CONFIG_AD5380) += ad5380.o
+obj-$(CONFIG_AD5421) += ad5421.o
+obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o
+obj-$(CONFIG_AD5064) += ad5064.o
+obj-$(CONFIG_AD5504) += ad5504.o
+obj-$(CONFIG_AD5446) += ad5446.o
+obj-$(CONFIG_AD5764) += ad5764.o
+obj-$(CONFIG_AD5791) += ad5791.o
+obj-$(CONFIG_AD5686) += ad5686.o
+obj-$(CONFIG_MAX517) += max517.o
diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c
new file mode 100644 (file)
index 0000000..276af02
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5648,
+ * AD5666, AD5668 Digital to analog converters driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define AD5064_MAX_DAC_CHANNELS                        8
+#define AD5064_MAX_VREFS                       4
+
+#define AD5064_ADDR(x)                         ((x) << 20)
+#define AD5064_CMD(x)                          ((x) << 24)
+
+#define AD5064_ADDR_DAC(chan)                  (chan)
+#define AD5064_ADDR_ALL_DAC                    0xF
+
+#define AD5064_CMD_WRITE_INPUT_N               0x0
+#define AD5064_CMD_UPDATE_DAC_N                        0x1
+#define AD5064_CMD_WRITE_INPUT_N_UPDATE_ALL    0x2
+#define AD5064_CMD_WRITE_INPUT_N_UPDATE_N      0x3
+#define AD5064_CMD_POWERDOWN_DAC               0x4
+#define AD5064_CMD_CLEAR                       0x5
+#define AD5064_CMD_LDAC_MASK                   0x6
+#define AD5064_CMD_RESET                       0x7
+#define AD5064_CMD_CONFIG                      0x8
+
+#define AD5064_CONFIG_DAISY_CHAIN_ENABLE       BIT(1)
+#define AD5064_CONFIG_INT_VREF_ENABLE          BIT(0)
+
+#define AD5064_LDAC_PWRDN_NONE                 0x0
+#define AD5064_LDAC_PWRDN_1K                   0x1
+#define AD5064_LDAC_PWRDN_100K                 0x2
+#define AD5064_LDAC_PWRDN_3STATE               0x3
+
+/**
+ * struct ad5064_chip_info - chip specific information
+ * @shared_vref:       whether the vref supply is shared between channels
+ * @internal_vref:     internal reference voltage. 0 if the chip has no internal
+ *                     vref.
+ * @channel:           channel specification
+ * @num_channels:      number of channels
+ */
+
+struct ad5064_chip_info {
+       bool shared_vref;
+       unsigned long internal_vref;
+       const struct iio_chan_spec *channels;
+       unsigned int num_channels;
+};
+
+/**
+ * struct ad5064_state - driver instance specific data
+ * @spi:               spi_device
+ * @chip_info:         chip model specific constants, available modes etc
+ * @vref_reg:          vref supply regulators
+ * @pwr_down:          whether channel is powered down
+ * @pwr_down_mode:     channel's current power down mode
+ * @dac_cache:         current DAC raw value (chip does not support readback)
+ * @use_internal_vref: set to true if the internal reference voltage should be
+ *                     used.
+ * @data:              spi transfer buffers
+ */
+
+struct ad5064_state {
+       struct spi_device               *spi;
+       const struct ad5064_chip_info   *chip_info;
+       struct regulator_bulk_data      vref_reg[AD5064_MAX_VREFS];
+       bool                            pwr_down[AD5064_MAX_DAC_CHANNELS];
+       u8                              pwr_down_mode[AD5064_MAX_DAC_CHANNELS];
+       unsigned int                    dac_cache[AD5064_MAX_DAC_CHANNELS];
+       bool                            use_internal_vref;
+
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+       __be32 data ____cacheline_aligned;
+};
+
+enum ad5064_type {
+       ID_AD5024,
+       ID_AD5025,
+       ID_AD5044,
+       ID_AD5045,
+       ID_AD5064,
+       ID_AD5064_1,
+       ID_AD5065,
+       ID_AD5628_1,
+       ID_AD5628_2,
+       ID_AD5648_1,
+       ID_AD5648_2,
+       ID_AD5666_1,
+       ID_AD5666_2,
+       ID_AD5668_1,
+       ID_AD5668_2,
+};
+
+static int ad5064_spi_write(struct ad5064_state *st, unsigned int cmd,
+       unsigned int addr, unsigned int val, unsigned int shift)
+{
+       val <<= shift;
+
+       st->data = cpu_to_be32(AD5064_CMD(cmd) | AD5064_ADDR(addr) | val);
+
+       return spi_write(st->spi, &st->data, sizeof(st->data));
+}
+
+static int ad5064_sync_powerdown_mode(struct ad5064_state *st,
+       unsigned int channel)
+{
+       unsigned int val;
+       int ret;
+
+       val = (0x1 << channel);
+
+       if (st->pwr_down[channel])
+               val |= st->pwr_down_mode[channel] << 8;
+
+       ret = ad5064_spi_write(st, AD5064_CMD_POWERDOWN_DAC, 0, val, 0);
+
+       return ret;
+}
+
+static const char * const ad5064_powerdown_modes[] = {
+       "1kohm_to_gnd",
+       "100kohm_to_gnd",
+       "three_state",
+};
+
+static int ad5064_get_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan)
+{
+       struct ad5064_state *st = iio_priv(indio_dev);
+
+       return st->pwr_down_mode[chan->channel] - 1;
+}
+
+static int ad5064_set_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, unsigned int mode)
+{
+       struct ad5064_state *st = iio_priv(indio_dev);
+       int ret;
+
+       mutex_lock(&indio_dev->mlock);
+       st->pwr_down_mode[chan->channel] = mode + 1;
+
+       ret = ad5064_sync_powerdown_mode(st, chan->channel);
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret;
+}
+
+static const struct iio_enum ad5064_powerdown_mode_enum = {
+       .items = ad5064_powerdown_modes,
+       .num_items = ARRAY_SIZE(ad5064_powerdown_modes),
+       .get = ad5064_get_powerdown_mode,
+       .set = ad5064_set_powerdown_mode,
+};
+
+static ssize_t ad5064_read_dac_powerdown(struct iio_dev *indio_dev,
+       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
+{
+       struct ad5064_state *st = iio_priv(indio_dev);
+
+       return sprintf(buf, "%d\n", st->pwr_down[chan->channel]);
+}
+
+static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev,
+        uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
+        size_t len)
+{
+       struct ad5064_state *st = iio_priv(indio_dev);
+       bool pwr_down;
+       int ret;
+
+       ret = strtobool(buf, &pwr_down);
+       if (ret)
+               return ret;
+
+       mutex_lock(&indio_dev->mlock);
+       st->pwr_down[chan->channel] = pwr_down;
+
+       ret = ad5064_sync_powerdown_mode(st, chan->channel);
+       mutex_unlock(&indio_dev->mlock);
+       return ret ? ret : len;
+}
+
+static int ad5064_get_vref(struct ad5064_state *st,
+       struct iio_chan_spec const *chan)
+{
+       unsigned int i;
+
+       if (st->use_internal_vref)
+               return st->chip_info->internal_vref;
+
+       i = st->chip_info->shared_vref ? 0 : chan->channel;
+       return regulator_get_voltage(st->vref_reg[i].consumer);
+}
+
+static int ad5064_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val,
+                          int *val2,
+                          long m)
+{
+       struct ad5064_state *st = iio_priv(indio_dev);
+       int scale_uv;
+
+       switch (m) {
+       case IIO_CHAN_INFO_RAW:
+               *val = st->dac_cache[chan->channel];
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               scale_uv = ad5064_get_vref(st, chan);
+               if (scale_uv < 0)
+                       return scale_uv;
+
+               scale_uv = (scale_uv * 100) >> chan->scan_type.realbits;
+               *val =  scale_uv / 100000;
+               *val2 = (scale_uv % 100000) * 10;
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               break;
+       }
+       return -EINVAL;
+}
+
+static int ad5064_write_raw(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan, int val, int val2, long mask)
+{
+       struct ad5064_state *st = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (val > (1 << chan->scan_type.realbits) || val < 0)
+                       return -EINVAL;
+
+               mutex_lock(&indio_dev->mlock);
+               ret = ad5064_spi_write(st, AD5064_CMD_WRITE_INPUT_N_UPDATE_N,
+                               chan->address, val, chan->scan_type.shift);
+               if (ret == 0)
+                       st->dac_cache[chan->channel] = val;
+               mutex_unlock(&indio_dev->mlock);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static const struct iio_info ad5064_info = {
+       .read_raw = ad5064_read_raw,
+       .write_raw = ad5064_write_raw,
+       .driver_module = THIS_MODULE,
+};
+
+static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
+       {
+               .name = "powerdown",
+               .read = ad5064_read_dac_powerdown,
+               .write = ad5064_write_dac_powerdown,
+       },
+       IIO_ENUM("powerdown_mode", false, &ad5064_powerdown_mode_enum),
+       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5064_powerdown_mode_enum),
+       { },
+};
+
+#define AD5064_CHANNEL(chan, bits) {                           \
+       .type = IIO_VOLTAGE,                                    \
+       .indexed = 1,                                           \
+       .output = 1,                                            \
+       .channel = (chan),                                      \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |           \
+       IIO_CHAN_INFO_SCALE_SEPARATE_BIT,                       \
+       .address = AD5064_ADDR_DAC(chan),                       \
+       .scan_type = IIO_ST('u', (bits), 16, 20 - (bits)),      \
+       .ext_info = ad5064_ext_info,                            \
+}
+
+#define DECLARE_AD5064_CHANNELS(name, bits) \
+const struct iio_chan_spec name[] = { \
+       AD5064_CHANNEL(0, bits), \
+       AD5064_CHANNEL(1, bits), \
+       AD5064_CHANNEL(2, bits), \
+       AD5064_CHANNEL(3, bits), \
+       AD5064_CHANNEL(4, bits), \
+       AD5064_CHANNEL(5, bits), \
+       AD5064_CHANNEL(6, bits), \
+       AD5064_CHANNEL(7, bits), \
+}
+
+static DECLARE_AD5064_CHANNELS(ad5024_channels, 12);
+static DECLARE_AD5064_CHANNELS(ad5044_channels, 14);
+static DECLARE_AD5064_CHANNELS(ad5064_channels, 16);
+
+static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
+       [ID_AD5024] = {
+               .shared_vref = false,
+               .channels = ad5024_channels,
+               .num_channels = 4,
+       },
+       [ID_AD5025] = {
+               .shared_vref = false,
+               .channels = ad5024_channels,
+               .num_channels = 2,
+       },
+       [ID_AD5044] = {
+               .shared_vref = false,
+               .channels = ad5044_channels,
+               .num_channels = 4,
+       },
+       [ID_AD5045] = {
+               .shared_vref = false,
+               .channels = ad5044_channels,
+               .num_channels = 2,
+       },
+       [ID_AD5064] = {
+               .shared_vref = false,
+               .channels = ad5064_channels,
+               .num_channels = 4,
+       },
+       [ID_AD5064_1] = {
+               .shared_vref = true,
+               .channels = ad5064_channels,
+               .num_channels = 4,
+       },
+       [ID_AD5065] = {
+               .shared_vref = false,
+               .channels = ad5064_channels,
+               .num_channels = 2,
+       },
+       [ID_AD5628_1] = {
+               .shared_vref = true,
+               .internal_vref = 2500000,
+               .channels = ad5024_channels,
+               .num_channels = 8,
+       },
+       [ID_AD5628_2] = {
+               .shared_vref = true,
+               .internal_vref = 5000000,
+               .channels = ad5024_channels,
+               .num_channels = 8,
+       },
+       [ID_AD5648_1] = {
+               .shared_vref = true,
+               .internal_vref = 2500000,
+               .channels = ad5044_channels,
+               .num_channels = 8,
+       },
+       [ID_AD5648_2] = {
+               .shared_vref = true,
+               .internal_vref = 5000000,
+               .channels = ad5044_channels,
+               .num_channels = 8,
+       },
+       [ID_AD5666_1] = {
+               .shared_vref = true,
+               .internal_vref = 2500000,
+               .channels = ad5064_channels,
+               .num_channels = 4,
+       },
+       [ID_AD5666_2] = {
+               .shared_vref = true,
+               .internal_vref = 5000000,
+               .channels = ad5064_channels,
+               .num_channels = 4,
+       },
+       [ID_AD5668_1] = {
+               .shared_vref = true,
+               .internal_vref = 2500000,
+               .channels = ad5064_channels,
+               .num_channels = 8,
+       },
+       [ID_AD5668_2] = {
+               .shared_vref = true,
+               .internal_vref = 5000000,
+               .channels = ad5064_channels,
+               .num_channels = 8,
+       },
+};
+
+static inline unsigned int ad5064_num_vref(struct ad5064_state *st)
+{
+       return st->chip_info->shared_vref ? 1 : st->chip_info->num_channels;
+}
+
+static const char * const ad5064_vref_names[] = {
+       "vrefA",
+       "vrefB",
+       "vrefC",
+       "vrefD",
+};
+
+static const char * const ad5064_vref_name(struct ad5064_state *st,
+       unsigned int vref)
+{
+       return st->chip_info->shared_vref ? "vref" : ad5064_vref_names[vref];
+}
+
+static int __devinit ad5064_probe(struct spi_device *spi)
+{
+       enum ad5064_type type = spi_get_device_id(spi)->driver_data;
+       struct iio_dev *indio_dev;
+       struct ad5064_state *st;
+       unsigned int i;
+       int ret;
+
+       indio_dev = iio_device_alloc(sizeof(*st));
+       if (indio_dev == NULL)
+               return  -ENOMEM;
+
+       st = iio_priv(indio_dev);
+       spi_set_drvdata(spi, indio_dev);
+
+       st->chip_info = &ad5064_chip_info_tbl[type];
+       st->spi = spi;
+
+       for (i = 0; i < ad5064_num_vref(st); ++i)
+               st->vref_reg[i].supply = ad5064_vref_name(st, i);
+
+       ret = regulator_bulk_get(&st->spi->dev, ad5064_num_vref(st),
+               st->vref_reg);
+       if (ret) {
+               if (!st->chip_info->internal_vref)
+                       goto error_free;
+               st->use_internal_vref = true;
+               ret = ad5064_spi_write(st, AD5064_CMD_CONFIG, 0,
+                       AD5064_CONFIG_INT_VREF_ENABLE, 0);
+               if (ret) {
+                       dev_err(&spi->dev, "Failed to enable internal vref: %d\n",
+                               ret);
+                       goto error_free;
+               }
+       } else {
+               ret = regulator_bulk_enable(ad5064_num_vref(st), st->vref_reg);
+               if (ret)
+                       goto error_free_reg;
+       }
+
+       for (i = 0; i < st->chip_info->num_channels; ++i) {
+               st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K;
+               st->dac_cache[i] = 0x8000;
+       }
+
+       indio_dev->dev.parent = &spi->dev;
+       indio_dev->name = spi_get_device_id(spi)->name;
+       indio_dev->info = &ad5064_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = st->chip_info->channels;
+       indio_dev->num_channels = st->chip_info->num_channels;
+
+       ret = iio_device_register(indio_dev);
+       if (ret)
+               goto error_disable_reg;
+
+       return 0;
+
+error_disable_reg:
+       if (!st->use_internal_vref)
+               regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
+error_free_reg:
+       if (!st->use_internal_vref)
+               regulator_bulk_free(ad5064_num_vref(st), st->vref_reg);
+error_free:
+       iio_device_free(indio_dev);
+
+       return ret;
+}
+
+
+static int __devexit ad5064_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+       struct ad5064_state *st = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+
+       if (!st->use_internal_vref) {
+               regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
+               regulator_bulk_free(ad5064_num_vref(st), st->vref_reg);
+       }
+
+       iio_device_free(indio_dev);
+
+       return 0;
+}
+
+static const struct spi_device_id ad5064_id[] = {
+       {"ad5024", ID_AD5024},
+       {"ad5025", ID_AD5025},
+       {"ad5044", ID_AD5044},
+       {"ad5045", ID_AD5045},
+       {"ad5064", ID_AD5064},
+       {"ad5064-1", ID_AD5064_1},
+       {"ad5065", ID_AD5065},
+       {"ad5628-1", ID_AD5628_1},
+       {"ad5628-2", ID_AD5628_2},
+       {"ad5648-1", ID_AD5648_1},
+       {"ad5648-2", ID_AD5648_2},
+       {"ad5666-1", ID_AD5666_1},
+       {"ad5666-2", ID_AD5666_2},
+       {"ad5668-1", ID_AD5668_1},
+       {"ad5668-2", ID_AD5668_2},
+       {"ad5668-3", ID_AD5668_2}, /* similar enough to ad5668-2 */
+       {}
+};
+MODULE_DEVICE_TABLE(spi, ad5064_id);
+
+static struct spi_driver ad5064_driver = {
+       .driver = {
+                  .name = "ad5064",
+                  .owner = THIS_MODULE,
+       },
+       .probe = ad5064_probe,
+       .remove = __devexit_p(ad5064_remove),
+       .id_table = ad5064_id,
+};
+module_spi_driver(ad5064_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices AD5024/25/44/45/64/64-1/65, AD5628/48/66/68 DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c
new file mode 100644 (file)
index 0000000..8fce84f
--- /dev/null
@@ -0,0 +1,570 @@
+/*
+ * Analog devices AD5360, AD5361, AD5362, AD5363, AD5370, AD5371, AD5373
+ * multi-channel Digital to Analog Converters driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define AD5360_CMD(x)                          ((x) << 22)
+#define AD5360_ADDR(x)                         ((x) << 16)
+
+#define AD5360_READBACK_TYPE(x)                        ((x) << 13)
+#define AD5360_READBACK_ADDR(x)                        ((x) << 7)
+
+#define AD5360_CHAN_ADDR(chan)                 ((chan) + 0x8)
+
+#define AD5360_CMD_WRITE_DATA                  0x3
+#define AD5360_CMD_WRITE_OFFSET                        0x2
+#define AD5360_CMD_WRITE_GAIN                  0x1
+#define AD5360_CMD_SPECIAL_FUNCTION            0x0
+
+/* Special function register addresses */
+#define AD5360_REG_SF_NOP                      0x0
+#define AD5360_REG_SF_CTRL                     0x1
+#define AD5360_REG_SF_OFS(x)                   (0x2 + (x))
+#define AD5360_REG_SF_READBACK                 0x5
+
+#define AD5360_SF_CTRL_PWR_DOWN                        BIT(0)
+
+#define AD5360_READBACK_X1A                    0x0
+#define AD5360_READBACK_X1B                    0x1
+#define AD5360_READBACK_OFFSET                 0x2
+#define AD5360_READBACK_GAIN                   0x3
+#define AD5360_READBACK_SF                     0x4
+
+
+/**
+ * struct ad5360_chip_info - chip specific information
+ * @channel_template:  channel specification template
+ * @num_channels:      number of channels
+ * @channels_per_group:        number of channels per group
+ * @num_vrefs:         number of vref supplies for the chip
+*/
+
+struct ad5360_chip_info {
+       struct iio_chan_spec    channel_template;
+       unsigned int            num_channels;
+       unsigned int            channels_per_group;
+       unsigned int            num_vrefs;
+};
+
+/**
+ * struct ad5360_state - driver instance specific data
+ * @spi:               spi_device
+ * @chip_info:         chip model specific constants, available modes etc
+ * @vref_reg:          vref supply regulators
+ * @ctrl:              control register cache
+ * @data:              spi transfer buffers
+ */
+
+struct ad5360_state {
+       struct spi_device               *spi;
+       const struct ad5360_chip_info   *chip_info;
+       struct regulator_bulk_data      vref_reg[3];
+       unsigned int                    ctrl;
+
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+       union {
+               __be32 d32;
+               u8 d8[4];
+       } data[2] ____cacheline_aligned;
+};
+
+enum ad5360_type {
+       ID_AD5360,
+       ID_AD5361,
+       ID_AD5362,
+       ID_AD5363,
+       ID_AD5370,
+       ID_AD5371,
+       ID_AD5372,
+       ID_AD5373,
+};
+
+#define AD5360_CHANNEL(bits) {                                 \
+       .type = IIO_VOLTAGE,                                    \
+       .indexed = 1,                                           \
+       .output = 1,                                            \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |           \
+               IIO_CHAN_INFO_SCALE_SEPARATE_BIT |              \
+               IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |             \
+               IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \
+               IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,   \
+       .scan_type = IIO_ST('u', (bits), 16, 16 - (bits))       \
+}
+
+static const struct ad5360_chip_info ad5360_chip_info_tbl[] = {
+       [ID_AD5360] = {
+               .channel_template = AD5360_CHANNEL(16),
+               .num_channels = 16,
+               .channels_per_group = 8,
+               .num_vrefs = 2,
+       },
+       [ID_AD5361] = {
+               .channel_template = AD5360_CHANNEL(14),
+               .num_channels = 16,
+               .channels_per_group = 8,
+               .num_vrefs = 2,
+       },
+       [ID_AD5362] = {
+               .channel_template = AD5360_CHANNEL(16),
+               .num_channels = 8,
+               .channels_per_group = 4,
+               .num_vrefs = 2,
+       },
+       [ID_AD5363] = {
+               .channel_template = AD5360_CHANNEL(14),
+               .num_channels = 8,
+               .channels_per_group = 4,
+               .num_vrefs = 2,
+       },
+       [ID_AD5370] = {
+               .channel_template = AD5360_CHANNEL(16),
+               .num_channels = 40,
+               .channels_per_group = 8,
+               .num_vrefs = 2,
+       },
+       [ID_AD5371] = {
+               .channel_template = AD5360_CHANNEL(14),
+               .num_channels = 40,
+               .channels_per_group = 8,
+               .num_vrefs = 3,
+       },
+       [ID_AD5372] = {
+               .channel_template = AD5360_CHANNEL(16),
+               .num_channels = 32,
+               .channels_per_group = 8,
+               .num_vrefs = 2,
+       },
+       [ID_AD5373] = {
+               .channel_template = AD5360_CHANNEL(14),
+               .num_channels = 32,
+               .channels_per_group = 8,
+               .num_vrefs = 2,
+       },
+};
+
+static unsigned int ad5360_get_channel_vref_index(struct ad5360_state *st,
+       unsigned int channel)
+{
+       unsigned int i;
+
+       /* The first groups have their own vref, while the remaining groups
+        * share the last vref */
+       i = channel / st->chip_info->channels_per_group;
+       if (i >= st->chip_info->num_vrefs)
+               i = st->chip_info->num_vrefs - 1;
+
+       return i;
+}
+
+static int ad5360_get_channel_vref(struct ad5360_state *st,
+       unsigned int channel)
+{
+       unsigned int i = ad5360_get_channel_vref_index(st, channel);
+
+       return regulator_get_voltage(st->vref_reg[i].consumer);
+}
+
+
+static int ad5360_write_unlocked(struct iio_dev *indio_dev,
+       unsigned int cmd, unsigned int addr, unsigned int val,
+       unsigned int shift)
+{
+       struct ad5360_state *st = iio_priv(indio_dev);
+
+       val <<= shift;
+       val |= AD5360_CMD(cmd) | AD5360_ADDR(addr);
+       st->data[0].d32 = cpu_to_be32(val);
+
+       return spi_write(st->spi, &st->data[0].d8[1], 3);
+}
+
+static int ad5360_write(struct iio_dev *indio_dev, unsigned int cmd,
+       unsigned int addr, unsigned int val, unsigned int shift)
+{
+       int ret;
+
+       mutex_lock(&indio_dev->mlock);
+       ret = ad5360_write_unlocked(indio_dev, cmd, addr, val, shift);
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret;
+}
+
+static int ad5360_read(struct iio_dev *indio_dev, unsigned int type,
+       unsigned int addr)
+{
+       struct ad5360_state *st = iio_priv(indio_dev);
+       struct spi_message m;
+       int ret;
+       struct spi_transfer t[] = {
+               {
+                       .tx_buf = &st->data[0].d8[1],
+                       .len = 3,
+                       .cs_change = 1,
+               }, {
+                       .rx_buf = &st->data[1].d8[1],
+                       .len = 3,
+               },
+       };
+
+       spi_message_init(&m);
+       spi_message_add_tail(&t[0], &m);
+       spi_message_add_tail(&t[1], &m);
+
+       mutex_lock(&indio_dev->mlock);
+
+       st->data[0].d32 = cpu_to_be32(AD5360_CMD(AD5360_CMD_SPECIAL_FUNCTION) |
+               AD5360_ADDR(AD5360_REG_SF_READBACK) |
+               AD5360_READBACK_TYPE(type) |
+               AD5360_READBACK_ADDR(addr));
+
+       ret = spi_sync(st->spi, &m);
+       if (ret >= 0)
+               ret = be32_to_cpu(st->data[1].d32) & 0xffff;
+
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret;
+}
+
+static ssize_t ad5360_read_dac_powerdown(struct device *dev,
+                                          struct device_attribute *attr,
+                                          char *buf)
+{
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct ad5360_state *st = iio_priv(indio_dev);
+
+       return sprintf(buf, "%d\n", (bool)(st->ctrl & AD5360_SF_CTRL_PWR_DOWN));
+}
+
+static int ad5360_update_ctrl(struct iio_dev *indio_dev, unsigned int set,
+       unsigned int clr)
+{
+       struct ad5360_state *st = iio_priv(indio_dev);
+       unsigned int ret;
+
+       mutex_lock(&indio_dev->mlock);
+
+       st->ctrl |= set;
+       st->ctrl &= ~clr;
+
+       ret = ad5360_write_unlocked(indio_dev, AD5360_CMD_SPECIAL_FUNCTION,
+                       AD5360_REG_SF_CTRL, st->ctrl, 0);
+
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret;
+}
+
+static ssize_t ad5360_write_dac_powerdown(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t len)
+{
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       bool pwr_down;
+       int ret;
+
+       ret = strtobool(buf, &pwr_down);
+       if (ret)
+               return ret;
+
+       if (pwr_down)
+               ret = ad5360_update_ctrl(indio_dev, AD5360_SF_CTRL_PWR_DOWN, 0);
+       else
+               ret = ad5360_update_ctrl(indio_dev, 0, AD5360_SF_CTRL_PWR_DOWN);
+
+       return ret ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(out_voltage_powerdown,
+                       S_IRUGO | S_IWUSR,
+                       ad5360_read_dac_powerdown,
+                       ad5360_write_dac_powerdown, 0);
+
+static struct attribute *ad5360_attributes[] = {
+       &iio_dev_attr_out_voltage_powerdown.dev_attr.attr,
+       NULL,
+};
+
+static const struct attribute_group ad5360_attribute_group = {
+       .attrs = ad5360_attributes,
+};
+
+static int ad5360_write_raw(struct iio_dev *indio_dev,
+                              struct iio_chan_spec const *chan,
+                              int val,
+                              int val2,
+                              long mask)
+{
+       struct ad5360_state *st = iio_priv(indio_dev);
+       int max_val = (1 << chan->scan_type.realbits);
+       unsigned int ofs_index;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (val >= max_val || val < 0)
+                       return -EINVAL;
+
+               return ad5360_write(indio_dev, AD5360_CMD_WRITE_DATA,
+                                chan->address, val, chan->scan_type.shift);
+
+       case IIO_CHAN_INFO_CALIBBIAS:
+               if (val >= max_val || val < 0)
+                       return -EINVAL;
+
+               return ad5360_write(indio_dev, AD5360_CMD_WRITE_OFFSET,
+                                chan->address, val, chan->scan_type.shift);
+
+       case IIO_CHAN_INFO_CALIBSCALE:
+               if (val >= max_val || val < 0)
+                       return -EINVAL;
+
+               return ad5360_write(indio_dev, AD5360_CMD_WRITE_GAIN,
+                                chan->address, val, chan->scan_type.shift);
+
+       case IIO_CHAN_INFO_OFFSET:
+               if (val <= -max_val || val > 0)
+                       return -EINVAL;
+
+               val = -val;
+
+               /* offset is supposed to have the same scale as raw, but it
+                * is always 14bits wide, so on a chip where the raw value has
+                * more bits, we need to shift offset. */
+               val >>= (chan->scan_type.realbits - 14);
+
+               /* There is one DAC offset register per vref. Changing one
+                * channels offset will also change the offset for all other
+                * channels which share the same vref supply. */
+               ofs_index = ad5360_get_channel_vref_index(st, chan->channel);
+               return ad5360_write(indio_dev, AD5360_CMD_SPECIAL_FUNCTION,
+                                AD5360_REG_SF_OFS(ofs_index), val, 0);
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int ad5360_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val,
+                          int *val2,
+                          long m)
+{
+       struct ad5360_state *st = iio_priv(indio_dev);
+       unsigned int ofs_index;
+       int scale_uv;
+       int ret;
+
+       switch (m) {
+       case IIO_CHAN_INFO_RAW:
+               ret = ad5360_read(indio_dev, AD5360_READBACK_X1A,
+                       chan->address);
+               if (ret < 0)
+                       return ret;
+               *val = ret >> chan->scan_type.shift;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               /* vout = 4 * vref * dac_code */
+               scale_uv = ad5360_get_channel_vref(st, chan->channel) * 4 * 100;
+               if (scale_uv < 0)
+                       return scale_uv;
+
+               scale_uv >>= (chan->scan_type.realbits);
+               *val =  scale_uv / 100000;
+               *val2 = (scale_uv % 100000) * 10;
+               return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               ret = ad5360_read(indio_dev, AD5360_READBACK_OFFSET,
+                       chan->address);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_CALIBSCALE:
+               ret = ad5360_read(indio_dev, AD5360_READBACK_GAIN,
+                       chan->address);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_OFFSET:
+               ofs_index = ad5360_get_channel_vref_index(st, chan->channel);
+               ret = ad5360_read(indio_dev, AD5360_READBACK_SF,
+                       AD5360_REG_SF_OFS(ofs_index));
+               if (ret < 0)
+                       return ret;
+
+               ret <<= (chan->scan_type.realbits - 14);
+               *val = -ret;
+               return IIO_VAL_INT;
+       }
+
+       return -EINVAL;
+}
+
+static const struct iio_info ad5360_info = {
+       .read_raw = ad5360_read_raw,
+       .write_raw = ad5360_write_raw,
+       .attrs = &ad5360_attribute_group,
+       .driver_module = THIS_MODULE,
+};
+
+static const char * const ad5360_vref_name[] = {
+        "vref0", "vref1", "vref2"
+};
+
+static int __devinit ad5360_alloc_channels(struct iio_dev *indio_dev)
+{
+       struct ad5360_state *st = iio_priv(indio_dev);
+       struct iio_chan_spec *channels;
+       unsigned int i;
+
+       channels = kcalloc(st->chip_info->num_channels,
+                          sizeof(struct iio_chan_spec), GFP_KERNEL);
+
+       if (!channels)
+               return -ENOMEM;
+
+       for (i = 0; i < st->chip_info->num_channels; ++i) {
+               channels[i] = st->chip_info->channel_template;
+               channels[i].channel = i;
+               channels[i].address = AD5360_CHAN_ADDR(i);
+       }
+
+       indio_dev->channels = channels;
+
+       return 0;
+}
+
+static int __devinit ad5360_probe(struct spi_device *spi)
+{
+       enum ad5360_type type = spi_get_device_id(spi)->driver_data;
+       struct iio_dev *indio_dev;
+       struct ad5360_state *st;
+       unsigned int i;
+       int ret;
+
+       indio_dev = iio_device_alloc(sizeof(*st));
+       if (indio_dev == NULL) {
+               dev_err(&spi->dev, "Failed to allocate iio device\n");
+               return  -ENOMEM;
+       }
+
+       st = iio_priv(indio_dev);
+       spi_set_drvdata(spi, indio_dev);
+
+       st->chip_info = &ad5360_chip_info_tbl[type];
+       st->spi = spi;
+
+       indio_dev->dev.parent = &spi->dev;
+       indio_dev->name = spi_get_device_id(spi)->name;
+       indio_dev->info = &ad5360_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->num_channels = st->chip_info->num_channels;
+
+       ret = ad5360_alloc_channels(indio_dev);
+       if (ret) {
+               dev_err(&spi->dev, "Failed to allocate channel spec: %d\n", ret);
+               goto error_free;
+       }
+
+       for (i = 0; i < st->chip_info->num_vrefs; ++i)
+               st->vref_reg[i].supply = ad5360_vref_name[i];
+
+       ret = regulator_bulk_get(&st->spi->dev, st->chip_info->num_vrefs,
+               st->vref_reg);
+       if (ret) {
+               dev_err(&spi->dev, "Failed to request vref regulators: %d\n", ret);
+               goto error_free_channels;
+       }
+
+       ret = regulator_bulk_enable(st->chip_info->num_vrefs, st->vref_reg);
+       if (ret) {
+               dev_err(&spi->dev, "Failed to enable vref regulators: %d\n", ret);
+               goto error_free_reg;
+       }
+
+       ret = iio_device_register(indio_dev);
+       if (ret) {
+               dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
+               goto error_disable_reg;
+       }
+
+       return 0;
+
+error_disable_reg:
+       regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
+error_free_reg:
+       regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg);
+error_free_channels:
+       kfree(indio_dev->channels);
+error_free:
+       iio_device_free(indio_dev);
+
+       return ret;
+}
+
+static int __devexit ad5360_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+       struct ad5360_state *st = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+
+       kfree(indio_dev->channels);
+
+       regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
+       regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg);
+
+       iio_device_free(indio_dev);
+
+       return 0;
+}
+
+static const struct spi_device_id ad5360_ids[] = {
+       { "ad5360", ID_AD5360 },
+       { "ad5361", ID_AD5361 },
+       { "ad5362", ID_AD5362 },
+       { "ad5363", ID_AD5363 },
+       { "ad5370", ID_AD5370 },
+       { "ad5371", ID_AD5371 },
+       { "ad5372", ID_AD5372 },
+       { "ad5373", ID_AD5373 },
+       {}
+};
+MODULE_DEVICE_TABLE(spi, ad5360_ids);
+
+static struct spi_driver ad5360_driver = {
+       .driver = {
+                  .name = "ad5360",
+                  .owner = THIS_MODULE,
+       },
+       .probe = ad5360_probe,
+       .remove = __devexit_p(ad5360_remove),
+       .id_table = ad5360_ids,
+};
+module_spi_driver(ad5360_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices AD5360/61/62/63/70/71/72/73 DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c
new file mode 100644 (file)
index 0000000..5dfb445
--- /dev/null
@@ -0,0 +1,657 @@
+/*
+ * Analog devices AD5380, AD5381, AD5382, AD5383, AD5390, AD5391, AD5392
+ * multi-channel Digital to Analog Converters driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define AD5380_REG_DATA(x)     (((x) << 2) | 3)
+#define AD5380_REG_OFFSET(x)   (((x) << 2) | 2)
+#define AD5380_REG_GAIN(x)     (((x) << 2) | 1)
+#define AD5380_REG_SF_PWR_DOWN (8 << 2)
+#define AD5380_REG_SF_PWR_UP   (9 << 2)
+#define AD5380_REG_SF_CTRL     (12 << 2)
+
+#define AD5380_CTRL_PWR_DOWN_MODE_OFFSET       13
+#define AD5380_CTRL_INT_VREF_2V5               BIT(12)
+#define AD5380_CTRL_INT_VREF_EN                        BIT(10)
+
+/**
+ * struct ad5380_chip_info - chip specific information
+ * @channel_template:  channel specification template
+ * @num_channels:      number of channels
+ * @int_vref:          internal vref in uV
+*/
+
+struct ad5380_chip_info {
+       struct iio_chan_spec    channel_template;
+       unsigned int            num_channels;
+       unsigned int            int_vref;
+};
+
+/**
+ * struct ad5380_state - driver instance specific data
+ * @regmap:            regmap instance used by the device
+ * @chip_info:         chip model specific constants, available modes etc
+ * @vref_reg:          vref supply regulator
+ * @vref:              actual reference voltage used in uA
+ * @pwr_down:          whether the chip is currently in power down mode
+ */
+
+struct ad5380_state {
+       struct regmap                   *regmap;
+       const struct ad5380_chip_info   *chip_info;
+       struct regulator                *vref_reg;
+       int                             vref;
+       bool                            pwr_down;
+};
+
+enum ad5380_type {
+       ID_AD5380_3,
+       ID_AD5380_5,
+       ID_AD5381_3,
+       ID_AD5381_5,
+       ID_AD5382_3,
+       ID_AD5382_5,
+       ID_AD5383_3,
+       ID_AD5383_5,
+       ID_AD5390_3,
+       ID_AD5390_5,
+       ID_AD5391_3,
+       ID_AD5391_5,
+       ID_AD5392_3,
+       ID_AD5392_5,
+};
+
+static ssize_t ad5380_read_dac_powerdown(struct iio_dev *indio_dev,
+       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
+{
+       struct ad5380_state *st = iio_priv(indio_dev);
+
+       return sprintf(buf, "%d\n", st->pwr_down);
+}
+
+static ssize_t ad5380_write_dac_powerdown(struct iio_dev *indio_dev,
+        uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
+        size_t len)
+{
+       struct ad5380_state *st = iio_priv(indio_dev);
+       bool pwr_down;
+       int ret;
+
+       ret = strtobool(buf, &pwr_down);
+       if (ret)
+               return ret;
+
+       mutex_lock(&indio_dev->mlock);
+
+       if (pwr_down)
+               ret = regmap_write(st->regmap, AD5380_REG_SF_PWR_DOWN, 0);
+       else
+               ret = regmap_write(st->regmap, AD5380_REG_SF_PWR_UP, 0);
+
+       st->pwr_down = pwr_down;
+
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret ? ret : len;
+}
+
+static const char * const ad5380_powerdown_modes[] = {
+       "100kohm_to_gnd",
+       "three_state",
+};
+
+static int ad5380_get_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan)
+{
+       struct ad5380_state *st = iio_priv(indio_dev);
+       unsigned int mode;
+       int ret;
+
+       ret = regmap_read(st->regmap, AD5380_REG_SF_CTRL, &mode);
+       if (ret)
+               return ret;
+
+       mode = (mode >> AD5380_CTRL_PWR_DOWN_MODE_OFFSET) & 1;
+
+       return mode;
+}
+
+static int ad5380_set_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, unsigned int mode)
+{
+       struct ad5380_state *st = iio_priv(indio_dev);
+       int ret;
+
+       ret = regmap_update_bits(st->regmap, AD5380_REG_SF_CTRL,
+               1 << AD5380_CTRL_PWR_DOWN_MODE_OFFSET,
+               mode << AD5380_CTRL_PWR_DOWN_MODE_OFFSET);
+
+       return ret;
+}
+
+static const struct iio_enum ad5380_powerdown_mode_enum = {
+       .items = ad5380_powerdown_modes,
+       .num_items = ARRAY_SIZE(ad5380_powerdown_modes),
+       .get = ad5380_get_powerdown_mode,
+       .set = ad5380_set_powerdown_mode,
+};
+
+static unsigned int ad5380_info_to_reg(struct iio_chan_spec const *chan,
+       long info)
+{
+       switch (info) {
+       case 0:
+               return AD5380_REG_DATA(chan->address);
+       case IIO_CHAN_INFO_CALIBBIAS:
+               return AD5380_REG_OFFSET(chan->address);
+       case IIO_CHAN_INFO_CALIBSCALE:
+               return AD5380_REG_GAIN(chan->address);
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static int ad5380_write_raw(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan, int val, int val2, long info)
+{
+       const unsigned int max_val = (1 << chan->scan_type.realbits);
+       struct ad5380_state *st = iio_priv(indio_dev);
+
+       switch (info) {
+       case IIO_CHAN_INFO_RAW:
+       case IIO_CHAN_INFO_CALIBSCALE:
+               if (val >= max_val || val < 0)
+                       return -EINVAL;
+
+               return regmap_write(st->regmap,
+                       ad5380_info_to_reg(chan, info),
+                       val << chan->scan_type.shift);
+       case IIO_CHAN_INFO_CALIBBIAS:
+               val += (1 << chan->scan_type.realbits) / 2;
+               if (val >= max_val || val < 0)
+                       return -EINVAL;
+
+               return regmap_write(st->regmap,
+                       AD5380_REG_OFFSET(chan->address),
+                       val << chan->scan_type.shift);
+       default:
+               break;
+       }
+       return -EINVAL;
+}
+
+static int ad5380_read_raw(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan, int *val, int *val2, long info)
+{
+       struct ad5380_state *st = iio_priv(indio_dev);
+       unsigned long scale_uv;
+       int ret;
+
+       switch (info) {
+       case IIO_CHAN_INFO_RAW:
+       case IIO_CHAN_INFO_CALIBSCALE:
+               ret = regmap_read(st->regmap, ad5380_info_to_reg(chan, info),
+                                       val);
+               if (ret)
+                       return ret;
+               *val >>= chan->scan_type.shift;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               ret = regmap_read(st->regmap, AD5380_REG_OFFSET(chan->address),
+                                       val);
+               if (ret)
+                       return ret;
+               *val >>= chan->scan_type.shift;
+               val -= (1 << chan->scan_type.realbits) / 2;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               scale_uv = ((2 * st->vref) >> chan->scan_type.realbits) * 100;
+               *val =  scale_uv / 100000;
+               *val2 = (scale_uv % 100000) * 10;
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static const struct iio_info ad5380_info = {
+       .read_raw = ad5380_read_raw,
+       .write_raw = ad5380_write_raw,
+       .driver_module = THIS_MODULE,
+};
+
+static struct iio_chan_spec_ext_info ad5380_ext_info[] = {
+       {
+               .name = "powerdown",
+               .read = ad5380_read_dac_powerdown,
+               .write = ad5380_write_dac_powerdown,
+       },
+       IIO_ENUM("powerdown_mode", true, &ad5380_powerdown_mode_enum),
+       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum),
+       { },
+};
+
+#define AD5380_CHANNEL(_bits) {                                        \
+       .type = IIO_VOLTAGE,                                    \
+       .indexed = 1,                                           \
+       .output = 1,                                            \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |           \
+               IIO_CHAN_INFO_SCALE_SHARED_BIT |                \
+               IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |         \
+               IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,           \
+       .scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits)),    \
+       .ext_info = ad5380_ext_info,                            \
+}
+
+static const struct ad5380_chip_info ad5380_chip_info_tbl[] = {
+       [ID_AD5380_3] = {
+               .channel_template = AD5380_CHANNEL(14),
+               .num_channels = 40,
+               .int_vref = 1250000,
+       },
+       [ID_AD5380_5] = {
+               .channel_template = AD5380_CHANNEL(14),
+               .num_channels = 40,
+               .int_vref = 2500000,
+       },
+       [ID_AD5381_3] = {
+               .channel_template = AD5380_CHANNEL(12),
+               .num_channels = 16,
+               .int_vref = 1250000,
+       },
+       [ID_AD5381_5] = {
+               .channel_template = AD5380_CHANNEL(12),
+               .num_channels = 16,
+               .int_vref = 2500000,
+       },
+       [ID_AD5382_3] = {
+               .channel_template = AD5380_CHANNEL(14),
+               .num_channels = 32,
+               .int_vref = 1250000,
+       },
+       [ID_AD5382_5] = {
+               .channel_template = AD5380_CHANNEL(14),
+               .num_channels = 32,
+               .int_vref = 2500000,
+       },
+       [ID_AD5383_3] = {
+               .channel_template = AD5380_CHANNEL(12),
+               .num_channels = 32,
+               .int_vref = 1250000,
+       },
+       [ID_AD5383_5] = {
+               .channel_template = AD5380_CHANNEL(12),
+               .num_channels = 32,
+               .int_vref = 2500000,
+       },
+       [ID_AD5390_3] = {
+               .channel_template = AD5380_CHANNEL(14),
+               .num_channels = 16,
+               .int_vref = 1250000,
+       },
+       [ID_AD5390_5] = {
+               .channel_template = AD5380_CHANNEL(14),
+               .num_channels = 16,
+               .int_vref = 2500000,
+       },
+       [ID_AD5391_3] = {
+               .channel_template = AD5380_CHANNEL(12),
+               .num_channels = 16,
+               .int_vref = 1250000,
+       },
+       [ID_AD5391_5] = {
+               .channel_template = AD5380_CHANNEL(12),
+               .num_channels = 16,
+               .int_vref = 2500000,
+       },
+       [ID_AD5392_3] = {
+               .channel_template = AD5380_CHANNEL(14),
+               .num_channels = 8,
+               .int_vref = 1250000,
+       },
+       [ID_AD5392_5] = {
+               .channel_template = AD5380_CHANNEL(14),
+               .num_channels = 8,
+               .int_vref = 2500000,
+       },
+};
+
+static int __devinit ad5380_alloc_channels(struct iio_dev *indio_dev)
+{
+       struct ad5380_state *st = iio_priv(indio_dev);
+       struct iio_chan_spec *channels;
+       unsigned int i;
+
+       channels = kcalloc(st->chip_info->num_channels,
+                          sizeof(struct iio_chan_spec), GFP_KERNEL);
+
+       if (!channels)
+               return -ENOMEM;
+
+       for (i = 0; i < st->chip_info->num_channels; ++i) {
+               channels[i] = st->chip_info->channel_template;
+               channels[i].channel = i;
+               channels[i].address = i;
+       }
+
+       indio_dev->channels = channels;
+
+       return 0;
+}
+
+static int __devinit ad5380_probe(struct device *dev, struct regmap *regmap,
+       enum ad5380_type type, const char *name)
+{
+       struct iio_dev *indio_dev;
+       struct ad5380_state *st;
+       unsigned int ctrl = 0;
+       int ret;
+
+       indio_dev = iio_device_alloc(sizeof(*st));
+       if (indio_dev == NULL) {
+               dev_err(dev, "Failed to allocate iio device\n");
+               ret = -ENOMEM;
+               goto error_regmap_exit;
+       }
+
+       st = iio_priv(indio_dev);
+       dev_set_drvdata(dev, indio_dev);
+
+       st->chip_info = &ad5380_chip_info_tbl[type];
+       st->regmap = regmap;
+
+       indio_dev->dev.parent = dev;
+       indio_dev->name = name;
+       indio_dev->info = &ad5380_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->num_channels = st->chip_info->num_channels;
+
+       ret = ad5380_alloc_channels(indio_dev);
+       if (ret) {
+               dev_err(dev, "Failed to allocate channel spec: %d\n", ret);
+               goto error_free;
+       }
+
+       if (st->chip_info->int_vref == 2500000)
+               ctrl |= AD5380_CTRL_INT_VREF_2V5;
+
+       st->vref_reg = regulator_get(dev, "vref");
+       if (!IS_ERR(st->vref_reg)) {
+               ret = regulator_enable(st->vref_reg);
+               if (ret) {
+                       dev_err(dev, "Failed to enable vref regulators: %d\n",
+                               ret);
+                       goto error_free_reg;
+               }
+
+               st->vref = regulator_get_voltage(st->vref_reg);
+       } else {
+               st->vref = st->chip_info->int_vref;
+               ctrl |= AD5380_CTRL_INT_VREF_EN;
+       }
+
+       ret = regmap_write(st->regmap, AD5380_REG_SF_CTRL, ctrl);
+       if (ret) {
+               dev_err(dev, "Failed to write to device: %d\n", ret);
+               goto error_disable_reg;
+       }
+
+       ret = iio_device_register(indio_dev);
+       if (ret) {
+               dev_err(dev, "Failed to register iio device: %d\n", ret);
+               goto error_disable_reg;
+       }
+
+       return 0;
+
+error_disable_reg:
+       if (!IS_ERR(st->vref_reg))
+               regulator_disable(st->vref_reg);
+error_free_reg:
+       if (!IS_ERR(st->vref_reg))
+               regulator_put(st->vref_reg);
+
+       kfree(indio_dev->channels);
+error_free:
+       iio_device_free(indio_dev);
+error_regmap_exit:
+       regmap_exit(regmap);
+
+       return ret;
+}
+
+static int __devexit ad5380_remove(struct device *dev)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct ad5380_state *st = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+
+       kfree(indio_dev->channels);
+
+       if (!IS_ERR(st->vref_reg)) {
+               regulator_disable(st->vref_reg);
+               regulator_put(st->vref_reg);
+       }
+
+       regmap_exit(st->regmap);
+       iio_device_free(indio_dev);
+
+       return 0;
+}
+
+static bool ad5380_reg_false(struct device *dev, unsigned int reg)
+{
+       return false;
+}
+
+static const struct regmap_config ad5380_regmap_config = {
+       .reg_bits = 10,
+       .val_bits = 14,
+
+       .max_register = AD5380_REG_DATA(40),
+       .cache_type = REGCACHE_RBTREE,
+
+       .volatile_reg = ad5380_reg_false,
+       .readable_reg = ad5380_reg_false,
+};
+
+#if IS_ENABLED(CONFIG_SPI_MASTER)
+
+static int __devinit ad5380_spi_probe(struct spi_device *spi)
+{
+       const struct spi_device_id *id = spi_get_device_id(spi);
+       struct regmap *regmap;
+
+       regmap = regmap_init_spi(spi, &ad5380_regmap_config);
+
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       return ad5380_probe(&spi->dev, regmap, id->driver_data, id->name);
+}
+
+static int __devexit ad5380_spi_remove(struct spi_device *spi)
+{
+       return ad5380_remove(&spi->dev);
+}
+
+static const struct spi_device_id ad5380_spi_ids[] = {
+       { "ad5380-3", ID_AD5380_3 },
+       { "ad5380-5", ID_AD5380_5 },
+       { "ad5381-3", ID_AD5381_3 },
+       { "ad5381-5", ID_AD5381_5 },
+       { "ad5382-3", ID_AD5382_3 },
+       { "ad5382-5", ID_AD5382_5 },
+       { "ad5383-3", ID_AD5383_3 },
+       { "ad5383-5", ID_AD5383_5 },
+       { "ad5384-3", ID_AD5380_3 },
+       { "ad5384-5", ID_AD5380_5 },
+       { "ad5390-3", ID_AD5390_3 },
+       { "ad5390-5", ID_AD5390_5 },
+       { "ad5391-3", ID_AD5391_3 },
+       { "ad5391-5", ID_AD5391_5 },
+       { "ad5392-3", ID_AD5392_3 },
+       { "ad5392-5", ID_AD5392_5 },
+       { }
+};
+MODULE_DEVICE_TABLE(spi, ad5380_spi_ids);
+
+static struct spi_driver ad5380_spi_driver = {
+       .driver = {
+                  .name = "ad5380",
+                  .owner = THIS_MODULE,
+       },
+       .probe = ad5380_spi_probe,
+       .remove = __devexit_p(ad5380_spi_remove),
+       .id_table = ad5380_spi_ids,
+};
+
+static inline int ad5380_spi_register_driver(void)
+{
+       return spi_register_driver(&ad5380_spi_driver);
+}
+
+static inline void ad5380_spi_unregister_driver(void)
+{
+       spi_unregister_driver(&ad5380_spi_driver);
+}
+
+#else
+
+static inline int ad5380_spi_register_driver(void)
+{
+       return 0;
+}
+
+static inline void ad5380_spi_unregister_driver(void)
+{
+}
+
+#endif
+
+#if IS_ENABLED(CONFIG_I2C)
+
+static int __devinit ad5380_i2c_probe(struct i2c_client *i2c,
+       const struct i2c_device_id *id)
+{
+       struct regmap *regmap;
+
+       regmap = regmap_init_i2c(i2c, &ad5380_regmap_config);
+
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       return ad5380_probe(&i2c->dev, regmap, id->driver_data, id->name);
+}
+
+static int __devexit ad5380_i2c_remove(struct i2c_client *i2c)
+{
+       return ad5380_remove(&i2c->dev);
+}
+
+static const struct i2c_device_id ad5380_i2c_ids[] = {
+       { "ad5380-3", ID_AD5380_3 },
+       { "ad5380-5", ID_AD5380_5 },
+       { "ad5381-3", ID_AD5381_3 },
+       { "ad5381-5", ID_AD5381_5 },
+       { "ad5382-3", ID_AD5382_3 },
+       { "ad5382-5", ID_AD5382_5 },
+       { "ad5383-3", ID_AD5383_3 },
+       { "ad5383-5", ID_AD5383_5 },
+       { "ad5384-3", ID_AD5380_3 },
+       { "ad5384-5", ID_AD5380_5 },
+       { "ad5390-3", ID_AD5390_3 },
+       { "ad5390-5", ID_AD5390_5 },
+       { "ad5391-3", ID_AD5391_3 },
+       { "ad5391-5", ID_AD5391_5 },
+       { "ad5392-3", ID_AD5392_3 },
+       { "ad5392-5", ID_AD5392_5 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, ad5380_i2c_ids);
+
+static struct i2c_driver ad5380_i2c_driver = {
+       .driver = {
+                  .name = "ad5380",
+                  .owner = THIS_MODULE,
+       },
+       .probe = ad5380_i2c_probe,
+       .remove = __devexit_p(ad5380_i2c_remove),
+       .id_table = ad5380_i2c_ids,
+};
+
+static inline int ad5380_i2c_register_driver(void)
+{
+       return i2c_add_driver(&ad5380_i2c_driver);
+}
+
+static inline void ad5380_i2c_unregister_driver(void)
+{
+       i2c_del_driver(&ad5380_i2c_driver);
+}
+
+#else
+
+static inline int ad5380_i2c_register_driver(void)
+{
+       return 0;
+}
+
+static inline void ad5380_i2c_unregister_driver(void)
+{
+}
+
+#endif
+
+static int __init ad5380_spi_init(void)
+{
+       int ret;
+
+       ret = ad5380_spi_register_driver();
+       if (ret)
+               return ret;
+
+       ret = ad5380_i2c_register_driver();
+       if (ret) {
+               ad5380_spi_unregister_driver();
+               return ret;
+       }
+
+       return 0;
+}
+module_init(ad5380_spi_init);
+
+static void __exit ad5380_spi_exit(void)
+{
+       ad5380_i2c_unregister_driver();
+       ad5380_spi_unregister_driver();
+
+}
+module_exit(ad5380_spi_exit);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices AD5380/81/82/83/84/90/91/92 DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c
new file mode 100644 (file)
index 0000000..cdbc5bf
--- /dev/null
@@ -0,0 +1,544 @@
+/*
+ * AD5421 Digital to analog converters  driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+#include <linux/iio/dac/ad5421.h>
+
+
+#define AD5421_REG_DAC_DATA            0x1
+#define AD5421_REG_CTRL                        0x2
+#define AD5421_REG_OFFSET              0x3
+#define AD5421_REG_GAIN                        0x4
+/* load dac and fault shared the same register number. Writing to it will cause
+ * a dac load command, reading from it will return the fault status register */
+#define AD5421_REG_LOAD_DAC            0x5
+#define AD5421_REG_FAULT               0x5
+#define AD5421_REG_FORCE_ALARM_CURRENT 0x6
+#define AD5421_REG_RESET               0x7
+#define AD5421_REG_START_CONVERSION    0x8
+#define AD5421_REG_NOOP                        0x9
+
+#define AD5421_CTRL_WATCHDOG_DISABLE   BIT(12)
+#define AD5421_CTRL_AUTO_FAULT_READBACK        BIT(11)
+#define AD5421_CTRL_MIN_CURRENT                BIT(9)
+#define AD5421_CTRL_ADC_SOURCE_TEMP    BIT(8)
+#define AD5421_CTRL_ADC_ENABLE         BIT(7)
+#define AD5421_CTRL_PWR_DOWN_INT_VREF  BIT(6)
+
+#define AD5421_FAULT_SPI                       BIT(15)
+#define AD5421_FAULT_PEC                       BIT(14)
+#define AD5421_FAULT_OVER_CURRENT              BIT(13)
+#define AD5421_FAULT_UNDER_CURRENT             BIT(12)
+#define AD5421_FAULT_TEMP_OVER_140             BIT(11)
+#define AD5421_FAULT_TEMP_OVER_100             BIT(10)
+#define AD5421_FAULT_UNDER_VOLTAGE_6V          BIT(9)
+#define AD5421_FAULT_UNDER_VOLTAGE_12V         BIT(8)
+
+/* These bits will cause the fault pin to go high */
+#define AD5421_FAULT_TRIGGER_IRQ \
+       (AD5421_FAULT_SPI | AD5421_FAULT_PEC | AD5421_FAULT_OVER_CURRENT | \
+       AD5421_FAULT_UNDER_CURRENT | AD5421_FAULT_TEMP_OVER_140)
+
+/**
+ * struct ad5421_state - driver instance specific data
+ * @spi:               spi_device
+ * @ctrl:              control register cache
+ * @current_range:     current range which the device is configured for
+ * @data:              spi transfer buffers
+ * @fault_mask:                software masking of events
+ */
+struct ad5421_state {
+       struct spi_device               *spi;
+       unsigned int                    ctrl;
+       enum ad5421_current_range       current_range;
+       unsigned int                    fault_mask;
+
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+       union {
+               u32 d32;
+               u8 d8[4];
+       } data[2] ____cacheline_aligned;
+};
+
+static const struct iio_chan_spec ad5421_channels[] = {
+       {
+               .type = IIO_CURRENT,
+               .indexed = 1,
+               .output = 1,
+               .channel = 0,
+               .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
+                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
+                       IIO_CHAN_INFO_OFFSET_SHARED_BIT |
+                       IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
+                       IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
+               .scan_type = IIO_ST('u', 16, 16, 0),
+               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
+                       IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
+       },
+       {
+               .type = IIO_TEMP,
+               .channel = -1,
+               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
+       },
+};
+
+static int ad5421_write_unlocked(struct iio_dev *indio_dev,
+       unsigned int reg, unsigned int val)
+{
+       struct ad5421_state *st = iio_priv(indio_dev);
+
+       st->data[0].d32 = cpu_to_be32((reg << 16) | val);
+
+       return spi_write(st->spi, &st->data[0].d8[1], 3);
+}
+
+static int ad5421_write(struct iio_dev *indio_dev, unsigned int reg,
+       unsigned int val)
+{
+       int ret;
+
+       mutex_lock(&indio_dev->mlock);
+       ret = ad5421_write_unlocked(indio_dev, reg, val);
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret;
+}
+
+static int ad5421_read(struct iio_dev *indio_dev, unsigned int reg)
+{
+       struct ad5421_state *st = iio_priv(indio_dev);
+       struct spi_message m;
+       int ret;
+       struct spi_transfer t[] = {
+               {
+                       .tx_buf = &st->data[0].d8[1],
+                       .len = 3,
+                       .cs_change = 1,
+               }, {
+                       .rx_buf = &st->data[1].d8[1],
+                       .len = 3,
+               },
+       };
+
+       spi_message_init(&m);
+       spi_message_add_tail(&t[0], &m);
+       spi_message_add_tail(&t[1], &m);
+
+       mutex_lock(&indio_dev->mlock);
+
+       st->data[0].d32 = cpu_to_be32((1 << 23) | (reg << 16));
+
+       ret = spi_sync(st->spi, &m);
+       if (ret >= 0)
+               ret = be32_to_cpu(st->data[1].d32) & 0xffff;
+
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret;
+}
+
+static int ad5421_update_ctrl(struct iio_dev *indio_dev, unsigned int set,
+       unsigned int clr)
+{
+       struct ad5421_state *st = iio_priv(indio_dev);
+       unsigned int ret;
+
+       mutex_lock(&indio_dev->mlock);
+
+       st->ctrl &= ~clr;
+       st->ctrl |= set;
+
+       ret = ad5421_write_unlocked(indio_dev, AD5421_REG_CTRL, st->ctrl);
+
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret;
+}
+
+static irqreturn_t ad5421_fault_handler(int irq, void *data)
+{
+       struct iio_dev *indio_dev = data;
+       struct ad5421_state *st = iio_priv(indio_dev);
+       unsigned int fault;
+       unsigned int old_fault = 0;
+       unsigned int events;
+
+       fault = ad5421_read(indio_dev, AD5421_REG_FAULT);
+       if (!fault)
+               return IRQ_NONE;
+
+       /* If we had a fault, this might mean that the DAC has lost its state
+        * and has been reset. Make sure that the control register actually
+        * contains what we expect it to contain. Otherwise the watchdog might
+        * be enabled and we get watchdog timeout faults, which will render the
+        * DAC unusable. */
+       ad5421_update_ctrl(indio_dev, 0, 0);
+
+
+       /* The fault pin stays high as long as a fault condition is present and
+        * it is not possible to mask fault conditions. For certain fault
+        * conditions for example like over-temperature it takes some time
+        * until the fault condition disappears. If we would exit the interrupt
+        * handler immediately after handling the event it would be entered
+        * again instantly. Thus we fall back to polling in case we detect that
+        * a interrupt condition is still present.
+        */
+       do {
+               /* 0xffff is a invalid value for the register and will only be
+                * read if there has been a communication error */
+               if (fault == 0xffff)
+                       fault = 0;
+
+               /* we are only interested in new events */
+               events = (old_fault ^ fault) & fault;
+               events &= st->fault_mask;
+
+               if (events & AD5421_FAULT_OVER_CURRENT) {
+                       iio_push_event(indio_dev,
+                               IIO_UNMOD_EVENT_CODE(IIO_CURRENT,
+                                       0,
+                                       IIO_EV_TYPE_THRESH,
+                                       IIO_EV_DIR_RISING),
+                       iio_get_time_ns());
+               }
+
+               if (events & AD5421_FAULT_UNDER_CURRENT) {
+                       iio_push_event(indio_dev,
+                               IIO_UNMOD_EVENT_CODE(IIO_CURRENT,
+                                       0,
+                                       IIO_EV_TYPE_THRESH,
+                                       IIO_EV_DIR_FALLING),
+                               iio_get_time_ns());
+               }
+
+               if (events & AD5421_FAULT_TEMP_OVER_140) {
+                       iio_push_event(indio_dev,
+                               IIO_UNMOD_EVENT_CODE(IIO_TEMP,
+                                       0,
+                                       IIO_EV_TYPE_MAG,
+                                       IIO_EV_DIR_RISING),
+                               iio_get_time_ns());
+               }
+
+               old_fault = fault;
+               fault = ad5421_read(indio_dev, AD5421_REG_FAULT);
+
+               /* still active? go to sleep for some time */
+               if (fault & AD5421_FAULT_TRIGGER_IRQ)
+                       msleep(1000);
+
+       } while (fault & AD5421_FAULT_TRIGGER_IRQ);
+
+
+       return IRQ_HANDLED;
+}
+
+static void ad5421_get_current_min_max(struct ad5421_state *st,
+       unsigned int *min, unsigned int *max)
+{
+       /* The current range is configured using external pins, which are
+        * usually hard-wired and not run-time switchable. */
+       switch (st->current_range) {
+       case AD5421_CURRENT_RANGE_4mA_20mA:
+               *min = 4000;
+               *max = 20000;
+               break;
+       case AD5421_CURRENT_RANGE_3mA8_21mA:
+               *min = 3800;
+               *max = 21000;
+               break;
+       case AD5421_CURRENT_RANGE_3mA2_24mA:
+               *min = 3200;
+               *max = 24000;
+               break;
+       default:
+               *min = 0;
+               *max = 1;
+               break;
+       }
+}
+
+static inline unsigned int ad5421_get_offset(struct ad5421_state *st)
+{
+       unsigned int min, max;
+
+       ad5421_get_current_min_max(st, &min, &max);
+       return (min * (1 << 16)) / (max - min);
+}
+
+static inline unsigned int ad5421_get_scale(struct ad5421_state *st)
+{
+       unsigned int min, max;
+
+       ad5421_get_current_min_max(st, &min, &max);
+       return ((max - min) * 1000) / (1 << 16);
+}
+
+static int ad5421_read_raw(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan, int *val, int *val2, long m)
+{
+       struct ad5421_state *st = iio_priv(indio_dev);
+       int ret;
+
+       if (chan->type != IIO_CURRENT)
+               return -EINVAL;
+
+       switch (m) {
+       case IIO_CHAN_INFO_RAW:
+               ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               *val = 0;
+               *val2 = ad5421_get_scale(st);
+               return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_OFFSET:
+               *val = ad5421_get_offset(st);
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               ret = ad5421_read(indio_dev, AD5421_REG_OFFSET);
+               if (ret < 0)
+                       return ret;
+               *val = ret - 32768;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_CALIBSCALE:
+               ret = ad5421_read(indio_dev, AD5421_REG_GAIN);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               return IIO_VAL_INT;
+       }
+
+       return -EINVAL;
+}
+
+static int ad5421_write_raw(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan, int val, int val2, long mask)
+{
+       const unsigned int max_val = 1 << 16;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (val >= max_val || val < 0)
+                       return -EINVAL;
+
+               return ad5421_write(indio_dev, AD5421_REG_DAC_DATA, val);
+       case IIO_CHAN_INFO_CALIBBIAS:
+               val += 32768;
+               if (val >= max_val || val < 0)
+                       return -EINVAL;
+
+               return ad5421_write(indio_dev, AD5421_REG_OFFSET, val);
+       case IIO_CHAN_INFO_CALIBSCALE:
+               if (val >= max_val || val < 0)
+                       return -EINVAL;
+
+               return ad5421_write(indio_dev, AD5421_REG_GAIN, val);
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int ad5421_write_event_config(struct iio_dev *indio_dev,
+       u64 event_code, int state)
+{
+       struct ad5421_state *st = iio_priv(indio_dev);
+       unsigned int mask;
+
+       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       case IIO_CURRENT:
+               if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+                       IIO_EV_DIR_RISING)
+                       mask = AD5421_FAULT_OVER_CURRENT;
+               else
+                       mask = AD5421_FAULT_UNDER_CURRENT;
+               break;
+       case IIO_TEMP:
+               mask = AD5421_FAULT_TEMP_OVER_140;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       mutex_lock(&indio_dev->mlock);
+       if (state)
+               st->fault_mask |= mask;
+       else
+               st->fault_mask &= ~mask;
+       mutex_unlock(&indio_dev->mlock);
+
+       return 0;
+}
+
+static int ad5421_read_event_config(struct iio_dev *indio_dev,
+       u64 event_code)
+{
+       struct ad5421_state *st = iio_priv(indio_dev);
+       unsigned int mask;
+
+       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       case IIO_CURRENT:
+               if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+                       IIO_EV_DIR_RISING)
+                       mask = AD5421_FAULT_OVER_CURRENT;
+               else
+                       mask = AD5421_FAULT_UNDER_CURRENT;
+               break;
+       case IIO_TEMP:
+               mask = AD5421_FAULT_TEMP_OVER_140;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return (bool)(st->fault_mask & mask);
+}
+
+static int ad5421_read_event_value(struct iio_dev *indio_dev, u64 event_code,
+       int *val)
+{
+       int ret;
+
+       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       case IIO_CURRENT:
+               ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               break;
+       case IIO_TEMP:
+               *val = 140000;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static const struct iio_info ad5421_info = {
+       .read_raw =             ad5421_read_raw,
+       .write_raw =            ad5421_write_raw,
+       .read_event_config =    ad5421_read_event_config,
+       .write_event_config =   ad5421_write_event_config,
+       .read_event_value =     ad5421_read_event_value,
+       .driver_module =        THIS_MODULE,
+};
+
+static int __devinit ad5421_probe(struct spi_device *spi)
+{
+       struct ad5421_platform_data *pdata = dev_get_platdata(&spi->dev);
+       struct iio_dev *indio_dev;
+       struct ad5421_state *st;
+       int ret;
+
+       indio_dev = iio_device_alloc(sizeof(*st));
+       if (indio_dev == NULL) {
+               dev_err(&spi->dev, "Failed to allocate iio device\n");
+               return  -ENOMEM;
+       }
+
+       st = iio_priv(indio_dev);
+       spi_set_drvdata(spi, indio_dev);
+
+       st->spi = spi;
+
+       indio_dev->dev.parent = &spi->dev;
+       indio_dev->name = "ad5421";
+       indio_dev->info = &ad5421_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = ad5421_channels;
+       indio_dev->num_channels = ARRAY_SIZE(ad5421_channels);
+
+       st->ctrl = AD5421_CTRL_WATCHDOG_DISABLE |
+                       AD5421_CTRL_AUTO_FAULT_READBACK;
+
+       if (pdata) {
+               st->current_range = pdata->current_range;
+               if (pdata->external_vref)
+                       st->ctrl |= AD5421_CTRL_PWR_DOWN_INT_VREF;
+       } else {
+               st->current_range = AD5421_CURRENT_RANGE_4mA_20mA;
+       }
+
+       /* write initial ctrl register value */
+       ad5421_update_ctrl(indio_dev, 0, 0);
+
+       if (spi->irq) {
+               ret = request_threaded_irq(spi->irq,
+                                          NULL,
+                                          ad5421_fault_handler,
+                                          IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+                                          "ad5421 fault",
+                                          indio_dev);
+               if (ret)
+                       goto error_free;
+       }
+
+       ret = iio_device_register(indio_dev);
+       if (ret) {
+               dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
+               goto error_free_irq;
+       }
+
+       return 0;
+
+error_free_irq:
+       if (spi->irq)
+               free_irq(spi->irq, indio_dev);
+error_free:
+       iio_device_free(indio_dev);
+
+       return ret;
+}
+
+static int __devexit ad5421_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+
+       iio_device_unregister(indio_dev);
+       if (spi->irq)
+               free_irq(spi->irq, indio_dev);
+       iio_device_free(indio_dev);
+
+       return 0;
+}
+
+static struct spi_driver ad5421_driver = {
+       .driver = {
+                  .name = "ad5421",
+                  .owner = THIS_MODULE,
+       },
+       .probe = ad5421_probe,
+       .remove = __devexit_p(ad5421_remove),
+};
+module_spi_driver(ad5421_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices AD5421 DAC");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:ad5421");
diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c
new file mode 100644 (file)
index 0000000..49f557f
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * AD5446 SPI DAC driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#include "ad5446.h"
+
+static int ad5446_write(struct ad5446_state *st, unsigned val)
+{
+       __be16 data = cpu_to_be16(val);
+       return spi_write(st->spi, &data, sizeof(data));
+}
+
+static int ad5660_write(struct ad5446_state *st, unsigned val)
+{
+       uint8_t data[3];
+
+       data[0] = (val >> 16) & 0xFF;
+       data[1] = (val >> 8) & 0xFF;
+       data[2] = val & 0xFF;
+
+       return spi_write(st->spi, data, sizeof(data));
+}
+
+static const char * const ad5446_powerdown_modes[] = {
+       "1kohm_to_gnd", "100kohm_to_gnd", "three_state"
+};
+
+static int ad5446_set_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, unsigned int mode)
+{
+       struct ad5446_state *st = iio_priv(indio_dev);
+
+       st->pwr_down_mode = mode + 1;
+
+       return 0;
+}
+
+static int ad5446_get_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan)
+{
+       struct ad5446_state *st = iio_priv(indio_dev);
+
+       return st->pwr_down_mode - 1;
+}
+
+static const struct iio_enum ad5446_powerdown_mode_enum = {
+       .items = ad5446_powerdown_modes,
+       .num_items = ARRAY_SIZE(ad5446_powerdown_modes),
+       .get = ad5446_get_powerdown_mode,
+       .set = ad5446_set_powerdown_mode,
+};
+
+static ssize_t ad5446_read_dac_powerdown(struct iio_dev *indio_dev,
+                                          uintptr_t private,
+                                          const struct iio_chan_spec *chan,
+                                          char *buf)
+{
+       struct ad5446_state *st = iio_priv(indio_dev);
+
+       return sprintf(buf, "%d\n", st->pwr_down);
+}
+
+static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev,
+                                           uintptr_t private,
+                                           const struct iio_chan_spec *chan,
+                                           const char *buf, size_t len)
+{
+       struct ad5446_state *st = iio_priv(indio_dev);
+       unsigned int shift;
+       unsigned int val;
+       bool powerdown;
+       int ret;
+
+       ret = strtobool(buf, &powerdown);
+       if (ret)
+               return ret;
+
+       mutex_lock(&indio_dev->mlock);
+       st->pwr_down = powerdown;
+
+       if (st->pwr_down) {
+               shift = chan->scan_type.realbits + chan->scan_type.shift;
+               val = st->pwr_down_mode << shift;
+       } else {
+               val = st->cached_val;
+       }
+
+       ret = st->chip_info->write(st, val);
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret ? ret : len;
+}
+
+static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = {
+       {
+               .name = "powerdown",
+               .read = ad5446_read_dac_powerdown,
+               .write = ad5446_write_dac_powerdown,
+       },
+       IIO_ENUM("powerdown_mode", false, &ad5446_powerdown_mode_enum),
+       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5446_powerdown_mode_enum),
+       { },
+};
+
+#define _AD5446_CHANNEL(bits, storage, shift, ext) { \
+       .type = IIO_VOLTAGE, \
+       .indexed = 1, \
+       .output = 1, \
+       .channel = 0, \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+       IIO_CHAN_INFO_SCALE_SHARED_BIT, \
+       .scan_type = IIO_ST('u', (bits), (storage), (shift)), \
+       .ext_info = (ext), \
+}
+
+#define AD5446_CHANNEL(bits, storage, shift) \
+       _AD5446_CHANNEL(bits, storage, shift, NULL)
+
+#define AD5446_CHANNEL_POWERDOWN(bits, storage, shift) \
+       _AD5446_CHANNEL(bits, storage, shift, ad5064_ext_info_powerdown)
+
+static const struct ad5446_chip_info ad5446_chip_info_tbl[] = {
+       [ID_AD5444] = {
+               .channel = AD5446_CHANNEL(12, 16, 2),
+               .write = ad5446_write,
+       },
+       [ID_AD5446] = {
+               .channel = AD5446_CHANNEL(14, 16, 0),
+               .write = ad5446_write,
+       },
+       [ID_AD5541A] = {
+               .channel = AD5446_CHANNEL(16, 16, 0),
+               .write = ad5446_write,
+       },
+       [ID_AD5512A] = {
+               .channel = AD5446_CHANNEL(12, 16, 4),
+               .write = ad5446_write,
+       },
+       [ID_AD5553] = {
+               .channel = AD5446_CHANNEL(14, 16, 0),
+               .write = ad5446_write,
+       },
+       [ID_AD5601] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6),
+               .write = ad5446_write,
+       },
+       [ID_AD5611] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4),
+               .write = ad5446_write,
+       },
+       [ID_AD5621] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
+               .write = ad5446_write,
+       },
+       [ID_AD5620_2500] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
+               .int_vref_mv = 2500,
+               .write = ad5446_write,
+       },
+       [ID_AD5620_1250] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
+               .int_vref_mv = 1250,
+               .write = ad5446_write,
+       },
+       [ID_AD5640_2500] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0),
+               .int_vref_mv = 2500,
+               .write = ad5446_write,
+       },
+       [ID_AD5640_1250] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0),
+               .int_vref_mv = 1250,
+               .write = ad5446_write,
+       },
+       [ID_AD5660_2500] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
+               .int_vref_mv = 2500,
+               .write = ad5660_write,
+       },
+       [ID_AD5660_1250] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
+               .int_vref_mv = 1250,
+               .write = ad5660_write,
+       },
+       [ID_AD5662] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
+               .write = ad5660_write,
+       },
+};
+
+static int ad5446_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val,
+                          int *val2,
+                          long m)
+{
+       struct ad5446_state *st = iio_priv(indio_dev);
+       unsigned long scale_uv;
+
+       switch (m) {
+       case IIO_CHAN_INFO_RAW:
+               *val = st->cached_val;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
+               *val =  scale_uv / 1000;
+               *val2 = (scale_uv % 1000) * 1000;
+               return IIO_VAL_INT_PLUS_MICRO;
+
+       }
+       return -EINVAL;
+}
+
+static int ad5446_write_raw(struct iio_dev *indio_dev,
+                              struct iio_chan_spec const *chan,
+                              int val,
+                              int val2,
+                              long mask)
+{
+       struct ad5446_state *st = iio_priv(indio_dev);
+       int ret = 0;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (val >= (1 << chan->scan_type.realbits) || val < 0)
+                       return -EINVAL;
+
+               val <<= chan->scan_type.shift;
+               mutex_lock(&indio_dev->mlock);
+               st->cached_val = val;
+               if (!st->pwr_down)
+                       ret = st->chip_info->write(st, val);
+               mutex_unlock(&indio_dev->mlock);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static const struct iio_info ad5446_info = {
+       .read_raw = ad5446_read_raw,
+       .write_raw = ad5446_write_raw,
+       .driver_module = THIS_MODULE,
+};
+
+static int __devinit ad5446_probe(struct spi_device *spi)
+{
+       struct ad5446_state *st;
+       struct iio_dev *indio_dev;
+       struct regulator *reg;
+       int ret, voltage_uv = 0;
+
+       reg = regulator_get(&spi->dev, "vcc");
+       if (!IS_ERR(reg)) {
+               ret = regulator_enable(reg);
+               if (ret)
+                       goto error_put_reg;
+
+               voltage_uv = regulator_get_voltage(reg);
+       }
+
+       indio_dev = iio_device_alloc(sizeof(*st));
+       if (indio_dev == NULL) {
+               ret = -ENOMEM;
+               goto error_disable_reg;
+       }
+       st = iio_priv(indio_dev);
+       st->chip_info =
+               &ad5446_chip_info_tbl[spi_get_device_id(spi)->driver_data];
+
+       spi_set_drvdata(spi, indio_dev);
+       st->reg = reg;
+       st->spi = spi;
+
+       /* Establish that the iio_dev is a child of the spi device */
+       indio_dev->dev.parent = &spi->dev;
+       indio_dev->name = spi_get_device_id(spi)->name;
+       indio_dev->info = &ad5446_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = &st->chip_info->channel;
+       indio_dev->num_channels = 1;
+
+       st->pwr_down_mode = MODE_PWRDWN_1k;
+
+       if (st->chip_info->int_vref_mv)
+               st->vref_mv = st->chip_info->int_vref_mv;
+       else if (voltage_uv)
+               st->vref_mv = voltage_uv / 1000;
+       else
+               dev_warn(&spi->dev, "reference voltage unspecified\n");
+
+       ret = iio_device_register(indio_dev);
+       if (ret)
+               goto error_free_device;
+
+       return 0;
+
+error_free_device:
+       iio_device_free(indio_dev);
+error_disable_reg:
+       if (!IS_ERR(reg))
+               regulator_disable(reg);
+error_put_reg:
+       if (!IS_ERR(reg))
+               regulator_put(reg);
+
+       return ret;
+}
+
+static int ad5446_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+       struct ad5446_state *st = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+       if (!IS_ERR(st->reg)) {
+               regulator_disable(st->reg);
+               regulator_put(st->reg);
+       }
+       iio_device_free(indio_dev);
+
+       return 0;
+}
+
+static const struct spi_device_id ad5446_id[] = {
+       {"ad5444", ID_AD5444},
+       {"ad5446", ID_AD5446},
+       {"ad5512a", ID_AD5512A},
+       {"ad5541a", ID_AD5541A},
+       {"ad5542a", ID_AD5541A}, /* ad5541a and ad5542a are compatible */
+       {"ad5543", ID_AD5541A}, /* ad5541a and ad5543 are compatible */
+       {"ad5553", ID_AD5553},
+       {"ad5601", ID_AD5601},
+       {"ad5611", ID_AD5611},
+       {"ad5621", ID_AD5621},
+       {"ad5620-2500", ID_AD5620_2500}, /* AD5620/40/60: */
+       {"ad5620-1250", ID_AD5620_1250}, /* part numbers may look differently */
+       {"ad5640-2500", ID_AD5640_2500},
+       {"ad5640-1250", ID_AD5640_1250},
+       {"ad5660-2500", ID_AD5660_2500},
+       {"ad5660-1250", ID_AD5660_1250},
+       {"ad5662", ID_AD5662},
+       {}
+};
+MODULE_DEVICE_TABLE(spi, ad5446_id);
+
+static struct spi_driver ad5446_driver = {
+       .driver = {
+               .name   = "ad5446",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = ad5446_probe,
+       .remove         = __devexit_p(ad5446_remove),
+       .id_table       = ad5446_id,
+};
+module_spi_driver(ad5446_driver);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/ad5446.h b/drivers/iio/dac/ad5446.h
new file mode 100644 (file)
index 0000000..dfd68ce
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * AD5446 SPI DAC driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+#ifndef IIO_DAC_AD5446_H_
+#define IIO_DAC_AD5446_H_
+
+/* DAC Control Bits */
+
+#define AD5446_LOAD            (0x0 << 14) /* Load and update */
+#define AD5446_SDO_DIS         (0x1 << 14) /* Disable SDO */
+#define AD5446_NOP             (0x2 << 14) /* No operation */
+#define AD5446_CLK_RISING      (0x3 << 14) /* Clock data on rising edge */
+
+#define AD5620_LOAD            (0x0 << 14) /* Load and update Norm Operation*/
+#define AD5620_PWRDWN_1k       (0x1 << 14) /* Power-down: 1kOhm to GND */
+#define AD5620_PWRDWN_100k     (0x2 << 14) /* Power-down: 100kOhm to GND */
+#define AD5620_PWRDWN_TRISTATE (0x3 << 14) /* Power-down: Three-state */
+
+#define AD5660_LOAD            (0x0 << 16) /* Load and update Norm Operation*/
+#define AD5660_PWRDWN_1k       (0x1 << 16) /* Power-down: 1kOhm to GND */
+#define AD5660_PWRDWN_100k     (0x2 << 16) /* Power-down: 100kOhm to GND */
+#define AD5660_PWRDWN_TRISTATE (0x3 << 16) /* Power-down: Three-state */
+
+#define MODE_PWRDWN_1k         0x1
+#define MODE_PWRDWN_100k       0x2
+#define MODE_PWRDWN_TRISTATE   0x3
+
+/**
+ * struct ad5446_state - driver instance specific data
+ * @spi:               spi_device
+ * @chip_info:         chip model specific constants, available modes etc
+ * @reg:               supply regulator
+ * @vref_mv:           actual reference voltage used
+ */
+
+struct ad5446_state {
+       struct spi_device               *spi;
+       const struct ad5446_chip_info   *chip_info;
+       struct regulator                *reg;
+       unsigned short                  vref_mv;
+       unsigned                        cached_val;
+       unsigned                        pwr_down_mode;
+       unsigned                        pwr_down;
+};
+
+/**
+ * struct ad5446_chip_info - chip specific information
+ * @channel:           channel spec for the DAC
+ * @int_vref_mv:       AD5620/40/60: the internal reference voltage
+ * @write:             chip specific helper function to write to the register
+ */
+
+struct ad5446_chip_info {
+       struct iio_chan_spec    channel;
+       u16                     int_vref_mv;
+       int                     (*write)(struct ad5446_state *st, unsigned val);
+};
+
+/**
+ * ad5446_supported_device_ids:
+ * The AD5620/40/60 parts are available in different fixed internal reference
+ * voltage options. The actual part numbers may look differently
+ * (and a bit cryptic), however this style is used to make clear which
+ * parts are supported here.
+ */
+
+enum ad5446_supported_device_ids {
+       ID_AD5444,
+       ID_AD5446,
+       ID_AD5541A,
+       ID_AD5512A,
+       ID_AD5553,
+       ID_AD5601,
+       ID_AD5611,
+       ID_AD5621,
+       ID_AD5620_2500,
+       ID_AD5620_1250,
+       ID_AD5640_2500,
+       ID_AD5640_1250,
+       ID_AD5660_2500,
+       ID_AD5660_1250,
+       ID_AD5662,
+};
+
+#endif /* IIO_DAC_AD5446_H_ */
diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c
new file mode 100644 (file)
index 0000000..242bdc7
--- /dev/null
@@ -0,0 +1,393 @@
+/*
+ * AD5504, AD5501 High Voltage Digital to Analog Converter
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+#include <linux/iio/dac/ad5504.h>
+
+#define AD5505_BITS                    12
+#define AD5504_RES_MASK                        ((1 << (AD5505_BITS)) - 1)
+
+#define AD5504_CMD_READ                        (1 << 15)
+#define AD5504_CMD_WRITE               (0 << 15)
+#define AD5504_ADDR(addr)              ((addr) << 12)
+
+/* Registers */
+#define AD5504_ADDR_NOOP               0
+#define AD5504_ADDR_DAC(x)             ((x) + 1)
+#define AD5504_ADDR_ALL_DAC            5
+#define AD5504_ADDR_CTRL               7
+
+/* Control Register */
+#define AD5504_DAC_PWR(ch)             ((ch) << 2)
+#define AD5504_DAC_PWRDWN_MODE(mode)   ((mode) << 6)
+#define AD5504_DAC_PWRDN_20K           0
+#define AD5504_DAC_PWRDN_3STATE                1
+
+/**
+ * struct ad5446_state - driver instance specific data
+ * @us:                        spi_device
+ * @reg:               supply regulator
+ * @vref_mv:           actual reference voltage used
+ * @pwr_down_mask      power down mask
+ * @pwr_down_mode      current power down mode
+ */
+
+struct ad5504_state {
+       struct spi_device               *spi;
+       struct regulator                *reg;
+       unsigned short                  vref_mv;
+       unsigned                        pwr_down_mask;
+       unsigned                        pwr_down_mode;
+};
+
+/**
+ * ad5504_supported_device_ids:
+ */
+
+enum ad5504_supported_device_ids {
+       ID_AD5504,
+       ID_AD5501,
+};
+
+static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val)
+{
+       u16 tmp = cpu_to_be16(AD5504_CMD_WRITE |
+                             AD5504_ADDR(addr) |
+                             (val & AD5504_RES_MASK));
+
+       return spi_write(spi, (u8 *)&tmp, 2);
+}
+
+static int ad5504_spi_read(struct spi_device *spi, u8 addr)
+{
+       u16 tmp = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr));
+       u16 val;
+       int ret;
+       struct spi_transfer     t = {
+                       .tx_buf         = &tmp,
+                       .rx_buf         = &val,
+                       .len            = 2,
+               };
+       struct spi_message      m;
+
+       spi_message_init(&m);
+       spi_message_add_tail(&t, &m);
+       ret = spi_sync(spi, &m);
+
+       if (ret < 0)
+               return ret;
+
+       return be16_to_cpu(val) & AD5504_RES_MASK;
+}
+
+static int ad5504_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val,
+                          int *val2,
+                          long m)
+{
+       struct ad5504_state *st = iio_priv(indio_dev);
+       unsigned long scale_uv;
+       int ret;
+
+       switch (m) {
+       case IIO_CHAN_INFO_RAW:
+               ret = ad5504_spi_read(st->spi, chan->address);
+               if (ret < 0)
+                       return ret;
+
+               *val = ret;
+
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
+               *val =  scale_uv / 1000;
+               *val2 = (scale_uv % 1000) * 1000;
+               return IIO_VAL_INT_PLUS_MICRO;
+
+       }
+       return -EINVAL;
+}
+
+static int ad5504_write_raw(struct iio_dev *indio_dev,
+                              struct iio_chan_spec const *chan,
+                              int val,
+                              int val2,
+                              long mask)
+{
+       struct ad5504_state *st = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (val >= (1 << chan->scan_type.realbits) || val < 0)
+                       return -EINVAL;
+
+               return ad5504_spi_write(st->spi, chan->address, val);
+       default:
+               ret = -EINVAL;
+       }
+
+       return -EINVAL;
+}
+
+static const char * const ad5504_powerdown_modes[] = {
+       "20kohm_to_gnd",
+       "three_state",
+};
+
+static int ad5504_get_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan)
+{
+       struct ad5504_state *st = iio_priv(indio_dev);
+
+       return st->pwr_down_mode;
+}
+
+static int ad5504_set_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, unsigned int mode)
+{
+       struct ad5504_state *st = iio_priv(indio_dev);
+
+       st->pwr_down_mode = mode;
+
+       return 0;
+}
+
+static const struct iio_enum ad5504_powerdown_mode_enum = {
+       .items = ad5504_powerdown_modes,
+       .num_items = ARRAY_SIZE(ad5504_powerdown_modes),
+       .get = ad5504_get_powerdown_mode,
+       .set = ad5504_set_powerdown_mode,
+};
+
+static ssize_t ad5504_read_dac_powerdown(struct iio_dev *indio_dev,
+       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
+{
+       struct ad5504_state *st = iio_priv(indio_dev);
+
+       return sprintf(buf, "%d\n",
+                       !(st->pwr_down_mask & (1 << chan->channel)));
+}
+
+static ssize_t ad5504_write_dac_powerdown(struct iio_dev *indio_dev,
+       uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
+       size_t len)
+{
+       bool pwr_down;
+       int ret;
+       struct ad5504_state *st = iio_priv(indio_dev);
+
+       ret = strtobool(buf, &pwr_down);
+       if (ret)
+               return ret;
+
+       if (pwr_down)
+               st->pwr_down_mask |= (1 << chan->channel);
+       else
+               st->pwr_down_mask &= ~(1 << chan->channel);
+
+       ret = ad5504_spi_write(st->spi, AD5504_ADDR_CTRL,
+                               AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) |
+                               AD5504_DAC_PWR(st->pwr_down_mask));
+
+       /* writes to the CTRL register must be followed by a NOOP */
+       ad5504_spi_write(st->spi, AD5504_ADDR_NOOP, 0);
+
+       return ret ? ret : len;
+}
+
+static IIO_CONST_ATTR(temp0_thresh_rising_value, "110000");
+static IIO_CONST_ATTR(temp0_thresh_rising_en, "1");
+
+static struct attribute *ad5504_ev_attributes[] = {
+       &iio_const_attr_temp0_thresh_rising_value.dev_attr.attr,
+       &iio_const_attr_temp0_thresh_rising_en.dev_attr.attr,
+       NULL,
+};
+
+static struct attribute_group ad5504_ev_attribute_group = {
+       .attrs = ad5504_ev_attributes,
+       .name = "events",
+};
+
+static irqreturn_t ad5504_event_handler(int irq, void *private)
+{
+       iio_push_event(private,
+                      IIO_UNMOD_EVENT_CODE(IIO_TEMP,
+                                           0,
+                                           IIO_EV_TYPE_THRESH,
+                                           IIO_EV_DIR_RISING),
+                      iio_get_time_ns());
+
+       return IRQ_HANDLED;
+}
+
+static const struct iio_info ad5504_info = {
+       .write_raw = ad5504_write_raw,
+       .read_raw = ad5504_read_raw,
+       .event_attrs = &ad5504_ev_attribute_group,
+       .driver_module = THIS_MODULE,
+};
+
+static const struct iio_chan_spec_ext_info ad5504_ext_info[] = {
+       {
+               .name = "powerdown",
+               .read = ad5504_read_dac_powerdown,
+               .write = ad5504_write_dac_powerdown,
+       },
+       IIO_ENUM("powerdown_mode", true, &ad5504_powerdown_mode_enum),
+       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum),
+       { },
+};
+
+#define AD5504_CHANNEL(_chan) { \
+       .type = IIO_VOLTAGE, \
+       .indexed = 1, \
+       .output = 1, \
+       .channel = (_chan), \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+                    IIO_CHAN_INFO_SCALE_SHARED_BIT, \
+       .address = AD5504_ADDR_DAC(_chan), \
+       .scan_type = IIO_ST('u', 12, 16, 0), \
+       .ext_info = ad5504_ext_info, \
+}
+
+static const struct iio_chan_spec ad5504_channels[] = {
+       AD5504_CHANNEL(0),
+       AD5504_CHANNEL(1),
+       AD5504_CHANNEL(2),
+       AD5504_CHANNEL(3),
+};
+
+static int __devinit ad5504_probe(struct spi_device *spi)
+{
+       struct ad5504_platform_data *pdata = spi->dev.platform_data;
+       struct iio_dev *indio_dev;
+       struct ad5504_state *st;
+       struct regulator *reg;
+       int ret, voltage_uv = 0;
+
+       indio_dev = iio_device_alloc(sizeof(*st));
+       if (indio_dev == NULL) {
+               ret = -ENOMEM;
+               goto error_ret;
+       }
+       reg = regulator_get(&spi->dev, "vcc");
+       if (!IS_ERR(reg)) {
+               ret = regulator_enable(reg);
+               if (ret)
+                       goto error_put_reg;
+
+               voltage_uv = regulator_get_voltage(reg);
+       }
+
+       spi_set_drvdata(spi, indio_dev);
+       st = iio_priv(indio_dev);
+       if (voltage_uv)
+               st->vref_mv = voltage_uv / 1000;
+       else if (pdata)
+               st->vref_mv = pdata->vref_mv;
+       else
+               dev_warn(&spi->dev, "reference voltage unspecified\n");
+
+       st->reg = reg;
+       st->spi = spi;
+       indio_dev->dev.parent = &spi->dev;
+       indio_dev->name = spi_get_device_id(st->spi)->name;
+       indio_dev->info = &ad5504_info;
+       if (spi_get_device_id(st->spi)->driver_data == ID_AD5501)
+               indio_dev->num_channels = 1;
+       else
+               indio_dev->num_channels = 4;
+       indio_dev->channels = ad5504_channels;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       if (spi->irq) {
+               ret = request_threaded_irq(spi->irq,
+                                          NULL,
+                                          &ad5504_event_handler,
+                                          IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                          spi_get_device_id(st->spi)->name,
+                                          indio_dev);
+               if (ret)
+                       goto error_disable_reg;
+       }
+
+       ret = iio_device_register(indio_dev);
+       if (ret)
+               goto error_free_irq;
+
+       return 0;
+
+error_free_irq:
+       if (spi->irq)
+               free_irq(spi->irq, indio_dev);
+error_disable_reg:
+       if (!IS_ERR(reg))
+               regulator_disable(reg);
+error_put_reg:
+       if (!IS_ERR(reg))
+               regulator_put(reg);
+
+       iio_device_free(indio_dev);
+error_ret:
+       return ret;
+}
+
+static int __devexit ad5504_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+       struct ad5504_state *st = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+       if (spi->irq)
+               free_irq(spi->irq, indio_dev);
+
+       if (!IS_ERR(st->reg)) {
+               regulator_disable(st->reg);
+               regulator_put(st->reg);
+       }
+       iio_device_free(indio_dev);
+
+       return 0;
+}
+
+static const struct spi_device_id ad5504_id[] = {
+       {"ad5504", ID_AD5504},
+       {"ad5501", ID_AD5501},
+       {}
+};
+MODULE_DEVICE_TABLE(spi, ad5504_id);
+
+static struct spi_driver ad5504_driver = {
+       .driver = {
+                  .name = "ad5504",
+                  .owner = THIS_MODULE,
+                  },
+       .probe = ad5504_probe,
+       .remove = __devexit_p(ad5504_remove),
+       .id_table = ad5504_id,
+};
+module_spi_driver(ad5504_driver);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/ad5624r.h b/drivers/iio/dac/ad5624r.h
new file mode 100644 (file)
index 0000000..5dca302
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * AD5624R SPI DAC driver
+ *
+ * Copyright 2010-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+#ifndef SPI_AD5624R_H_
+#define SPI_AD5624R_H_
+
+#define AD5624R_DAC_CHANNELS                   4
+
+#define AD5624R_ADDR_DAC0                      0x0
+#define AD5624R_ADDR_DAC1                      0x1
+#define AD5624R_ADDR_DAC2                      0x2
+#define AD5624R_ADDR_DAC3                      0x3
+#define AD5624R_ADDR_ALL_DAC                   0x7
+
+#define AD5624R_CMD_WRITE_INPUT_N              0x0
+#define AD5624R_CMD_UPDATE_DAC_N               0x1
+#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_ALL   0x2
+#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_N     0x3
+#define AD5624R_CMD_POWERDOWN_DAC              0x4
+#define AD5624R_CMD_RESET                      0x5
+#define AD5624R_CMD_LDAC_SETUP                 0x6
+#define AD5624R_CMD_INTERNAL_REFER_SETUP       0x7
+
+#define AD5624R_LDAC_PWRDN_NONE                        0x0
+#define AD5624R_LDAC_PWRDN_1K                  0x1
+#define AD5624R_LDAC_PWRDN_100K                        0x2
+#define AD5624R_LDAC_PWRDN_3STATE              0x3
+
+/**
+ * struct ad5624r_chip_info - chip specific information
+ * @channels:          channel spec for the DAC
+ * @int_vref_mv:       AD5620/40/60: the internal reference voltage
+ */
+
+struct ad5624r_chip_info {
+       const struct iio_chan_spec      *channels;
+       u16                             int_vref_mv;
+};
+
+/**
+ * struct ad5446_state - driver instance specific data
+ * @indio_dev:         the industrial I/O device
+ * @us:                        spi_device
+ * @chip_info:         chip model specific constants, available modes etc
+ * @reg:               supply regulator
+ * @vref_mv:           actual reference voltage used
+ * @pwr_down_mask      power down mask
+ * @pwr_down_mode      current power down mode
+ */
+
+struct ad5624r_state {
+       struct spi_device               *us;
+       const struct ad5624r_chip_info  *chip_info;
+       struct regulator                *reg;
+       unsigned short                  vref_mv;
+       unsigned                        pwr_down_mask;
+       unsigned                        pwr_down_mode;
+};
+
+/**
+ * ad5624r_supported_device_ids:
+ * The AD5624/44/64 parts are available in different
+ * fixed internal reference voltage options.
+ */
+
+enum ad5624r_supported_device_ids {
+       ID_AD5624R3,
+       ID_AD5644R3,
+       ID_AD5664R3,
+       ID_AD5624R5,
+       ID_AD5644R5,
+       ID_AD5664R5,
+};
+
+#endif /* SPI_AD5624R_H_ */
diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c
new file mode 100644 (file)
index 0000000..6a7d6a4
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * AD5624R, AD5644R, AD5664R Digital to analog convertors spi driver
+ *
+ * Copyright 2010-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#include "ad5624r.h"
+
+static int ad5624r_spi_write(struct spi_device *spi,
+                            u8 cmd, u8 addr, u16 val, u8 len)
+{
+       u32 data;
+       u8 msg[3];
+
+       /*
+        * The input shift register is 24 bits wide. The first two bits are
+        * don't care bits. The next three are the command bits, C2 to C0,
+        * followed by the 3-bit DAC address, A2 to A0, and then the
+        * 16-, 14-, 12-bit data-word. The data-word comprises the 16-,
+        * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits,
+        * for the AD5664R, AD5644R, and AD5624R, respectively.
+        */
+       data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << (16 - len));
+       msg[0] = data >> 16;
+       msg[1] = data >> 8;
+       msg[2] = data;
+
+       return spi_write(spi, msg, 3);
+}
+
+static int ad5624r_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val,
+                          int *val2,
+                          long m)
+{
+       struct ad5624r_state *st = iio_priv(indio_dev);
+       unsigned long scale_uv;
+
+       switch (m) {
+       case IIO_CHAN_INFO_SCALE:
+               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
+               *val =  scale_uv / 1000;
+               *val2 = (scale_uv % 1000) * 1000;
+               return IIO_VAL_INT_PLUS_MICRO;
+
+       }
+       return -EINVAL;
+}
+
+static int ad5624r_write_raw(struct iio_dev *indio_dev,
+                              struct iio_chan_spec const *chan,
+                              int val,
+                              int val2,
+                              long mask)
+{
+       struct ad5624r_state *st = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (val >= (1 << chan->scan_type.realbits) || val < 0)
+                       return -EINVAL;
+
+               return ad5624r_spi_write(st->us,
+                               AD5624R_CMD_WRITE_INPUT_N_UPDATE_N,
+                               chan->address, val,
+                               chan->scan_type.shift);
+       default:
+               ret = -EINVAL;
+       }
+
+       return -EINVAL;
+}
+
+static const char * const ad5624r_powerdown_modes[] = {
+       "1kohm_to_gnd",
+       "100kohm_to_gnd",
+       "three_state"
+};
+
+static int ad5624r_get_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan)
+{
+       struct ad5624r_state *st = iio_priv(indio_dev);
+
+       return st->pwr_down_mode;
+}
+
+static int ad5624r_set_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, unsigned int mode)
+{
+       struct ad5624r_state *st = iio_priv(indio_dev);
+
+       st->pwr_down_mode = mode;
+
+       return 0;
+}
+
+static const struct iio_enum ad5624r_powerdown_mode_enum = {
+       .items = ad5624r_powerdown_modes,
+       .num_items = ARRAY_SIZE(ad5624r_powerdown_modes),
+       .get = ad5624r_get_powerdown_mode,
+       .set = ad5624r_set_powerdown_mode,
+};
+
+static ssize_t ad5624r_read_dac_powerdown(struct iio_dev *indio_dev,
+       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
+{
+       struct ad5624r_state *st = iio_priv(indio_dev);
+
+       return sprintf(buf, "%d\n",
+                       !!(st->pwr_down_mask & (1 << chan->channel)));
+}
+
+static ssize_t ad5624r_write_dac_powerdown(struct iio_dev *indio_dev,
+       uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
+       size_t len)
+{
+       bool pwr_down;
+       int ret;
+       struct ad5624r_state *st = iio_priv(indio_dev);
+
+       ret = strtobool(buf, &pwr_down);
+       if (ret)
+               return ret;
+
+       if (pwr_down)
+               st->pwr_down_mask |= (1 << chan->channel);
+       else
+               st->pwr_down_mask &= ~(1 << chan->channel);
+
+       ret = ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0,
+                               (st->pwr_down_mode << 4) |
+                               st->pwr_down_mask, 16);
+
+       return ret ? ret : len;
+}
+
+static const struct iio_info ad5624r_info = {
+       .write_raw = ad5624r_write_raw,
+       .read_raw = ad5624r_read_raw,
+       .driver_module = THIS_MODULE,
+};
+
+static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = {
+       {
+               .name = "powerdown",
+               .read = ad5624r_read_dac_powerdown,
+               .write = ad5624r_write_dac_powerdown,
+       },
+       IIO_ENUM("powerdown_mode", true, &ad5624r_powerdown_mode_enum),
+       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum),
+       { },
+};
+
+#define AD5624R_CHANNEL(_chan, _bits) { \
+       .type = IIO_VOLTAGE, \
+       .indexed = 1, \
+       .output = 1, \
+       .channel = (_chan), \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
+                    IIO_CHAN_INFO_SCALE_SHARED_BIT, \
+       .address = (_chan), \
+       .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \
+       .ext_info = ad5624r_ext_info, \
+}
+
+#define DECLARE_AD5624R_CHANNELS(_name, _bits) \
+       const struct iio_chan_spec _name##_channels[] = { \
+               AD5624R_CHANNEL(0, _bits), \
+               AD5624R_CHANNEL(1, _bits), \
+               AD5624R_CHANNEL(2, _bits), \
+               AD5624R_CHANNEL(3, _bits), \
+}
+
+static DECLARE_AD5624R_CHANNELS(ad5624r, 12);
+static DECLARE_AD5624R_CHANNELS(ad5644r, 14);
+static DECLARE_AD5624R_CHANNELS(ad5664r, 16);
+
+static const struct ad5624r_chip_info ad5624r_chip_info_tbl[] = {
+       [ID_AD5624R3] = {
+               .channels = ad5624r_channels,
+               .int_vref_mv = 1250,
+       },
+       [ID_AD5624R5] = {
+               .channels = ad5624r_channels,
+               .int_vref_mv = 2500,
+       },
+       [ID_AD5644R3] = {
+               .channels = ad5644r_channels,
+               .int_vref_mv = 1250,
+       },
+       [ID_AD5644R5] = {
+               .channels = ad5644r_channels,
+               .int_vref_mv = 2500,
+       },
+       [ID_AD5664R3] = {
+               .channels = ad5664r_channels,
+               .int_vref_mv = 1250,
+       },
+       [ID_AD5664R5] = {
+               .channels = ad5664r_channels,
+               .int_vref_mv = 2500,
+       },
+};
+
+static int __devinit ad5624r_probe(struct spi_device *spi)
+{
+       struct ad5624r_state *st;
+       struct iio_dev *indio_dev;
+       int ret, voltage_uv = 0;
+
+       indio_dev = iio_device_alloc(sizeof(*st));
+       if (indio_dev == NULL) {
+               ret = -ENOMEM;
+               goto error_ret;
+       }
+       st = iio_priv(indio_dev);
+       st->reg = regulator_get(&spi->dev, "vcc");
+       if (!IS_ERR(st->reg)) {
+               ret = regulator_enable(st->reg);
+               if (ret)
+                       goto error_put_reg;
+
+               voltage_uv = regulator_get_voltage(st->reg);
+       }
+
+       spi_set_drvdata(spi, indio_dev);
+       st->chip_info =
+               &ad5624r_chip_info_tbl[spi_get_device_id(spi)->driver_data];
+
+       if (voltage_uv)
+               st->vref_mv = voltage_uv / 1000;
+       else
+               st->vref_mv = st->chip_info->int_vref_mv;
+
+       st->us = spi;
+
+       indio_dev->dev.parent = &spi->dev;
+       indio_dev->name = spi_get_device_id(spi)->name;
+       indio_dev->info = &ad5624r_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = st->chip_info->channels;
+       indio_dev->num_channels = AD5624R_DAC_CHANNELS;
+
+       ret = ad5624r_spi_write(spi, AD5624R_CMD_INTERNAL_REFER_SETUP, 0,
+                               !!voltage_uv, 16);
+       if (ret)
+               goto error_disable_reg;
+
+       ret = iio_device_register(indio_dev);
+       if (ret)
+               goto error_disable_reg;
+
+       return 0;
+
+error_disable_reg:
+       if (!IS_ERR(st->reg))
+               regulator_disable(st->reg);
+error_put_reg:
+       if (!IS_ERR(st->reg))
+               regulator_put(st->reg);
+       iio_device_free(indio_dev);
+error_ret:
+
+       return ret;
+}
+
+static int __devexit ad5624r_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+       struct ad5624r_state *st = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+       if (!IS_ERR(st->reg)) {
+               regulator_disable(st->reg);
+               regulator_put(st->reg);
+       }
+       iio_device_free(indio_dev);
+
+       return 0;
+}
+
+static const struct spi_device_id ad5624r_id[] = {
+       {"ad5624r3", ID_AD5624R3},
+       {"ad5644r3", ID_AD5644R3},
+       {"ad5664r3", ID_AD5664R3},
+       {"ad5624r5", ID_AD5624R5},
+       {"ad5644r5", ID_AD5644R5},
+       {"ad5664r5", ID_AD5664R5},
+       {}
+};
+MODULE_DEVICE_TABLE(spi, ad5624r_id);
+
+static struct spi_driver ad5624r_driver = {
+       .driver = {
+                  .name = "ad5624r",
+                  .owner = THIS_MODULE,
+                  },
+       .probe = ad5624r_probe,
+       .remove = __devexit_p(ad5624r_remove),
+       .id_table = ad5624r_id,
+};
+module_spi_driver(ad5624r_driver);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices AD5624/44/64R DAC spi driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c
new file mode 100644 (file)
index 0000000..6948d75
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * AD5686R, AD5685R, AD5684R Digital to analog converters  driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define AD5686_DAC_CHANNELS                    4
+
+#define AD5686_ADDR(x)                         ((x) << 16)
+#define AD5686_CMD(x)                          ((x) << 20)
+
+#define AD5686_ADDR_DAC(chan)          (0x1 << (chan))
+#define AD5686_ADDR_ALL_DAC                    0xF
+
+#define AD5686_CMD_NOOP                                0x0
+#define AD5686_CMD_WRITE_INPUT_N               0x1
+#define AD5686_CMD_UPDATE_DAC_N                        0x2
+#define AD5686_CMD_WRITE_INPUT_N_UPDATE_N      0x3
+#define AD5686_CMD_POWERDOWN_DAC               0x4
+#define AD5686_CMD_LDAC_MASK                   0x5
+#define AD5686_CMD_RESET                       0x6
+#define AD5686_CMD_INTERNAL_REFER_SETUP                0x7
+#define AD5686_CMD_DAISY_CHAIN_ENABLE          0x8
+#define AD5686_CMD_READBACK_ENABLE             0x9
+
+#define AD5686_LDAC_PWRDN_NONE                 0x0
+#define AD5686_LDAC_PWRDN_1K                   0x1
+#define AD5686_LDAC_PWRDN_100K                 0x2
+#define AD5686_LDAC_PWRDN_3STATE               0x3
+
+/**
+ * struct ad5686_chip_info - chip specific information
+ * @int_vref_mv:       AD5620/40/60: the internal reference voltage
+ * @channel:           channel specification
+*/
+
+struct ad5686_chip_info {
+       u16                             int_vref_mv;
+       struct iio_chan_spec            channel[AD5686_DAC_CHANNELS];
+};
+
+/**
+ * struct ad5446_state - driver instance specific data
+ * @spi:               spi_device
+ * @chip_info:         chip model specific constants, available modes etc
+ * @reg:               supply regulator
+ * @vref_mv:           actual reference voltage used
+ * @pwr_down_mask:     power down mask
+ * @pwr_down_mode:     current power down mode
+ * @data:              spi transfer buffers
+ */
+
+struct ad5686_state {
+       struct spi_device               *spi;
+       const struct ad5686_chip_info   *chip_info;
+       struct regulator                *reg;
+       unsigned short                  vref_mv;
+       unsigned                        pwr_down_mask;
+       unsigned                        pwr_down_mode;
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+
+       union {
+               u32 d32;
+               u8 d8[4];
+       } data[3] ____cacheline_aligned;
+};
+
+/**
+ * ad5686_supported_device_ids:
+ */
+
+enum ad5686_supported_device_ids {
+       ID_AD5684,
+       ID_AD5685,
+       ID_AD5686,
+};
+static int ad5686_spi_write(struct ad5686_state *st,
+                            u8 cmd, u8 addr, u16 val, u8 shift)
+{
+       val <<= shift;
+
+       st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
+                             AD5686_ADDR(addr) |
+                             val);
+
+       return spi_write(st->spi, &st->data[0].d8[1], 3);
+}
+
+static int ad5686_spi_read(struct ad5686_state *st, u8 addr)
+{
+       struct spi_transfer t[] = {
+               {
+                       .tx_buf = &st->data[0].d8[1],
+                       .len = 3,
+                       .cs_change = 1,
+               }, {
+                       .tx_buf = &st->data[1].d8[1],
+                       .rx_buf = &st->data[2].d8[1],
+                       .len = 3,
+               },
+       };
+       struct spi_message m;
+       int ret;
+
+       spi_message_init(&m);
+       spi_message_add_tail(&t[0], &m);
+       spi_message_add_tail(&t[1], &m);
+
+       st->data[0].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_READBACK_ENABLE) |
+                             AD5686_ADDR(addr));
+       st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP));
+
+       ret = spi_sync(st->spi, &m);
+       if (ret < 0)
+               return ret;
+
+       return be32_to_cpu(st->data[2].d32);
+}
+
+static const char * const ad5686_powerdown_modes[] = {
+       "1kohm_to_gnd",
+       "100kohm_to_gnd",
+       "three_state"
+};
+
+static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan)
+{
+       struct ad5686_state *st = iio_priv(indio_dev);
+
+       return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1;
+}
+
+static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, unsigned int mode)
+{
+       struct ad5686_state *st = iio_priv(indio_dev);
+
+       st->pwr_down_mode &= ~(0x3 << (chan->channel * 2));
+       st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2));
+
+       return 0;
+}
+
+static const struct iio_enum ad5686_powerdown_mode_enum = {
+       .items = ad5686_powerdown_modes,
+       .num_items = ARRAY_SIZE(ad5686_powerdown_modes),
+       .get = ad5686_get_powerdown_mode,
+       .set = ad5686_set_powerdown_mode,
+};
+
+static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev,
+       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
+{
+       struct ad5686_state *st = iio_priv(indio_dev);
+
+       return sprintf(buf, "%d\n", !!(st->pwr_down_mask &
+                       (0x3 << (chan->channel * 2))));
+}
+
+static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
+        uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
+        size_t len)
+{
+       bool readin;
+       int ret;
+       struct ad5686_state *st = iio_priv(indio_dev);
+
+       ret = strtobool(buf, &readin);
+       if (ret)
+               return ret;
+
+       if (readin == true)
+               st->pwr_down_mask |= (0x3 << (chan->channel * 2));
+       else
+               st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));
+
+       ret = ad5686_spi_write(st, AD5686_CMD_POWERDOWN_DAC, 0,
+                              st->pwr_down_mask & st->pwr_down_mode, 0);
+
+       return ret ? ret : len;
+}
+
+static int ad5686_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val,
+                          int *val2,
+                          long m)
+{
+       struct ad5686_state *st = iio_priv(indio_dev);
+       unsigned long scale_uv;
+       int ret;
+
+       switch (m) {
+       case IIO_CHAN_INFO_RAW:
+               mutex_lock(&indio_dev->mlock);
+               ret = ad5686_spi_read(st, chan->address);
+               mutex_unlock(&indio_dev->mlock);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               return IIO_VAL_INT;
+               break;
+       case IIO_CHAN_INFO_SCALE:
+               scale_uv = (st->vref_mv * 100000)
+                       >> (chan->scan_type.realbits);
+               *val =  scale_uv / 100000;
+               *val2 = (scale_uv % 100000) * 10;
+               return IIO_VAL_INT_PLUS_MICRO;
+
+       }
+       return -EINVAL;
+}
+
+static int ad5686_write_raw(struct iio_dev *indio_dev,
+                              struct iio_chan_spec const *chan,
+                              int val,
+                              int val2,
+                              long mask)
+{
+       struct ad5686_state *st = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (val > (1 << chan->scan_type.realbits) || val < 0)
+                       return -EINVAL;
+
+               mutex_lock(&indio_dev->mlock);
+               ret = ad5686_spi_write(st,
+                                AD5686_CMD_WRITE_INPUT_N_UPDATE_N,
+                                chan->address,
+                                val,
+                                chan->scan_type.shift);
+               mutex_unlock(&indio_dev->mlock);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static const struct iio_info ad5686_info = {
+       .read_raw = ad5686_read_raw,
+       .write_raw = ad5686_write_raw,
+       .driver_module = THIS_MODULE,
+};
+
+static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
+       {
+               .name = "powerdown",
+               .read = ad5686_read_dac_powerdown,
+               .write = ad5686_write_dac_powerdown,
+       },
+       IIO_ENUM("powerdown_mode", false, &ad5686_powerdown_mode_enum),
+       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum),
+       { },
+};
+
+#define AD5868_CHANNEL(chan, bits, shift) {                    \
+               .type = IIO_VOLTAGE,                            \
+               .indexed = 1,                                   \
+               .output = 1,                                    \
+               .channel = chan,                                \
+               .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |   \
+               IIO_CHAN_INFO_SCALE_SHARED_BIT,                 \
+               .address = AD5686_ADDR_DAC(chan),                       \
+               .scan_type = IIO_ST('u', bits, 16, shift),      \
+               .ext_info = ad5686_ext_info,                    \
+}
+
+static const struct ad5686_chip_info ad5686_chip_info_tbl[] = {
+       [ID_AD5684] = {
+               .channel[0] = AD5868_CHANNEL(0, 12, 4),
+               .channel[1] = AD5868_CHANNEL(1, 12, 4),
+               .channel[2] = AD5868_CHANNEL(2, 12, 4),
+               .channel[3] = AD5868_CHANNEL(3, 12, 4),
+               .int_vref_mv = 2500,
+       },
+       [ID_AD5685] = {
+               .channel[0] = AD5868_CHANNEL(0, 14, 2),
+               .channel[1] = AD5868_CHANNEL(1, 14, 2),
+               .channel[2] = AD5868_CHANNEL(2, 14, 2),
+               .channel[3] = AD5868_CHANNEL(3, 14, 2),
+               .int_vref_mv = 2500,
+       },
+       [ID_AD5686] = {
+               .channel[0] = AD5868_CHANNEL(0, 16, 0),
+               .channel[1] = AD5868_CHANNEL(1, 16, 0),
+               .channel[2] = AD5868_CHANNEL(2, 16, 0),
+               .channel[3] = AD5868_CHANNEL(3, 16, 0),
+               .int_vref_mv = 2500,
+       },
+};
+
+
+static int __devinit ad5686_probe(struct spi_device *spi)
+{
+       struct ad5686_state *st;
+       struct iio_dev *indio_dev;
+       int ret, regdone = 0, voltage_uv = 0;
+
+       indio_dev = iio_device_alloc(sizeof(*st));
+       if (indio_dev == NULL)
+               return  -ENOMEM;
+
+       st = iio_priv(indio_dev);
+       spi_set_drvdata(spi, indio_dev);
+
+       st->reg = regulator_get(&spi->dev, "vcc");
+       if (!IS_ERR(st->reg)) {
+               ret = regulator_enable(st->reg);
+               if (ret)
+                       goto error_put_reg;
+
+               voltage_uv = regulator_get_voltage(st->reg);
+       }
+
+       st->chip_info =
+               &ad5686_chip_info_tbl[spi_get_device_id(spi)->driver_data];
+
+       if (voltage_uv)
+               st->vref_mv = voltage_uv / 1000;
+       else
+               st->vref_mv = st->chip_info->int_vref_mv;
+
+       st->spi = spi;
+
+       /* Set all the power down mode for all channels to 1K pulldown */
+       st->pwr_down_mode = 0x55;
+
+       indio_dev->dev.parent = &spi->dev;
+       indio_dev->name = spi_get_device_id(spi)->name;
+       indio_dev->info = &ad5686_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = st->chip_info->channel;
+       indio_dev->num_channels = AD5686_DAC_CHANNELS;
+
+       regdone = 1;
+       ret = ad5686_spi_write(st, AD5686_CMD_INTERNAL_REFER_SETUP, 0,
+                               !!voltage_uv, 0);
+       if (ret)
+               goto error_disable_reg;
+
+       ret = iio_device_register(indio_dev);
+       if (ret)
+               goto error_disable_reg;
+
+       return 0;
+
+error_disable_reg:
+       if (!IS_ERR(st->reg))
+               regulator_disable(st->reg);
+error_put_reg:
+       if (!IS_ERR(st->reg))
+               regulator_put(st->reg);
+
+       iio_device_free(indio_dev);
+
+       return ret;
+}
+
+static int __devexit ad5686_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+       struct ad5686_state *st = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+       if (!IS_ERR(st->reg)) {
+               regulator_disable(st->reg);
+               regulator_put(st->reg);
+       }
+       iio_device_free(indio_dev);
+
+       return 0;
+}
+
+static const struct spi_device_id ad5686_id[] = {
+       {"ad5684", ID_AD5684},
+       {"ad5685", ID_AD5685},
+       {"ad5686", ID_AD5686},
+       {}
+};
+MODULE_DEVICE_TABLE(spi, ad5686_id);
+
+static struct spi_driver ad5686_driver = {
+       .driver = {
+                  .name = "ad5686",
+                  .owner = THIS_MODULE,
+                  },
+       .probe = ad5686_probe,
+       .remove = __devexit_p(ad5686_remove),
+       .id_table = ad5686_id,
+};
+module_spi_driver(ad5686_driver);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c
new file mode 100644 (file)
index 0000000..ffce304
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ * Analog devices AD5764, AD5764R, AD5744, AD5744R quad-channel
+ * Digital to Analog Converters driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define AD5764_REG_SF_NOP                      0x0
+#define AD5764_REG_SF_CONFIG                   0x1
+#define AD5764_REG_SF_CLEAR                    0x4
+#define AD5764_REG_SF_LOAD                     0x5
+#define AD5764_REG_DATA(x)                     ((2 << 3) | (x))
+#define AD5764_REG_COARSE_GAIN(x)              ((3 << 3) | (x))
+#define AD5764_REG_FINE_GAIN(x)                        ((4 << 3) | (x))
+#define AD5764_REG_OFFSET(x)                   ((5 << 3) | (x))
+
+#define AD5764_NUM_CHANNELS 4
+
+/**
+ * struct ad5764_chip_info - chip specific information
+ * @int_vref:  Value of the internal reference voltage in uV - 0 if external
+ *             reference voltage is used
+ * @channel    channel specification
+*/
+
+struct ad5764_chip_info {
+       unsigned long int_vref;
+       const struct iio_chan_spec *channels;
+};
+
+/**
+ * struct ad5764_state - driver instance specific data
+ * @spi:               spi_device
+ * @chip_info:         chip info
+ * @vref_reg:          vref supply regulators
+ * @data:              spi transfer buffers
+ */
+
+struct ad5764_state {
+       struct spi_device               *spi;
+       const struct ad5764_chip_info   *chip_info;
+       struct regulator_bulk_data      vref_reg[2];
+
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+       union {
+               __be32 d32;
+               u8 d8[4];
+       } data[2] ____cacheline_aligned;
+};
+
+enum ad5764_type {
+       ID_AD5744,
+       ID_AD5744R,
+       ID_AD5764,
+       ID_AD5764R,
+};
+
+#define AD5764_CHANNEL(_chan, _bits) {                         \
+       .type = IIO_VOLTAGE,                                    \
+       .indexed = 1,                                           \
+       .output = 1,                                            \
+       .channel = (_chan),                                     \
+       .address = (_chan),                                     \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |           \
+               IIO_CHAN_INFO_OFFSET_SHARED_BIT |               \
+               IIO_CHAN_INFO_SCALE_SEPARATE_BIT |              \
+               IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |         \
+               IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,           \
+       .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits))     \
+}
+
+#define DECLARE_AD5764_CHANNELS(_name, _bits) \
+const struct iio_chan_spec _name##_channels[] = { \
+       AD5764_CHANNEL(0, (_bits)), \
+       AD5764_CHANNEL(1, (_bits)), \
+       AD5764_CHANNEL(2, (_bits)), \
+       AD5764_CHANNEL(3, (_bits)), \
+};
+
+static DECLARE_AD5764_CHANNELS(ad5764, 16);
+static DECLARE_AD5764_CHANNELS(ad5744, 14);
+
+static const struct ad5764_chip_info ad5764_chip_infos[] = {
+       [ID_AD5744] = {
+               .int_vref = 0,
+               .channels = ad5744_channels,
+       },
+       [ID_AD5744R] = {
+               .int_vref = 5000000,
+               .channels = ad5744_channels,
+       },
+       [ID_AD5764] = {
+               .int_vref = 0,
+               .channels = ad5764_channels,
+       },
+       [ID_AD5764R] = {
+               .int_vref = 5000000,
+               .channels = ad5764_channels,
+       },
+};
+
+static int ad5764_write(struct iio_dev *indio_dev, unsigned int reg,
+       unsigned int val)
+{
+       struct ad5764_state *st = iio_priv(indio_dev);
+       int ret;
+
+       mutex_lock(&indio_dev->mlock);
+       st->data[0].d32 = cpu_to_be32((reg << 16) | val);
+
+       ret = spi_write(st->spi, &st->data[0].d8[1], 3);
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret;
+}
+
+static int ad5764_read(struct iio_dev *indio_dev, unsigned int reg,
+       unsigned int *val)
+{
+       struct ad5764_state *st = iio_priv(indio_dev);
+       struct spi_message m;
+       int ret;
+       struct spi_transfer t[] = {
+               {
+                       .tx_buf = &st->data[0].d8[1],
+                       .len = 3,
+                       .cs_change = 1,
+               }, {
+                       .rx_buf = &st->data[1].d8[1],
+                       .len = 3,
+               },
+       };
+
+       spi_message_init(&m);
+       spi_message_add_tail(&t[0], &m);
+       spi_message_add_tail(&t[1], &m);
+
+       mutex_lock(&indio_dev->mlock);
+
+       st->data[0].d32 = cpu_to_be32((1 << 23) | (reg << 16));
+
+       ret = spi_sync(st->spi, &m);
+       if (ret >= 0)
+               *val = be32_to_cpu(st->data[1].d32) & 0xffff;
+
+       mutex_unlock(&indio_dev->mlock);
+
+       return ret;
+}
+
+static int ad5764_chan_info_to_reg(struct iio_chan_spec const *chan, long info)
+{
+       switch (info) {
+       case 0:
+               return AD5764_REG_DATA(chan->address);
+       case IIO_CHAN_INFO_CALIBBIAS:
+               return AD5764_REG_OFFSET(chan->address);
+       case IIO_CHAN_INFO_CALIBSCALE:
+               return AD5764_REG_FINE_GAIN(chan->address);
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static int ad5764_write_raw(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan, int val, int val2, long info)
+{
+       const int max_val = (1 << chan->scan_type.realbits);
+       unsigned int reg;
+
+       switch (info) {
+       case IIO_CHAN_INFO_RAW:
+               if (val >= max_val || val < 0)
+                       return -EINVAL;
+               val <<= chan->scan_type.shift;
+               break;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               if (val >= 128 || val < -128)
+                       return -EINVAL;
+               break;
+       case IIO_CHAN_INFO_CALIBSCALE:
+               if (val >= 32 || val < -32)
+                       return -EINVAL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       reg = ad5764_chan_info_to_reg(chan, info);
+       return ad5764_write(indio_dev, reg, (u16)val);
+}
+
+static int ad5764_get_channel_vref(struct ad5764_state *st,
+       unsigned int channel)
+{
+       if (st->chip_info->int_vref)
+               return st->chip_info->int_vref;
+       else
+               return regulator_get_voltage(st->vref_reg[channel / 2].consumer);
+}
+
+static int ad5764_read_raw(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan, int *val, int *val2, long info)
+{
+       struct ad5764_state *st = iio_priv(indio_dev);
+       unsigned long scale_uv;
+       unsigned int reg;
+       int vref;
+       int ret;
+
+       switch (info) {
+       case IIO_CHAN_INFO_RAW:
+               reg = AD5764_REG_DATA(chan->address);
+               ret = ad5764_read(indio_dev, reg, val);
+               if (ret < 0)
+                       return ret;
+               *val >>= chan->scan_type.shift;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               reg = AD5764_REG_OFFSET(chan->address);
+               ret = ad5764_read(indio_dev, reg, val);
+               if (ret < 0)
+                       return ret;
+               *val = sign_extend32(*val, 7);
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_CALIBSCALE:
+               reg = AD5764_REG_FINE_GAIN(chan->address);
+               ret = ad5764_read(indio_dev, reg, val);
+               if (ret < 0)
+                       return ret;
+               *val = sign_extend32(*val, 5);
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               /* vout = 4 * vref + ((dac_code / 65535) - 0.5) */
+               vref = ad5764_get_channel_vref(st, chan->channel);
+               if (vref < 0)
+                       return vref;
+
+               scale_uv = (vref * 4 * 100) >> chan->scan_type.realbits;
+               *val = scale_uv / 100000;
+               *val2 = (scale_uv % 100000) * 10;
+               return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_OFFSET:
+               *val = -(1 << chan->scan_type.realbits) / 2;
+               return IIO_VAL_INT;
+       }
+
+       return -EINVAL;
+}
+
+static const struct iio_info ad5764_info = {
+       .read_raw = ad5764_read_raw,
+       .write_raw = ad5764_write_raw,
+       .driver_module = THIS_MODULE,
+};
+
+static int __devinit ad5764_probe(struct spi_device *spi)
+{
+       enum ad5764_type type = spi_get_device_id(spi)->driver_data;
+       struct iio_dev *indio_dev;
+       struct ad5764_state *st;
+       int ret;
+
+       indio_dev = iio_device_alloc(sizeof(*st));
+       if (indio_dev == NULL) {
+               dev_err(&spi->dev, "Failed to allocate iio device\n");
+               return -ENOMEM;
+       }
+
+       st = iio_priv(indio_dev);
+       spi_set_drvdata(spi, indio_dev);
+
+       st->spi = spi;
+       st->chip_info = &ad5764_chip_infos[type];
+
+       indio_dev->dev.parent = &spi->dev;
+       indio_dev->name = spi_get_device_id(spi)->name;
+       indio_dev->info = &ad5764_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->num_channels = AD5764_NUM_CHANNELS;
+       indio_dev->channels = st->chip_info->channels;
+
+       if (st->chip_info->int_vref == 0) {
+               st->vref_reg[0].supply = "vrefAB";
+               st->vref_reg[1].supply = "vrefCD";
+
+               ret = regulator_bulk_get(&st->spi->dev,
+                       ARRAY_SIZE(st->vref_reg), st->vref_reg);
+               if (ret) {
+                       dev_err(&spi->dev, "Failed to request vref regulators: %d\n",
+                               ret);
+                       goto error_free;
+               }
+
+               ret = regulator_bulk_enable(ARRAY_SIZE(st->vref_reg),
+                       st->vref_reg);
+               if (ret) {
+                       dev_err(&spi->dev, "Failed to enable vref regulators: %d\n",
+                               ret);
+                       goto error_free_reg;
+               }
+       }
+
+       ret = iio_device_register(indio_dev);
+       if (ret) {
+               dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
+               goto error_disable_reg;
+       }
+
+       return 0;
+
+error_disable_reg:
+       if (st->chip_info->int_vref == 0)
+               regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
+error_free_reg:
+       if (st->chip_info->int_vref == 0)
+               regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg);
+error_free:
+       iio_device_free(indio_dev);
+
+       return ret;
+}
+
+static int __devexit ad5764_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+       struct ad5764_state *st = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+
+       if (st->chip_info->int_vref == 0) {
+               regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
+               regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg);
+       }
+
+       iio_device_free(indio_dev);
+
+       return 0;
+}
+
+static const struct spi_device_id ad5764_ids[] = {
+       { "ad5744", ID_AD5744 },
+       { "ad5744r", ID_AD5744R },
+       { "ad5764", ID_AD5764 },
+       { "ad5764r", ID_AD5764R },
+       { }
+};
+MODULE_DEVICE_TABLE(spi, ad5764_ids);
+
+static struct spi_driver ad5764_driver = {
+       .driver = {
+               .name = "ad5764",
+               .owner = THIS_MODULE,
+       },
+       .probe = ad5764_probe,
+       .remove = __devexit_p(ad5764_remove),
+       .id_table = ad5764_ids,
+};
+module_spi_driver(ad5764_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices AD5744/AD5744R/AD5764/AD5764R DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c
new file mode 100644 (file)
index 0000000..2bd2e37
--- /dev/null
@@ -0,0 +1,485 @@
+/*
+ * AD5760, AD5780, AD5781, AD5790, AD5791 Voltage Output Digital to Analog
+ * Converter
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/dac/ad5791.h>
+
+#define AD5791_RES_MASK(x)             ((1 << (x)) - 1)
+#define AD5791_DAC_MASK                        AD5791_RES_MASK(20)
+#define AD5791_DAC_MSB                 (1 << 19)
+
+#define AD5791_CMD_READ                        (1 << 23)
+#define AD5791_CMD_WRITE               (0 << 23)
+#define AD5791_ADDR(addr)              ((addr) << 20)
+
+/* Registers */
+#define AD5791_ADDR_NOOP               0
+#define AD5791_ADDR_DAC0               1
+#define AD5791_ADDR_CTRL               2
+#define AD5791_ADDR_CLRCODE            3
+#define AD5791_ADDR_SW_CTRL            4
+
+/* Control Register */
+#define AD5791_CTRL_RBUF               (1 << 1)
+#define AD5791_CTRL_OPGND              (1 << 2)
+#define AD5791_CTRL_DACTRI             (1 << 3)
+#define AD5791_CTRL_BIN2SC             (1 << 4)
+#define AD5791_CTRL_SDODIS             (1 << 5)
+#define AD5761_CTRL_LINCOMP(x)         ((x) << 6)
+
+#define AD5791_LINCOMP_0_10            0
+#define AD5791_LINCOMP_10_12           1
+#define AD5791_LINCOMP_12_16           2
+#define AD5791_LINCOMP_16_19           3
+#define AD5791_LINCOMP_19_20           12
+
+#define AD5780_LINCOMP_0_10            0
+#define AD5780_LINCOMP_10_20           12
+
+/* Software Control Register */
+#define AD5791_SWCTRL_LDAC             (1 << 0)
+#define AD5791_SWCTRL_CLR              (1 << 1)
+#define AD5791_SWCTRL_RESET            (1 << 2)
+
+#define AD5791_DAC_PWRDN_6K            0
+#define AD5791_DAC_PWRDN_3STATE                1
+
+/**
+ * struct ad5791_chip_info - chip specific information
+ * @get_lin_comp:      function pointer to the device specific function
+ */
+
+struct ad5791_chip_info {
+       int (*get_lin_comp)     (unsigned int span);
+};
+
+/**
+ * struct ad5791_state - driver instance specific data
+ * @us:                        spi_device
+ * @reg_vdd:           positive supply regulator
+ * @reg_vss:           negative supply regulator
+ * @chip_info:         chip model specific constants
+ * @vref_mv:           actual reference voltage used
+ * @vref_neg_mv:       voltage of the negative supply
+ * @pwr_down_mode      current power down mode
+ */
+
+struct ad5791_state {
+       struct spi_device               *spi;
+       struct regulator                *reg_vdd;
+       struct regulator                *reg_vss;
+       const struct ad5791_chip_info   *chip_info;
+       unsigned short                  vref_mv;
+       unsigned int                    vref_neg_mv;
+       unsigned                        ctrl;
+       unsigned                        pwr_down_mode;
+       bool                            pwr_down;
+};
+
+/**
+ * ad5791_supported_device_ids:
+ */
+
+enum ad5791_supported_device_ids {
+       ID_AD5760,
+       ID_AD5780,
+       ID_AD5781,
+       ID_AD5791,
+};
+
+static int ad5791_spi_write(struct spi_device *spi, u8 addr, u32 val)
+{
+       union {
+               u32 d32;
+               u8 d8[4];
+       } data;
+
+       data.d32 = cpu_to_be32(AD5791_CMD_WRITE |
+                             AD5791_ADDR(addr) |
+                             (val & AD5791_DAC_MASK));
+
+       return spi_write(spi, &data.d8[1], 3);
+}
+
+static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val)
+{
+       union {
+               u32 d32;
+               u8 d8[4];
+       } data[3];
+       int ret;
+       struct spi_message msg;
+       struct spi_transfer xfers[] = {
+               {
+                       .tx_buf = &data[0].d8[1],
+                       .bits_per_word = 8,
+                       .len = 3,
+                       .cs_change = 1,
+               }, {
+                       .tx_buf = &data[1].d8[1],
+                       .rx_buf = &data[2].d8[1],
+                       .bits_per_word = 8,
+                       .len = 3,
+               },
+       };
+
+       data[0].d32 = cpu_to_be32(AD5791_CMD_READ |
+                             AD5791_ADDR(addr));
+       data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP));
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&xfers[0], &msg);
+       spi_message_add_tail(&xfers[1], &msg);
+       ret = spi_sync(spi, &msg);
+
+       *val = be32_to_cpu(data[2].d32);
+
+       return ret;
+}
+
+static const char * const ad5791_powerdown_modes[] = {
+       "6kohm_to_gnd",
+       "three_state",
+};
+
+static int ad5791_get_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan)
+{
+       struct ad5791_state *st = iio_priv(indio_dev);
+
+       return st->pwr_down_mode;
+}
+
+static int ad5791_set_powerdown_mode(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, unsigned int mode)
+{
+       struct ad5791_state *st = iio_priv(indio_dev);
+
+       st->pwr_down_mode = mode;
+
+       return 0;
+}
+
+static const struct iio_enum ad5791_powerdown_mode_enum = {
+       .items = ad5791_powerdown_modes,
+       .num_items = ARRAY_SIZE(ad5791_powerdown_modes),
+       .get = ad5791_get_powerdown_mode,
+       .set = ad5791_set_powerdown_mode,
+};
+
+static ssize_t ad5791_read_dac_powerdown(struct iio_dev *indio_dev,
+       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
+{
+       struct ad5791_state *st = iio_priv(indio_dev);
+
+       return sprintf(buf, "%d\n", st->pwr_down);
+}
+
+static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev,
+        uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
+        size_t len)
+{
+       bool pwr_down;
+       int ret;
+       struct ad5791_state *st = iio_priv(indio_dev);
+
+       ret = strtobool(buf, &pwr_down);
+       if (ret)
+               return ret;
+
+       if (!pwr_down) {
+               st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
+       } else {
+               if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K)
+                       st->ctrl |= AD5791_CTRL_OPGND;
+               else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE)
+                       st->ctrl |= AD5791_CTRL_DACTRI;
+       }
+       st->pwr_down = pwr_down;
+
+       ret = ad5791_spi_write(st->spi, AD5791_ADDR_CTRL, st->ctrl);
+
+       return ret ? ret : len;
+}
+
+static int ad5791_get_lin_comp(unsigned int span)
+{
+       if (span <= 10000)
+               return AD5791_LINCOMP_0_10;
+       else if (span <= 12000)
+               return AD5791_LINCOMP_10_12;
+       else if (span <= 16000)
+               return AD5791_LINCOMP_12_16;
+       else if (span <= 19000)
+               return AD5791_LINCOMP_16_19;
+       else
+               return AD5791_LINCOMP_19_20;
+}
+
+static int ad5780_get_lin_comp(unsigned int span)
+{
+       if (span <= 10000)
+               return AD5780_LINCOMP_0_10;
+       else
+               return AD5780_LINCOMP_10_20;
+}
+static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
+       [ID_AD5760] = {
+               .get_lin_comp = ad5780_get_lin_comp,
+       },
+       [ID_AD5780] = {
+               .get_lin_comp = ad5780_get_lin_comp,
+       },
+       [ID_AD5781] = {
+               .get_lin_comp = ad5791_get_lin_comp,
+       },
+       [ID_AD5791] = {
+               .get_lin_comp = ad5791_get_lin_comp,
+       },
+};
+
+static int ad5791_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val,
+                          int *val2,
+                          long m)
+{
+       struct ad5791_state *st = iio_priv(indio_dev);
+       u64 val64;
+       int ret;
+
+       switch (m) {
+       case IIO_CHAN_INFO_RAW:
+               ret = ad5791_spi_read(st->spi, chan->address, val);
+               if (ret)
+                       return ret;
+               *val &= AD5791_DAC_MASK;
+               *val >>= chan->scan_type.shift;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               *val = 0;
+               *val2 = (((u64)st->vref_mv) * 1000000ULL) >> chan->scan_type.realbits;
+               return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_OFFSET:
+               val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
+               do_div(val64, st->vref_mv);
+               *val = -val64;
+               return IIO_VAL_INT;
+       default:
+               return -EINVAL;
+       }
+
+};
+
+static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
+       {
+               .name = "powerdown",
+               .shared = true,
+               .read = ad5791_read_dac_powerdown,
+               .write = ad5791_write_dac_powerdown,
+       },
+       IIO_ENUM("powerdown_mode", true, &ad5791_powerdown_mode_enum),
+       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
+       { },
+};
+
+#define AD5791_CHAN(bits, shift) {                     \
+       .type = IIO_VOLTAGE,                            \
+       .output = 1,                                    \
+       .indexed = 1,                                   \
+       .address = AD5791_ADDR_DAC0,                    \
+       .channel = 0,                                   \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |   \
+               IIO_CHAN_INFO_SCALE_SHARED_BIT |        \
+               IIO_CHAN_INFO_OFFSET_SHARED_BIT,        \
+       .scan_type = IIO_ST('u', bits, 24, shift),      \
+       .ext_info = ad5791_ext_info,                    \
+}
+
+static const struct iio_chan_spec ad5791_channels[] = {
+       [ID_AD5760] = AD5791_CHAN(16, 4),
+       [ID_AD5780] = AD5791_CHAN(18, 2),
+       [ID_AD5781] = AD5791_CHAN(18, 2),
+       [ID_AD5791] = AD5791_CHAN(20, 0)
+};
+
+static int ad5791_write_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan,
+                           int val,
+                           int val2,
+                           long mask)
+{
+       struct ad5791_state *st = iio_priv(indio_dev);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               val &= AD5791_RES_MASK(chan->scan_type.realbits);
+               val <<= chan->scan_type.shift;
+
+               return ad5791_spi_write(st->spi, chan->address, val);
+
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct iio_info ad5791_info = {
+       .read_raw = &ad5791_read_raw,
+       .write_raw = &ad5791_write_raw,
+       .driver_module = THIS_MODULE,
+};
+
+static int __devinit ad5791_probe(struct spi_device *spi)
+{
+       struct ad5791_platform_data *pdata = spi->dev.platform_data;
+       struct iio_dev *indio_dev;
+       struct ad5791_state *st;
+       int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
+
+       indio_dev = iio_device_alloc(sizeof(*st));
+       if (indio_dev == NULL) {
+               ret = -ENOMEM;
+               goto error_ret;
+       }
+       st = iio_priv(indio_dev);
+       st->reg_vdd = regulator_get(&spi->dev, "vdd");
+       if (!IS_ERR(st->reg_vdd)) {
+               ret = regulator_enable(st->reg_vdd);
+               if (ret)
+                       goto error_put_reg_pos;
+
+               pos_voltage_uv = regulator_get_voltage(st->reg_vdd);
+       }
+
+       st->reg_vss = regulator_get(&spi->dev, "vss");
+       if (!IS_ERR(st->reg_vss)) {
+               ret = regulator_enable(st->reg_vss);
+               if (ret)
+                       goto error_put_reg_neg;
+
+               neg_voltage_uv = regulator_get_voltage(st->reg_vss);
+       }
+
+       st->pwr_down = true;
+       st->spi = spi;
+
+       if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) {
+               st->vref_mv = (pos_voltage_uv + neg_voltage_uv) / 1000;
+               st->vref_neg_mv = neg_voltage_uv / 1000;
+       } else if (pdata) {
+               st->vref_mv = pdata->vref_pos_mv + pdata->vref_neg_mv;
+               st->vref_neg_mv = pdata->vref_neg_mv;
+       } else {
+               dev_warn(&spi->dev, "reference voltage unspecified\n");
+       }
+
+       ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
+       if (ret)
+               goto error_disable_reg_neg;
+
+       st->chip_info = &ad5791_chip_info_tbl[spi_get_device_id(spi)
+                                             ->driver_data];
+
+
+       st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv))
+                 | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) |
+                 AD5791_CTRL_BIN2SC;
+
+       ret = ad5791_spi_write(spi, AD5791_ADDR_CTRL, st->ctrl |
+               AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
+       if (ret)
+               goto error_disable_reg_neg;
+
+       spi_set_drvdata(spi, indio_dev);
+       indio_dev->dev.parent = &spi->dev;
+       indio_dev->info = &ad5791_info;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels
+               = &ad5791_channels[spi_get_device_id(spi)->driver_data];
+       indio_dev->num_channels = 1;
+       indio_dev->name = spi_get_device_id(st->spi)->name;
+       ret = iio_device_register(indio_dev);
+       if (ret)
+               goto error_disable_reg_neg;
+
+       return 0;
+
+error_disable_reg_neg:
+       if (!IS_ERR(st->reg_vss))
+               regulator_disable(st->reg_vss);
+error_put_reg_neg:
+       if (!IS_ERR(st->reg_vss))
+               regulator_put(st->reg_vss);
+
+       if (!IS_ERR(st->reg_vdd))
+               regulator_disable(st->reg_vdd);
+error_put_reg_pos:
+       if (!IS_ERR(st->reg_vdd))
+               regulator_put(st->reg_vdd);
+       iio_device_free(indio_dev);
+error_ret:
+
+       return ret;
+}
+
+static int __devexit ad5791_remove(struct spi_device *spi)
+{
+       struct iio_dev *indio_dev = spi_get_drvdata(spi);
+       struct ad5791_state *st = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+       if (!IS_ERR(st->reg_vdd)) {
+               regulator_disable(st->reg_vdd);
+               regulator_put(st->reg_vdd);
+       }
+
+       if (!IS_ERR(st->reg_vss)) {
+               regulator_disable(st->reg_vss);
+               regulator_put(st->reg_vss);
+       }
+       iio_device_free(indio_dev);
+
+       return 0;
+}
+
+static const struct spi_device_id ad5791_id[] = {
+       {"ad5760", ID_AD5760},
+       {"ad5780", ID_AD5780},
+       {"ad5781", ID_AD5781},
+       {"ad5790", ID_AD5791},
+       {"ad5791", ID_AD5791},
+       {}
+};
+MODULE_DEVICE_TABLE(spi, ad5791_id);
+
+static struct spi_driver ad5791_driver = {
+       .driver = {
+                  .name = "ad5791",
+                  .owner = THIS_MODULE,
+                  },
+       .probe = ad5791_probe,
+       .remove = __devexit_p(ad5791_remove),
+       .id_table = ad5791_id,
+};
+module_spi_driver(ad5791_driver);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c
new file mode 100644 (file)
index 0000000..92c77c8
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ *  max517.c - Support for Maxim MAX517, MAX518 and MAX519
+ *
+ *  Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/dac/max517.h>
+
+#define MAX517_DRV_NAME        "max517"
+
+/* Commands */
+#define COMMAND_CHANNEL0       0x00
+#define COMMAND_CHANNEL1       0x01 /* for MAX518 and MAX519 */
+#define COMMAND_PD             0x08 /* Power Down */
+
+enum max517_device_ids {
+       ID_MAX517,
+       ID_MAX518,
+       ID_MAX519,
+};
+
+struct max517_data {
+       struct iio_dev          *indio_dev;
+       struct i2c_client       *client;
+       unsigned short          vref_mv[2];
+};
+
+/*
+ * channel: bit 0: channel 1
+ *          bit 1: channel 2
+ * (this way, it's possible to set both channels at once)
+ */
+static int max517_set_value(struct iio_dev *indio_dev,
+       long val, int channel)
+{
+       struct max517_data *data = iio_priv(indio_dev);
+       struct i2c_client *client = data->client;
+       u8 outbuf[2];
+       int res;
+
+       if (val < 0 || val > 255)
+               return -EINVAL;
+
+       outbuf[0] = channel;
+       outbuf[1] = val;
+
+       res = i2c_master_send(client, outbuf, 2);
+       if (res < 0)
+               return res;
+       else if (res != 2)
+               return -EIO;
+       else
+               return 0;
+}
+
+static int max517_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val,
+                          int *val2,
+                          long m)
+{
+       struct max517_data *data = iio_priv(indio_dev);
+       unsigned int scale_uv;
+
+       switch (m) {
+       case IIO_CHAN_INFO_SCALE:
+               /* Corresponds to Vref / 2^(bits) */
+               scale_uv = (data->vref_mv[chan->channel] * 1000) >> 8;
+               *val =  scale_uv / 1000000;
+               *val2 = scale_uv % 1000000;
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               break;
+       }
+       return -EINVAL;
+}
+
+static int max517_write_raw(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan, int val, int val2, long mask)
+{
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               ret = max517_set_value(indio_dev, val, chan->channel);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int max517_suspend(struct device *dev)
+{
+       u8 outbuf = COMMAND_PD;
+
+       return i2c_master_send(to_i2c_client(dev), &outbuf, 1);
+}
+
+static int max517_resume(struct device *dev)
+{
+       u8 outbuf = 0;
+
+       return i2c_master_send(to_i2c_client(dev), &outbuf, 1);
+}
+
+static SIMPLE_DEV_PM_OPS(max517_pm_ops, max517_suspend, max517_resume);
+#define MAX517_PM_OPS (&max517_pm_ops)
+#else
+#define MAX517_PM_OPS NULL
+#endif
+
+static const struct iio_info max517_info = {
+       .read_raw = max517_read_raw,
+       .write_raw = max517_write_raw,
+       .driver_module = THIS_MODULE,
+};
+
+#define MAX517_CHANNEL(chan) {                         \
+       .type = IIO_VOLTAGE,                            \
+       .indexed = 1,                                   \
+       .output = 1,                                    \
+       .channel = (chan),                              \
+       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |   \
+       IIO_CHAN_INFO_SCALE_SEPARATE_BIT,               \
+       .scan_type = IIO_ST('u', 8, 8, 0),              \
+}
+
+static const struct iio_chan_spec max517_channels[] = {
+       MAX517_CHANNEL(0),
+       MAX517_CHANNEL(1)
+};
+
+static int max517_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+{
+       struct max517_data *data;
+       struct iio_dev *indio_dev;
+       struct max517_platform_data *platform_data = client->dev.platform_data;
+       int err;
+
+       indio_dev = iio_device_alloc(sizeof(*data));
+       if (indio_dev == NULL) {
+               err = -ENOMEM;
+               goto exit;
+       }
+       data = iio_priv(indio_dev);
+       i2c_set_clientdata(client, indio_dev);
+       data->client = client;
+
+       /* establish that the iio_dev is a child of the i2c device */
+       indio_dev->dev.parent = &client->dev;
+
+       /* reduced channel set for MAX517 */
+       if (id->driver_data == ID_MAX517)
+               indio_dev->num_channels = 1;
+       else
+               indio_dev->num_channels = 2;
+       indio_dev->channels = max517_channels;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->info = &max517_info;
+
+       /*
+        * Reference voltage on MAX518 and default is 5V, else take vref_mv
+        * from platform_data
+        */
+       if (id->driver_data == ID_MAX518 || !platform_data) {
+               data->vref_mv[0] = data->vref_mv[1] = 5000; /* mV */
+       } else {
+               data->vref_mv[0] = platform_data->vref_mv[0];
+               data->vref_mv[1] = platform_data->vref_mv[1];
+       }
+
+       err = iio_device_register(indio_dev);
+       if (err)
+               goto exit_free_device;
+
+       dev_info(&client->dev, "DAC registered\n");
+
+       return 0;
+
+exit_free_device:
+       iio_device_free(indio_dev);
+exit:
+       return err;
+}
+
+static int max517_remove(struct i2c_client *client)
+{
+       iio_device_unregister(i2c_get_clientdata(client));
+       iio_device_free(i2c_get_clientdata(client));
+
+       return 0;
+}
+
+static const struct i2c_device_id max517_id[] = {
+       { "max517", ID_MAX517 },
+       { "max518", ID_MAX518 },
+       { "max519", ID_MAX519 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, max517_id);
+
+static struct i2c_driver max517_driver = {
+       .driver = {
+               .name   = MAX517_DRV_NAME,
+               .pm             = MAX517_PM_OPS,
+       },
+       .probe          = max517_probe,
+       .remove         = max517_remove,
+       .id_table       = max517_id,
+};
+module_i2c_driver(max517_driver);
+
+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
+MODULE_DESCRIPTION("MAX517/MAX518/MAX519 8-bit DAC");
+MODULE_LICENSE("GPL");
index 3c8e5ec26ac18787686d8dfe3a30c1fe2374eef3..04cd6ec1f70f1fd966e93d831c364d02a3762ba3 100644 (file)
@@ -29,7 +29,6 @@ source "drivers/staging/iio/accel/Kconfig"
 source "drivers/staging/iio/adc/Kconfig"
 source "drivers/staging/iio/addac/Kconfig"
 source "drivers/staging/iio/cdc/Kconfig"
-source "drivers/staging/iio/dac/Kconfig"
 source "drivers/staging/iio/frequency/Kconfig"
 source "drivers/staging/iio/gyro/Kconfig"
 source "drivers/staging/iio/impedance-analyzer/Kconfig"
index 6a46d5afb380c189d7238a60b867bab8e0c87352..fa6937d92ee3205b0ddbef9b75a002b0a893b21b 100644 (file)
@@ -17,7 +17,6 @@ obj-y += accel/
 obj-y += adc/
 obj-y += addac/
 obj-y += cdc/
-obj-y += dac/
 obj-y += frequency/
 obj-y += gyro/
 obj-y += impedance-analyzer/
diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig
deleted file mode 100644 (file)
index a626f03..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-#
-# DAC drivers
-#
-menu "Digital to analog converters"
-
-config AD5064
-       tristate "Analog Devices AD5064/64-1/65/44/45/24/25, AD5628/48/66/68 DAC driver"
-       depends on SPI
-       help
-         Say yes here to build support for Analog Devices AD5024, AD5025, AD5044,
-         AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5648, AD5666, AD5668 Digital
-         to Analog Converter.
-
-         To compile this driver as a module, choose M here: the
-         module will be called ad5064.
-
-config AD5360
-       tristate "Analog Devices Analog Devices AD5360/61/62/63/70/71/73 DAC driver"
-       depends on SPI
-       help
-         Say yes here to build support for Analog Devices AD5360, AD5361,
-         AD5362, AD5363, AD5370, AD5371, AD5373 multi-channel
-         Digital to Analog Converters (DAC).
-
-         To compile this driver as module choose M here: the module will be called
-         ad5360.
-
-config AD5380
-       tristate "Analog Devices AD5380/81/82/83/84/90/91/92 DAC driver"
-       depends on (SPI_MASTER || I2C)
-       select REGMAP_I2C if I2C
-       select REGMAP_SPI if SPI_MASTER
-       help
-         Say yes here to build support for Analog Devices AD5380, AD5381,
-         AD5382, AD5383, AD5384, AD5390, AD5391, AD5392 multi-channel
-         Digital to Analog Converters (DAC).
-
-         To compile this driver as module choose M here: the module will be called
-         ad5380.
-
-config AD5421
-       tristate "Analog Devices AD5421 DAC driver"
-       depends on SPI
-       help
-         Say yes here to build support for Analog Devices AD5421 loop-powered
-         digital-to-analog convertors (DAC).
-
-         To compile this driver as module choose M here: the module will be called
-         ad5421.
-
-config AD5624R_SPI
-       tristate "Analog Devices AD5624/44/64R DAC spi driver"
-       depends on SPI
-       help
-         Say yes here to build support for Analog Devices AD5624R, AD5644R and
-         AD5664R converters (DAC). This driver uses the common SPI interface.
-
-config AD5446
-       tristate "Analog Devices AD5446 and similar single channel DACs driver"
-       depends on SPI
-       help
-         Say yes here to build support for Analog Devices AD5444, AD5446,
-         AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5611, AD5620,
-         AD5621, AD5640, AD5660, AD5662 DACs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called ad5446.
-
-config AD5504
-       tristate "Analog Devices AD5504/AD5501 DAC SPI driver"
-       depends on SPI
-       help
-         Say yes here to build support for Analog Devices AD5504, AD5501,
-         High Voltage Digital to Analog Converter.
-
-         To compile this driver as a module, choose M here: the
-         module will be called ad5504.
-
-config AD5764
-       tristate "Analog Devices AD5764/64R/44/44R DAC driver"
-       depends on SPI_MASTER
-       help
-         Say yes here to build support for Analog Devices AD5764, AD5764R, AD5744,
-         AD5744R Digital to Analog Converter.
-
-         To compile this driver as a module, choose M here: the
-         module will be called ad5764.
-
-config AD5791
-       tristate "Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC SPI driver"
-       depends on SPI
-       help
-         Say yes here to build support for Analog Devices AD5760, AD5780,
-         AD5781, AD5790, AD5791 High Resolution Voltage Output Digital to
-         Analog Converter.
-
-         To compile this driver as a module, choose M here: the
-         module will be called ad5791.
-
-config AD5686
-       tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver"
-       depends on SPI
-       help
-         Say yes here to build support for Analog Devices AD5686R, AD5685R,
-         AD5684R, AD5791 Voltage Output Digital to
-         Analog Converter.
-
-         To compile this driver as a module, choose M here: the
-         module will be called ad5686.
-
-config MAX517
-       tristate "Maxim MAX517/518/519 DAC driver"
-       depends on I2C && EXPERIMENTAL
-       help
-         If you say yes here you get support for the Maxim chips MAX517,
-         MAX518 and MAX519 (I2C 8-Bit DACs with rail-to-rail outputs).
-
-         This driver can also be built as a module.  If so, the module
-         will be called max517.
-
-endmenu
diff --git a/drivers/staging/iio/dac/Makefile b/drivers/staging/iio/dac/Makefile
deleted file mode 100644 (file)
index 8ab1d26..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# Makefile for industrial I/O DAC drivers
-#
-
-obj-$(CONFIG_AD5360) += ad5360.o
-obj-$(CONFIG_AD5380) += ad5380.o
-obj-$(CONFIG_AD5421) += ad5421.o
-obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o
-obj-$(CONFIG_AD5064) += ad5064.o
-obj-$(CONFIG_AD5504) += ad5504.o
-obj-$(CONFIG_AD5446) += ad5446.o
-obj-$(CONFIG_AD5764) += ad5764.o
-obj-$(CONFIG_AD5791) += ad5791.o
-obj-$(CONFIG_AD5686) += ad5686.o
-obj-$(CONFIG_MAX517) += max517.o
diff --git a/drivers/staging/iio/dac/ad5064.c b/drivers/staging/iio/dac/ad5064.c
deleted file mode 100644 (file)
index 276af02..0000000
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5648,
- * AD5666, AD5668 Digital to analog converters driver
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/regulator/consumer.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#define AD5064_MAX_DAC_CHANNELS                        8
-#define AD5064_MAX_VREFS                       4
-
-#define AD5064_ADDR(x)                         ((x) << 20)
-#define AD5064_CMD(x)                          ((x) << 24)
-
-#define AD5064_ADDR_DAC(chan)                  (chan)
-#define AD5064_ADDR_ALL_DAC                    0xF
-
-#define AD5064_CMD_WRITE_INPUT_N               0x0
-#define AD5064_CMD_UPDATE_DAC_N                        0x1
-#define AD5064_CMD_WRITE_INPUT_N_UPDATE_ALL    0x2
-#define AD5064_CMD_WRITE_INPUT_N_UPDATE_N      0x3
-#define AD5064_CMD_POWERDOWN_DAC               0x4
-#define AD5064_CMD_CLEAR                       0x5
-#define AD5064_CMD_LDAC_MASK                   0x6
-#define AD5064_CMD_RESET                       0x7
-#define AD5064_CMD_CONFIG                      0x8
-
-#define AD5064_CONFIG_DAISY_CHAIN_ENABLE       BIT(1)
-#define AD5064_CONFIG_INT_VREF_ENABLE          BIT(0)
-
-#define AD5064_LDAC_PWRDN_NONE                 0x0
-#define AD5064_LDAC_PWRDN_1K                   0x1
-#define AD5064_LDAC_PWRDN_100K                 0x2
-#define AD5064_LDAC_PWRDN_3STATE               0x3
-
-/**
- * struct ad5064_chip_info - chip specific information
- * @shared_vref:       whether the vref supply is shared between channels
- * @internal_vref:     internal reference voltage. 0 if the chip has no internal
- *                     vref.
- * @channel:           channel specification
- * @num_channels:      number of channels
- */
-
-struct ad5064_chip_info {
-       bool shared_vref;
-       unsigned long internal_vref;
-       const struct iio_chan_spec *channels;
-       unsigned int num_channels;
-};
-
-/**
- * struct ad5064_state - driver instance specific data
- * @spi:               spi_device
- * @chip_info:         chip model specific constants, available modes etc
- * @vref_reg:          vref supply regulators
- * @pwr_down:          whether channel is powered down
- * @pwr_down_mode:     channel's current power down mode
- * @dac_cache:         current DAC raw value (chip does not support readback)
- * @use_internal_vref: set to true if the internal reference voltage should be
- *                     used.
- * @data:              spi transfer buffers
- */
-
-struct ad5064_state {
-       struct spi_device               *spi;
-       const struct ad5064_chip_info   *chip_info;
-       struct regulator_bulk_data      vref_reg[AD5064_MAX_VREFS];
-       bool                            pwr_down[AD5064_MAX_DAC_CHANNELS];
-       u8                              pwr_down_mode[AD5064_MAX_DAC_CHANNELS];
-       unsigned int                    dac_cache[AD5064_MAX_DAC_CHANNELS];
-       bool                            use_internal_vref;
-
-       /*
-        * DMA (thus cache coherency maintenance) requires the
-        * transfer buffers to live in their own cache lines.
-        */
-       __be32 data ____cacheline_aligned;
-};
-
-enum ad5064_type {
-       ID_AD5024,
-       ID_AD5025,
-       ID_AD5044,
-       ID_AD5045,
-       ID_AD5064,
-       ID_AD5064_1,
-       ID_AD5065,
-       ID_AD5628_1,
-       ID_AD5628_2,
-       ID_AD5648_1,
-       ID_AD5648_2,
-       ID_AD5666_1,
-       ID_AD5666_2,
-       ID_AD5668_1,
-       ID_AD5668_2,
-};
-
-static int ad5064_spi_write(struct ad5064_state *st, unsigned int cmd,
-       unsigned int addr, unsigned int val, unsigned int shift)
-{
-       val <<= shift;
-
-       st->data = cpu_to_be32(AD5064_CMD(cmd) | AD5064_ADDR(addr) | val);
-
-       return spi_write(st->spi, &st->data, sizeof(st->data));
-}
-
-static int ad5064_sync_powerdown_mode(struct ad5064_state *st,
-       unsigned int channel)
-{
-       unsigned int val;
-       int ret;
-
-       val = (0x1 << channel);
-
-       if (st->pwr_down[channel])
-               val |= st->pwr_down_mode[channel] << 8;
-
-       ret = ad5064_spi_write(st, AD5064_CMD_POWERDOWN_DAC, 0, val, 0);
-
-       return ret;
-}
-
-static const char * const ad5064_powerdown_modes[] = {
-       "1kohm_to_gnd",
-       "100kohm_to_gnd",
-       "three_state",
-};
-
-static int ad5064_get_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan)
-{
-       struct ad5064_state *st = iio_priv(indio_dev);
-
-       return st->pwr_down_mode[chan->channel] - 1;
-}
-
-static int ad5064_set_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan, unsigned int mode)
-{
-       struct ad5064_state *st = iio_priv(indio_dev);
-       int ret;
-
-       mutex_lock(&indio_dev->mlock);
-       st->pwr_down_mode[chan->channel] = mode + 1;
-
-       ret = ad5064_sync_powerdown_mode(st, chan->channel);
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret;
-}
-
-static const struct iio_enum ad5064_powerdown_mode_enum = {
-       .items = ad5064_powerdown_modes,
-       .num_items = ARRAY_SIZE(ad5064_powerdown_modes),
-       .get = ad5064_get_powerdown_mode,
-       .set = ad5064_set_powerdown_mode,
-};
-
-static ssize_t ad5064_read_dac_powerdown(struct iio_dev *indio_dev,
-       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
-{
-       struct ad5064_state *st = iio_priv(indio_dev);
-
-       return sprintf(buf, "%d\n", st->pwr_down[chan->channel]);
-}
-
-static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev,
-        uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
-        size_t len)
-{
-       struct ad5064_state *st = iio_priv(indio_dev);
-       bool pwr_down;
-       int ret;
-
-       ret = strtobool(buf, &pwr_down);
-       if (ret)
-               return ret;
-
-       mutex_lock(&indio_dev->mlock);
-       st->pwr_down[chan->channel] = pwr_down;
-
-       ret = ad5064_sync_powerdown_mode(st, chan->channel);
-       mutex_unlock(&indio_dev->mlock);
-       return ret ? ret : len;
-}
-
-static int ad5064_get_vref(struct ad5064_state *st,
-       struct iio_chan_spec const *chan)
-{
-       unsigned int i;
-
-       if (st->use_internal_vref)
-               return st->chip_info->internal_vref;
-
-       i = st->chip_info->shared_vref ? 0 : chan->channel;
-       return regulator_get_voltage(st->vref_reg[i].consumer);
-}
-
-static int ad5064_read_raw(struct iio_dev *indio_dev,
-                          struct iio_chan_spec const *chan,
-                          int *val,
-                          int *val2,
-                          long m)
-{
-       struct ad5064_state *st = iio_priv(indio_dev);
-       int scale_uv;
-
-       switch (m) {
-       case IIO_CHAN_INFO_RAW:
-               *val = st->dac_cache[chan->channel];
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_SCALE:
-               scale_uv = ad5064_get_vref(st, chan);
-               if (scale_uv < 0)
-                       return scale_uv;
-
-               scale_uv = (scale_uv * 100) >> chan->scan_type.realbits;
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
-       default:
-               break;
-       }
-       return -EINVAL;
-}
-
-static int ad5064_write_raw(struct iio_dev *indio_dev,
-       struct iio_chan_spec const *chan, int val, int val2, long mask)
-{
-       struct ad5064_state *st = iio_priv(indio_dev);
-       int ret;
-
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW:
-               if (val > (1 << chan->scan_type.realbits) || val < 0)
-                       return -EINVAL;
-
-               mutex_lock(&indio_dev->mlock);
-               ret = ad5064_spi_write(st, AD5064_CMD_WRITE_INPUT_N_UPDATE_N,
-                               chan->address, val, chan->scan_type.shift);
-               if (ret == 0)
-                       st->dac_cache[chan->channel] = val;
-               mutex_unlock(&indio_dev->mlock);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static const struct iio_info ad5064_info = {
-       .read_raw = ad5064_read_raw,
-       .write_raw = ad5064_write_raw,
-       .driver_module = THIS_MODULE,
-};
-
-static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
-       {
-               .name = "powerdown",
-               .read = ad5064_read_dac_powerdown,
-               .write = ad5064_write_dac_powerdown,
-       },
-       IIO_ENUM("powerdown_mode", false, &ad5064_powerdown_mode_enum),
-       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5064_powerdown_mode_enum),
-       { },
-};
-
-#define AD5064_CHANNEL(chan, bits) {                           \
-       .type = IIO_VOLTAGE,                                    \
-       .indexed = 1,                                           \
-       .output = 1,                                            \
-       .channel = (chan),                                      \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |           \
-       IIO_CHAN_INFO_SCALE_SEPARATE_BIT,                       \
-       .address = AD5064_ADDR_DAC(chan),                       \
-       .scan_type = IIO_ST('u', (bits), 16, 20 - (bits)),      \
-       .ext_info = ad5064_ext_info,                            \
-}
-
-#define DECLARE_AD5064_CHANNELS(name, bits) \
-const struct iio_chan_spec name[] = { \
-       AD5064_CHANNEL(0, bits), \
-       AD5064_CHANNEL(1, bits), \
-       AD5064_CHANNEL(2, bits), \
-       AD5064_CHANNEL(3, bits), \
-       AD5064_CHANNEL(4, bits), \
-       AD5064_CHANNEL(5, bits), \
-       AD5064_CHANNEL(6, bits), \
-       AD5064_CHANNEL(7, bits), \
-}
-
-static DECLARE_AD5064_CHANNELS(ad5024_channels, 12);
-static DECLARE_AD5064_CHANNELS(ad5044_channels, 14);
-static DECLARE_AD5064_CHANNELS(ad5064_channels, 16);
-
-static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
-       [ID_AD5024] = {
-               .shared_vref = false,
-               .channels = ad5024_channels,
-               .num_channels = 4,
-       },
-       [ID_AD5025] = {
-               .shared_vref = false,
-               .channels = ad5024_channels,
-               .num_channels = 2,
-       },
-       [ID_AD5044] = {
-               .shared_vref = false,
-               .channels = ad5044_channels,
-               .num_channels = 4,
-       },
-       [ID_AD5045] = {
-               .shared_vref = false,
-               .channels = ad5044_channels,
-               .num_channels = 2,
-       },
-       [ID_AD5064] = {
-               .shared_vref = false,
-               .channels = ad5064_channels,
-               .num_channels = 4,
-       },
-       [ID_AD5064_1] = {
-               .shared_vref = true,
-               .channels = ad5064_channels,
-               .num_channels = 4,
-       },
-       [ID_AD5065] = {
-               .shared_vref = false,
-               .channels = ad5064_channels,
-               .num_channels = 2,
-       },
-       [ID_AD5628_1] = {
-               .shared_vref = true,
-               .internal_vref = 2500000,
-               .channels = ad5024_channels,
-               .num_channels = 8,
-       },
-       [ID_AD5628_2] = {
-               .shared_vref = true,
-               .internal_vref = 5000000,
-               .channels = ad5024_channels,
-               .num_channels = 8,
-       },
-       [ID_AD5648_1] = {
-               .shared_vref = true,
-               .internal_vref = 2500000,
-               .channels = ad5044_channels,
-               .num_channels = 8,
-       },
-       [ID_AD5648_2] = {
-               .shared_vref = true,
-               .internal_vref = 5000000,
-               .channels = ad5044_channels,
-               .num_channels = 8,
-       },
-       [ID_AD5666_1] = {
-               .shared_vref = true,
-               .internal_vref = 2500000,
-               .channels = ad5064_channels,
-               .num_channels = 4,
-       },
-       [ID_AD5666_2] = {
-               .shared_vref = true,
-               .internal_vref = 5000000,
-               .channels = ad5064_channels,
-               .num_channels = 4,
-       },
-       [ID_AD5668_1] = {
-               .shared_vref = true,
-               .internal_vref = 2500000,
-               .channels = ad5064_channels,
-               .num_channels = 8,
-       },
-       [ID_AD5668_2] = {
-               .shared_vref = true,
-               .internal_vref = 5000000,
-               .channels = ad5064_channels,
-               .num_channels = 8,
-       },
-};
-
-static inline unsigned int ad5064_num_vref(struct ad5064_state *st)
-{
-       return st->chip_info->shared_vref ? 1 : st->chip_info->num_channels;
-}
-
-static const char * const ad5064_vref_names[] = {
-       "vrefA",
-       "vrefB",
-       "vrefC",
-       "vrefD",
-};
-
-static const char * const ad5064_vref_name(struct ad5064_state *st,
-       unsigned int vref)
-{
-       return st->chip_info->shared_vref ? "vref" : ad5064_vref_names[vref];
-}
-
-static int __devinit ad5064_probe(struct spi_device *spi)
-{
-       enum ad5064_type type = spi_get_device_id(spi)->driver_data;
-       struct iio_dev *indio_dev;
-       struct ad5064_state *st;
-       unsigned int i;
-       int ret;
-
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL)
-               return  -ENOMEM;
-
-       st = iio_priv(indio_dev);
-       spi_set_drvdata(spi, indio_dev);
-
-       st->chip_info = &ad5064_chip_info_tbl[type];
-       st->spi = spi;
-
-       for (i = 0; i < ad5064_num_vref(st); ++i)
-               st->vref_reg[i].supply = ad5064_vref_name(st, i);
-
-       ret = regulator_bulk_get(&st->spi->dev, ad5064_num_vref(st),
-               st->vref_reg);
-       if (ret) {
-               if (!st->chip_info->internal_vref)
-                       goto error_free;
-               st->use_internal_vref = true;
-               ret = ad5064_spi_write(st, AD5064_CMD_CONFIG, 0,
-                       AD5064_CONFIG_INT_VREF_ENABLE, 0);
-               if (ret) {
-                       dev_err(&spi->dev, "Failed to enable internal vref: %d\n",
-                               ret);
-                       goto error_free;
-               }
-       } else {
-               ret = regulator_bulk_enable(ad5064_num_vref(st), st->vref_reg);
-               if (ret)
-                       goto error_free_reg;
-       }
-
-       for (i = 0; i < st->chip_info->num_channels; ++i) {
-               st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K;
-               st->dac_cache[i] = 0x8000;
-       }
-
-       indio_dev->dev.parent = &spi->dev;
-       indio_dev->name = spi_get_device_id(spi)->name;
-       indio_dev->info = &ad5064_info;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->channels = st->chip_info->channels;
-       indio_dev->num_channels = st->chip_info->num_channels;
-
-       ret = iio_device_register(indio_dev);
-       if (ret)
-               goto error_disable_reg;
-
-       return 0;
-
-error_disable_reg:
-       if (!st->use_internal_vref)
-               regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
-error_free_reg:
-       if (!st->use_internal_vref)
-               regulator_bulk_free(ad5064_num_vref(st), st->vref_reg);
-error_free:
-       iio_device_free(indio_dev);
-
-       return ret;
-}
-
-
-static int __devexit ad5064_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-       struct ad5064_state *st = iio_priv(indio_dev);
-
-       iio_device_unregister(indio_dev);
-
-       if (!st->use_internal_vref) {
-               regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
-               regulator_bulk_free(ad5064_num_vref(st), st->vref_reg);
-       }
-
-       iio_device_free(indio_dev);
-
-       return 0;
-}
-
-static const struct spi_device_id ad5064_id[] = {
-       {"ad5024", ID_AD5024},
-       {"ad5025", ID_AD5025},
-       {"ad5044", ID_AD5044},
-       {"ad5045", ID_AD5045},
-       {"ad5064", ID_AD5064},
-       {"ad5064-1", ID_AD5064_1},
-       {"ad5065", ID_AD5065},
-       {"ad5628-1", ID_AD5628_1},
-       {"ad5628-2", ID_AD5628_2},
-       {"ad5648-1", ID_AD5648_1},
-       {"ad5648-2", ID_AD5648_2},
-       {"ad5666-1", ID_AD5666_1},
-       {"ad5666-2", ID_AD5666_2},
-       {"ad5668-1", ID_AD5668_1},
-       {"ad5668-2", ID_AD5668_2},
-       {"ad5668-3", ID_AD5668_2}, /* similar enough to ad5668-2 */
-       {}
-};
-MODULE_DEVICE_TABLE(spi, ad5064_id);
-
-static struct spi_driver ad5064_driver = {
-       .driver = {
-                  .name = "ad5064",
-                  .owner = THIS_MODULE,
-       },
-       .probe = ad5064_probe,
-       .remove = __devexit_p(ad5064_remove),
-       .id_table = ad5064_id,
-};
-module_spi_driver(ad5064_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("Analog Devices AD5024/25/44/45/64/64-1/65, AD5628/48/66/68 DAC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5360.c b/drivers/staging/iio/dac/ad5360.c
deleted file mode 100644 (file)
index 8fce84f..0000000
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * Analog devices AD5360, AD5361, AD5362, AD5363, AD5370, AD5371, AD5373
- * multi-channel Digital to Analog Converters driver
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/regulator/consumer.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#define AD5360_CMD(x)                          ((x) << 22)
-#define AD5360_ADDR(x)                         ((x) << 16)
-
-#define AD5360_READBACK_TYPE(x)                        ((x) << 13)
-#define AD5360_READBACK_ADDR(x)                        ((x) << 7)
-
-#define AD5360_CHAN_ADDR(chan)                 ((chan) + 0x8)
-
-#define AD5360_CMD_WRITE_DATA                  0x3
-#define AD5360_CMD_WRITE_OFFSET                        0x2
-#define AD5360_CMD_WRITE_GAIN                  0x1
-#define AD5360_CMD_SPECIAL_FUNCTION            0x0
-
-/* Special function register addresses */
-#define AD5360_REG_SF_NOP                      0x0
-#define AD5360_REG_SF_CTRL                     0x1
-#define AD5360_REG_SF_OFS(x)                   (0x2 + (x))
-#define AD5360_REG_SF_READBACK                 0x5
-
-#define AD5360_SF_CTRL_PWR_DOWN                        BIT(0)
-
-#define AD5360_READBACK_X1A                    0x0
-#define AD5360_READBACK_X1B                    0x1
-#define AD5360_READBACK_OFFSET                 0x2
-#define AD5360_READBACK_GAIN                   0x3
-#define AD5360_READBACK_SF                     0x4
-
-
-/**
- * struct ad5360_chip_info - chip specific information
- * @channel_template:  channel specification template
- * @num_channels:      number of channels
- * @channels_per_group:        number of channels per group
- * @num_vrefs:         number of vref supplies for the chip
-*/
-
-struct ad5360_chip_info {
-       struct iio_chan_spec    channel_template;
-       unsigned int            num_channels;
-       unsigned int            channels_per_group;
-       unsigned int            num_vrefs;
-};
-
-/**
- * struct ad5360_state - driver instance specific data
- * @spi:               spi_device
- * @chip_info:         chip model specific constants, available modes etc
- * @vref_reg:          vref supply regulators
- * @ctrl:              control register cache
- * @data:              spi transfer buffers
- */
-
-struct ad5360_state {
-       struct spi_device               *spi;
-       const struct ad5360_chip_info   *chip_info;
-       struct regulator_bulk_data      vref_reg[3];
-       unsigned int                    ctrl;
-
-       /*
-        * DMA (thus cache coherency maintenance) requires the
-        * transfer buffers to live in their own cache lines.
-        */
-       union {
-               __be32 d32;
-               u8 d8[4];
-       } data[2] ____cacheline_aligned;
-};
-
-enum ad5360_type {
-       ID_AD5360,
-       ID_AD5361,
-       ID_AD5362,
-       ID_AD5363,
-       ID_AD5370,
-       ID_AD5371,
-       ID_AD5372,
-       ID_AD5373,
-};
-
-#define AD5360_CHANNEL(bits) {                                 \
-       .type = IIO_VOLTAGE,                                    \
-       .indexed = 1,                                           \
-       .output = 1,                                            \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |           \
-               IIO_CHAN_INFO_SCALE_SEPARATE_BIT |              \
-               IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |             \
-               IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \
-               IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,   \
-       .scan_type = IIO_ST('u', (bits), 16, 16 - (bits))       \
-}
-
-static const struct ad5360_chip_info ad5360_chip_info_tbl[] = {
-       [ID_AD5360] = {
-               .channel_template = AD5360_CHANNEL(16),
-               .num_channels = 16,
-               .channels_per_group = 8,
-               .num_vrefs = 2,
-       },
-       [ID_AD5361] = {
-               .channel_template = AD5360_CHANNEL(14),
-               .num_channels = 16,
-               .channels_per_group = 8,
-               .num_vrefs = 2,
-       },
-       [ID_AD5362] = {
-               .channel_template = AD5360_CHANNEL(16),
-               .num_channels = 8,
-               .channels_per_group = 4,
-               .num_vrefs = 2,
-       },
-       [ID_AD5363] = {
-               .channel_template = AD5360_CHANNEL(14),
-               .num_channels = 8,
-               .channels_per_group = 4,
-               .num_vrefs = 2,
-       },
-       [ID_AD5370] = {
-               .channel_template = AD5360_CHANNEL(16),
-               .num_channels = 40,
-               .channels_per_group = 8,
-               .num_vrefs = 2,
-       },
-       [ID_AD5371] = {
-               .channel_template = AD5360_CHANNEL(14),
-               .num_channels = 40,
-               .channels_per_group = 8,
-               .num_vrefs = 3,
-       },
-       [ID_AD5372] = {
-               .channel_template = AD5360_CHANNEL(16),
-               .num_channels = 32,
-               .channels_per_group = 8,
-               .num_vrefs = 2,
-       },
-       [ID_AD5373] = {
-               .channel_template = AD5360_CHANNEL(14),
-               .num_channels = 32,
-               .channels_per_group = 8,
-               .num_vrefs = 2,
-       },
-};
-
-static unsigned int ad5360_get_channel_vref_index(struct ad5360_state *st,
-       unsigned int channel)
-{
-       unsigned int i;
-
-       /* The first groups have their own vref, while the remaining groups
-        * share the last vref */
-       i = channel / st->chip_info->channels_per_group;
-       if (i >= st->chip_info->num_vrefs)
-               i = st->chip_info->num_vrefs - 1;
-
-       return i;
-}
-
-static int ad5360_get_channel_vref(struct ad5360_state *st,
-       unsigned int channel)
-{
-       unsigned int i = ad5360_get_channel_vref_index(st, channel);
-
-       return regulator_get_voltage(st->vref_reg[i].consumer);
-}
-
-
-static int ad5360_write_unlocked(struct iio_dev *indio_dev,
-       unsigned int cmd, unsigned int addr, unsigned int val,
-       unsigned int shift)
-{
-       struct ad5360_state *st = iio_priv(indio_dev);
-
-       val <<= shift;
-       val |= AD5360_CMD(cmd) | AD5360_ADDR(addr);
-       st->data[0].d32 = cpu_to_be32(val);
-
-       return spi_write(st->spi, &st->data[0].d8[1], 3);
-}
-
-static int ad5360_write(struct iio_dev *indio_dev, unsigned int cmd,
-       unsigned int addr, unsigned int val, unsigned int shift)
-{
-       int ret;
-
-       mutex_lock(&indio_dev->mlock);
-       ret = ad5360_write_unlocked(indio_dev, cmd, addr, val, shift);
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret;
-}
-
-static int ad5360_read(struct iio_dev *indio_dev, unsigned int type,
-       unsigned int addr)
-{
-       struct ad5360_state *st = iio_priv(indio_dev);
-       struct spi_message m;
-       int ret;
-       struct spi_transfer t[] = {
-               {
-                       .tx_buf = &st->data[0].d8[1],
-                       .len = 3,
-                       .cs_change = 1,
-               }, {
-                       .rx_buf = &st->data[1].d8[1],
-                       .len = 3,
-               },
-       };
-
-       spi_message_init(&m);
-       spi_message_add_tail(&t[0], &m);
-       spi_message_add_tail(&t[1], &m);
-
-       mutex_lock(&indio_dev->mlock);
-
-       st->data[0].d32 = cpu_to_be32(AD5360_CMD(AD5360_CMD_SPECIAL_FUNCTION) |
-               AD5360_ADDR(AD5360_REG_SF_READBACK) |
-               AD5360_READBACK_TYPE(type) |
-               AD5360_READBACK_ADDR(addr));
-
-       ret = spi_sync(st->spi, &m);
-       if (ret >= 0)
-               ret = be32_to_cpu(st->data[1].d32) & 0xffff;
-
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret;
-}
-
-static ssize_t ad5360_read_dac_powerdown(struct device *dev,
-                                          struct device_attribute *attr,
-                                          char *buf)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct ad5360_state *st = iio_priv(indio_dev);
-
-       return sprintf(buf, "%d\n", (bool)(st->ctrl & AD5360_SF_CTRL_PWR_DOWN));
-}
-
-static int ad5360_update_ctrl(struct iio_dev *indio_dev, unsigned int set,
-       unsigned int clr)
-{
-       struct ad5360_state *st = iio_priv(indio_dev);
-       unsigned int ret;
-
-       mutex_lock(&indio_dev->mlock);
-
-       st->ctrl |= set;
-       st->ctrl &= ~clr;
-
-       ret = ad5360_write_unlocked(indio_dev, AD5360_CMD_SPECIAL_FUNCTION,
-                       AD5360_REG_SF_CTRL, st->ctrl, 0);
-
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret;
-}
-
-static ssize_t ad5360_write_dac_powerdown(struct device *dev,
-       struct device_attribute *attr, const char *buf, size_t len)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       bool pwr_down;
-       int ret;
-
-       ret = strtobool(buf, &pwr_down);
-       if (ret)
-               return ret;
-
-       if (pwr_down)
-               ret = ad5360_update_ctrl(indio_dev, AD5360_SF_CTRL_PWR_DOWN, 0);
-       else
-               ret = ad5360_update_ctrl(indio_dev, 0, AD5360_SF_CTRL_PWR_DOWN);
-
-       return ret ? ret : len;
-}
-
-static IIO_DEVICE_ATTR(out_voltage_powerdown,
-                       S_IRUGO | S_IWUSR,
-                       ad5360_read_dac_powerdown,
-                       ad5360_write_dac_powerdown, 0);
-
-static struct attribute *ad5360_attributes[] = {
-       &iio_dev_attr_out_voltage_powerdown.dev_attr.attr,
-       NULL,
-};
-
-static const struct attribute_group ad5360_attribute_group = {
-       .attrs = ad5360_attributes,
-};
-
-static int ad5360_write_raw(struct iio_dev *indio_dev,
-                              struct iio_chan_spec const *chan,
-                              int val,
-                              int val2,
-                              long mask)
-{
-       struct ad5360_state *st = iio_priv(indio_dev);
-       int max_val = (1 << chan->scan_type.realbits);
-       unsigned int ofs_index;
-
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW:
-               if (val >= max_val || val < 0)
-                       return -EINVAL;
-
-               return ad5360_write(indio_dev, AD5360_CMD_WRITE_DATA,
-                                chan->address, val, chan->scan_type.shift);
-
-       case IIO_CHAN_INFO_CALIBBIAS:
-               if (val >= max_val || val < 0)
-                       return -EINVAL;
-
-               return ad5360_write(indio_dev, AD5360_CMD_WRITE_OFFSET,
-                                chan->address, val, chan->scan_type.shift);
-
-       case IIO_CHAN_INFO_CALIBSCALE:
-               if (val >= max_val || val < 0)
-                       return -EINVAL;
-
-               return ad5360_write(indio_dev, AD5360_CMD_WRITE_GAIN,
-                                chan->address, val, chan->scan_type.shift);
-
-       case IIO_CHAN_INFO_OFFSET:
-               if (val <= -max_val || val > 0)
-                       return -EINVAL;
-
-               val = -val;
-
-               /* offset is supposed to have the same scale as raw, but it
-                * is always 14bits wide, so on a chip where the raw value has
-                * more bits, we need to shift offset. */
-               val >>= (chan->scan_type.realbits - 14);
-
-               /* There is one DAC offset register per vref. Changing one
-                * channels offset will also change the offset for all other
-                * channels which share the same vref supply. */
-               ofs_index = ad5360_get_channel_vref_index(st, chan->channel);
-               return ad5360_write(indio_dev, AD5360_CMD_SPECIAL_FUNCTION,
-                                AD5360_REG_SF_OFS(ofs_index), val, 0);
-       default:
-               break;
-       }
-
-       return -EINVAL;
-}
-
-static int ad5360_read_raw(struct iio_dev *indio_dev,
-                          struct iio_chan_spec const *chan,
-                          int *val,
-                          int *val2,
-                          long m)
-{
-       struct ad5360_state *st = iio_priv(indio_dev);
-       unsigned int ofs_index;
-       int scale_uv;
-       int ret;
-
-       switch (m) {
-       case IIO_CHAN_INFO_RAW:
-               ret = ad5360_read(indio_dev, AD5360_READBACK_X1A,
-                       chan->address);
-               if (ret < 0)
-                       return ret;
-               *val = ret >> chan->scan_type.shift;
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_SCALE:
-               /* vout = 4 * vref * dac_code */
-               scale_uv = ad5360_get_channel_vref(st, chan->channel) * 4 * 100;
-               if (scale_uv < 0)
-                       return scale_uv;
-
-               scale_uv >>= (chan->scan_type.realbits);
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
-       case IIO_CHAN_INFO_CALIBBIAS:
-               ret = ad5360_read(indio_dev, AD5360_READBACK_OFFSET,
-                       chan->address);
-               if (ret < 0)
-                       return ret;
-               *val = ret;
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_CALIBSCALE:
-               ret = ad5360_read(indio_dev, AD5360_READBACK_GAIN,
-                       chan->address);
-               if (ret < 0)
-                       return ret;
-               *val = ret;
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_OFFSET:
-               ofs_index = ad5360_get_channel_vref_index(st, chan->channel);
-               ret = ad5360_read(indio_dev, AD5360_READBACK_SF,
-                       AD5360_REG_SF_OFS(ofs_index));
-               if (ret < 0)
-                       return ret;
-
-               ret <<= (chan->scan_type.realbits - 14);
-               *val = -ret;
-               return IIO_VAL_INT;
-       }
-
-       return -EINVAL;
-}
-
-static const struct iio_info ad5360_info = {
-       .read_raw = ad5360_read_raw,
-       .write_raw = ad5360_write_raw,
-       .attrs = &ad5360_attribute_group,
-       .driver_module = THIS_MODULE,
-};
-
-static const char * const ad5360_vref_name[] = {
-        "vref0", "vref1", "vref2"
-};
-
-static int __devinit ad5360_alloc_channels(struct iio_dev *indio_dev)
-{
-       struct ad5360_state *st = iio_priv(indio_dev);
-       struct iio_chan_spec *channels;
-       unsigned int i;
-
-       channels = kcalloc(st->chip_info->num_channels,
-                          sizeof(struct iio_chan_spec), GFP_KERNEL);
-
-       if (!channels)
-               return -ENOMEM;
-
-       for (i = 0; i < st->chip_info->num_channels; ++i) {
-               channels[i] = st->chip_info->channel_template;
-               channels[i].channel = i;
-               channels[i].address = AD5360_CHAN_ADDR(i);
-       }
-
-       indio_dev->channels = channels;
-
-       return 0;
-}
-
-static int __devinit ad5360_probe(struct spi_device *spi)
-{
-       enum ad5360_type type = spi_get_device_id(spi)->driver_data;
-       struct iio_dev *indio_dev;
-       struct ad5360_state *st;
-       unsigned int i;
-       int ret;
-
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               dev_err(&spi->dev, "Failed to allocate iio device\n");
-               return  -ENOMEM;
-       }
-
-       st = iio_priv(indio_dev);
-       spi_set_drvdata(spi, indio_dev);
-
-       st->chip_info = &ad5360_chip_info_tbl[type];
-       st->spi = spi;
-
-       indio_dev->dev.parent = &spi->dev;
-       indio_dev->name = spi_get_device_id(spi)->name;
-       indio_dev->info = &ad5360_info;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->num_channels = st->chip_info->num_channels;
-
-       ret = ad5360_alloc_channels(indio_dev);
-       if (ret) {
-               dev_err(&spi->dev, "Failed to allocate channel spec: %d\n", ret);
-               goto error_free;
-       }
-
-       for (i = 0; i < st->chip_info->num_vrefs; ++i)
-               st->vref_reg[i].supply = ad5360_vref_name[i];
-
-       ret = regulator_bulk_get(&st->spi->dev, st->chip_info->num_vrefs,
-               st->vref_reg);
-       if (ret) {
-               dev_err(&spi->dev, "Failed to request vref regulators: %d\n", ret);
-               goto error_free_channels;
-       }
-
-       ret = regulator_bulk_enable(st->chip_info->num_vrefs, st->vref_reg);
-       if (ret) {
-               dev_err(&spi->dev, "Failed to enable vref regulators: %d\n", ret);
-               goto error_free_reg;
-       }
-
-       ret = iio_device_register(indio_dev);
-       if (ret) {
-               dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
-               goto error_disable_reg;
-       }
-
-       return 0;
-
-error_disable_reg:
-       regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
-error_free_reg:
-       regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg);
-error_free_channels:
-       kfree(indio_dev->channels);
-error_free:
-       iio_device_free(indio_dev);
-
-       return ret;
-}
-
-static int __devexit ad5360_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-       struct ad5360_state *st = iio_priv(indio_dev);
-
-       iio_device_unregister(indio_dev);
-
-       kfree(indio_dev->channels);
-
-       regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
-       regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg);
-
-       iio_device_free(indio_dev);
-
-       return 0;
-}
-
-static const struct spi_device_id ad5360_ids[] = {
-       { "ad5360", ID_AD5360 },
-       { "ad5361", ID_AD5361 },
-       { "ad5362", ID_AD5362 },
-       { "ad5363", ID_AD5363 },
-       { "ad5370", ID_AD5370 },
-       { "ad5371", ID_AD5371 },
-       { "ad5372", ID_AD5372 },
-       { "ad5373", ID_AD5373 },
-       {}
-};
-MODULE_DEVICE_TABLE(spi, ad5360_ids);
-
-static struct spi_driver ad5360_driver = {
-       .driver = {
-                  .name = "ad5360",
-                  .owner = THIS_MODULE,
-       },
-       .probe = ad5360_probe,
-       .remove = __devexit_p(ad5360_remove),
-       .id_table = ad5360_ids,
-};
-module_spi_driver(ad5360_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("Analog Devices AD5360/61/62/63/70/71/72/73 DAC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5380.c b/drivers/staging/iio/dac/ad5380.c
deleted file mode 100644 (file)
index 5dfb445..0000000
+++ /dev/null
@@ -1,657 +0,0 @@
-/*
- * Analog devices AD5380, AD5381, AD5382, AD5383, AD5390, AD5391, AD5392
- * multi-channel Digital to Analog Converters driver
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#define AD5380_REG_DATA(x)     (((x) << 2) | 3)
-#define AD5380_REG_OFFSET(x)   (((x) << 2) | 2)
-#define AD5380_REG_GAIN(x)     (((x) << 2) | 1)
-#define AD5380_REG_SF_PWR_DOWN (8 << 2)
-#define AD5380_REG_SF_PWR_UP   (9 << 2)
-#define AD5380_REG_SF_CTRL     (12 << 2)
-
-#define AD5380_CTRL_PWR_DOWN_MODE_OFFSET       13
-#define AD5380_CTRL_INT_VREF_2V5               BIT(12)
-#define AD5380_CTRL_INT_VREF_EN                        BIT(10)
-
-/**
- * struct ad5380_chip_info - chip specific information
- * @channel_template:  channel specification template
- * @num_channels:      number of channels
- * @int_vref:          internal vref in uV
-*/
-
-struct ad5380_chip_info {
-       struct iio_chan_spec    channel_template;
-       unsigned int            num_channels;
-       unsigned int            int_vref;
-};
-
-/**
- * struct ad5380_state - driver instance specific data
- * @regmap:            regmap instance used by the device
- * @chip_info:         chip model specific constants, available modes etc
- * @vref_reg:          vref supply regulator
- * @vref:              actual reference voltage used in uA
- * @pwr_down:          whether the chip is currently in power down mode
- */
-
-struct ad5380_state {
-       struct regmap                   *regmap;
-       const struct ad5380_chip_info   *chip_info;
-       struct regulator                *vref_reg;
-       int                             vref;
-       bool                            pwr_down;
-};
-
-enum ad5380_type {
-       ID_AD5380_3,
-       ID_AD5380_5,
-       ID_AD5381_3,
-       ID_AD5381_5,
-       ID_AD5382_3,
-       ID_AD5382_5,
-       ID_AD5383_3,
-       ID_AD5383_5,
-       ID_AD5390_3,
-       ID_AD5390_5,
-       ID_AD5391_3,
-       ID_AD5391_5,
-       ID_AD5392_3,
-       ID_AD5392_5,
-};
-
-static ssize_t ad5380_read_dac_powerdown(struct iio_dev *indio_dev,
-       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
-{
-       struct ad5380_state *st = iio_priv(indio_dev);
-
-       return sprintf(buf, "%d\n", st->pwr_down);
-}
-
-static ssize_t ad5380_write_dac_powerdown(struct iio_dev *indio_dev,
-        uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
-        size_t len)
-{
-       struct ad5380_state *st = iio_priv(indio_dev);
-       bool pwr_down;
-       int ret;
-
-       ret = strtobool(buf, &pwr_down);
-       if (ret)
-               return ret;
-
-       mutex_lock(&indio_dev->mlock);
-
-       if (pwr_down)
-               ret = regmap_write(st->regmap, AD5380_REG_SF_PWR_DOWN, 0);
-       else
-               ret = regmap_write(st->regmap, AD5380_REG_SF_PWR_UP, 0);
-
-       st->pwr_down = pwr_down;
-
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret ? ret : len;
-}
-
-static const char * const ad5380_powerdown_modes[] = {
-       "100kohm_to_gnd",
-       "three_state",
-};
-
-static int ad5380_get_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan)
-{
-       struct ad5380_state *st = iio_priv(indio_dev);
-       unsigned int mode;
-       int ret;
-
-       ret = regmap_read(st->regmap, AD5380_REG_SF_CTRL, &mode);
-       if (ret)
-               return ret;
-
-       mode = (mode >> AD5380_CTRL_PWR_DOWN_MODE_OFFSET) & 1;
-
-       return mode;
-}
-
-static int ad5380_set_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan, unsigned int mode)
-{
-       struct ad5380_state *st = iio_priv(indio_dev);
-       int ret;
-
-       ret = regmap_update_bits(st->regmap, AD5380_REG_SF_CTRL,
-               1 << AD5380_CTRL_PWR_DOWN_MODE_OFFSET,
-               mode << AD5380_CTRL_PWR_DOWN_MODE_OFFSET);
-
-       return ret;
-}
-
-static const struct iio_enum ad5380_powerdown_mode_enum = {
-       .items = ad5380_powerdown_modes,
-       .num_items = ARRAY_SIZE(ad5380_powerdown_modes),
-       .get = ad5380_get_powerdown_mode,
-       .set = ad5380_set_powerdown_mode,
-};
-
-static unsigned int ad5380_info_to_reg(struct iio_chan_spec const *chan,
-       long info)
-{
-       switch (info) {
-       case 0:
-               return AD5380_REG_DATA(chan->address);
-       case IIO_CHAN_INFO_CALIBBIAS:
-               return AD5380_REG_OFFSET(chan->address);
-       case IIO_CHAN_INFO_CALIBSCALE:
-               return AD5380_REG_GAIN(chan->address);
-       default:
-               break;
-       }
-
-       return 0;
-}
-
-static int ad5380_write_raw(struct iio_dev *indio_dev,
-       struct iio_chan_spec const *chan, int val, int val2, long info)
-{
-       const unsigned int max_val = (1 << chan->scan_type.realbits);
-       struct ad5380_state *st = iio_priv(indio_dev);
-
-       switch (info) {
-       case IIO_CHAN_INFO_RAW:
-       case IIO_CHAN_INFO_CALIBSCALE:
-               if (val >= max_val || val < 0)
-                       return -EINVAL;
-
-               return regmap_write(st->regmap,
-                       ad5380_info_to_reg(chan, info),
-                       val << chan->scan_type.shift);
-       case IIO_CHAN_INFO_CALIBBIAS:
-               val += (1 << chan->scan_type.realbits) / 2;
-               if (val >= max_val || val < 0)
-                       return -EINVAL;
-
-               return regmap_write(st->regmap,
-                       AD5380_REG_OFFSET(chan->address),
-                       val << chan->scan_type.shift);
-       default:
-               break;
-       }
-       return -EINVAL;
-}
-
-static int ad5380_read_raw(struct iio_dev *indio_dev,
-       struct iio_chan_spec const *chan, int *val, int *val2, long info)
-{
-       struct ad5380_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
-       int ret;
-
-       switch (info) {
-       case IIO_CHAN_INFO_RAW:
-       case IIO_CHAN_INFO_CALIBSCALE:
-               ret = regmap_read(st->regmap, ad5380_info_to_reg(chan, info),
-                                       val);
-               if (ret)
-                       return ret;
-               *val >>= chan->scan_type.shift;
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_CALIBBIAS:
-               ret = regmap_read(st->regmap, AD5380_REG_OFFSET(chan->address),
-                                       val);
-               if (ret)
-                       return ret;
-               *val >>= chan->scan_type.shift;
-               val -= (1 << chan->scan_type.realbits) / 2;
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_SCALE:
-               scale_uv = ((2 * st->vref) >> chan->scan_type.realbits) * 100;
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
-       default:
-               break;
-       }
-
-       return -EINVAL;
-}
-
-static const struct iio_info ad5380_info = {
-       .read_raw = ad5380_read_raw,
-       .write_raw = ad5380_write_raw,
-       .driver_module = THIS_MODULE,
-};
-
-static struct iio_chan_spec_ext_info ad5380_ext_info[] = {
-       {
-               .name = "powerdown",
-               .read = ad5380_read_dac_powerdown,
-               .write = ad5380_write_dac_powerdown,
-       },
-       IIO_ENUM("powerdown_mode", true, &ad5380_powerdown_mode_enum),
-       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum),
-       { },
-};
-
-#define AD5380_CHANNEL(_bits) {                                        \
-       .type = IIO_VOLTAGE,                                    \
-       .indexed = 1,                                           \
-       .output = 1,                                            \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |           \
-               IIO_CHAN_INFO_SCALE_SHARED_BIT |                \
-               IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |         \
-               IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,           \
-       .scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits)),    \
-       .ext_info = ad5380_ext_info,                            \
-}
-
-static const struct ad5380_chip_info ad5380_chip_info_tbl[] = {
-       [ID_AD5380_3] = {
-               .channel_template = AD5380_CHANNEL(14),
-               .num_channels = 40,
-               .int_vref = 1250000,
-       },
-       [ID_AD5380_5] = {
-               .channel_template = AD5380_CHANNEL(14),
-               .num_channels = 40,
-               .int_vref = 2500000,
-       },
-       [ID_AD5381_3] = {
-               .channel_template = AD5380_CHANNEL(12),
-               .num_channels = 16,
-               .int_vref = 1250000,
-       },
-       [ID_AD5381_5] = {
-               .channel_template = AD5380_CHANNEL(12),
-               .num_channels = 16,
-               .int_vref = 2500000,
-       },
-       [ID_AD5382_3] = {
-               .channel_template = AD5380_CHANNEL(14),
-               .num_channels = 32,
-               .int_vref = 1250000,
-       },
-       [ID_AD5382_5] = {
-               .channel_template = AD5380_CHANNEL(14),
-               .num_channels = 32,
-               .int_vref = 2500000,
-       },
-       [ID_AD5383_3] = {
-               .channel_template = AD5380_CHANNEL(12),
-               .num_channels = 32,
-               .int_vref = 1250000,
-       },
-       [ID_AD5383_5] = {
-               .channel_template = AD5380_CHANNEL(12),
-               .num_channels = 32,
-               .int_vref = 2500000,
-       },
-       [ID_AD5390_3] = {
-               .channel_template = AD5380_CHANNEL(14),
-               .num_channels = 16,
-               .int_vref = 1250000,
-       },
-       [ID_AD5390_5] = {
-               .channel_template = AD5380_CHANNEL(14),
-               .num_channels = 16,
-               .int_vref = 2500000,
-       },
-       [ID_AD5391_3] = {
-               .channel_template = AD5380_CHANNEL(12),
-               .num_channels = 16,
-               .int_vref = 1250000,
-       },
-       [ID_AD5391_5] = {
-               .channel_template = AD5380_CHANNEL(12),
-               .num_channels = 16,
-               .int_vref = 2500000,
-       },
-       [ID_AD5392_3] = {
-               .channel_template = AD5380_CHANNEL(14),
-               .num_channels = 8,
-               .int_vref = 1250000,
-       },
-       [ID_AD5392_5] = {
-               .channel_template = AD5380_CHANNEL(14),
-               .num_channels = 8,
-               .int_vref = 2500000,
-       },
-};
-
-static int __devinit ad5380_alloc_channels(struct iio_dev *indio_dev)
-{
-       struct ad5380_state *st = iio_priv(indio_dev);
-       struct iio_chan_spec *channels;
-       unsigned int i;
-
-       channels = kcalloc(st->chip_info->num_channels,
-                          sizeof(struct iio_chan_spec), GFP_KERNEL);
-
-       if (!channels)
-               return -ENOMEM;
-
-       for (i = 0; i < st->chip_info->num_channels; ++i) {
-               channels[i] = st->chip_info->channel_template;
-               channels[i].channel = i;
-               channels[i].address = i;
-       }
-
-       indio_dev->channels = channels;
-
-       return 0;
-}
-
-static int __devinit ad5380_probe(struct device *dev, struct regmap *regmap,
-       enum ad5380_type type, const char *name)
-{
-       struct iio_dev *indio_dev;
-       struct ad5380_state *st;
-       unsigned int ctrl = 0;
-       int ret;
-
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               dev_err(dev, "Failed to allocate iio device\n");
-               ret = -ENOMEM;
-               goto error_regmap_exit;
-       }
-
-       st = iio_priv(indio_dev);
-       dev_set_drvdata(dev, indio_dev);
-
-       st->chip_info = &ad5380_chip_info_tbl[type];
-       st->regmap = regmap;
-
-       indio_dev->dev.parent = dev;
-       indio_dev->name = name;
-       indio_dev->info = &ad5380_info;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->num_channels = st->chip_info->num_channels;
-
-       ret = ad5380_alloc_channels(indio_dev);
-       if (ret) {
-               dev_err(dev, "Failed to allocate channel spec: %d\n", ret);
-               goto error_free;
-       }
-
-       if (st->chip_info->int_vref == 2500000)
-               ctrl |= AD5380_CTRL_INT_VREF_2V5;
-
-       st->vref_reg = regulator_get(dev, "vref");
-       if (!IS_ERR(st->vref_reg)) {
-               ret = regulator_enable(st->vref_reg);
-               if (ret) {
-                       dev_err(dev, "Failed to enable vref regulators: %d\n",
-                               ret);
-                       goto error_free_reg;
-               }
-
-               st->vref = regulator_get_voltage(st->vref_reg);
-       } else {
-               st->vref = st->chip_info->int_vref;
-               ctrl |= AD5380_CTRL_INT_VREF_EN;
-       }
-
-       ret = regmap_write(st->regmap, AD5380_REG_SF_CTRL, ctrl);
-       if (ret) {
-               dev_err(dev, "Failed to write to device: %d\n", ret);
-               goto error_disable_reg;
-       }
-
-       ret = iio_device_register(indio_dev);
-       if (ret) {
-               dev_err(dev, "Failed to register iio device: %d\n", ret);
-               goto error_disable_reg;
-       }
-
-       return 0;
-
-error_disable_reg:
-       if (!IS_ERR(st->vref_reg))
-               regulator_disable(st->vref_reg);
-error_free_reg:
-       if (!IS_ERR(st->vref_reg))
-               regulator_put(st->vref_reg);
-
-       kfree(indio_dev->channels);
-error_free:
-       iio_device_free(indio_dev);
-error_regmap_exit:
-       regmap_exit(regmap);
-
-       return ret;
-}
-
-static int __devexit ad5380_remove(struct device *dev)
-{
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       struct ad5380_state *st = iio_priv(indio_dev);
-
-       iio_device_unregister(indio_dev);
-
-       kfree(indio_dev->channels);
-
-       if (!IS_ERR(st->vref_reg)) {
-               regulator_disable(st->vref_reg);
-               regulator_put(st->vref_reg);
-       }
-
-       regmap_exit(st->regmap);
-       iio_device_free(indio_dev);
-
-       return 0;
-}
-
-static bool ad5380_reg_false(struct device *dev, unsigned int reg)
-{
-       return false;
-}
-
-static const struct regmap_config ad5380_regmap_config = {
-       .reg_bits = 10,
-       .val_bits = 14,
-
-       .max_register = AD5380_REG_DATA(40),
-       .cache_type = REGCACHE_RBTREE,
-
-       .volatile_reg = ad5380_reg_false,
-       .readable_reg = ad5380_reg_false,
-};
-
-#if IS_ENABLED(CONFIG_SPI_MASTER)
-
-static int __devinit ad5380_spi_probe(struct spi_device *spi)
-{
-       const struct spi_device_id *id = spi_get_device_id(spi);
-       struct regmap *regmap;
-
-       regmap = regmap_init_spi(spi, &ad5380_regmap_config);
-
-       if (IS_ERR(regmap))
-               return PTR_ERR(regmap);
-
-       return ad5380_probe(&spi->dev, regmap, id->driver_data, id->name);
-}
-
-static int __devexit ad5380_spi_remove(struct spi_device *spi)
-{
-       return ad5380_remove(&spi->dev);
-}
-
-static const struct spi_device_id ad5380_spi_ids[] = {
-       { "ad5380-3", ID_AD5380_3 },
-       { "ad5380-5", ID_AD5380_5 },
-       { "ad5381-3", ID_AD5381_3 },
-       { "ad5381-5", ID_AD5381_5 },
-       { "ad5382-3", ID_AD5382_3 },
-       { "ad5382-5", ID_AD5382_5 },
-       { "ad5383-3", ID_AD5383_3 },
-       { "ad5383-5", ID_AD5383_5 },
-       { "ad5384-3", ID_AD5380_3 },
-       { "ad5384-5", ID_AD5380_5 },
-       { "ad5390-3", ID_AD5390_3 },
-       { "ad5390-5", ID_AD5390_5 },
-       { "ad5391-3", ID_AD5391_3 },
-       { "ad5391-5", ID_AD5391_5 },
-       { "ad5392-3", ID_AD5392_3 },
-       { "ad5392-5", ID_AD5392_5 },
-       { }
-};
-MODULE_DEVICE_TABLE(spi, ad5380_spi_ids);
-
-static struct spi_driver ad5380_spi_driver = {
-       .driver = {
-                  .name = "ad5380",
-                  .owner = THIS_MODULE,
-       },
-       .probe = ad5380_spi_probe,
-       .remove = __devexit_p(ad5380_spi_remove),
-       .id_table = ad5380_spi_ids,
-};
-
-static inline int ad5380_spi_register_driver(void)
-{
-       return spi_register_driver(&ad5380_spi_driver);
-}
-
-static inline void ad5380_spi_unregister_driver(void)
-{
-       spi_unregister_driver(&ad5380_spi_driver);
-}
-
-#else
-
-static inline int ad5380_spi_register_driver(void)
-{
-       return 0;
-}
-
-static inline void ad5380_spi_unregister_driver(void)
-{
-}
-
-#endif
-
-#if IS_ENABLED(CONFIG_I2C)
-
-static int __devinit ad5380_i2c_probe(struct i2c_client *i2c,
-       const struct i2c_device_id *id)
-{
-       struct regmap *regmap;
-
-       regmap = regmap_init_i2c(i2c, &ad5380_regmap_config);
-
-       if (IS_ERR(regmap))
-               return PTR_ERR(regmap);
-
-       return ad5380_probe(&i2c->dev, regmap, id->driver_data, id->name);
-}
-
-static int __devexit ad5380_i2c_remove(struct i2c_client *i2c)
-{
-       return ad5380_remove(&i2c->dev);
-}
-
-static const struct i2c_device_id ad5380_i2c_ids[] = {
-       { "ad5380-3", ID_AD5380_3 },
-       { "ad5380-5", ID_AD5380_5 },
-       { "ad5381-3", ID_AD5381_3 },
-       { "ad5381-5", ID_AD5381_5 },
-       { "ad5382-3", ID_AD5382_3 },
-       { "ad5382-5", ID_AD5382_5 },
-       { "ad5383-3", ID_AD5383_3 },
-       { "ad5383-5", ID_AD5383_5 },
-       { "ad5384-3", ID_AD5380_3 },
-       { "ad5384-5", ID_AD5380_5 },
-       { "ad5390-3", ID_AD5390_3 },
-       { "ad5390-5", ID_AD5390_5 },
-       { "ad5391-3", ID_AD5391_3 },
-       { "ad5391-5", ID_AD5391_5 },
-       { "ad5392-3", ID_AD5392_3 },
-       { "ad5392-5", ID_AD5392_5 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, ad5380_i2c_ids);
-
-static struct i2c_driver ad5380_i2c_driver = {
-       .driver = {
-                  .name = "ad5380",
-                  .owner = THIS_MODULE,
-       },
-       .probe = ad5380_i2c_probe,
-       .remove = __devexit_p(ad5380_i2c_remove),
-       .id_table = ad5380_i2c_ids,
-};
-
-static inline int ad5380_i2c_register_driver(void)
-{
-       return i2c_add_driver(&ad5380_i2c_driver);
-}
-
-static inline void ad5380_i2c_unregister_driver(void)
-{
-       i2c_del_driver(&ad5380_i2c_driver);
-}
-
-#else
-
-static inline int ad5380_i2c_register_driver(void)
-{
-       return 0;
-}
-
-static inline void ad5380_i2c_unregister_driver(void)
-{
-}
-
-#endif
-
-static int __init ad5380_spi_init(void)
-{
-       int ret;
-
-       ret = ad5380_spi_register_driver();
-       if (ret)
-               return ret;
-
-       ret = ad5380_i2c_register_driver();
-       if (ret) {
-               ad5380_spi_unregister_driver();
-               return ret;
-       }
-
-       return 0;
-}
-module_init(ad5380_spi_init);
-
-static void __exit ad5380_spi_exit(void)
-{
-       ad5380_i2c_unregister_driver();
-       ad5380_spi_unregister_driver();
-
-}
-module_exit(ad5380_spi_exit);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("Analog Devices AD5380/81/82/83/84/90/91/92 DAC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5421.c b/drivers/staging/iio/dac/ad5421.c
deleted file mode 100644 (file)
index ea2f83b..0000000
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * AD5421 Digital to analog converters  driver
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/events.h>
-#include "ad5421.h"
-
-
-#define AD5421_REG_DAC_DATA            0x1
-#define AD5421_REG_CTRL                        0x2
-#define AD5421_REG_OFFSET              0x3
-#define AD5421_REG_GAIN                        0x4
-/* load dac and fault shared the same register number. Writing to it will cause
- * a dac load command, reading from it will return the fault status register */
-#define AD5421_REG_LOAD_DAC            0x5
-#define AD5421_REG_FAULT               0x5
-#define AD5421_REG_FORCE_ALARM_CURRENT 0x6
-#define AD5421_REG_RESET               0x7
-#define AD5421_REG_START_CONVERSION    0x8
-#define AD5421_REG_NOOP                        0x9
-
-#define AD5421_CTRL_WATCHDOG_DISABLE   BIT(12)
-#define AD5421_CTRL_AUTO_FAULT_READBACK        BIT(11)
-#define AD5421_CTRL_MIN_CURRENT                BIT(9)
-#define AD5421_CTRL_ADC_SOURCE_TEMP    BIT(8)
-#define AD5421_CTRL_ADC_ENABLE         BIT(7)
-#define AD5421_CTRL_PWR_DOWN_INT_VREF  BIT(6)
-
-#define AD5421_FAULT_SPI                       BIT(15)
-#define AD5421_FAULT_PEC                       BIT(14)
-#define AD5421_FAULT_OVER_CURRENT              BIT(13)
-#define AD5421_FAULT_UNDER_CURRENT             BIT(12)
-#define AD5421_FAULT_TEMP_OVER_140             BIT(11)
-#define AD5421_FAULT_TEMP_OVER_100             BIT(10)
-#define AD5421_FAULT_UNDER_VOLTAGE_6V          BIT(9)
-#define AD5421_FAULT_UNDER_VOLTAGE_12V         BIT(8)
-
-/* These bits will cause the fault pin to go high */
-#define AD5421_FAULT_TRIGGER_IRQ \
-       (AD5421_FAULT_SPI | AD5421_FAULT_PEC | AD5421_FAULT_OVER_CURRENT | \
-       AD5421_FAULT_UNDER_CURRENT | AD5421_FAULT_TEMP_OVER_140)
-
-/**
- * struct ad5421_state - driver instance specific data
- * @spi:               spi_device
- * @ctrl:              control register cache
- * @current_range:     current range which the device is configured for
- * @data:              spi transfer buffers
- * @fault_mask:                software masking of events
- */
-struct ad5421_state {
-       struct spi_device               *spi;
-       unsigned int                    ctrl;
-       enum ad5421_current_range       current_range;
-       unsigned int                    fault_mask;
-
-       /*
-        * DMA (thus cache coherency maintenance) requires the
-        * transfer buffers to live in their own cache lines.
-        */
-       union {
-               u32 d32;
-               u8 d8[4];
-       } data[2] ____cacheline_aligned;
-};
-
-static const struct iio_chan_spec ad5421_channels[] = {
-       {
-               .type = IIO_CURRENT,
-               .indexed = 1,
-               .output = 1,
-               .channel = 0,
-               .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
-                       IIO_CHAN_INFO_SCALE_SHARED_BIT |
-                       IIO_CHAN_INFO_OFFSET_SHARED_BIT |
-                       IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
-                       IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
-               .scan_type = IIO_ST('u', 16, 16, 0),
-               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
-                       IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
-       },
-       {
-               .type = IIO_TEMP,
-               .channel = -1,
-               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
-       },
-};
-
-static int ad5421_write_unlocked(struct iio_dev *indio_dev,
-       unsigned int reg, unsigned int val)
-{
-       struct ad5421_state *st = iio_priv(indio_dev);
-
-       st->data[0].d32 = cpu_to_be32((reg << 16) | val);
-
-       return spi_write(st->spi, &st->data[0].d8[1], 3);
-}
-
-static int ad5421_write(struct iio_dev *indio_dev, unsigned int reg,
-       unsigned int val)
-{
-       int ret;
-
-       mutex_lock(&indio_dev->mlock);
-       ret = ad5421_write_unlocked(indio_dev, reg, val);
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret;
-}
-
-static int ad5421_read(struct iio_dev *indio_dev, unsigned int reg)
-{
-       struct ad5421_state *st = iio_priv(indio_dev);
-       struct spi_message m;
-       int ret;
-       struct spi_transfer t[] = {
-               {
-                       .tx_buf = &st->data[0].d8[1],
-                       .len = 3,
-                       .cs_change = 1,
-               }, {
-                       .rx_buf = &st->data[1].d8[1],
-                       .len = 3,
-               },
-       };
-
-       spi_message_init(&m);
-       spi_message_add_tail(&t[0], &m);
-       spi_message_add_tail(&t[1], &m);
-
-       mutex_lock(&indio_dev->mlock);
-
-       st->data[0].d32 = cpu_to_be32((1 << 23) | (reg << 16));
-
-       ret = spi_sync(st->spi, &m);
-       if (ret >= 0)
-               ret = be32_to_cpu(st->data[1].d32) & 0xffff;
-
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret;
-}
-
-static int ad5421_update_ctrl(struct iio_dev *indio_dev, unsigned int set,
-       unsigned int clr)
-{
-       struct ad5421_state *st = iio_priv(indio_dev);
-       unsigned int ret;
-
-       mutex_lock(&indio_dev->mlock);
-
-       st->ctrl &= ~clr;
-       st->ctrl |= set;
-
-       ret = ad5421_write_unlocked(indio_dev, AD5421_REG_CTRL, st->ctrl);
-
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret;
-}
-
-static irqreturn_t ad5421_fault_handler(int irq, void *data)
-{
-       struct iio_dev *indio_dev = data;
-       struct ad5421_state *st = iio_priv(indio_dev);
-       unsigned int fault;
-       unsigned int old_fault = 0;
-       unsigned int events;
-
-       fault = ad5421_read(indio_dev, AD5421_REG_FAULT);
-       if (!fault)
-               return IRQ_NONE;
-
-       /* If we had a fault, this might mean that the DAC has lost its state
-        * and has been reset. Make sure that the control register actually
-        * contains what we expect it to contain. Otherwise the watchdog might
-        * be enabled and we get watchdog timeout faults, which will render the
-        * DAC unusable. */
-       ad5421_update_ctrl(indio_dev, 0, 0);
-
-
-       /* The fault pin stays high as long as a fault condition is present and
-        * it is not possible to mask fault conditions. For certain fault
-        * conditions for example like over-temperature it takes some time
-        * until the fault condition disappears. If we would exit the interrupt
-        * handler immediately after handling the event it would be entered
-        * again instantly. Thus we fall back to polling in case we detect that
-        * a interrupt condition is still present.
-        */
-       do {
-               /* 0xffff is a invalid value for the register and will only be
-                * read if there has been a communication error */
-               if (fault == 0xffff)
-                       fault = 0;
-
-               /* we are only interested in new events */
-               events = (old_fault ^ fault) & fault;
-               events &= st->fault_mask;
-
-               if (events & AD5421_FAULT_OVER_CURRENT) {
-                       iio_push_event(indio_dev,
-                               IIO_UNMOD_EVENT_CODE(IIO_CURRENT,
-                                       0,
-                                       IIO_EV_TYPE_THRESH,
-                                       IIO_EV_DIR_RISING),
-                       iio_get_time_ns());
-               }
-
-               if (events & AD5421_FAULT_UNDER_CURRENT) {
-                       iio_push_event(indio_dev,
-                               IIO_UNMOD_EVENT_CODE(IIO_CURRENT,
-                                       0,
-                                       IIO_EV_TYPE_THRESH,
-                                       IIO_EV_DIR_FALLING),
-                               iio_get_time_ns());
-               }
-
-               if (events & AD5421_FAULT_TEMP_OVER_140) {
-                       iio_push_event(indio_dev,
-                               IIO_UNMOD_EVENT_CODE(IIO_TEMP,
-                                       0,
-                                       IIO_EV_TYPE_MAG,
-                                       IIO_EV_DIR_RISING),
-                               iio_get_time_ns());
-               }
-
-               old_fault = fault;
-               fault = ad5421_read(indio_dev, AD5421_REG_FAULT);
-
-               /* still active? go to sleep for some time */
-               if (fault & AD5421_FAULT_TRIGGER_IRQ)
-                       msleep(1000);
-
-       } while (fault & AD5421_FAULT_TRIGGER_IRQ);
-
-
-       return IRQ_HANDLED;
-}
-
-static void ad5421_get_current_min_max(struct ad5421_state *st,
-       unsigned int *min, unsigned int *max)
-{
-       /* The current range is configured using external pins, which are
-        * usually hard-wired and not run-time switchable. */
-       switch (st->current_range) {
-       case AD5421_CURRENT_RANGE_4mA_20mA:
-               *min = 4000;
-               *max = 20000;
-               break;
-       case AD5421_CURRENT_RANGE_3mA8_21mA:
-               *min = 3800;
-               *max = 21000;
-               break;
-       case AD5421_CURRENT_RANGE_3mA2_24mA:
-               *min = 3200;
-               *max = 24000;
-               break;
-       default:
-               *min = 0;
-               *max = 1;
-               break;
-       }
-}
-
-static inline unsigned int ad5421_get_offset(struct ad5421_state *st)
-{
-       unsigned int min, max;
-
-       ad5421_get_current_min_max(st, &min, &max);
-       return (min * (1 << 16)) / (max - min);
-}
-
-static inline unsigned int ad5421_get_scale(struct ad5421_state *st)
-{
-       unsigned int min, max;
-
-       ad5421_get_current_min_max(st, &min, &max);
-       return ((max - min) * 1000) / (1 << 16);
-}
-
-static int ad5421_read_raw(struct iio_dev *indio_dev,
-       struct iio_chan_spec const *chan, int *val, int *val2, long m)
-{
-       struct ad5421_state *st = iio_priv(indio_dev);
-       int ret;
-
-       if (chan->type != IIO_CURRENT)
-               return -EINVAL;
-
-       switch (m) {
-       case IIO_CHAN_INFO_RAW:
-               ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA);
-               if (ret < 0)
-                       return ret;
-               *val = ret;
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_SCALE:
-               *val = 0;
-               *val2 = ad5421_get_scale(st);
-               return IIO_VAL_INT_PLUS_MICRO;
-       case IIO_CHAN_INFO_OFFSET:
-               *val = ad5421_get_offset(st);
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_CALIBBIAS:
-               ret = ad5421_read(indio_dev, AD5421_REG_OFFSET);
-               if (ret < 0)
-                       return ret;
-               *val = ret - 32768;
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_CALIBSCALE:
-               ret = ad5421_read(indio_dev, AD5421_REG_GAIN);
-               if (ret < 0)
-                       return ret;
-               *val = ret;
-               return IIO_VAL_INT;
-       }
-
-       return -EINVAL;
-}
-
-static int ad5421_write_raw(struct iio_dev *indio_dev,
-       struct iio_chan_spec const *chan, int val, int val2, long mask)
-{
-       const unsigned int max_val = 1 << 16;
-
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW:
-               if (val >= max_val || val < 0)
-                       return -EINVAL;
-
-               return ad5421_write(indio_dev, AD5421_REG_DAC_DATA, val);
-       case IIO_CHAN_INFO_CALIBBIAS:
-               val += 32768;
-               if (val >= max_val || val < 0)
-                       return -EINVAL;
-
-               return ad5421_write(indio_dev, AD5421_REG_OFFSET, val);
-       case IIO_CHAN_INFO_CALIBSCALE:
-               if (val >= max_val || val < 0)
-                       return -EINVAL;
-
-               return ad5421_write(indio_dev, AD5421_REG_GAIN, val);
-       default:
-               break;
-       }
-
-       return -EINVAL;
-}
-
-static int ad5421_write_event_config(struct iio_dev *indio_dev,
-       u64 event_code, int state)
-{
-       struct ad5421_state *st = iio_priv(indio_dev);
-       unsigned int mask;
-
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
-       case IIO_CURRENT:
-               if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING)
-                       mask = AD5421_FAULT_OVER_CURRENT;
-               else
-                       mask = AD5421_FAULT_UNDER_CURRENT;
-               break;
-       case IIO_TEMP:
-               mask = AD5421_FAULT_TEMP_OVER_140;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       mutex_lock(&indio_dev->mlock);
-       if (state)
-               st->fault_mask |= mask;
-       else
-               st->fault_mask &= ~mask;
-       mutex_unlock(&indio_dev->mlock);
-
-       return 0;
-}
-
-static int ad5421_read_event_config(struct iio_dev *indio_dev,
-       u64 event_code)
-{
-       struct ad5421_state *st = iio_priv(indio_dev);
-       unsigned int mask;
-
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
-       case IIO_CURRENT:
-               if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING)
-                       mask = AD5421_FAULT_OVER_CURRENT;
-               else
-                       mask = AD5421_FAULT_UNDER_CURRENT;
-               break;
-       case IIO_TEMP:
-               mask = AD5421_FAULT_TEMP_OVER_140;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return (bool)(st->fault_mask & mask);
-}
-
-static int ad5421_read_event_value(struct iio_dev *indio_dev, u64 event_code,
-       int *val)
-{
-       int ret;
-
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
-       case IIO_CURRENT:
-               ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA);
-               if (ret < 0)
-                       return ret;
-               *val = ret;
-               break;
-       case IIO_TEMP:
-               *val = 140000;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static const struct iio_info ad5421_info = {
-       .read_raw =             ad5421_read_raw,
-       .write_raw =            ad5421_write_raw,
-       .read_event_config =    ad5421_read_event_config,
-       .write_event_config =   ad5421_write_event_config,
-       .read_event_value =     ad5421_read_event_value,
-       .driver_module =        THIS_MODULE,
-};
-
-static int __devinit ad5421_probe(struct spi_device *spi)
-{
-       struct ad5421_platform_data *pdata = dev_get_platdata(&spi->dev);
-       struct iio_dev *indio_dev;
-       struct ad5421_state *st;
-       int ret;
-
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               dev_err(&spi->dev, "Failed to allocate iio device\n");
-               return  -ENOMEM;
-       }
-
-       st = iio_priv(indio_dev);
-       spi_set_drvdata(spi, indio_dev);
-
-       st->spi = spi;
-
-       indio_dev->dev.parent = &spi->dev;
-       indio_dev->name = "ad5421";
-       indio_dev->info = &ad5421_info;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->channels = ad5421_channels;
-       indio_dev->num_channels = ARRAY_SIZE(ad5421_channels);
-
-       st->ctrl = AD5421_CTRL_WATCHDOG_DISABLE |
-                       AD5421_CTRL_AUTO_FAULT_READBACK;
-
-       if (pdata) {
-               st->current_range = pdata->current_range;
-               if (pdata->external_vref)
-                       st->ctrl |= AD5421_CTRL_PWR_DOWN_INT_VREF;
-       } else {
-               st->current_range = AD5421_CURRENT_RANGE_4mA_20mA;
-       }
-
-       /* write initial ctrl register value */
-       ad5421_update_ctrl(indio_dev, 0, 0);
-
-       if (spi->irq) {
-               ret = request_threaded_irq(spi->irq,
-                                          NULL,
-                                          ad5421_fault_handler,
-                                          IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-                                          "ad5421 fault",
-                                          indio_dev);
-               if (ret)
-                       goto error_free;
-       }
-
-       ret = iio_device_register(indio_dev);
-       if (ret) {
-               dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
-               goto error_free_irq;
-       }
-
-       return 0;
-
-error_free_irq:
-       if (spi->irq)
-               free_irq(spi->irq, indio_dev);
-error_free:
-       iio_device_free(indio_dev);
-
-       return ret;
-}
-
-static int __devexit ad5421_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-
-       iio_device_unregister(indio_dev);
-       if (spi->irq)
-               free_irq(spi->irq, indio_dev);
-       iio_device_free(indio_dev);
-
-       return 0;
-}
-
-static struct spi_driver ad5421_driver = {
-       .driver = {
-                  .name = "ad5421",
-                  .owner = THIS_MODULE,
-       },
-       .probe = ad5421_probe,
-       .remove = __devexit_p(ad5421_remove),
-};
-module_spi_driver(ad5421_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("Analog Devices AD5421 DAC");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:ad5421");
diff --git a/drivers/staging/iio/dac/ad5421.h b/drivers/staging/iio/dac/ad5421.h
deleted file mode 100644 (file)
index cd2bb84..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef __IIO_DAC_AD5421_H__
-#define __IIO_DAC_AD5421_H__
-
-/*
- * TODO: This file needs to go into include/linux/iio
- */
-
-/**
- * enum ad5421_current_range - Current range the AD5421 is configured for.
- * @AD5421_CURRENT_RANGE_4mA_20mA: 4 mA to 20 mA (RANGE1,0 pins = 00)
- * @AD5421_CURRENT_RANGE_3mA8_21mA: 3.8 mA to 21 mA (RANGE1,0 pins = x1)
- * @AD5421_CURRENT_RANGE_3mA2_24mA: 3.2 mA to 24 mA (RANGE1,0 pins = 10)
- */
-
-enum ad5421_current_range {
-       AD5421_CURRENT_RANGE_4mA_20mA,
-       AD5421_CURRENT_RANGE_3mA8_21mA,
-       AD5421_CURRENT_RANGE_3mA2_24mA,
-};
-
-/**
- * struct ad5421_platform_data - AD5421 DAC driver platform data
- * @external_vref: whether an external reference voltage is used or not
- * @current_range: Current range the AD5421 is configured for
- */
-
-struct ad5421_platform_data {
-       bool external_vref;
-       enum ad5421_current_range current_range;
-};
-
-#endif
diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c
deleted file mode 100644 (file)
index 49f557f..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * AD5446 SPI DAC driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-#include <linux/spi/spi.h>
-#include <linux/regulator/consumer.h>
-#include <linux/err.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#include "ad5446.h"
-
-static int ad5446_write(struct ad5446_state *st, unsigned val)
-{
-       __be16 data = cpu_to_be16(val);
-       return spi_write(st->spi, &data, sizeof(data));
-}
-
-static int ad5660_write(struct ad5446_state *st, unsigned val)
-{
-       uint8_t data[3];
-
-       data[0] = (val >> 16) & 0xFF;
-       data[1] = (val >> 8) & 0xFF;
-       data[2] = val & 0xFF;
-
-       return spi_write(st->spi, data, sizeof(data));
-}
-
-static const char * const ad5446_powerdown_modes[] = {
-       "1kohm_to_gnd", "100kohm_to_gnd", "three_state"
-};
-
-static int ad5446_set_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan, unsigned int mode)
-{
-       struct ad5446_state *st = iio_priv(indio_dev);
-
-       st->pwr_down_mode = mode + 1;
-
-       return 0;
-}
-
-static int ad5446_get_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan)
-{
-       struct ad5446_state *st = iio_priv(indio_dev);
-
-       return st->pwr_down_mode - 1;
-}
-
-static const struct iio_enum ad5446_powerdown_mode_enum = {
-       .items = ad5446_powerdown_modes,
-       .num_items = ARRAY_SIZE(ad5446_powerdown_modes),
-       .get = ad5446_get_powerdown_mode,
-       .set = ad5446_set_powerdown_mode,
-};
-
-static ssize_t ad5446_read_dac_powerdown(struct iio_dev *indio_dev,
-                                          uintptr_t private,
-                                          const struct iio_chan_spec *chan,
-                                          char *buf)
-{
-       struct ad5446_state *st = iio_priv(indio_dev);
-
-       return sprintf(buf, "%d\n", st->pwr_down);
-}
-
-static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev,
-                                           uintptr_t private,
-                                           const struct iio_chan_spec *chan,
-                                           const char *buf, size_t len)
-{
-       struct ad5446_state *st = iio_priv(indio_dev);
-       unsigned int shift;
-       unsigned int val;
-       bool powerdown;
-       int ret;
-
-       ret = strtobool(buf, &powerdown);
-       if (ret)
-               return ret;
-
-       mutex_lock(&indio_dev->mlock);
-       st->pwr_down = powerdown;
-
-       if (st->pwr_down) {
-               shift = chan->scan_type.realbits + chan->scan_type.shift;
-               val = st->pwr_down_mode << shift;
-       } else {
-               val = st->cached_val;
-       }
-
-       ret = st->chip_info->write(st, val);
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret ? ret : len;
-}
-
-static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = {
-       {
-               .name = "powerdown",
-               .read = ad5446_read_dac_powerdown,
-               .write = ad5446_write_dac_powerdown,
-       },
-       IIO_ENUM("powerdown_mode", false, &ad5446_powerdown_mode_enum),
-       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5446_powerdown_mode_enum),
-       { },
-};
-
-#define _AD5446_CHANNEL(bits, storage, shift, ext) { \
-       .type = IIO_VOLTAGE, \
-       .indexed = 1, \
-       .output = 1, \
-       .channel = 0, \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
-       IIO_CHAN_INFO_SCALE_SHARED_BIT, \
-       .scan_type = IIO_ST('u', (bits), (storage), (shift)), \
-       .ext_info = (ext), \
-}
-
-#define AD5446_CHANNEL(bits, storage, shift) \
-       _AD5446_CHANNEL(bits, storage, shift, NULL)
-
-#define AD5446_CHANNEL_POWERDOWN(bits, storage, shift) \
-       _AD5446_CHANNEL(bits, storage, shift, ad5064_ext_info_powerdown)
-
-static const struct ad5446_chip_info ad5446_chip_info_tbl[] = {
-       [ID_AD5444] = {
-               .channel = AD5446_CHANNEL(12, 16, 2),
-               .write = ad5446_write,
-       },
-       [ID_AD5446] = {
-               .channel = AD5446_CHANNEL(14, 16, 0),
-               .write = ad5446_write,
-       },
-       [ID_AD5541A] = {
-               .channel = AD5446_CHANNEL(16, 16, 0),
-               .write = ad5446_write,
-       },
-       [ID_AD5512A] = {
-               .channel = AD5446_CHANNEL(12, 16, 4),
-               .write = ad5446_write,
-       },
-       [ID_AD5553] = {
-               .channel = AD5446_CHANNEL(14, 16, 0),
-               .write = ad5446_write,
-       },
-       [ID_AD5601] = {
-               .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6),
-               .write = ad5446_write,
-       },
-       [ID_AD5611] = {
-               .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4),
-               .write = ad5446_write,
-       },
-       [ID_AD5621] = {
-               .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
-               .write = ad5446_write,
-       },
-       [ID_AD5620_2500] = {
-               .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
-               .int_vref_mv = 2500,
-               .write = ad5446_write,
-       },
-       [ID_AD5620_1250] = {
-               .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
-               .int_vref_mv = 1250,
-               .write = ad5446_write,
-       },
-       [ID_AD5640_2500] = {
-               .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0),
-               .int_vref_mv = 2500,
-               .write = ad5446_write,
-       },
-       [ID_AD5640_1250] = {
-               .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0),
-               .int_vref_mv = 1250,
-               .write = ad5446_write,
-       },
-       [ID_AD5660_2500] = {
-               .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
-               .int_vref_mv = 2500,
-               .write = ad5660_write,
-       },
-       [ID_AD5660_1250] = {
-               .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
-               .int_vref_mv = 1250,
-               .write = ad5660_write,
-       },
-       [ID_AD5662] = {
-               .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0),
-               .write = ad5660_write,
-       },
-};
-
-static int ad5446_read_raw(struct iio_dev *indio_dev,
-                          struct iio_chan_spec const *chan,
-                          int *val,
-                          int *val2,
-                          long m)
-{
-       struct ad5446_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
-
-       switch (m) {
-       case IIO_CHAN_INFO_RAW:
-               *val = st->cached_val;
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
-
-       }
-       return -EINVAL;
-}
-
-static int ad5446_write_raw(struct iio_dev *indio_dev,
-                              struct iio_chan_spec const *chan,
-                              int val,
-                              int val2,
-                              long mask)
-{
-       struct ad5446_state *st = iio_priv(indio_dev);
-       int ret = 0;
-
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW:
-               if (val >= (1 << chan->scan_type.realbits) || val < 0)
-                       return -EINVAL;
-
-               val <<= chan->scan_type.shift;
-               mutex_lock(&indio_dev->mlock);
-               st->cached_val = val;
-               if (!st->pwr_down)
-                       ret = st->chip_info->write(st, val);
-               mutex_unlock(&indio_dev->mlock);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static const struct iio_info ad5446_info = {
-       .read_raw = ad5446_read_raw,
-       .write_raw = ad5446_write_raw,
-       .driver_module = THIS_MODULE,
-};
-
-static int __devinit ad5446_probe(struct spi_device *spi)
-{
-       struct ad5446_state *st;
-       struct iio_dev *indio_dev;
-       struct regulator *reg;
-       int ret, voltage_uv = 0;
-
-       reg = regulator_get(&spi->dev, "vcc");
-       if (!IS_ERR(reg)) {
-               ret = regulator_enable(reg);
-               if (ret)
-                       goto error_put_reg;
-
-               voltage_uv = regulator_get_voltage(reg);
-       }
-
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_disable_reg;
-       }
-       st = iio_priv(indio_dev);
-       st->chip_info =
-               &ad5446_chip_info_tbl[spi_get_device_id(spi)->driver_data];
-
-       spi_set_drvdata(spi, indio_dev);
-       st->reg = reg;
-       st->spi = spi;
-
-       /* Establish that the iio_dev is a child of the spi device */
-       indio_dev->dev.parent = &spi->dev;
-       indio_dev->name = spi_get_device_id(spi)->name;
-       indio_dev->info = &ad5446_info;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->channels = &st->chip_info->channel;
-       indio_dev->num_channels = 1;
-
-       st->pwr_down_mode = MODE_PWRDWN_1k;
-
-       if (st->chip_info->int_vref_mv)
-               st->vref_mv = st->chip_info->int_vref_mv;
-       else if (voltage_uv)
-               st->vref_mv = voltage_uv / 1000;
-       else
-               dev_warn(&spi->dev, "reference voltage unspecified\n");
-
-       ret = iio_device_register(indio_dev);
-       if (ret)
-               goto error_free_device;
-
-       return 0;
-
-error_free_device:
-       iio_device_free(indio_dev);
-error_disable_reg:
-       if (!IS_ERR(reg))
-               regulator_disable(reg);
-error_put_reg:
-       if (!IS_ERR(reg))
-               regulator_put(reg);
-
-       return ret;
-}
-
-static int ad5446_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-       struct ad5446_state *st = iio_priv(indio_dev);
-
-       iio_device_unregister(indio_dev);
-       if (!IS_ERR(st->reg)) {
-               regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
-
-       return 0;
-}
-
-static const struct spi_device_id ad5446_id[] = {
-       {"ad5444", ID_AD5444},
-       {"ad5446", ID_AD5446},
-       {"ad5512a", ID_AD5512A},
-       {"ad5541a", ID_AD5541A},
-       {"ad5542a", ID_AD5541A}, /* ad5541a and ad5542a are compatible */
-       {"ad5543", ID_AD5541A}, /* ad5541a and ad5543 are compatible */
-       {"ad5553", ID_AD5553},
-       {"ad5601", ID_AD5601},
-       {"ad5611", ID_AD5611},
-       {"ad5621", ID_AD5621},
-       {"ad5620-2500", ID_AD5620_2500}, /* AD5620/40/60: */
-       {"ad5620-1250", ID_AD5620_1250}, /* part numbers may look differently */
-       {"ad5640-2500", ID_AD5640_2500},
-       {"ad5640-1250", ID_AD5640_1250},
-       {"ad5660-2500", ID_AD5660_2500},
-       {"ad5660-1250", ID_AD5660_1250},
-       {"ad5662", ID_AD5662},
-       {}
-};
-MODULE_DEVICE_TABLE(spi, ad5446_id);
-
-static struct spi_driver ad5446_driver = {
-       .driver = {
-               .name   = "ad5446",
-               .owner  = THIS_MODULE,
-       },
-       .probe          = ad5446_probe,
-       .remove         = __devexit_p(ad5446_remove),
-       .id_table       = ad5446_id,
-};
-module_spi_driver(ad5446_driver);
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h
deleted file mode 100644 (file)
index dfd68ce..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * AD5446 SPI DAC driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-#ifndef IIO_DAC_AD5446_H_
-#define IIO_DAC_AD5446_H_
-
-/* DAC Control Bits */
-
-#define AD5446_LOAD            (0x0 << 14) /* Load and update */
-#define AD5446_SDO_DIS         (0x1 << 14) /* Disable SDO */
-#define AD5446_NOP             (0x2 << 14) /* No operation */
-#define AD5446_CLK_RISING      (0x3 << 14) /* Clock data on rising edge */
-
-#define AD5620_LOAD            (0x0 << 14) /* Load and update Norm Operation*/
-#define AD5620_PWRDWN_1k       (0x1 << 14) /* Power-down: 1kOhm to GND */
-#define AD5620_PWRDWN_100k     (0x2 << 14) /* Power-down: 100kOhm to GND */
-#define AD5620_PWRDWN_TRISTATE (0x3 << 14) /* Power-down: Three-state */
-
-#define AD5660_LOAD            (0x0 << 16) /* Load and update Norm Operation*/
-#define AD5660_PWRDWN_1k       (0x1 << 16) /* Power-down: 1kOhm to GND */
-#define AD5660_PWRDWN_100k     (0x2 << 16) /* Power-down: 100kOhm to GND */
-#define AD5660_PWRDWN_TRISTATE (0x3 << 16) /* Power-down: Three-state */
-
-#define MODE_PWRDWN_1k         0x1
-#define MODE_PWRDWN_100k       0x2
-#define MODE_PWRDWN_TRISTATE   0x3
-
-/**
- * struct ad5446_state - driver instance specific data
- * @spi:               spi_device
- * @chip_info:         chip model specific constants, available modes etc
- * @reg:               supply regulator
- * @vref_mv:           actual reference voltage used
- */
-
-struct ad5446_state {
-       struct spi_device               *spi;
-       const struct ad5446_chip_info   *chip_info;
-       struct regulator                *reg;
-       unsigned short                  vref_mv;
-       unsigned                        cached_val;
-       unsigned                        pwr_down_mode;
-       unsigned                        pwr_down;
-};
-
-/**
- * struct ad5446_chip_info - chip specific information
- * @channel:           channel spec for the DAC
- * @int_vref_mv:       AD5620/40/60: the internal reference voltage
- * @write:             chip specific helper function to write to the register
- */
-
-struct ad5446_chip_info {
-       struct iio_chan_spec    channel;
-       u16                     int_vref_mv;
-       int                     (*write)(struct ad5446_state *st, unsigned val);
-};
-
-/**
- * ad5446_supported_device_ids:
- * The AD5620/40/60 parts are available in different fixed internal reference
- * voltage options. The actual part numbers may look differently
- * (and a bit cryptic), however this style is used to make clear which
- * parts are supported here.
- */
-
-enum ad5446_supported_device_ids {
-       ID_AD5444,
-       ID_AD5446,
-       ID_AD5541A,
-       ID_AD5512A,
-       ID_AD5553,
-       ID_AD5601,
-       ID_AD5611,
-       ID_AD5621,
-       ID_AD5620_2500,
-       ID_AD5620_1250,
-       ID_AD5640_2500,
-       ID_AD5640_1250,
-       ID_AD5660_2500,
-       ID_AD5660_1250,
-       ID_AD5662,
-};
-
-#endif /* IIO_DAC_AD5446_H_ */
diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c
deleted file mode 100644 (file)
index 1289e9b..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * AD5504, AD5501 High Voltage Digital to Analog Converter
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/regulator/consumer.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/events.h>
-
-#include "ad5504.h"
-
-#define AD5505_BITS                    12
-#define AD5504_RES_MASK                        ((1 << (AD5505_BITS)) - 1)
-
-#define AD5504_CMD_READ                        (1 << 15)
-#define AD5504_CMD_WRITE               (0 << 15)
-#define AD5504_ADDR(addr)              ((addr) << 12)
-
-/* Registers */
-#define AD5504_ADDR_NOOP               0
-#define AD5504_ADDR_DAC(x)             ((x) + 1)
-#define AD5504_ADDR_ALL_DAC            5
-#define AD5504_ADDR_CTRL               7
-
-/* Control Register */
-#define AD5504_DAC_PWR(ch)             ((ch) << 2)
-#define AD5504_DAC_PWRDWN_MODE(mode)   ((mode) << 6)
-#define AD5504_DAC_PWRDN_20K           0
-#define AD5504_DAC_PWRDN_3STATE                1
-
-/**
- * struct ad5446_state - driver instance specific data
- * @us:                        spi_device
- * @reg:               supply regulator
- * @vref_mv:           actual reference voltage used
- * @pwr_down_mask      power down mask
- * @pwr_down_mode      current power down mode
- */
-
-struct ad5504_state {
-       struct spi_device               *spi;
-       struct regulator                *reg;
-       unsigned short                  vref_mv;
-       unsigned                        pwr_down_mask;
-       unsigned                        pwr_down_mode;
-};
-
-/**
- * ad5504_supported_device_ids:
- */
-
-enum ad5504_supported_device_ids {
-       ID_AD5504,
-       ID_AD5501,
-};
-
-static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val)
-{
-       u16 tmp = cpu_to_be16(AD5504_CMD_WRITE |
-                             AD5504_ADDR(addr) |
-                             (val & AD5504_RES_MASK));
-
-       return spi_write(spi, (u8 *)&tmp, 2);
-}
-
-static int ad5504_spi_read(struct spi_device *spi, u8 addr)
-{
-       u16 tmp = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr));
-       u16 val;
-       int ret;
-       struct spi_transfer     t = {
-                       .tx_buf         = &tmp,
-                       .rx_buf         = &val,
-                       .len            = 2,
-               };
-       struct spi_message      m;
-
-       spi_message_init(&m);
-       spi_message_add_tail(&t, &m);
-       ret = spi_sync(spi, &m);
-
-       if (ret < 0)
-               return ret;
-
-       return be16_to_cpu(val) & AD5504_RES_MASK;
-}
-
-static int ad5504_read_raw(struct iio_dev *indio_dev,
-                          struct iio_chan_spec const *chan,
-                          int *val,
-                          int *val2,
-                          long m)
-{
-       struct ad5504_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
-       int ret;
-
-       switch (m) {
-       case IIO_CHAN_INFO_RAW:
-               ret = ad5504_spi_read(st->spi, chan->address);
-               if (ret < 0)
-                       return ret;
-
-               *val = ret;
-
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
-
-       }
-       return -EINVAL;
-}
-
-static int ad5504_write_raw(struct iio_dev *indio_dev,
-                              struct iio_chan_spec const *chan,
-                              int val,
-                              int val2,
-                              long mask)
-{
-       struct ad5504_state *st = iio_priv(indio_dev);
-       int ret;
-
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW:
-               if (val >= (1 << chan->scan_type.realbits) || val < 0)
-                       return -EINVAL;
-
-               return ad5504_spi_write(st->spi, chan->address, val);
-       default:
-               ret = -EINVAL;
-       }
-
-       return -EINVAL;
-}
-
-static const char * const ad5504_powerdown_modes[] = {
-       "20kohm_to_gnd",
-       "three_state",
-};
-
-static int ad5504_get_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan)
-{
-       struct ad5504_state *st = iio_priv(indio_dev);
-
-       return st->pwr_down_mode;
-}
-
-static int ad5504_set_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan, unsigned int mode)
-{
-       struct ad5504_state *st = iio_priv(indio_dev);
-
-       st->pwr_down_mode = mode;
-
-       return 0;
-}
-
-static const struct iio_enum ad5504_powerdown_mode_enum = {
-       .items = ad5504_powerdown_modes,
-       .num_items = ARRAY_SIZE(ad5504_powerdown_modes),
-       .get = ad5504_get_powerdown_mode,
-       .set = ad5504_set_powerdown_mode,
-};
-
-static ssize_t ad5504_read_dac_powerdown(struct iio_dev *indio_dev,
-       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
-{
-       struct ad5504_state *st = iio_priv(indio_dev);
-
-       return sprintf(buf, "%d\n",
-                       !(st->pwr_down_mask & (1 << chan->channel)));
-}
-
-static ssize_t ad5504_write_dac_powerdown(struct iio_dev *indio_dev,
-       uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
-       size_t len)
-{
-       bool pwr_down;
-       int ret;
-       struct ad5504_state *st = iio_priv(indio_dev);
-
-       ret = strtobool(buf, &pwr_down);
-       if (ret)
-               return ret;
-
-       if (pwr_down)
-               st->pwr_down_mask |= (1 << chan->channel);
-       else
-               st->pwr_down_mask &= ~(1 << chan->channel);
-
-       ret = ad5504_spi_write(st->spi, AD5504_ADDR_CTRL,
-                               AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) |
-                               AD5504_DAC_PWR(st->pwr_down_mask));
-
-       /* writes to the CTRL register must be followed by a NOOP */
-       ad5504_spi_write(st->spi, AD5504_ADDR_NOOP, 0);
-
-       return ret ? ret : len;
-}
-
-static IIO_CONST_ATTR(temp0_thresh_rising_value, "110000");
-static IIO_CONST_ATTR(temp0_thresh_rising_en, "1");
-
-static struct attribute *ad5504_ev_attributes[] = {
-       &iio_const_attr_temp0_thresh_rising_value.dev_attr.attr,
-       &iio_const_attr_temp0_thresh_rising_en.dev_attr.attr,
-       NULL,
-};
-
-static struct attribute_group ad5504_ev_attribute_group = {
-       .attrs = ad5504_ev_attributes,
-       .name = "events",
-};
-
-static irqreturn_t ad5504_event_handler(int irq, void *private)
-{
-       iio_push_event(private,
-                      IIO_UNMOD_EVENT_CODE(IIO_TEMP,
-                                           0,
-                                           IIO_EV_TYPE_THRESH,
-                                           IIO_EV_DIR_RISING),
-                      iio_get_time_ns());
-
-       return IRQ_HANDLED;
-}
-
-static const struct iio_info ad5504_info = {
-       .write_raw = ad5504_write_raw,
-       .read_raw = ad5504_read_raw,
-       .event_attrs = &ad5504_ev_attribute_group,
-       .driver_module = THIS_MODULE,
-};
-
-static const struct iio_chan_spec_ext_info ad5504_ext_info[] = {
-       {
-               .name = "powerdown",
-               .read = ad5504_read_dac_powerdown,
-               .write = ad5504_write_dac_powerdown,
-       },
-       IIO_ENUM("powerdown_mode", true, &ad5504_powerdown_mode_enum),
-       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum),
-       { },
-};
-
-#define AD5504_CHANNEL(_chan) { \
-       .type = IIO_VOLTAGE, \
-       .indexed = 1, \
-       .output = 1, \
-       .channel = (_chan), \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
-                    IIO_CHAN_INFO_SCALE_SHARED_BIT, \
-       .address = AD5504_ADDR_DAC(_chan), \
-       .scan_type = IIO_ST('u', 12, 16, 0), \
-       .ext_info = ad5504_ext_info, \
-}
-
-static const struct iio_chan_spec ad5504_channels[] = {
-       AD5504_CHANNEL(0),
-       AD5504_CHANNEL(1),
-       AD5504_CHANNEL(2),
-       AD5504_CHANNEL(3),
-};
-
-static int __devinit ad5504_probe(struct spi_device *spi)
-{
-       struct ad5504_platform_data *pdata = spi->dev.platform_data;
-       struct iio_dev *indio_dev;
-       struct ad5504_state *st;
-       struct regulator *reg;
-       int ret, voltage_uv = 0;
-
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
-       reg = regulator_get(&spi->dev, "vcc");
-       if (!IS_ERR(reg)) {
-               ret = regulator_enable(reg);
-               if (ret)
-                       goto error_put_reg;
-
-               voltage_uv = regulator_get_voltage(reg);
-       }
-
-       spi_set_drvdata(spi, indio_dev);
-       st = iio_priv(indio_dev);
-       if (voltage_uv)
-               st->vref_mv = voltage_uv / 1000;
-       else if (pdata)
-               st->vref_mv = pdata->vref_mv;
-       else
-               dev_warn(&spi->dev, "reference voltage unspecified\n");
-
-       st->reg = reg;
-       st->spi = spi;
-       indio_dev->dev.parent = &spi->dev;
-       indio_dev->name = spi_get_device_id(st->spi)->name;
-       indio_dev->info = &ad5504_info;
-       if (spi_get_device_id(st->spi)->driver_data == ID_AD5501)
-               indio_dev->num_channels = 1;
-       else
-               indio_dev->num_channels = 4;
-       indio_dev->channels = ad5504_channels;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-
-       if (spi->irq) {
-               ret = request_threaded_irq(spi->irq,
-                                          NULL,
-                                          &ad5504_event_handler,
-                                          IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                                          spi_get_device_id(st->spi)->name,
-                                          indio_dev);
-               if (ret)
-                       goto error_disable_reg;
-       }
-
-       ret = iio_device_register(indio_dev);
-       if (ret)
-               goto error_free_irq;
-
-       return 0;
-
-error_free_irq:
-       if (spi->irq)
-               free_irq(spi->irq, indio_dev);
-error_disable_reg:
-       if (!IS_ERR(reg))
-               regulator_disable(reg);
-error_put_reg:
-       if (!IS_ERR(reg))
-               regulator_put(reg);
-
-       iio_device_free(indio_dev);
-error_ret:
-       return ret;
-}
-
-static int __devexit ad5504_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-       struct ad5504_state *st = iio_priv(indio_dev);
-
-       iio_device_unregister(indio_dev);
-       if (spi->irq)
-               free_irq(spi->irq, indio_dev);
-
-       if (!IS_ERR(st->reg)) {
-               regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
-
-       return 0;
-}
-
-static const struct spi_device_id ad5504_id[] = {
-       {"ad5504", ID_AD5504},
-       {"ad5501", ID_AD5501},
-       {}
-};
-MODULE_DEVICE_TABLE(spi, ad5504_id);
-
-static struct spi_driver ad5504_driver = {
-       .driver = {
-                  .name = "ad5504",
-                  .owner = THIS_MODULE,
-                  },
-       .probe = ad5504_probe,
-       .remove = __devexit_p(ad5504_remove),
-       .id_table = ad5504_id,
-};
-module_spi_driver(ad5504_driver);
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5504.h b/drivers/staging/iio/dac/ad5504.h
deleted file mode 100644 (file)
index d4980bf..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * AD5504 SPI DAC driver
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#ifndef SPI_AD5504_H_
-#define SPI_AD5504_H_
-
-/*
- * TODO: struct ad5504_platform_data needs to go into include/linux/iio
- */
-
-struct ad5504_platform_data {
-       u16                             vref_mv;
-};
-
-#endif /* SPI_AD5504_H_ */
diff --git a/drivers/staging/iio/dac/ad5624r.h b/drivers/staging/iio/dac/ad5624r.h
deleted file mode 100644 (file)
index 5dca302..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * AD5624R SPI DAC driver
- *
- * Copyright 2010-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-#ifndef SPI_AD5624R_H_
-#define SPI_AD5624R_H_
-
-#define AD5624R_DAC_CHANNELS                   4
-
-#define AD5624R_ADDR_DAC0                      0x0
-#define AD5624R_ADDR_DAC1                      0x1
-#define AD5624R_ADDR_DAC2                      0x2
-#define AD5624R_ADDR_DAC3                      0x3
-#define AD5624R_ADDR_ALL_DAC                   0x7
-
-#define AD5624R_CMD_WRITE_INPUT_N              0x0
-#define AD5624R_CMD_UPDATE_DAC_N               0x1
-#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_ALL   0x2
-#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_N     0x3
-#define AD5624R_CMD_POWERDOWN_DAC              0x4
-#define AD5624R_CMD_RESET                      0x5
-#define AD5624R_CMD_LDAC_SETUP                 0x6
-#define AD5624R_CMD_INTERNAL_REFER_SETUP       0x7
-
-#define AD5624R_LDAC_PWRDN_NONE                        0x0
-#define AD5624R_LDAC_PWRDN_1K                  0x1
-#define AD5624R_LDAC_PWRDN_100K                        0x2
-#define AD5624R_LDAC_PWRDN_3STATE              0x3
-
-/**
- * struct ad5624r_chip_info - chip specific information
- * @channels:          channel spec for the DAC
- * @int_vref_mv:       AD5620/40/60: the internal reference voltage
- */
-
-struct ad5624r_chip_info {
-       const struct iio_chan_spec      *channels;
-       u16                             int_vref_mv;
-};
-
-/**
- * struct ad5446_state - driver instance specific data
- * @indio_dev:         the industrial I/O device
- * @us:                        spi_device
- * @chip_info:         chip model specific constants, available modes etc
- * @reg:               supply regulator
- * @vref_mv:           actual reference voltage used
- * @pwr_down_mask      power down mask
- * @pwr_down_mode      current power down mode
- */
-
-struct ad5624r_state {
-       struct spi_device               *us;
-       const struct ad5624r_chip_info  *chip_info;
-       struct regulator                *reg;
-       unsigned short                  vref_mv;
-       unsigned                        pwr_down_mask;
-       unsigned                        pwr_down_mode;
-};
-
-/**
- * ad5624r_supported_device_ids:
- * The AD5624/44/64 parts are available in different
- * fixed internal reference voltage options.
- */
-
-enum ad5624r_supported_device_ids {
-       ID_AD5624R3,
-       ID_AD5644R3,
-       ID_AD5664R3,
-       ID_AD5624R5,
-       ID_AD5644R5,
-       ID_AD5664R5,
-};
-
-#endif /* SPI_AD5624R_H_ */
diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c
deleted file mode 100644 (file)
index 6a7d6a4..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * AD5624R, AD5644R, AD5664R Digital to analog convertors spi driver
- *
- * Copyright 2010-2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/regulator/consumer.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#include "ad5624r.h"
-
-static int ad5624r_spi_write(struct spi_device *spi,
-                            u8 cmd, u8 addr, u16 val, u8 len)
-{
-       u32 data;
-       u8 msg[3];
-
-       /*
-        * The input shift register is 24 bits wide. The first two bits are
-        * don't care bits. The next three are the command bits, C2 to C0,
-        * followed by the 3-bit DAC address, A2 to A0, and then the
-        * 16-, 14-, 12-bit data-word. The data-word comprises the 16-,
-        * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits,
-        * for the AD5664R, AD5644R, and AD5624R, respectively.
-        */
-       data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << (16 - len));
-       msg[0] = data >> 16;
-       msg[1] = data >> 8;
-       msg[2] = data;
-
-       return spi_write(spi, msg, 3);
-}
-
-static int ad5624r_read_raw(struct iio_dev *indio_dev,
-                          struct iio_chan_spec const *chan,
-                          int *val,
-                          int *val2,
-                          long m)
-{
-       struct ad5624r_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
-
-       switch (m) {
-       case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
-
-       }
-       return -EINVAL;
-}
-
-static int ad5624r_write_raw(struct iio_dev *indio_dev,
-                              struct iio_chan_spec const *chan,
-                              int val,
-                              int val2,
-                              long mask)
-{
-       struct ad5624r_state *st = iio_priv(indio_dev);
-       int ret;
-
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW:
-               if (val >= (1 << chan->scan_type.realbits) || val < 0)
-                       return -EINVAL;
-
-               return ad5624r_spi_write(st->us,
-                               AD5624R_CMD_WRITE_INPUT_N_UPDATE_N,
-                               chan->address, val,
-                               chan->scan_type.shift);
-       default:
-               ret = -EINVAL;
-       }
-
-       return -EINVAL;
-}
-
-static const char * const ad5624r_powerdown_modes[] = {
-       "1kohm_to_gnd",
-       "100kohm_to_gnd",
-       "three_state"
-};
-
-static int ad5624r_get_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan)
-{
-       struct ad5624r_state *st = iio_priv(indio_dev);
-
-       return st->pwr_down_mode;
-}
-
-static int ad5624r_set_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan, unsigned int mode)
-{
-       struct ad5624r_state *st = iio_priv(indio_dev);
-
-       st->pwr_down_mode = mode;
-
-       return 0;
-}
-
-static const struct iio_enum ad5624r_powerdown_mode_enum = {
-       .items = ad5624r_powerdown_modes,
-       .num_items = ARRAY_SIZE(ad5624r_powerdown_modes),
-       .get = ad5624r_get_powerdown_mode,
-       .set = ad5624r_set_powerdown_mode,
-};
-
-static ssize_t ad5624r_read_dac_powerdown(struct iio_dev *indio_dev,
-       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
-{
-       struct ad5624r_state *st = iio_priv(indio_dev);
-
-       return sprintf(buf, "%d\n",
-                       !!(st->pwr_down_mask & (1 << chan->channel)));
-}
-
-static ssize_t ad5624r_write_dac_powerdown(struct iio_dev *indio_dev,
-       uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
-       size_t len)
-{
-       bool pwr_down;
-       int ret;
-       struct ad5624r_state *st = iio_priv(indio_dev);
-
-       ret = strtobool(buf, &pwr_down);
-       if (ret)
-               return ret;
-
-       if (pwr_down)
-               st->pwr_down_mask |= (1 << chan->channel);
-       else
-               st->pwr_down_mask &= ~(1 << chan->channel);
-
-       ret = ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0,
-                               (st->pwr_down_mode << 4) |
-                               st->pwr_down_mask, 16);
-
-       return ret ? ret : len;
-}
-
-static const struct iio_info ad5624r_info = {
-       .write_raw = ad5624r_write_raw,
-       .read_raw = ad5624r_read_raw,
-       .driver_module = THIS_MODULE,
-};
-
-static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = {
-       {
-               .name = "powerdown",
-               .read = ad5624r_read_dac_powerdown,
-               .write = ad5624r_write_dac_powerdown,
-       },
-       IIO_ENUM("powerdown_mode", true, &ad5624r_powerdown_mode_enum),
-       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum),
-       { },
-};
-
-#define AD5624R_CHANNEL(_chan, _bits) { \
-       .type = IIO_VOLTAGE, \
-       .indexed = 1, \
-       .output = 1, \
-       .channel = (_chan), \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
-                    IIO_CHAN_INFO_SCALE_SHARED_BIT, \
-       .address = (_chan), \
-       .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \
-       .ext_info = ad5624r_ext_info, \
-}
-
-#define DECLARE_AD5624R_CHANNELS(_name, _bits) \
-       const struct iio_chan_spec _name##_channels[] = { \
-               AD5624R_CHANNEL(0, _bits), \
-               AD5624R_CHANNEL(1, _bits), \
-               AD5624R_CHANNEL(2, _bits), \
-               AD5624R_CHANNEL(3, _bits), \
-}
-
-static DECLARE_AD5624R_CHANNELS(ad5624r, 12);
-static DECLARE_AD5624R_CHANNELS(ad5644r, 14);
-static DECLARE_AD5624R_CHANNELS(ad5664r, 16);
-
-static const struct ad5624r_chip_info ad5624r_chip_info_tbl[] = {
-       [ID_AD5624R3] = {
-               .channels = ad5624r_channels,
-               .int_vref_mv = 1250,
-       },
-       [ID_AD5624R5] = {
-               .channels = ad5624r_channels,
-               .int_vref_mv = 2500,
-       },
-       [ID_AD5644R3] = {
-               .channels = ad5644r_channels,
-               .int_vref_mv = 1250,
-       },
-       [ID_AD5644R5] = {
-               .channels = ad5644r_channels,
-               .int_vref_mv = 2500,
-       },
-       [ID_AD5664R3] = {
-               .channels = ad5664r_channels,
-               .int_vref_mv = 1250,
-       },
-       [ID_AD5664R5] = {
-               .channels = ad5664r_channels,
-               .int_vref_mv = 2500,
-       },
-};
-
-static int __devinit ad5624r_probe(struct spi_device *spi)
-{
-       struct ad5624r_state *st;
-       struct iio_dev *indio_dev;
-       int ret, voltage_uv = 0;
-
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
-       st = iio_priv(indio_dev);
-       st->reg = regulator_get(&spi->dev, "vcc");
-       if (!IS_ERR(st->reg)) {
-               ret = regulator_enable(st->reg);
-               if (ret)
-                       goto error_put_reg;
-
-               voltage_uv = regulator_get_voltage(st->reg);
-       }
-
-       spi_set_drvdata(spi, indio_dev);
-       st->chip_info =
-               &ad5624r_chip_info_tbl[spi_get_device_id(spi)->driver_data];
-
-       if (voltage_uv)
-               st->vref_mv = voltage_uv / 1000;
-       else
-               st->vref_mv = st->chip_info->int_vref_mv;
-
-       st->us = spi;
-
-       indio_dev->dev.parent = &spi->dev;
-       indio_dev->name = spi_get_device_id(spi)->name;
-       indio_dev->info = &ad5624r_info;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->channels = st->chip_info->channels;
-       indio_dev->num_channels = AD5624R_DAC_CHANNELS;
-
-       ret = ad5624r_spi_write(spi, AD5624R_CMD_INTERNAL_REFER_SETUP, 0,
-                               !!voltage_uv, 16);
-       if (ret)
-               goto error_disable_reg;
-
-       ret = iio_device_register(indio_dev);
-       if (ret)
-               goto error_disable_reg;
-
-       return 0;
-
-error_disable_reg:
-       if (!IS_ERR(st->reg))
-               regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-       iio_device_free(indio_dev);
-error_ret:
-
-       return ret;
-}
-
-static int __devexit ad5624r_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-       struct ad5624r_state *st = iio_priv(indio_dev);
-
-       iio_device_unregister(indio_dev);
-       if (!IS_ERR(st->reg)) {
-               regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
-
-       return 0;
-}
-
-static const struct spi_device_id ad5624r_id[] = {
-       {"ad5624r3", ID_AD5624R3},
-       {"ad5644r3", ID_AD5644R3},
-       {"ad5664r3", ID_AD5664R3},
-       {"ad5624r5", ID_AD5624R5},
-       {"ad5644r5", ID_AD5644R5},
-       {"ad5664r5", ID_AD5664R5},
-       {}
-};
-MODULE_DEVICE_TABLE(spi, ad5624r_id);
-
-static struct spi_driver ad5624r_driver = {
-       .driver = {
-                  .name = "ad5624r",
-                  .owner = THIS_MODULE,
-                  },
-       .probe = ad5624r_probe,
-       .remove = __devexit_p(ad5624r_remove),
-       .id_table = ad5624r_id,
-};
-module_spi_driver(ad5624r_driver);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices AD5624/44/64R DAC spi driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c
deleted file mode 100644 (file)
index 6948d75..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * AD5686R, AD5685R, AD5684R Digital to analog converters  driver
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/regulator/consumer.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#define AD5686_DAC_CHANNELS                    4
-
-#define AD5686_ADDR(x)                         ((x) << 16)
-#define AD5686_CMD(x)                          ((x) << 20)
-
-#define AD5686_ADDR_DAC(chan)          (0x1 << (chan))
-#define AD5686_ADDR_ALL_DAC                    0xF
-
-#define AD5686_CMD_NOOP                                0x0
-#define AD5686_CMD_WRITE_INPUT_N               0x1
-#define AD5686_CMD_UPDATE_DAC_N                        0x2
-#define AD5686_CMD_WRITE_INPUT_N_UPDATE_N      0x3
-#define AD5686_CMD_POWERDOWN_DAC               0x4
-#define AD5686_CMD_LDAC_MASK                   0x5
-#define AD5686_CMD_RESET                       0x6
-#define AD5686_CMD_INTERNAL_REFER_SETUP                0x7
-#define AD5686_CMD_DAISY_CHAIN_ENABLE          0x8
-#define AD5686_CMD_READBACK_ENABLE             0x9
-
-#define AD5686_LDAC_PWRDN_NONE                 0x0
-#define AD5686_LDAC_PWRDN_1K                   0x1
-#define AD5686_LDAC_PWRDN_100K                 0x2
-#define AD5686_LDAC_PWRDN_3STATE               0x3
-
-/**
- * struct ad5686_chip_info - chip specific information
- * @int_vref_mv:       AD5620/40/60: the internal reference voltage
- * @channel:           channel specification
-*/
-
-struct ad5686_chip_info {
-       u16                             int_vref_mv;
-       struct iio_chan_spec            channel[AD5686_DAC_CHANNELS];
-};
-
-/**
- * struct ad5446_state - driver instance specific data
- * @spi:               spi_device
- * @chip_info:         chip model specific constants, available modes etc
- * @reg:               supply regulator
- * @vref_mv:           actual reference voltage used
- * @pwr_down_mask:     power down mask
- * @pwr_down_mode:     current power down mode
- * @data:              spi transfer buffers
- */
-
-struct ad5686_state {
-       struct spi_device               *spi;
-       const struct ad5686_chip_info   *chip_info;
-       struct regulator                *reg;
-       unsigned short                  vref_mv;
-       unsigned                        pwr_down_mask;
-       unsigned                        pwr_down_mode;
-       /*
-        * DMA (thus cache coherency maintenance) requires the
-        * transfer buffers to live in their own cache lines.
-        */
-
-       union {
-               u32 d32;
-               u8 d8[4];
-       } data[3] ____cacheline_aligned;
-};
-
-/**
- * ad5686_supported_device_ids:
- */
-
-enum ad5686_supported_device_ids {
-       ID_AD5684,
-       ID_AD5685,
-       ID_AD5686,
-};
-static int ad5686_spi_write(struct ad5686_state *st,
-                            u8 cmd, u8 addr, u16 val, u8 shift)
-{
-       val <<= shift;
-
-       st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
-                             AD5686_ADDR(addr) |
-                             val);
-
-       return spi_write(st->spi, &st->data[0].d8[1], 3);
-}
-
-static int ad5686_spi_read(struct ad5686_state *st, u8 addr)
-{
-       struct spi_transfer t[] = {
-               {
-                       .tx_buf = &st->data[0].d8[1],
-                       .len = 3,
-                       .cs_change = 1,
-               }, {
-                       .tx_buf = &st->data[1].d8[1],
-                       .rx_buf = &st->data[2].d8[1],
-                       .len = 3,
-               },
-       };
-       struct spi_message m;
-       int ret;
-
-       spi_message_init(&m);
-       spi_message_add_tail(&t[0], &m);
-       spi_message_add_tail(&t[1], &m);
-
-       st->data[0].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_READBACK_ENABLE) |
-                             AD5686_ADDR(addr));
-       st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP));
-
-       ret = spi_sync(st->spi, &m);
-       if (ret < 0)
-               return ret;
-
-       return be32_to_cpu(st->data[2].d32);
-}
-
-static const char * const ad5686_powerdown_modes[] = {
-       "1kohm_to_gnd",
-       "100kohm_to_gnd",
-       "three_state"
-};
-
-static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan)
-{
-       struct ad5686_state *st = iio_priv(indio_dev);
-
-       return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1;
-}
-
-static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan, unsigned int mode)
-{
-       struct ad5686_state *st = iio_priv(indio_dev);
-
-       st->pwr_down_mode &= ~(0x3 << (chan->channel * 2));
-       st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2));
-
-       return 0;
-}
-
-static const struct iio_enum ad5686_powerdown_mode_enum = {
-       .items = ad5686_powerdown_modes,
-       .num_items = ARRAY_SIZE(ad5686_powerdown_modes),
-       .get = ad5686_get_powerdown_mode,
-       .set = ad5686_set_powerdown_mode,
-};
-
-static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev,
-       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
-{
-       struct ad5686_state *st = iio_priv(indio_dev);
-
-       return sprintf(buf, "%d\n", !!(st->pwr_down_mask &
-                       (0x3 << (chan->channel * 2))));
-}
-
-static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
-        uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
-        size_t len)
-{
-       bool readin;
-       int ret;
-       struct ad5686_state *st = iio_priv(indio_dev);
-
-       ret = strtobool(buf, &readin);
-       if (ret)
-               return ret;
-
-       if (readin == true)
-               st->pwr_down_mask |= (0x3 << (chan->channel * 2));
-       else
-               st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));
-
-       ret = ad5686_spi_write(st, AD5686_CMD_POWERDOWN_DAC, 0,
-                              st->pwr_down_mask & st->pwr_down_mode, 0);
-
-       return ret ? ret : len;
-}
-
-static int ad5686_read_raw(struct iio_dev *indio_dev,
-                          struct iio_chan_spec const *chan,
-                          int *val,
-                          int *val2,
-                          long m)
-{
-       struct ad5686_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
-       int ret;
-
-       switch (m) {
-       case IIO_CHAN_INFO_RAW:
-               mutex_lock(&indio_dev->mlock);
-               ret = ad5686_spi_read(st, chan->address);
-               mutex_unlock(&indio_dev->mlock);
-               if (ret < 0)
-                       return ret;
-               *val = ret;
-               return IIO_VAL_INT;
-               break;
-       case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 100000)
-                       >> (chan->scan_type.realbits);
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
-
-       }
-       return -EINVAL;
-}
-
-static int ad5686_write_raw(struct iio_dev *indio_dev,
-                              struct iio_chan_spec const *chan,
-                              int val,
-                              int val2,
-                              long mask)
-{
-       struct ad5686_state *st = iio_priv(indio_dev);
-       int ret;
-
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW:
-               if (val > (1 << chan->scan_type.realbits) || val < 0)
-                       return -EINVAL;
-
-               mutex_lock(&indio_dev->mlock);
-               ret = ad5686_spi_write(st,
-                                AD5686_CMD_WRITE_INPUT_N_UPDATE_N,
-                                chan->address,
-                                val,
-                                chan->scan_type.shift);
-               mutex_unlock(&indio_dev->mlock);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static const struct iio_info ad5686_info = {
-       .read_raw = ad5686_read_raw,
-       .write_raw = ad5686_write_raw,
-       .driver_module = THIS_MODULE,
-};
-
-static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
-       {
-               .name = "powerdown",
-               .read = ad5686_read_dac_powerdown,
-               .write = ad5686_write_dac_powerdown,
-       },
-       IIO_ENUM("powerdown_mode", false, &ad5686_powerdown_mode_enum),
-       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum),
-       { },
-};
-
-#define AD5868_CHANNEL(chan, bits, shift) {                    \
-               .type = IIO_VOLTAGE,                            \
-               .indexed = 1,                                   \
-               .output = 1,                                    \
-               .channel = chan,                                \
-               .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |   \
-               IIO_CHAN_INFO_SCALE_SHARED_BIT,                 \
-               .address = AD5686_ADDR_DAC(chan),                       \
-               .scan_type = IIO_ST('u', bits, 16, shift),      \
-               .ext_info = ad5686_ext_info,                    \
-}
-
-static const struct ad5686_chip_info ad5686_chip_info_tbl[] = {
-       [ID_AD5684] = {
-               .channel[0] = AD5868_CHANNEL(0, 12, 4),
-               .channel[1] = AD5868_CHANNEL(1, 12, 4),
-               .channel[2] = AD5868_CHANNEL(2, 12, 4),
-               .channel[3] = AD5868_CHANNEL(3, 12, 4),
-               .int_vref_mv = 2500,
-       },
-       [ID_AD5685] = {
-               .channel[0] = AD5868_CHANNEL(0, 14, 2),
-               .channel[1] = AD5868_CHANNEL(1, 14, 2),
-               .channel[2] = AD5868_CHANNEL(2, 14, 2),
-               .channel[3] = AD5868_CHANNEL(3, 14, 2),
-               .int_vref_mv = 2500,
-       },
-       [ID_AD5686] = {
-               .channel[0] = AD5868_CHANNEL(0, 16, 0),
-               .channel[1] = AD5868_CHANNEL(1, 16, 0),
-               .channel[2] = AD5868_CHANNEL(2, 16, 0),
-               .channel[3] = AD5868_CHANNEL(3, 16, 0),
-               .int_vref_mv = 2500,
-       },
-};
-
-
-static int __devinit ad5686_probe(struct spi_device *spi)
-{
-       struct ad5686_state *st;
-       struct iio_dev *indio_dev;
-       int ret, regdone = 0, voltage_uv = 0;
-
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL)
-               return  -ENOMEM;
-
-       st = iio_priv(indio_dev);
-       spi_set_drvdata(spi, indio_dev);
-
-       st->reg = regulator_get(&spi->dev, "vcc");
-       if (!IS_ERR(st->reg)) {
-               ret = regulator_enable(st->reg);
-               if (ret)
-                       goto error_put_reg;
-
-               voltage_uv = regulator_get_voltage(st->reg);
-       }
-
-       st->chip_info =
-               &ad5686_chip_info_tbl[spi_get_device_id(spi)->driver_data];
-
-       if (voltage_uv)
-               st->vref_mv = voltage_uv / 1000;
-       else
-               st->vref_mv = st->chip_info->int_vref_mv;
-
-       st->spi = spi;
-
-       /* Set all the power down mode for all channels to 1K pulldown */
-       st->pwr_down_mode = 0x55;
-
-       indio_dev->dev.parent = &spi->dev;
-       indio_dev->name = spi_get_device_id(spi)->name;
-       indio_dev->info = &ad5686_info;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->channels = st->chip_info->channel;
-       indio_dev->num_channels = AD5686_DAC_CHANNELS;
-
-       regdone = 1;
-       ret = ad5686_spi_write(st, AD5686_CMD_INTERNAL_REFER_SETUP, 0,
-                               !!voltage_uv, 0);
-       if (ret)
-               goto error_disable_reg;
-
-       ret = iio_device_register(indio_dev);
-       if (ret)
-               goto error_disable_reg;
-
-       return 0;
-
-error_disable_reg:
-       if (!IS_ERR(st->reg))
-               regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-
-       iio_device_free(indio_dev);
-
-       return ret;
-}
-
-static int __devexit ad5686_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-       struct ad5686_state *st = iio_priv(indio_dev);
-
-       iio_device_unregister(indio_dev);
-       if (!IS_ERR(st->reg)) {
-               regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
-
-       return 0;
-}
-
-static const struct spi_device_id ad5686_id[] = {
-       {"ad5684", ID_AD5684},
-       {"ad5685", ID_AD5685},
-       {"ad5686", ID_AD5686},
-       {}
-};
-MODULE_DEVICE_TABLE(spi, ad5686_id);
-
-static struct spi_driver ad5686_driver = {
-       .driver = {
-                  .name = "ad5686",
-                  .owner = THIS_MODULE,
-                  },
-       .probe = ad5686_probe,
-       .remove = __devexit_p(ad5686_remove),
-       .id_table = ad5686_id,
-};
-module_spi_driver(ad5686_driver);
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5764.c b/drivers/staging/iio/dac/ad5764.c
deleted file mode 100644 (file)
index ffce304..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Analog devices AD5764, AD5764R, AD5744, AD5744R quad-channel
- * Digital to Analog Converters driver
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/regulator/consumer.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#define AD5764_REG_SF_NOP                      0x0
-#define AD5764_REG_SF_CONFIG                   0x1
-#define AD5764_REG_SF_CLEAR                    0x4
-#define AD5764_REG_SF_LOAD                     0x5
-#define AD5764_REG_DATA(x)                     ((2 << 3) | (x))
-#define AD5764_REG_COARSE_GAIN(x)              ((3 << 3) | (x))
-#define AD5764_REG_FINE_GAIN(x)                        ((4 << 3) | (x))
-#define AD5764_REG_OFFSET(x)                   ((5 << 3) | (x))
-
-#define AD5764_NUM_CHANNELS 4
-
-/**
- * struct ad5764_chip_info - chip specific information
- * @int_vref:  Value of the internal reference voltage in uV - 0 if external
- *             reference voltage is used
- * @channel    channel specification
-*/
-
-struct ad5764_chip_info {
-       unsigned long int_vref;
-       const struct iio_chan_spec *channels;
-};
-
-/**
- * struct ad5764_state - driver instance specific data
- * @spi:               spi_device
- * @chip_info:         chip info
- * @vref_reg:          vref supply regulators
- * @data:              spi transfer buffers
- */
-
-struct ad5764_state {
-       struct spi_device               *spi;
-       const struct ad5764_chip_info   *chip_info;
-       struct regulator_bulk_data      vref_reg[2];
-
-       /*
-        * DMA (thus cache coherency maintenance) requires the
-        * transfer buffers to live in their own cache lines.
-        */
-       union {
-               __be32 d32;
-               u8 d8[4];
-       } data[2] ____cacheline_aligned;
-};
-
-enum ad5764_type {
-       ID_AD5744,
-       ID_AD5744R,
-       ID_AD5764,
-       ID_AD5764R,
-};
-
-#define AD5764_CHANNEL(_chan, _bits) {                         \
-       .type = IIO_VOLTAGE,                                    \
-       .indexed = 1,                                           \
-       .output = 1,                                            \
-       .channel = (_chan),                                     \
-       .address = (_chan),                                     \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |           \
-               IIO_CHAN_INFO_OFFSET_SHARED_BIT |               \
-               IIO_CHAN_INFO_SCALE_SEPARATE_BIT |              \
-               IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |         \
-               IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,           \
-       .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits))     \
-}
-
-#define DECLARE_AD5764_CHANNELS(_name, _bits) \
-const struct iio_chan_spec _name##_channels[] = { \
-       AD5764_CHANNEL(0, (_bits)), \
-       AD5764_CHANNEL(1, (_bits)), \
-       AD5764_CHANNEL(2, (_bits)), \
-       AD5764_CHANNEL(3, (_bits)), \
-};
-
-static DECLARE_AD5764_CHANNELS(ad5764, 16);
-static DECLARE_AD5764_CHANNELS(ad5744, 14);
-
-static const struct ad5764_chip_info ad5764_chip_infos[] = {
-       [ID_AD5744] = {
-               .int_vref = 0,
-               .channels = ad5744_channels,
-       },
-       [ID_AD5744R] = {
-               .int_vref = 5000000,
-               .channels = ad5744_channels,
-       },
-       [ID_AD5764] = {
-               .int_vref = 0,
-               .channels = ad5764_channels,
-       },
-       [ID_AD5764R] = {
-               .int_vref = 5000000,
-               .channels = ad5764_channels,
-       },
-};
-
-static int ad5764_write(struct iio_dev *indio_dev, unsigned int reg,
-       unsigned int val)
-{
-       struct ad5764_state *st = iio_priv(indio_dev);
-       int ret;
-
-       mutex_lock(&indio_dev->mlock);
-       st->data[0].d32 = cpu_to_be32((reg << 16) | val);
-
-       ret = spi_write(st->spi, &st->data[0].d8[1], 3);
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret;
-}
-
-static int ad5764_read(struct iio_dev *indio_dev, unsigned int reg,
-       unsigned int *val)
-{
-       struct ad5764_state *st = iio_priv(indio_dev);
-       struct spi_message m;
-       int ret;
-       struct spi_transfer t[] = {
-               {
-                       .tx_buf = &st->data[0].d8[1],
-                       .len = 3,
-                       .cs_change = 1,
-               }, {
-                       .rx_buf = &st->data[1].d8[1],
-                       .len = 3,
-               },
-       };
-
-       spi_message_init(&m);
-       spi_message_add_tail(&t[0], &m);
-       spi_message_add_tail(&t[1], &m);
-
-       mutex_lock(&indio_dev->mlock);
-
-       st->data[0].d32 = cpu_to_be32((1 << 23) | (reg << 16));
-
-       ret = spi_sync(st->spi, &m);
-       if (ret >= 0)
-               *val = be32_to_cpu(st->data[1].d32) & 0xffff;
-
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret;
-}
-
-static int ad5764_chan_info_to_reg(struct iio_chan_spec const *chan, long info)
-{
-       switch (info) {
-       case 0:
-               return AD5764_REG_DATA(chan->address);
-       case IIO_CHAN_INFO_CALIBBIAS:
-               return AD5764_REG_OFFSET(chan->address);
-       case IIO_CHAN_INFO_CALIBSCALE:
-               return AD5764_REG_FINE_GAIN(chan->address);
-       default:
-               break;
-       }
-
-       return 0;
-}
-
-static int ad5764_write_raw(struct iio_dev *indio_dev,
-       struct iio_chan_spec const *chan, int val, int val2, long info)
-{
-       const int max_val = (1 << chan->scan_type.realbits);
-       unsigned int reg;
-
-       switch (info) {
-       case IIO_CHAN_INFO_RAW:
-               if (val >= max_val || val < 0)
-                       return -EINVAL;
-               val <<= chan->scan_type.shift;
-               break;
-       case IIO_CHAN_INFO_CALIBBIAS:
-               if (val >= 128 || val < -128)
-                       return -EINVAL;
-               break;
-       case IIO_CHAN_INFO_CALIBSCALE:
-               if (val >= 32 || val < -32)
-                       return -EINVAL;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       reg = ad5764_chan_info_to_reg(chan, info);
-       return ad5764_write(indio_dev, reg, (u16)val);
-}
-
-static int ad5764_get_channel_vref(struct ad5764_state *st,
-       unsigned int channel)
-{
-       if (st->chip_info->int_vref)
-               return st->chip_info->int_vref;
-       else
-               return regulator_get_voltage(st->vref_reg[channel / 2].consumer);
-}
-
-static int ad5764_read_raw(struct iio_dev *indio_dev,
-       struct iio_chan_spec const *chan, int *val, int *val2, long info)
-{
-       struct ad5764_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
-       unsigned int reg;
-       int vref;
-       int ret;
-
-       switch (info) {
-       case IIO_CHAN_INFO_RAW:
-               reg = AD5764_REG_DATA(chan->address);
-               ret = ad5764_read(indio_dev, reg, val);
-               if (ret < 0)
-                       return ret;
-               *val >>= chan->scan_type.shift;
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_CALIBBIAS:
-               reg = AD5764_REG_OFFSET(chan->address);
-               ret = ad5764_read(indio_dev, reg, val);
-               if (ret < 0)
-                       return ret;
-               *val = sign_extend32(*val, 7);
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_CALIBSCALE:
-               reg = AD5764_REG_FINE_GAIN(chan->address);
-               ret = ad5764_read(indio_dev, reg, val);
-               if (ret < 0)
-                       return ret;
-               *val = sign_extend32(*val, 5);
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_SCALE:
-               /* vout = 4 * vref + ((dac_code / 65535) - 0.5) */
-               vref = ad5764_get_channel_vref(st, chan->channel);
-               if (vref < 0)
-                       return vref;
-
-               scale_uv = (vref * 4 * 100) >> chan->scan_type.realbits;
-               *val = scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
-       case IIO_CHAN_INFO_OFFSET:
-               *val = -(1 << chan->scan_type.realbits) / 2;
-               return IIO_VAL_INT;
-       }
-
-       return -EINVAL;
-}
-
-static const struct iio_info ad5764_info = {
-       .read_raw = ad5764_read_raw,
-       .write_raw = ad5764_write_raw,
-       .driver_module = THIS_MODULE,
-};
-
-static int __devinit ad5764_probe(struct spi_device *spi)
-{
-       enum ad5764_type type = spi_get_device_id(spi)->driver_data;
-       struct iio_dev *indio_dev;
-       struct ad5764_state *st;
-       int ret;
-
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               dev_err(&spi->dev, "Failed to allocate iio device\n");
-               return -ENOMEM;
-       }
-
-       st = iio_priv(indio_dev);
-       spi_set_drvdata(spi, indio_dev);
-
-       st->spi = spi;
-       st->chip_info = &ad5764_chip_infos[type];
-
-       indio_dev->dev.parent = &spi->dev;
-       indio_dev->name = spi_get_device_id(spi)->name;
-       indio_dev->info = &ad5764_info;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->num_channels = AD5764_NUM_CHANNELS;
-       indio_dev->channels = st->chip_info->channels;
-
-       if (st->chip_info->int_vref == 0) {
-               st->vref_reg[0].supply = "vrefAB";
-               st->vref_reg[1].supply = "vrefCD";
-
-               ret = regulator_bulk_get(&st->spi->dev,
-                       ARRAY_SIZE(st->vref_reg), st->vref_reg);
-               if (ret) {
-                       dev_err(&spi->dev, "Failed to request vref regulators: %d\n",
-                               ret);
-                       goto error_free;
-               }
-
-               ret = regulator_bulk_enable(ARRAY_SIZE(st->vref_reg),
-                       st->vref_reg);
-               if (ret) {
-                       dev_err(&spi->dev, "Failed to enable vref regulators: %d\n",
-                               ret);
-                       goto error_free_reg;
-               }
-       }
-
-       ret = iio_device_register(indio_dev);
-       if (ret) {
-               dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
-               goto error_disable_reg;
-       }
-
-       return 0;
-
-error_disable_reg:
-       if (st->chip_info->int_vref == 0)
-               regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
-error_free_reg:
-       if (st->chip_info->int_vref == 0)
-               regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg);
-error_free:
-       iio_device_free(indio_dev);
-
-       return ret;
-}
-
-static int __devexit ad5764_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-       struct ad5764_state *st = iio_priv(indio_dev);
-
-       iio_device_unregister(indio_dev);
-
-       if (st->chip_info->int_vref == 0) {
-               regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
-               regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg);
-       }
-
-       iio_device_free(indio_dev);
-
-       return 0;
-}
-
-static const struct spi_device_id ad5764_ids[] = {
-       { "ad5744", ID_AD5744 },
-       { "ad5744r", ID_AD5744R },
-       { "ad5764", ID_AD5764 },
-       { "ad5764r", ID_AD5764R },
-       { }
-};
-MODULE_DEVICE_TABLE(spi, ad5764_ids);
-
-static struct spi_driver ad5764_driver = {
-       .driver = {
-               .name = "ad5764",
-               .owner = THIS_MODULE,
-       },
-       .probe = ad5764_probe,
-       .remove = __devexit_p(ad5764_remove),
-       .id_table = ad5764_ids,
-};
-module_spi_driver(ad5764_driver);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("Analog Devices AD5744/AD5744R/AD5764/AD5764R DAC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c
deleted file mode 100644 (file)
index 5de28c2..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * AD5760, AD5780, AD5781, AD5790, AD5791 Voltage Output Digital to Analog
- * Converter
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#include <linux/interrupt.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/regulator/consumer.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#include "ad5791.h"
-
-#define AD5791_RES_MASK(x)             ((1 << (x)) - 1)
-#define AD5791_DAC_MASK                        AD5791_RES_MASK(20)
-#define AD5791_DAC_MSB                 (1 << 19)
-
-#define AD5791_CMD_READ                        (1 << 23)
-#define AD5791_CMD_WRITE               (0 << 23)
-#define AD5791_ADDR(addr)              ((addr) << 20)
-
-/* Registers */
-#define AD5791_ADDR_NOOP               0
-#define AD5791_ADDR_DAC0               1
-#define AD5791_ADDR_CTRL               2
-#define AD5791_ADDR_CLRCODE            3
-#define AD5791_ADDR_SW_CTRL            4
-
-/* Control Register */
-#define AD5791_CTRL_RBUF               (1 << 1)
-#define AD5791_CTRL_OPGND              (1 << 2)
-#define AD5791_CTRL_DACTRI             (1 << 3)
-#define AD5791_CTRL_BIN2SC             (1 << 4)
-#define AD5791_CTRL_SDODIS             (1 << 5)
-#define AD5761_CTRL_LINCOMP(x)         ((x) << 6)
-
-#define AD5791_LINCOMP_0_10            0
-#define AD5791_LINCOMP_10_12           1
-#define AD5791_LINCOMP_12_16           2
-#define AD5791_LINCOMP_16_19           3
-#define AD5791_LINCOMP_19_20           12
-
-#define AD5780_LINCOMP_0_10            0
-#define AD5780_LINCOMP_10_20           12
-
-/* Software Control Register */
-#define AD5791_SWCTRL_LDAC             (1 << 0)
-#define AD5791_SWCTRL_CLR              (1 << 1)
-#define AD5791_SWCTRL_RESET            (1 << 2)
-
-#define AD5791_DAC_PWRDN_6K            0
-#define AD5791_DAC_PWRDN_3STATE                1
-
-/**
- * struct ad5791_chip_info - chip specific information
- * @get_lin_comp:      function pointer to the device specific function
- */
-
-struct ad5791_chip_info {
-       int (*get_lin_comp)     (unsigned int span);
-};
-
-/**
- * struct ad5791_state - driver instance specific data
- * @us:                        spi_device
- * @reg_vdd:           positive supply regulator
- * @reg_vss:           negative supply regulator
- * @chip_info:         chip model specific constants
- * @vref_mv:           actual reference voltage used
- * @vref_neg_mv:       voltage of the negative supply
- * @pwr_down_mode      current power down mode
- */
-
-struct ad5791_state {
-       struct spi_device               *spi;
-       struct regulator                *reg_vdd;
-       struct regulator                *reg_vss;
-       const struct ad5791_chip_info   *chip_info;
-       unsigned short                  vref_mv;
-       unsigned int                    vref_neg_mv;
-       unsigned                        ctrl;
-       unsigned                        pwr_down_mode;
-       bool                            pwr_down;
-};
-
-/**
- * ad5791_supported_device_ids:
- */
-
-enum ad5791_supported_device_ids {
-       ID_AD5760,
-       ID_AD5780,
-       ID_AD5781,
-       ID_AD5791,
-};
-
-static int ad5791_spi_write(struct spi_device *spi, u8 addr, u32 val)
-{
-       union {
-               u32 d32;
-               u8 d8[4];
-       } data;
-
-       data.d32 = cpu_to_be32(AD5791_CMD_WRITE |
-                             AD5791_ADDR(addr) |
-                             (val & AD5791_DAC_MASK));
-
-       return spi_write(spi, &data.d8[1], 3);
-}
-
-static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val)
-{
-       union {
-               u32 d32;
-               u8 d8[4];
-       } data[3];
-       int ret;
-       struct spi_message msg;
-       struct spi_transfer xfers[] = {
-               {
-                       .tx_buf = &data[0].d8[1],
-                       .bits_per_word = 8,
-                       .len = 3,
-                       .cs_change = 1,
-               }, {
-                       .tx_buf = &data[1].d8[1],
-                       .rx_buf = &data[2].d8[1],
-                       .bits_per_word = 8,
-                       .len = 3,
-               },
-       };
-
-       data[0].d32 = cpu_to_be32(AD5791_CMD_READ |
-                             AD5791_ADDR(addr));
-       data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP));
-
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfers[0], &msg);
-       spi_message_add_tail(&xfers[1], &msg);
-       ret = spi_sync(spi, &msg);
-
-       *val = be32_to_cpu(data[2].d32);
-
-       return ret;
-}
-
-static const char * const ad5791_powerdown_modes[] = {
-       "6kohm_to_gnd",
-       "three_state",
-};
-
-static int ad5791_get_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan)
-{
-       struct ad5791_state *st = iio_priv(indio_dev);
-
-       return st->pwr_down_mode;
-}
-
-static int ad5791_set_powerdown_mode(struct iio_dev *indio_dev,
-       const struct iio_chan_spec *chan, unsigned int mode)
-{
-       struct ad5791_state *st = iio_priv(indio_dev);
-
-       st->pwr_down_mode = mode;
-
-       return 0;
-}
-
-static const struct iio_enum ad5791_powerdown_mode_enum = {
-       .items = ad5791_powerdown_modes,
-       .num_items = ARRAY_SIZE(ad5791_powerdown_modes),
-       .get = ad5791_get_powerdown_mode,
-       .set = ad5791_set_powerdown_mode,
-};
-
-static ssize_t ad5791_read_dac_powerdown(struct iio_dev *indio_dev,
-       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
-{
-       struct ad5791_state *st = iio_priv(indio_dev);
-
-       return sprintf(buf, "%d\n", st->pwr_down);
-}
-
-static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev,
-        uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
-        size_t len)
-{
-       bool pwr_down;
-       int ret;
-       struct ad5791_state *st = iio_priv(indio_dev);
-
-       ret = strtobool(buf, &pwr_down);
-       if (ret)
-               return ret;
-
-       if (!pwr_down) {
-               st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
-       } else {
-               if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K)
-                       st->ctrl |= AD5791_CTRL_OPGND;
-               else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE)
-                       st->ctrl |= AD5791_CTRL_DACTRI;
-       }
-       st->pwr_down = pwr_down;
-
-       ret = ad5791_spi_write(st->spi, AD5791_ADDR_CTRL, st->ctrl);
-
-       return ret ? ret : len;
-}
-
-static int ad5791_get_lin_comp(unsigned int span)
-{
-       if (span <= 10000)
-               return AD5791_LINCOMP_0_10;
-       else if (span <= 12000)
-               return AD5791_LINCOMP_10_12;
-       else if (span <= 16000)
-               return AD5791_LINCOMP_12_16;
-       else if (span <= 19000)
-               return AD5791_LINCOMP_16_19;
-       else
-               return AD5791_LINCOMP_19_20;
-}
-
-static int ad5780_get_lin_comp(unsigned int span)
-{
-       if (span <= 10000)
-               return AD5780_LINCOMP_0_10;
-       else
-               return AD5780_LINCOMP_10_20;
-}
-static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
-       [ID_AD5760] = {
-               .get_lin_comp = ad5780_get_lin_comp,
-       },
-       [ID_AD5780] = {
-               .get_lin_comp = ad5780_get_lin_comp,
-       },
-       [ID_AD5781] = {
-               .get_lin_comp = ad5791_get_lin_comp,
-       },
-       [ID_AD5791] = {
-               .get_lin_comp = ad5791_get_lin_comp,
-       },
-};
-
-static int ad5791_read_raw(struct iio_dev *indio_dev,
-                          struct iio_chan_spec const *chan,
-                          int *val,
-                          int *val2,
-                          long m)
-{
-       struct ad5791_state *st = iio_priv(indio_dev);
-       u64 val64;
-       int ret;
-
-       switch (m) {
-       case IIO_CHAN_INFO_RAW:
-               ret = ad5791_spi_read(st->spi, chan->address, val);
-               if (ret)
-                       return ret;
-               *val &= AD5791_DAC_MASK;
-               *val >>= chan->scan_type.shift;
-               return IIO_VAL_INT;
-       case IIO_CHAN_INFO_SCALE:
-               *val = 0;
-               *val2 = (((u64)st->vref_mv) * 1000000ULL) >> chan->scan_type.realbits;
-               return IIO_VAL_INT_PLUS_MICRO;
-       case IIO_CHAN_INFO_OFFSET:
-               val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
-               do_div(val64, st->vref_mv);
-               *val = -val64;
-               return IIO_VAL_INT;
-       default:
-               return -EINVAL;
-       }
-
-};
-
-static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
-       {
-               .name = "powerdown",
-               .shared = true,
-               .read = ad5791_read_dac_powerdown,
-               .write = ad5791_write_dac_powerdown,
-       },
-       IIO_ENUM("powerdown_mode", true, &ad5791_powerdown_mode_enum),
-       IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
-       { },
-};
-
-#define AD5791_CHAN(bits, shift) {                     \
-       .type = IIO_VOLTAGE,                            \
-       .output = 1,                                    \
-       .indexed = 1,                                   \
-       .address = AD5791_ADDR_DAC0,                    \
-       .channel = 0,                                   \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |   \
-               IIO_CHAN_INFO_SCALE_SHARED_BIT |        \
-               IIO_CHAN_INFO_OFFSET_SHARED_BIT,        \
-       .scan_type = IIO_ST('u', bits, 24, shift),      \
-       .ext_info = ad5791_ext_info,                    \
-}
-
-static const struct iio_chan_spec ad5791_channels[] = {
-       [ID_AD5760] = AD5791_CHAN(16, 4),
-       [ID_AD5780] = AD5791_CHAN(18, 2),
-       [ID_AD5781] = AD5791_CHAN(18, 2),
-       [ID_AD5791] = AD5791_CHAN(20, 0)
-};
-
-static int ad5791_write_raw(struct iio_dev *indio_dev,
-                           struct iio_chan_spec const *chan,
-                           int val,
-                           int val2,
-                           long mask)
-{
-       struct ad5791_state *st = iio_priv(indio_dev);
-
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW:
-               val &= AD5791_RES_MASK(chan->scan_type.realbits);
-               val <<= chan->scan_type.shift;
-
-               return ad5791_spi_write(st->spi, chan->address, val);
-
-       default:
-               return -EINVAL;
-       }
-}
-
-static const struct iio_info ad5791_info = {
-       .read_raw = &ad5791_read_raw,
-       .write_raw = &ad5791_write_raw,
-       .driver_module = THIS_MODULE,
-};
-
-static int __devinit ad5791_probe(struct spi_device *spi)
-{
-       struct ad5791_platform_data *pdata = spi->dev.platform_data;
-       struct iio_dev *indio_dev;
-       struct ad5791_state *st;
-       int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
-
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
-       st = iio_priv(indio_dev);
-       st->reg_vdd = regulator_get(&spi->dev, "vdd");
-       if (!IS_ERR(st->reg_vdd)) {
-               ret = regulator_enable(st->reg_vdd);
-               if (ret)
-                       goto error_put_reg_pos;
-
-               pos_voltage_uv = regulator_get_voltage(st->reg_vdd);
-       }
-
-       st->reg_vss = regulator_get(&spi->dev, "vss");
-       if (!IS_ERR(st->reg_vss)) {
-               ret = regulator_enable(st->reg_vss);
-               if (ret)
-                       goto error_put_reg_neg;
-
-               neg_voltage_uv = regulator_get_voltage(st->reg_vss);
-       }
-
-       st->pwr_down = true;
-       st->spi = spi;
-
-       if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) {
-               st->vref_mv = (pos_voltage_uv + neg_voltage_uv) / 1000;
-               st->vref_neg_mv = neg_voltage_uv / 1000;
-       } else if (pdata) {
-               st->vref_mv = pdata->vref_pos_mv + pdata->vref_neg_mv;
-               st->vref_neg_mv = pdata->vref_neg_mv;
-       } else {
-               dev_warn(&spi->dev, "reference voltage unspecified\n");
-       }
-
-       ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
-       if (ret)
-               goto error_disable_reg_neg;
-
-       st->chip_info = &ad5791_chip_info_tbl[spi_get_device_id(spi)
-                                             ->driver_data];
-
-
-       st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv))
-                 | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) |
-                 AD5791_CTRL_BIN2SC;
-
-       ret = ad5791_spi_write(spi, AD5791_ADDR_CTRL, st->ctrl |
-               AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
-       if (ret)
-               goto error_disable_reg_neg;
-
-       spi_set_drvdata(spi, indio_dev);
-       indio_dev->dev.parent = &spi->dev;
-       indio_dev->info = &ad5791_info;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->channels
-               = &ad5791_channels[spi_get_device_id(spi)->driver_data];
-       indio_dev->num_channels = 1;
-       indio_dev->name = spi_get_device_id(st->spi)->name;
-       ret = iio_device_register(indio_dev);
-       if (ret)
-               goto error_disable_reg_neg;
-
-       return 0;
-
-error_disable_reg_neg:
-       if (!IS_ERR(st->reg_vss))
-               regulator_disable(st->reg_vss);
-error_put_reg_neg:
-       if (!IS_ERR(st->reg_vss))
-               regulator_put(st->reg_vss);
-
-       if (!IS_ERR(st->reg_vdd))
-               regulator_disable(st->reg_vdd);
-error_put_reg_pos:
-       if (!IS_ERR(st->reg_vdd))
-               regulator_put(st->reg_vdd);
-       iio_device_free(indio_dev);
-error_ret:
-
-       return ret;
-}
-
-static int __devexit ad5791_remove(struct spi_device *spi)
-{
-       struct iio_dev *indio_dev = spi_get_drvdata(spi);
-       struct ad5791_state *st = iio_priv(indio_dev);
-
-       iio_device_unregister(indio_dev);
-       if (!IS_ERR(st->reg_vdd)) {
-               regulator_disable(st->reg_vdd);
-               regulator_put(st->reg_vdd);
-       }
-
-       if (!IS_ERR(st->reg_vss)) {
-               regulator_disable(st->reg_vss);
-               regulator_put(st->reg_vss);
-       }
-       iio_device_free(indio_dev);
-
-       return 0;
-}
-
-static const struct spi_device_id ad5791_id[] = {
-       {"ad5760", ID_AD5760},
-       {"ad5780", ID_AD5780},
-       {"ad5781", ID_AD5781},
-       {"ad5790", ID_AD5791},
-       {"ad5791", ID_AD5791},
-       {}
-};
-MODULE_DEVICE_TABLE(spi, ad5791_id);
-
-static struct spi_driver ad5791_driver = {
-       .driver = {
-                  .name = "ad5791",
-                  .owner = THIS_MODULE,
-                  },
-       .probe = ad5791_probe,
-       .remove = __devexit_p(ad5791_remove),
-       .id_table = ad5791_id,
-};
-module_spi_driver(ad5791_driver);
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5791.h b/drivers/staging/iio/dac/ad5791.h
deleted file mode 100644 (file)
index 87a6c92..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * AD5791 SPI DAC driver
- *
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- */
-
-#ifndef SPI_AD5791_H_
-#define SPI_AD5791_H_
-
-/*
- * TODO: struct ad5791_platform_data needs to go into include/linux/iio
- */
-
-/**
- * struct ad5791_platform_data - platform specific information
- * @vref_pos_mv:       Vdd Positive Analog Supply Volatge (mV)
- * @vref_neg_mv:       Vdd Negative Analog Supply Volatge (mV)
- * @use_rbuf_gain2:    ext. amplifier connected in gain of two configuration
- */
-
-struct ad5791_platform_data {
-       u16                             vref_pos_mv;
-       u16                             vref_neg_mv;
-       bool                            use_rbuf_gain2;
-};
-
-#endif /* SPI_AD5791_H_ */
diff --git a/drivers/staging/iio/dac/max517.c b/drivers/staging/iio/dac/max517.c
deleted file mode 100644 (file)
index 403e06f..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- *  max517.c - Support for Maxim MAX517, MAX518 and MAX519
- *
- *  Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#include "max517.h"
-
-#define MAX517_DRV_NAME        "max517"
-
-/* Commands */
-#define COMMAND_CHANNEL0       0x00
-#define COMMAND_CHANNEL1       0x01 /* for MAX518 and MAX519 */
-#define COMMAND_PD             0x08 /* Power Down */
-
-enum max517_device_ids {
-       ID_MAX517,
-       ID_MAX518,
-       ID_MAX519,
-};
-
-struct max517_data {
-       struct iio_dev          *indio_dev;
-       struct i2c_client       *client;
-       unsigned short          vref_mv[2];
-};
-
-/*
- * channel: bit 0: channel 1
- *          bit 1: channel 2
- * (this way, it's possible to set both channels at once)
- */
-static int max517_set_value(struct iio_dev *indio_dev,
-       long val, int channel)
-{
-       struct max517_data *data = iio_priv(indio_dev);
-       struct i2c_client *client = data->client;
-       u8 outbuf[2];
-       int res;
-
-       if (val < 0 || val > 255)
-               return -EINVAL;
-
-       outbuf[0] = channel;
-       outbuf[1] = val;
-
-       res = i2c_master_send(client, outbuf, 2);
-       if (res < 0)
-               return res;
-       else if (res != 2)
-               return -EIO;
-       else
-               return 0;
-}
-
-static int max517_read_raw(struct iio_dev *indio_dev,
-                          struct iio_chan_spec const *chan,
-                          int *val,
-                          int *val2,
-                          long m)
-{
-       struct max517_data *data = iio_priv(indio_dev);
-       unsigned int scale_uv;
-
-       switch (m) {
-       case IIO_CHAN_INFO_SCALE:
-               /* Corresponds to Vref / 2^(bits) */
-               scale_uv = (data->vref_mv[chan->channel] * 1000) >> 8;
-               *val =  scale_uv / 1000000;
-               *val2 = scale_uv % 1000000;
-               return IIO_VAL_INT_PLUS_MICRO;
-       default:
-               break;
-       }
-       return -EINVAL;
-}
-
-static int max517_write_raw(struct iio_dev *indio_dev,
-       struct iio_chan_spec const *chan, int val, int val2, long mask)
-{
-       int ret;
-
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW:
-               ret = max517_set_value(indio_dev, val, chan->channel);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int max517_suspend(struct device *dev)
-{
-       u8 outbuf = COMMAND_PD;
-
-       return i2c_master_send(to_i2c_client(dev), &outbuf, 1);
-}
-
-static int max517_resume(struct device *dev)
-{
-       u8 outbuf = 0;
-
-       return i2c_master_send(to_i2c_client(dev), &outbuf, 1);
-}
-
-static SIMPLE_DEV_PM_OPS(max517_pm_ops, max517_suspend, max517_resume);
-#define MAX517_PM_OPS (&max517_pm_ops)
-#else
-#define MAX517_PM_OPS NULL
-#endif
-
-static const struct iio_info max517_info = {
-       .read_raw = max517_read_raw,
-       .write_raw = max517_write_raw,
-       .driver_module = THIS_MODULE,
-};
-
-#define MAX517_CHANNEL(chan) {                         \
-       .type = IIO_VOLTAGE,                            \
-       .indexed = 1,                                   \
-       .output = 1,                                    \
-       .channel = (chan),                              \
-       .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |   \
-       IIO_CHAN_INFO_SCALE_SEPARATE_BIT,               \
-       .scan_type = IIO_ST('u', 8, 8, 0),              \
-}
-
-static const struct iio_chan_spec max517_channels[] = {
-       MAX517_CHANNEL(0),
-       MAX517_CHANNEL(1)
-};
-
-static int max517_probe(struct i2c_client *client,
-                       const struct i2c_device_id *id)
-{
-       struct max517_data *data;
-       struct iio_dev *indio_dev;
-       struct max517_platform_data *platform_data = client->dev.platform_data;
-       int err;
-
-       indio_dev = iio_device_alloc(sizeof(*data));
-       if (indio_dev == NULL) {
-               err = -ENOMEM;
-               goto exit;
-       }
-       data = iio_priv(indio_dev);
-       i2c_set_clientdata(client, indio_dev);
-       data->client = client;
-
-       /* establish that the iio_dev is a child of the i2c device */
-       indio_dev->dev.parent = &client->dev;
-
-       /* reduced channel set for MAX517 */
-       if (id->driver_data == ID_MAX517)
-               indio_dev->num_channels = 1;
-       else
-               indio_dev->num_channels = 2;
-       indio_dev->channels = max517_channels;
-       indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->info = &max517_info;
-
-       /*
-        * Reference voltage on MAX518 and default is 5V, else take vref_mv
-        * from platform_data
-        */
-       if (id->driver_data == ID_MAX518 || !platform_data) {
-               data->vref_mv[0] = data->vref_mv[1] = 5000; /* mV */
-       } else {
-               data->vref_mv[0] = platform_data->vref_mv[0];
-               data->vref_mv[1] = platform_data->vref_mv[1];
-       }
-
-       err = iio_device_register(indio_dev);
-       if (err)
-               goto exit_free_device;
-
-       dev_info(&client->dev, "DAC registered\n");
-
-       return 0;
-
-exit_free_device:
-       iio_device_free(indio_dev);
-exit:
-       return err;
-}
-
-static int max517_remove(struct i2c_client *client)
-{
-       iio_device_unregister(i2c_get_clientdata(client));
-       iio_device_free(i2c_get_clientdata(client));
-
-       return 0;
-}
-
-static const struct i2c_device_id max517_id[] = {
-       { "max517", ID_MAX517 },
-       { "max518", ID_MAX518 },
-       { "max519", ID_MAX519 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, max517_id);
-
-static struct i2c_driver max517_driver = {
-       .driver = {
-               .name   = MAX517_DRV_NAME,
-               .pm             = MAX517_PM_OPS,
-       },
-       .probe          = max517_probe,
-       .remove         = max517_remove,
-       .id_table       = max517_id,
-};
-module_i2c_driver(max517_driver);
-
-MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
-MODULE_DESCRIPTION("MAX517/MAX518/MAX519 8-bit DAC");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/dac/max517.h b/drivers/staging/iio/dac/max517.h
deleted file mode 100644 (file)
index 8106cf2..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * MAX517 DAC driver
- *
- * Copyright 2011 Roland Stigge <stigge@antcom.de>
- *
- * Licensed under the GPL-2 or later.
- */
-#ifndef IIO_DAC_MAX517_H_
-#define IIO_DAC_MAX517_H_
-
-/*
- * TODO: struct max517_platform_data needs to go into include/linux/iio
- */
-
-struct max517_platform_data {
-       u16                             vref_mv[2];
-};
-
-#endif /* IIO_DAC_MAX517_H_ */
diff --git a/include/linux/iio/dac/ad5421.h b/include/linux/iio/dac/ad5421.h
new file mode 100644 (file)
index 0000000..8fd8f05
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __IIO_DAC_AD5421_H__
+#define __IIO_DAC_AD5421_H__
+
+/**
+ * enum ad5421_current_range - Current range the AD5421 is configured for.
+ * @AD5421_CURRENT_RANGE_4mA_20mA: 4 mA to 20 mA (RANGE1,0 pins = 00)
+ * @AD5421_CURRENT_RANGE_3mA8_21mA: 3.8 mA to 21 mA (RANGE1,0 pins = x1)
+ * @AD5421_CURRENT_RANGE_3mA2_24mA: 3.2 mA to 24 mA (RANGE1,0 pins = 10)
+ */
+
+enum ad5421_current_range {
+       AD5421_CURRENT_RANGE_4mA_20mA,
+       AD5421_CURRENT_RANGE_3mA8_21mA,
+       AD5421_CURRENT_RANGE_3mA2_24mA,
+};
+
+/**
+ * struct ad5421_platform_data - AD5421 DAC driver platform data
+ * @external_vref: whether an external reference voltage is used or not
+ * @current_range: Current range the AD5421 is configured for
+ */
+
+struct ad5421_platform_data {
+       bool external_vref;
+       enum ad5421_current_range current_range;
+};
+
+#endif
diff --git a/include/linux/iio/dac/ad5504.h b/include/linux/iio/dac/ad5504.h
new file mode 100644 (file)
index 0000000..4389537
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * AD5504 SPI DAC driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef SPI_AD5504_H_
+#define SPI_AD5504_H_
+
+struct ad5504_platform_data {
+       u16                             vref_mv;
+};
+
+#endif /* SPI_AD5504_H_ */
diff --git a/include/linux/iio/dac/ad5791.h b/include/linux/iio/dac/ad5791.h
new file mode 100644 (file)
index 0000000..45ee281
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * AD5791 SPI DAC driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef SPI_AD5791_H_
+#define SPI_AD5791_H_
+
+/**
+ * struct ad5791_platform_data - platform specific information
+ * @vref_pos_mv:       Vdd Positive Analog Supply Volatge (mV)
+ * @vref_neg_mv:       Vdd Negative Analog Supply Volatge (mV)
+ * @use_rbuf_gain2:    ext. amplifier connected in gain of two configuration
+ */
+
+struct ad5791_platform_data {
+       u16                             vref_pos_mv;
+       u16                             vref_neg_mv;
+       bool                            use_rbuf_gain2;
+};
+
+#endif /* SPI_AD5791_H_ */
diff --git a/include/linux/iio/dac/max517.h b/include/linux/iio/dac/max517.h
new file mode 100644 (file)
index 0000000..f6d1d25
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * MAX517 DAC driver
+ *
+ * Copyright 2011 Roland Stigge <stigge@antcom.de>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+#ifndef IIO_DAC_MAX517_H_
+#define IIO_DAC_MAX517_H_
+
+struct max517_platform_data {
+       u16                             vref_mv[2];
+};
+
+#endif /* IIO_DAC_MAX517_H_ */