diff options
| author | Lars-Peter Clausen <lars@metafoo.de> | 2012-10-16 12:29:00 -0400 |
|---|---|---|
| committer | Jonathan Cameron <jic23@kernel.org> | 2012-10-19 13:46:51 -0400 |
| commit | 8341dc04dfb33fbae71727ae648e20c51abc40e3 (patch) | |
| tree | e28437da9541d0f18e79ed99ea747b61b1feb36c | |
| parent | 103d9fb907058e4eb052f4f7302d1b07eb6a7792 (diff) | |
iio:dac: Add support for the ad5449
This patch adds support for the AD5415, AD5426, AD5429, AD5432, AD5439, AD5443
and AD5449 single and dual channel DACs.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
| -rw-r--r-- | drivers/iio/dac/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/iio/dac/Makefile | 1 | ||||
| -rw-r--r-- | drivers/iio/dac/ad5449.c | 375 | ||||
| -rw-r--r-- | include/linux/platform_data/ad5449.h | 40 |
4 files changed, 426 insertions, 0 deletions
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index b1c0ee5294ca..f68756e6dd62 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig | |||
| @@ -67,6 +67,16 @@ config AD5446 | |||
| 67 | To compile this driver as a module, choose M here: the | 67 | To compile this driver as a module, choose M here: the |
| 68 | module will be called ad5446. | 68 | module will be called ad5446. |
| 69 | 69 | ||
| 70 | config AD5449 | ||
| 71 | tristate "Analog Device AD5449 and similar DACs driver" | ||
| 72 | depends on SPI_MASTER | ||
| 73 | help | ||
| 74 | Say yes here to build support for Analog Devices AD5415, AD5426, AD5429, | ||
| 75 | AD5432, AD5439, AD5443, AD5449 Digital to Analog Converters. | ||
| 76 | |||
| 77 | To compile this driver as a module, choose M here: the | ||
| 78 | module will be called ad5449. | ||
| 79 | |||
| 70 | config AD5504 | 80 | config AD5504 |
| 71 | tristate "Analog Devices AD5504/AD5501 DAC SPI driver" | 81 | tristate "Analog Devices AD5504/AD5501 DAC SPI driver" |
| 72 | depends on SPI | 82 | depends on SPI |
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index c0d333b23ba3..5b528ebb3343 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile | |||
| @@ -9,6 +9,7 @@ obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o | |||
| 9 | obj-$(CONFIG_AD5064) += ad5064.o | 9 | obj-$(CONFIG_AD5064) += ad5064.o |
| 10 | obj-$(CONFIG_AD5504) += ad5504.o | 10 | obj-$(CONFIG_AD5504) += ad5504.o |
| 11 | obj-$(CONFIG_AD5446) += ad5446.o | 11 | obj-$(CONFIG_AD5446) += ad5446.o |
| 12 | obj-$(CONFIG_AD5449) += ad5449.o | ||
| 12 | obj-$(CONFIG_AD5755) += ad5755.o | 13 | obj-$(CONFIG_AD5755) += ad5755.o |
| 13 | obj-$(CONFIG_AD5764) += ad5764.o | 14 | obj-$(CONFIG_AD5764) += ad5764.o |
| 14 | obj-$(CONFIG_AD5791) += ad5791.o | 15 | obj-$(CONFIG_AD5791) += ad5791.o |
diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c new file mode 100644 index 000000000000..5b43030fe6e3 --- /dev/null +++ b/drivers/iio/dac/ad5449.c | |||
| @@ -0,0 +1,375 @@ | |||
| 1 | /* | ||
| 2 | * AD5415, AD5426, AD5429, AD5432, AD5439, AD5443, AD5449 Digital to Analog | ||
| 3 | * Converter driver. | ||
| 4 | * | ||
| 5 | * Copyright 2012 Analog Devices Inc. | ||
| 6 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
| 7 | * | ||
| 8 | * Licensed under the GPL-2. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/device.h> | ||
| 12 | #include <linux/err.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/spi/spi.h> | ||
| 16 | #include <linux/slab.h> | ||
| 17 | #include <linux/sysfs.h> | ||
| 18 | #include <linux/regulator/consumer.h> | ||
| 19 | #include <asm/unaligned.h> | ||
| 20 | |||
| 21 | #include <linux/iio/iio.h> | ||
| 22 | #include <linux/iio/sysfs.h> | ||
| 23 | |||
| 24 | #include <linux/platform_data/ad5449.h> | ||
| 25 | |||
| 26 | #define AD5449_MAX_CHANNELS 2 | ||
| 27 | #define AD5449_MAX_VREFS 2 | ||
| 28 | |||
| 29 | #define AD5449_CMD_NOOP 0x0 | ||
| 30 | #define AD5449_CMD_LOAD_AND_UPDATE(x) (0x1 + (x) * 3) | ||
| 31 | #define AD5449_CMD_READ(x) (0x2 + (x) * 3) | ||
| 32 | #define AD5449_CMD_LOAD(x) (0x3 + (x) * 3) | ||
| 33 | #define AD5449_CMD_CTRL 13 | ||
| 34 | |||
| 35 | #define AD5449_CTRL_SDO_OFFSET 10 | ||
| 36 | #define AD5449_CTRL_DAISY_CHAIN BIT(9) | ||
| 37 | #define AD5449_CTRL_HCLR_TO_MIDSCALE BIT(8) | ||
| 38 | #define AD5449_CTRL_SAMPLE_RISING BIT(7) | ||
| 39 | |||
| 40 | /** | ||
| 41 | * struct ad5449_chip_info - chip specific information | ||
| 42 | * @channels: Channel specification | ||
| 43 | * @num_channels: Number of channels | ||
| 44 | * @has_ctrl: Chip has a control register | ||
| 45 | */ | ||
| 46 | struct ad5449_chip_info { | ||
| 47 | const struct iio_chan_spec *channels; | ||
| 48 | unsigned int num_channels; | ||
| 49 | bool has_ctrl; | ||
| 50 | }; | ||
| 51 | |||
| 52 | /** | ||
| 53 | * struct ad5449 - driver instance specific data | ||
| 54 | * @spi: the SPI device for this driver instance | ||
| 55 | * @chip_info: chip model specific constants, available modes etc | ||
| 56 | * @vref_reg: vref supply regulators | ||
| 57 | * @has_sdo: whether the SDO line is connected | ||
| 58 | * @dac_cache: Cache for the DAC values | ||
| 59 | * @data: spi transfer buffers | ||
| 60 | */ | ||
| 61 | struct ad5449 { | ||
| 62 | struct spi_device *spi; | ||
| 63 | const struct ad5449_chip_info *chip_info; | ||
| 64 | struct regulator_bulk_data vref_reg[AD5449_MAX_VREFS]; | ||
| 65 | |||
| 66 | bool has_sdo; | ||
| 67 | uint16_t dac_cache[AD5449_MAX_CHANNELS]; | ||
| 68 | |||
| 69 | /* | ||
| 70 | * DMA (thus cache coherency maintenance) requires the | ||
| 71 | * transfer buffers to live in their own cache lines. | ||
| 72 | */ | ||
| 73 | __be16 data[2] ____cacheline_aligned; | ||
| 74 | }; | ||
| 75 | |||
| 76 | enum ad5449_type { | ||
| 77 | ID_AD5426, | ||
| 78 | ID_AD5429, | ||
| 79 | ID_AD5432, | ||
| 80 | ID_AD5439, | ||
| 81 | ID_AD5443, | ||
| 82 | ID_AD5449, | ||
| 83 | }; | ||
| 84 | |||
| 85 | static int ad5449_write(struct iio_dev *indio_dev, unsigned int addr, | ||
| 86 | unsigned int val) | ||
| 87 | { | ||
| 88 | struct ad5449 *st = iio_priv(indio_dev); | ||
| 89 | int ret; | ||
| 90 | |||
| 91 | mutex_lock(&indio_dev->mlock); | ||
| 92 | st->data[0] = cpu_to_be16((addr << 12) | val); | ||
| 93 | ret = spi_write(st->spi, st->data, 2); | ||
| 94 | mutex_unlock(&indio_dev->mlock); | ||
| 95 | |||
| 96 | return ret; | ||
| 97 | } | ||
| 98 | |||
| 99 | static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr, | ||
| 100 | unsigned int *val) | ||
| 101 | { | ||
| 102 | struct ad5449 *st = iio_priv(indio_dev); | ||
| 103 | int ret; | ||
| 104 | struct spi_message msg; | ||
| 105 | struct spi_transfer t[] = { | ||
| 106 | { | ||
| 107 | .tx_buf = &st->data[0], | ||
| 108 | .len = 2, | ||
| 109 | .cs_change = 1, | ||
| 110 | }, { | ||
| 111 | .tx_buf = &st->data[1], | ||
| 112 | .rx_buf = &st->data[1], | ||
| 113 | .len = 2, | ||
| 114 | }, | ||
| 115 | }; | ||
| 116 | |||
| 117 | spi_message_init(&msg); | ||
| 118 | spi_message_add_tail(&t[0], &msg); | ||
| 119 | spi_message_add_tail(&t[1], &msg); | ||
| 120 | |||
| 121 | mutex_lock(&indio_dev->mlock); | ||
| 122 | st->data[0] = cpu_to_be16(addr << 12); | ||
| 123 | st->data[1] = cpu_to_be16(AD5449_CMD_NOOP); | ||
| 124 | |||
| 125 | ret = spi_sync(st->spi, &msg); | ||
| 126 | if (ret < 0) | ||
| 127 | return ret; | ||
| 128 | |||
| 129 | *val = be16_to_cpu(st->data[1]); | ||
| 130 | mutex_unlock(&indio_dev->mlock); | ||
| 131 | |||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | static int ad5449_read_raw(struct iio_dev *indio_dev, | ||
| 136 | struct iio_chan_spec const *chan, int *val, int *val2, long info) | ||
| 137 | { | ||
| 138 | struct ad5449 *st = iio_priv(indio_dev); | ||
| 139 | struct regulator_bulk_data *reg; | ||
| 140 | int scale_uv; | ||
| 141 | int ret; | ||
| 142 | |||
| 143 | switch (info) { | ||
| 144 | case IIO_CHAN_INFO_RAW: | ||
| 145 | if (st->has_sdo) { | ||
| 146 | ret = ad5449_read(indio_dev, | ||
| 147 | AD5449_CMD_READ(chan->address), val); | ||
| 148 | if (ret) | ||
| 149 | return ret; | ||
| 150 | *val &= 0xfff; | ||
| 151 | } else { | ||
| 152 | *val = st->dac_cache[chan->address]; | ||
| 153 | } | ||
| 154 | |||
| 155 | return IIO_VAL_INT; | ||
| 156 | case IIO_CHAN_INFO_SCALE: | ||
| 157 | reg = &st->vref_reg[chan->channel]; | ||
| 158 | scale_uv = regulator_get_voltage(reg->consumer); | ||
| 159 | if (scale_uv < 0) | ||
| 160 | return scale_uv; | ||
| 161 | |||
| 162 | *val = scale_uv / 1000; | ||
