aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2012-10-16 12:29:00 -0400
committerJonathan Cameron <jic23@kernel.org>2012-10-19 13:46:51 -0400
commit8341dc04dfb33fbae71727ae648e20c51abc40e3 (patch)
treee28437da9541d0f18e79ed99ea747b61b1feb36c /drivers/iio
parent103d9fb907058e4eb052f4f7302d1b07eb6a7792 (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>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/dac/Kconfig10
-rw-r--r--drivers/iio/dac/Makefile1
-rw-r--r--drivers/iio/dac/ad5449.c375
3 files changed, 386 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
70config 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
70config AD5504 80config 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
9obj-$(CONFIG_AD5064) += ad5064.o 9obj-$(CONFIG_AD5064) += ad5064.o
10obj-$(CONFIG_AD5504) += ad5504.o 10obj-$(CONFIG_AD5504) += ad5504.o
11obj-$(CONFIG_AD5446) += ad5446.o 11obj-$(CONFIG_AD5446) += ad5446.o
12obj-$(CONFIG_AD5449) += ad5449.o
12obj-$(CONFIG_AD5755) += ad5755.o 13obj-$(CONFIG_AD5755) += ad5755.o
13obj-$(CONFIG_AD5764) += ad5764.o 14obj-$(CONFIG_AD5764) += ad5764.o
14obj-$(CONFIG_AD5791) += ad5791.o 15obj-$(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 */
46struct 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 */
61struct 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
76enum ad5449_type {
77 ID_AD5426,
78 ID_AD5429,
79 ID_AD5432,
80 ID_AD5439,
81 ID_AD5443,
82 ID_AD5449,
83};
84
85static 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
99static 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
135static 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;
163 *val2 = chan->scan_type.realbits;
164
165 return IIO_VAL_FRACTIONAL_LOG2;
166 default:
167 break;
168 }
169
170 return -EINVAL;
171}
172
173static int ad5449_write_raw(struct iio_dev *indio_dev,
174 struct iio_chan_spec const *chan, int val, int val2, long info)
175{
176 struct ad5449 *st = iio_priv(indio_dev);
177 int ret;
178
179 switch (info) {
180 case IIO_CHAN_INFO_RAW:
181 if (val < 0 || val >= (1 << chan->scan_type.realbits))
182 return -EINVAL;
183
184 ret = ad5449_write(indio_dev,
185 AD5449_CMD_LOAD_AND_UPDATE(chan->address),
186 val << chan->scan_type.shift);
187 if (ret == 0)
188 st->dac_cache[chan->address] = val;
189 break;
190 default:
191 ret = -EINVAL;
192 }
193
194 return ret;
195}
196
197static const struct iio_info ad5449_info = {
198 .read_raw = ad5449_read_raw,
199 .write_raw = ad5449_write_raw,
200 .driver_module = THIS_MODULE,
201};
202
203#define AD5449_CHANNEL(chan, bits) { \
204 .type = IIO_VOLTAGE, \
205 .indexed = 1, \
206 .output = 1, \
207 .channel = (chan), \
208 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
209 IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
210 .address = (chan), \
211 .scan_type = IIO_ST('u', (bits), 16, 12 - (bits)), \
212}
213
214#define DECLARE_AD5449_CHANNELS(name, bits) \
215const struct iio_chan_spec name[] = { \
216 AD5449_CHANNEL(0, bits), \
217 AD5449_CHANNEL(1, bits), \
218}
219
220static DECLARE_AD5449_CHANNELS(ad5429_channels, 8);
221static DECLARE_AD5449_CHANNELS(ad5439_channels, 10);
222static DECLARE_AD5449_CHANNELS(ad5449_channels, 12);
223
224static const struct ad5449_chip_info ad5449_chip_info[] = {
225 [ID_AD5426] = {
226 .channels = ad5429_channels,
227 .num_channels = 1,
228 .has_ctrl = false,
229 },
230 [ID_AD5429] = {
231 .channels = ad5429_channels,
232 .num_channels = 2,
233 .has_ctrl = true,
234 },
235 [ID_AD5432] = {
236 .channels = ad5439_channels,
237 .num_channels = 1,
238 .has_ctrl = false,
239 },
240 [ID_AD5439] = {
241 .channels = ad5439_channels,
242 .num_channels = 2,
243 .has_ctrl = true,
244 },
245 [ID_AD5443] = {
246 .channels = ad5449_channels,
247 .num_channels = 1,
248 .has_ctrl = false,
249 },
250 [ID_AD5449] = {
251 .channels = ad5449_channels,
252 .num_channels = 2,
253 .has_ctrl = true,
254 },
255};
256
257static const char *ad5449_vref_name(struct ad5449 *st, int n)
258{
259 if (st->chip_info->num_channels == 1)
260 return "VREF";
261
262 if (n == 0)
263 return "VREFA";
264 else
265 return "VREFB";
266}
267
268static int __devinit ad5449_spi_probe(struct spi_device *spi)
269{
270 struct ad5449_platform_data *pdata = spi->dev.platform_data;
271 const struct spi_device_id *id = spi_get_device_id(spi);
272 struct iio_dev *indio_dev;
273 struct ad5449 *st;
274 unsigned int i;
275 int ret;
276
277 indio_dev = iio_device_alloc(sizeof(*st));
278 if (indio_dev == NULL)
279 return -ENOMEM;
280
281 st = iio_priv(indio_dev);
282 spi_set_drvdata(spi, indio_dev);
283
284 st->chip_info = &ad5449_chip_info[id->driver_data];
285 st->spi = spi;
286
287 for (i = 0; i < st->chip_info->num_channels; ++i)
288 st->vref_reg[i].supply = ad5449_vref_name(st, i);
289
290 ret = regulator_bulk_get(&spi->dev, st->chip_info->num_channels,
291 st->vref_reg);
292 if (ret)
293 goto error_free;
294
295 ret = regulator_bulk_enable(st->chip_info->num_channels, st->vref_reg);
296 if (ret)
297 goto error_free_reg;
298
299 indio_dev->dev.parent = &spi->dev;
300 indio_dev->name = id->name;
301 indio_dev->info = &ad5449_info;
302 indio_dev->modes = INDIO_DIRECT_MODE;
303 indio_dev->channels = st->chip_info->channels;
304 indio_dev->num_channels = st->chip_info->num_channels;
305
306 if (st->chip_info->has_ctrl) {
307 unsigned int ctrl = 0x00;
308 if (pdata) {
309 if (pdata->hardware_clear_to_midscale)
310 ctrl |= AD5449_CTRL_HCLR_TO_MIDSCALE;
311 ctrl |= pdata->sdo_mode << AD5449_CTRL_SDO_OFFSET;
312 st->has_sdo = pdata->sdo_mode != AD5449_SDO_DISABLED;
313 } else {
314 st->has_sdo = true;
315 }
316 ad5449_write(indio_dev, AD5449_CMD_CTRL, ctrl);
317 }
318
319 ret = iio_device_register(indio_dev);
320 if (ret)
321 goto error_disable_reg;
322
323 return 0;
324
325error_disable_reg:
326 regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
327error_free_reg:
328 regulator_bulk_free(st->chip_info->num_channels, st->vref_reg);
329error_free:
330 iio_device_free(indio_dev);
331
332 return ret;
333}
334
335static int __devexit ad5449_spi_remove(struct spi_device *spi)
336{
337 struct iio_dev *indio_dev = spi_get_drvdata(spi);
338 struct ad5449 *st = iio_priv(indio_dev);
339
340 iio_device_unregister(indio_dev);
341
342 regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
343 regulator_bulk_free(st->chip_info->num_channels, st->vref_reg);
344
345 iio_device_free(indio_dev);
346
347 return 0;
348}
349
350static const struct spi_device_id ad5449_spi_ids[] = {
351 { "ad5415", ID_AD5449 },
352 { "ad5426", ID_AD5426 },
353 { "ad5429", ID_AD5429 },
354 { "ad5432", ID_AD5432 },
355 { "ad5439", ID_AD5439 },
356 { "ad5443", ID_AD5443 },
357 { "ad5449", ID_AD5449 },
358 {}
359};
360MODULE_DEVICE_TABLE(spi, ad5449_spi_ids);
361
362static struct spi_driver ad5449_spi_driver = {
363 .driver = {
364 .name = "ad5449",
365 .owner = THIS_MODULE,
366 },
367 .probe = ad5449_spi_probe,
368 .remove = __devexit_p(ad5449_spi_remove),
369 .id_table = ad5449_spi_ids,
370};
371module_spi_driver(ad5449_spi_driver);
372
373MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
374MODULE_DESCRIPTION("Analog Devices AD5449 and similar DACs");
375MODULE_LICENSE("GPL v2");