aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/iio/dac
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/staging/iio/dac
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/staging/iio/dac')
-rw-r--r--drivers/staging/iio/dac/Kconfig64
-rw-r--r--drivers/staging/iio/dac/Makefile10
-rw-r--r--drivers/staging/iio/dac/ad5446.c480
-rw-r--r--drivers/staging/iio/dac/ad5446.h109
-rw-r--r--drivers/staging/iio/dac/ad5504.c397
-rw-r--r--drivers/staging/iio/dac/ad5504.h68
-rw-r--r--drivers/staging/iio/dac/ad5624r.h79
-rw-r--r--drivers/staging/iio/dac/ad5624r_spi.c336
-rw-r--r--drivers/staging/iio/dac/ad5686.c497
-rw-r--r--drivers/staging/iio/dac/ad5791.c442
-rw-r--r--drivers/staging/iio/dac/ad5791.h114
-rw-r--r--drivers/staging/iio/dac/dac.h6
-rw-r--r--drivers/staging/iio/dac/max517.c295
-rw-r--r--drivers/staging/iio/dac/max517.h19
14 files changed, 2916 insertions, 0 deletions
diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig
new file mode 100644
index 00000000000..7ddae357f20
--- /dev/null
+++ b/drivers/staging/iio/dac/Kconfig
@@ -0,0 +1,64 @@
1#
2# DAC drivers
3#
4comment "Digital to analog convertors"
5
6config AD5624R_SPI
7 tristate "Analog Devices AD5624/44/64R DAC spi driver"
8 depends on SPI
9 help
10 Say yes here to build support for Analog Devices AD5624R, AD5644R and
11 AD5664R convertors (DAC). This driver uses the common SPI interface.
12
13config AD5446
14 tristate "Analog Devices AD5444/6, AD5620/40/60 and AD5542A/12A DAC SPI driver"
15 depends on SPI
16 help
17 Say yes here to build support for Analog Devices AD5444, AD5446,
18 AD5512A, AD5542A, AD5543, AD5553, AD5601, AD5611, AD5620, AD5621,
19 AD5640, AD5660 DACs.
20
21 To compile this driver as a module, choose M here: the
22 module will be called ad5446.
23
24config AD5504
25 tristate "Analog Devices AD5504/AD5501 DAC SPI driver"
26 depends on SPI
27 help
28 Say yes here to build support for Analog Devices AD5504, AD5501,
29 High Voltage Digital to Analog Converter.
30
31 To compile this driver as a module, choose M here: the
32 module will be called ad5504.
33
34config AD5791
35 tristate "Analog Devices AD5760/AD5780/AD5781/AD5791 DAC SPI driver"
36 depends on SPI
37 help
38 Say yes here to build support for Analog Devices AD5760, AD5780,
39 AD5781, AD5791 High Resolution Voltage Output Digital to
40 Analog Converter.
41
42 To compile this driver as a module, choose M here: the
43 module will be called ad5791.
44
45config AD5686
46 tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver"
47 depends on SPI
48 help
49 Say yes here to build support for Analog Devices AD5686R, AD5685R,
50 AD5684R, AD5791 Voltage Output Digital to
51 Analog Converter.
52
53 To compile this driver as a module, choose M here: the
54 module will be called ad5686.
55
56config MAX517
57 tristate "Maxim MAX517/518/519 DAC driver"
58 depends on I2C && EXPERIMENTAL
59 help
60 If you say yes here you get support for the Maxim chips MAX517,
61 MAX518 and MAX519 (I2C 8-Bit DACs with rail-to-rail outputs).
62
63 This driver can also be built as a module. If so, the module
64 will be called max517.
diff --git a/drivers/staging/iio/dac/Makefile b/drivers/staging/iio/dac/Makefile
new file mode 100644
index 00000000000..7f4f2ed031e
--- /dev/null
+++ b/drivers/staging/iio/dac/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for industrial I/O DAC drivers
3#
4
5obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o
6obj-$(CONFIG_AD5504) += ad5504.o
7obj-$(CONFIG_AD5446) += ad5446.o
8obj-$(CONFIG_AD5791) += ad5791.o
9obj-$(CONFIG_AD5686) += ad5686.o
10obj-$(CONFIG_MAX517) += max517.o
diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c
new file mode 100644
index 00000000000..e8a9d0bf1ed
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5446.c
@@ -0,0 +1,480 @@
1/*
2 * AD5446 SPI DAC driver
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/interrupt.h>
10#include <linux/workqueue.h>
11#include <linux/device.h>
12#include <linux/kernel.h>
13#include <linux/slab.h>
14#include <linux/sysfs.h>
15#include <linux/list.h>
16#include <linux/spi/spi.h>
17#include <linux/regulator/consumer.h>
18#include <linux/err.h>
19
20#include "../iio.h"
21#include "../sysfs.h"
22#include "dac.h"
23
24#include "ad5446.h"
25
26static void ad5446_store_sample(struct ad5446_state *st, unsigned val)
27{
28 st->data.d16 = cpu_to_be16(AD5446_LOAD |
29 (val << st->chip_info->left_shift));
30}
31
32static void ad5542_store_sample(struct ad5446_state *st, unsigned val)
33{
34 st->data.d16 = cpu_to_be16(val << st->chip_info->left_shift);
35}
36
37static void ad5620_store_sample(struct ad5446_state *st, unsigned val)
38{
39 st->data.d16 = cpu_to_be16(AD5620_LOAD |
40 (val << st->chip_info->left_shift));
41}
42
43static void ad5660_store_sample(struct ad5446_state *st, unsigned val)
44{
45 val |= AD5660_LOAD;
46 st->data.d24[0] = (val >> 16) & 0xFF;
47 st->data.d24[1] = (val >> 8) & 0xFF;
48 st->data.d24[2] = val & 0xFF;
49}
50
51static void ad5620_store_pwr_down(struct ad5446_state *st, unsigned mode)
52{
53 st->data.d16 = cpu_to_be16(mode << 14);
54}
55
56static void ad5660_store_pwr_down(struct ad5446_state *st, unsigned mode)
57{
58 unsigned val = mode << 16;
59
60 st->data.d24[0] = (val >> 16) & 0xFF;
61 st->data.d24[1] = (val >> 8) & 0xFF;
62 st->data.d24[2] = val & 0xFF;
63}
64
65static ssize_t ad5446_write(struct device *dev,
66 struct device_attribute *attr,
67 const char *buf,
68 size_t len)
69{
70 struct iio_dev *dev_info = dev_get_drvdata(dev);
71 struct ad5446_state *st = iio_priv(dev_info);
72 int ret;
73 long val;
74
75 ret = strict_strtol(buf, 10, &val);
76 if (ret)
77 goto error_ret;
78
79 if (val > RES_MASK(st->chip_info->bits)) {
80 ret = -EINVAL;
81 goto error_ret;
82 }
83
84 mutex_lock(&dev_info->mlock);
85 st->cached_val = val;
86 st->chip_info->store_sample(st, val);
87 ret = spi_sync(st->spi, &st->msg);
88 mutex_unlock(&dev_info->mlock);
89
90error_ret:
91 return ret ? ret : len;
92}
93
94static IIO_DEV_ATTR_OUT_RAW(0, ad5446_write, 0);
95
96static ssize_t ad5446_show_scale(struct device *dev,
97 struct device_attribute *attr,
98 char *buf)
99{
100 struct iio_dev *dev_info = dev_get_drvdata(dev);
101 struct ad5446_state *st = iio_priv(dev_info);
102 /* Corresponds to Vref / 2^(bits) */
103 unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits;
104
105 return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
106}
107static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5446_show_scale, NULL, 0);
108
109static ssize_t ad5446_write_powerdown_mode(struct device *dev,
110 struct device_attribute *attr,
111 const char *buf, size_t len)
112{
113 struct iio_dev *dev_info = dev_get_drvdata(dev);
114 struct ad5446_state *st = iio_priv(dev_info);
115
116 if (sysfs_streq(buf, "1kohm_to_gnd"))
117 st->pwr_down_mode = MODE_PWRDWN_1k;
118 else if (sysfs_streq(buf, "100kohm_to_gnd"))
119 st->pwr_down_mode = MODE_PWRDWN_100k;
120 else if (sysfs_streq(buf, "three_state"))
121 st->pwr_down_mode = MODE_PWRDWN_TRISTATE;
122 else
123 return -EINVAL;
124
125 return len;
126}
127
128static ssize_t ad5446_read_powerdown_mode(struct device *dev,
129 struct device_attribute *attr, char *buf)
130{
131 struct iio_dev *dev_info = dev_get_drvdata(dev);
132 struct ad5446_state *st = iio_priv(dev_info);
133
134 char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"};
135
136 return sprintf(buf, "%s\n", mode[st->pwr_down_mode]);
137}
138
139static ssize_t ad5446_read_dac_powerdown(struct device *dev,
140 struct device_attribute *attr,
141 char *buf)
142{
143 struct iio_dev *dev_info = dev_get_drvdata(dev);
144 struct ad5446_state *st = iio_priv(dev_info);
145
146 return sprintf(buf, "%d\n", st->pwr_down);
147}
148
149static ssize_t ad5446_write_dac_powerdown(struct device *dev,
150 struct device_attribute *attr,
151 const char *buf, size_t len)
152{
153 struct iio_dev *dev_info = dev_get_drvdata(dev);
154 struct ad5446_state *st = iio_priv(dev_info);
155 unsigned long readin;
156 int ret;
157
158 ret = strict_strtol(buf, 10, &readin);
159 if (ret)
160 return ret;
161
162 if (readin > 1)
163 ret = -EINVAL;
164
165 mutex_lock(&dev_info->mlock);
166 st->pwr_down = readin;
167
168 if (st->pwr_down)
169 st->chip_info->store_pwr_down(st, st->pwr_down_mode);
170 else
171 st->chip_info->store_sample(st, st->cached_val);
172
173 ret = spi_sync(st->spi, &st->msg);
174 mutex_unlock(&dev_info->mlock);
175
176 return ret ? ret : len;
177}
178
179static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO | S_IWUSR,
180 ad5446_read_powerdown_mode,
181 ad5446_write_powerdown_mode, 0);
182
183static IIO_CONST_ATTR(out_powerdown_mode_available,
184 "1kohm_to_gnd 100kohm_to_gnd three_state");
185
186static IIO_DEVICE_ATTR(out0_powerdown, S_IRUGO | S_IWUSR,
187 ad5446_read_dac_powerdown,
188 ad5446_write_dac_powerdown, 0);
189
190static struct attribute *ad5446_attributes[] = {
191 &iio_dev_attr_out0_raw.dev_attr.attr,
192 &iio_dev_attr_out_scale.dev_attr.attr,
193 &iio_dev_attr_out0_powerdown.dev_attr.attr,
194 &iio_dev_attr_out_powerdown_mode.dev_attr.attr,
195 &iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
196 NULL,
197};
198
199static mode_t ad5446_attr_is_visible(struct kobject *kobj,
200 struct attribute *attr, int n)
201{
202 struct device *dev = container_of(kobj, struct device, kobj);
203 struct iio_dev *dev_info = dev_get_drvdata(dev);
204 struct ad5446_state *st = iio_priv(dev_info);
205
206 mode_t mode = attr->mode;
207
208 if (!st->chip_info->store_pwr_down &&
209 (attr == &iio_dev_attr_out0_powerdown.dev_attr.attr ||
210 attr == &iio_dev_attr_out_powerdown_mode.dev_attr.attr ||
211 attr ==
212 &iio_const_attr_out_powerdown_mode_available.dev_attr.attr))
213 mode = 0;
214
215 return mode;
216}
217
218static const struct attribute_group ad5446_attribute_group = {
219 .attrs = ad5446_attributes,
220 .is_visible = ad5446_attr_is_visible,
221};
222
223static const struct ad5446_chip_info ad5446_chip_info_tbl[] = {
224 [ID_AD5444] = {
225 .bits = 12,
226 .storagebits = 16,
227 .left_shift = 2,
228 .store_sample = ad5446_store_sample,
229 },
230 [ID_AD5446] = {
231 .bits = 14,
232 .storagebits = 16,
233 .left_shift = 0,
234 .store_sample = ad5446_store_sample,
235 },
236 [ID_AD5541A] = {
237 .bits = 16,
238 .storagebits = 16,
239 .left_shift = 0,
240 .store_sample = ad5542_store_sample,
241 },
242 [ID_AD5542A] = {
243 .bits = 16,
244 .storagebits = 16,
245 .left_shift = 0,
246 .store_sample = ad5542_store_sample,
247 },
248 [ID_AD5543] = {
249 .bits = 16,
250 .storagebits = 16,
251 .left_shift = 0,
252 .store_sample = ad5542_store_sample,
253 },
254 [ID_AD5512A] = {
255 .bits = 12,
256 .storagebits = 16,
257 .left_shift = 4,
258 .store_sample = ad5542_store_sample,
259 },
260 [ID_AD5553] = {
261 .bits = 14,
262 .storagebits = 16,
263 .left_shift = 0,
264 .store_sample = ad5542_store_sample,
265 },
266 [ID_AD5601] = {
267 .bits = 8,
268 .storagebits = 16,
269 .left_shift = 6,
270 .store_sample = ad5542_store_sample,
271 .store_pwr_down = ad5620_store_pwr_down,
272 },
273 [ID_AD5611] = {
274 .bits = 10,
275 .storagebits = 16,
276 .left_shift = 4,
277 .store_sample = ad5542_store_sample,
278 .store_pwr_down = ad5620_store_pwr_down,
279 },
280 [ID_AD5621] = {
281 .bits = 12,
282 .storagebits = 16,
283 .left_shift = 2,
284 .store_sample = ad5542_store_sample,
285 .store_pwr_down = ad5620_store_pwr_down,
286 },
287 [ID_AD5620_2500] = {
288 .bits = 12,
289 .storagebits = 16,
290 .left_shift = 2,
291 .int_vref_mv = 2500,
292 .store_sample = ad5620_store_sample,
293 .store_pwr_down = ad5620_store_pwr_down,
294 },
295 [ID_AD5620_1250] = {
296 .bits = 12,
297 .storagebits = 16,
298 .left_shift = 2,
299 .int_vref_mv = 1250,
300 .store_sample = ad5620_store_sample,
301 .store_pwr_down = ad5620_store_pwr_down,
302 },
303 [ID_AD5640_2500] = {
304 .bits = 14,
305 .storagebits = 16,
306 .left_shift = 0,
307 .int_vref_mv = 2500,
308 .store_sample = ad5620_store_sample,
309 .store_pwr_down = ad5620_store_pwr_down,
310 },
311 [ID_AD5640_1250] = {
312 .bits = 14,
313 .storagebits = 16,
314 .left_shift = 0,
315 .int_vref_mv = 1250,
316 .store_sample = ad5620_store_sample,
317 .store_pwr_down = ad5620_store_pwr_down,
318 },
319 [ID_AD5660_2500] = {
320 .bits = 16,
321 .storagebits = 24,
322 .left_shift = 0,
323 .int_vref_mv = 2500,
324 .store_sample = ad5660_store_sample,
325 .store_pwr_down = ad5660_store_pwr_down,
326 },
327 [ID_AD5660_1250] = {
328 .bits = 16,
329 .storagebits = 24,
330 .left_shift = 0,
331 .int_vref_mv = 1250,
332 .store_sample = ad5660_store_sample,
333 .store_pwr_down = ad5660_store_pwr_down,
334 },
335};
336
337static const struct iio_info ad5446_info = {
338 .attrs = &ad5446_attribute_group,
339 .driver_module = THIS_MODULE,
340};
341
342static int __devinit ad5446_probe(struct spi_device *spi)
343{
344 struct ad5446_state *st;
345 struct iio_dev *indio_dev;
346 struct regulator *reg;
347 int ret, voltage_uv = 0;
348
349 reg = regulator_get(&spi->dev, "vcc");
350 if (!IS_ERR(reg)) {
351 ret = regulator_enable(reg);
352 if (ret)
353 goto error_put_reg;
354
355 voltage_uv = regulator_get_voltage(reg);
356 }
357
358 indio_dev = iio_allocate_device(sizeof(*st));
359 if (indio_dev == NULL) {
360 ret = -ENOMEM;
361 goto error_disable_reg;
362 }
363 st = iio_priv(indio_dev);
364 st->chip_info =
365 &ad5446_chip_info_tbl[spi_get_device_id(spi)->driver_data];
366
367 spi_set_drvdata(spi, indio_dev);
368 st->reg = reg;
369 st->spi = spi;
370
371 /* Estabilish that the iio_dev is a child of the spi device */
372 indio_dev->dev.parent = &spi->dev;
373 indio_dev->name = spi_get_device_id(spi)->name;
374 indio_dev->info = &ad5446_info;
375 indio_dev->modes = INDIO_DIRECT_MODE;
376
377 /* Setup default message */
378
379 st->xfer.tx_buf = &st->data;
380 st->xfer.len = st->chip_info->storagebits / 8;
381
382 spi_message_init(&st->msg);
383 spi_message_add_tail(&st->xfer, &st->msg);
384
385 switch (spi_get_device_id(spi)->driver_data) {
386 case ID_AD5620_2500:
387 case ID_AD5620_1250:
388 case ID_AD5640_2500:
389 case ID_AD5640_1250:
390 case ID_AD5660_2500:
391 case ID_AD5660_1250:
392 st->vref_mv = st->chip_info->int_vref_mv;
393 break;
394 default:
395 if (voltage_uv)
396 st->vref_mv = voltage_uv / 1000;
397 else
398 dev_warn(&spi->dev,
399 "reference voltage unspecified\n");
400 }
401
402 ret = iio_device_register(indio_dev);
403 if (ret)
404 goto error_free_device;
405
406 return 0;
407
408error_free_device:
409 iio_free_device(indio_dev);
410error_disable_reg:
411 if (!IS_ERR(reg))
412 regulator_disable(reg);
413error_put_reg:
414 if (!IS_ERR(reg))
415 regulator_put(reg);
416
417 return ret;
418}
419
420static int ad5446_remove(struct spi_device *spi)
421{
422 struct iio_dev *indio_dev = spi_get_drvdata(spi);
423 struct ad5446_state *st = iio_priv(indio_dev);
424 struct regulator *reg = st->reg;
425
426 iio_device_unregister(indio_dev);
427 if (!IS_ERR(reg)) {
428 regulator_disable(reg);
429 regulator_put(reg);
430 }
431 return 0;
432}
433
434static const struct spi_device_id ad5446_id[] = {
435 {"ad5444", ID_AD5444},
436 {"ad5446", ID_AD5446},
437 {"ad5512a", ID_AD5512A},
438 {"ad5541a", ID_AD5541A},
439 {"ad5542a", ID_AD5542A},
440 {"ad5543", ID_AD5543},
441 {"ad5553", ID_AD5553},
442 {"ad5601", ID_AD5601},
443 {"ad5611", ID_AD5611},
444 {"ad5621", ID_AD5621},
445 {"ad5620-2500", ID_AD5620_2500}, /* AD5620/40/60: */
446 {"ad5620-1250", ID_AD5620_1250}, /* part numbers may look differently */
447 {"ad5640-2500", ID_AD5640_2500},
448 {"ad5640-1250", ID_AD5640_1250},
449 {"ad5660-2500", ID_AD5660_2500},
450 {"ad5660-1250", ID_AD5660_1250},
451 {}
452};
453
454static struct spi_driver ad5446_driver = {
455 .driver = {
456 .name = "ad5446",
457 .bus = &spi_bus_type,
458 .owner = THIS_MODULE,
459 },
460 .probe = ad5446_probe,
461 .remove = __devexit_p(ad5446_remove),
462 .id_table = ad5446_id,
463};
464
465static int __init ad5446_init(void)
466{
467 return spi_register_driver(&ad5446_driver);
468}
469module_init(ad5446_init);
470
471static void __exit ad5446_exit(void)
472{
473 spi_unregister_driver(&ad5446_driver);
474}
475module_exit(ad5446_exit);
476
477MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
478MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC");
479MODULE_LICENSE("GPL v2");
480MODULE_ALIAS("spi:ad5446");
diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h
new file mode 100644
index 00000000000..7118d653ac3
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5446.h
@@ -0,0 +1,109 @@
1/*
2 * AD5446 SPI DAC driver
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8#ifndef IIO_DAC_AD5446_H_
9#define IIO_DAC_AD5446_H_
10
11/* DAC Control Bits */
12
13#define AD5446_LOAD (0x0 << 14) /* Load and update */
14#define AD5446_SDO_DIS (0x1 << 14) /* Disable SDO */
15#define AD5446_NOP (0x2 << 14) /* No operation */
16#define AD5446_CLK_RISING (0x3 << 14) /* Clock data on rising edge */
17
18#define AD5620_LOAD (0x0 << 14) /* Load and update Norm Operation*/
19#define AD5620_PWRDWN_1k (0x1 << 14) /* Power-down: 1kOhm to GND */
20#define AD5620_PWRDWN_100k (0x2 << 14) /* Power-down: 100kOhm to GND */
21#define AD5620_PWRDWN_TRISTATE (0x3 << 14) /* Power-down: Three-state */
22
23#define AD5660_LOAD (0x0 << 16) /* Load and update Norm Operation*/
24#define AD5660_PWRDWN_1k (0x1 << 16) /* Power-down: 1kOhm to GND */
25#define AD5660_PWRDWN_100k (0x2 << 16) /* Power-down: 100kOhm to GND */
26#define AD5660_PWRDWN_TRISTATE (0x3 << 16) /* Power-down: Three-state */
27
28#define RES_MASK(bits) ((1 << (bits)) - 1)
29
30#define MODE_PWRDWN_1k 0x1
31#define MODE_PWRDWN_100k 0x2
32#define MODE_PWRDWN_TRISTATE 0x3
33
34/**
35 * struct ad5446_state - driver instance specific data
36 * @spi: spi_device
37 * @chip_info: chip model specific constants, available modes etc
38 * @reg: supply regulator
39 * @poll_work: bottom half of polling interrupt handler
40 * @vref_mv: actual reference voltage used
41 * @xfer: default spi transfer
42 * @msg: default spi message
43 * @data: spi transmit buffer
44 */
45
46struct ad5446_state {
47 struct spi_device *spi;
48 const struct ad5446_chip_info *chip_info;
49 struct regulator *reg;
50 struct work_struct poll_work;
51 unsigned short vref_mv;
52 unsigned cached_val;
53 unsigned pwr_down_mode;
54 unsigned pwr_down;
55 struct spi_transfer xfer;
56 struct spi_message msg;
57 union {
58 unsigned short d16;
59 unsigned char d24[3];
60 } data;
61};
62
63/**
64 * struct ad5446_chip_info - chip specific information
65 * @bits: accuracy of the DAC in bits
66 * @storagebits: number of bits written to the DAC
67 * @left_shift: number of bits the datum must be shifted
68 * @int_vref_mv: AD5620/40/60: the internal reference voltage
69 * @store_sample: chip specific helper function to store the datum
70 * @store_sample: chip specific helper function to store the powerpown cmd
71 */
72
73struct ad5446_chip_info {
74 u8 bits;
75 u8 storagebits;
76 u8 left_shift;
77 u16 int_vref_mv;
78 void (*store_sample) (struct ad5446_state *st, unsigned val);
79 void (*store_pwr_down) (struct ad5446_state *st, unsigned mode);
80};
81
82/**
83 * ad5446_supported_device_ids:
84 * The AD5620/40/60 parts are available in different fixed internal reference
85 * voltage options. The actual part numbers may look differently
86 * (and a bit cryptic), however this style is used to make clear which
87 * parts are supported here.
88 */
89
90enum ad5446_supported_device_ids {
91 ID_AD5444,
92 ID_AD5446,
93 ID_AD5541A,
94 ID_AD5542A,
95 ID_AD5543,
96 ID_AD5512A,
97 ID_AD5553,
98 ID_AD5601,
99 ID_AD5611,
100 ID_AD5621,
101 ID_AD5620_2500,
102 ID_AD5620_1250,
103 ID_AD5640_2500,
104 ID_AD5640_1250,
105 ID_AD5660_2500,
106 ID_AD5660_1250,
107};
108
109#endif /* IIO_DAC_AD5446_H_ */
diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c
new file mode 100644
index 00000000000..1915f459868
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5504.c
@@ -0,0 +1,397 @@
1/*
2 * AD5504, AD5501 High Voltage Digital to Analog Converter
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/interrupt.h>
10#include <linux/gpio.h>
11#include <linux/fs.h>
12#include <linux/device.h>
13#include <linux/kernel.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h>
16#include <linux/sysfs.h>
17#include <linux/regulator/consumer.h>
18
19#include "../iio.h"
20#include "../sysfs.h"
21#include "dac.h"
22#include "ad5504.h"
23
24static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val)
25{
26 u16 tmp = cpu_to_be16(AD5504_CMD_WRITE |
27 AD5504_ADDR(addr) |
28 (val & AD5504_RES_MASK));
29
30 return spi_write(spi, (u8 *)&tmp, 2);
31}
32
33static int ad5504_spi_read(struct spi_device *spi, u8 addr, u16 *val)
34{
35 u16 tmp = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr));
36 int ret;
37 struct spi_transfer t = {
38 .tx_buf = &tmp,
39 .rx_buf = val,
40 .len = 2,
41 };
42 struct spi_message m;
43
44 spi_message_init(&m);
45 spi_message_add_tail(&t, &m);
46 ret = spi_sync(spi, &m);
47
48 *val = be16_to_cpu(*val) & AD5504_RES_MASK;
49
50 return ret;
51}
52
53static ssize_t ad5504_write_dac(struct device *dev,
54 struct device_attribute *attr,
55 const char *buf, size_t len)
56{
57 struct iio_dev *indio_dev = dev_get_drvdata(dev);
58 struct ad5504_state *st = iio_priv(indio_dev);
59 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
60 long readin;
61 int ret;
62
63 ret = strict_strtol(buf, 10, &readin);
64 if (ret)
65 return ret;
66
67 ret = ad5504_spi_write(st->spi, this_attr->address, readin);
68 return ret ? ret : len;
69}
70
71static ssize_t ad5504_read_dac(struct device *dev,
72 struct device_attribute *attr,
73 char *buf)
74{
75 struct iio_dev *indio_dev = dev_get_drvdata(dev);
76 struct ad5504_state *st = iio_priv(indio_dev);
77 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
78 int ret;
79 u16 val;
80
81 ret = ad5504_spi_read(st->spi, this_attr->address, &val);
82 if (ret)
83 return ret;
84
85 return sprintf(buf, "%d\n", val);
86}
87
88static ssize_t ad5504_read_powerdown_mode(struct device *dev,
89 struct device_attribute *attr, char *buf)
90{
91 struct iio_dev *indio_dev = dev_get_drvdata(dev);
92 struct ad5504_state *st = iio_priv(indio_dev);
93
94 const char mode[][14] = {"20kohm_to_gnd", "three_state"};
95
96 return sprintf(buf, "%s\n", mode[st->pwr_down_mode]);
97}
98
99static ssize_t ad5504_write_powerdown_mode(struct device *dev,
100 struct device_attribute *attr,
101 const char *buf, size_t len)
102{
103 struct iio_dev *indio_dev = dev_get_drvdata(dev);
104 struct ad5504_state *st = iio_priv(indio_dev);
105 int ret;
106
107 if (sysfs_streq(buf, "20kohm_to_gnd"))
108 st->pwr_down_mode = AD5504_DAC_PWRDN_20K;
109 else if (sysfs_streq(buf, "three_state"))
110 st->pwr_down_mode = AD5504_DAC_PWRDN_3STATE;
111 else
112 ret = -EINVAL;
113
114 return ret ? ret : len;
115}
116
117static ssize_t ad5504_read_dac_powerdown(struct device *dev,
118 struct device_attribute *attr,
119 char *buf)
120{
121 struct iio_dev *indio_dev = dev_get_drvdata(dev);
122 struct ad5504_state *st = iio_priv(indio_dev);
123 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
124
125 return sprintf(buf, "%d\n",
126 !(st->pwr_down_mask & (1 << this_attr->address)));
127}
128
129static ssize_t ad5504_write_dac_powerdown(struct device *dev,
130 struct device_attribute *attr,
131 const char *buf, size_t len)
132{
133 long readin;
134 int ret;
135 struct iio_dev *indio_dev = dev_get_drvdata(dev);
136 struct ad5504_state *st = iio_priv(indio_dev);
137 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
138
139 ret = strict_strtol(buf, 10, &readin);
140 if (ret)
141 return ret;
142
143 if (readin == 0)
144 st->pwr_down_mask |= (1 << this_attr->address);
145 else if (readin == 1)
146 st->pwr_down_mask &= ~(1 << this_attr->address);
147 else
148 ret = -EINVAL;
149
150 ret = ad5504_spi_write(st->spi, AD5504_ADDR_CTRL,
151 AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) |
152 AD5504_DAC_PWR(st->pwr_down_mask));
153
154 /* writes to the CTRL register must be followed by a NOOP */
155 ad5504_spi_write(st->spi, AD5504_ADDR_NOOP, 0);
156
157 return ret ? ret : len;
158}
159
160static ssize_t ad5504_show_scale(struct device *dev,
161 struct device_attribute *attr,
162 char *buf)
163{
164 struct iio_dev *indio_dev = dev_get_drvdata(dev);
165 struct ad5504_state *st = iio_priv(indio_dev);
166 /* Corresponds to Vref / 2^(bits) */
167 unsigned int scale_uv = (st->vref_mv * 1000) >> AD5505_BITS;
168
169 return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
170}
171static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5504_show_scale, NULL, 0);
172
173#define IIO_DEV_ATTR_OUT_RW_RAW(_num, _show, _store, _addr) \
174 IIO_DEVICE_ATTR(out##_num##_raw, \
175 S_IRUGO | S_IWUSR, _show, _store, _addr)
176
177static IIO_DEV_ATTR_OUT_RW_RAW(0, ad5504_read_dac,
178 ad5504_write_dac, AD5504_ADDR_DAC0);
179static IIO_DEV_ATTR_OUT_RW_RAW(1, ad5504_read_dac,
180 ad5504_write_dac, AD5504_ADDR_DAC1);
181static IIO_DEV_ATTR_OUT_RW_RAW(2, ad5504_read_dac,
182 ad5504_write_dac, AD5504_ADDR_DAC2);
183static IIO_DEV_ATTR_OUT_RW_RAW(3, ad5504_read_dac,
184 ad5504_write_dac, AD5504_ADDR_DAC3);
185
186static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO |
187 S_IWUSR, ad5504_read_powerdown_mode,
188 ad5504_write_powerdown_mode, 0);
189
190static IIO_CONST_ATTR(out_powerdown_mode_available,
191 "20kohm_to_gnd three_state");
192
193#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr) \
194 IIO_DEVICE_ATTR(out##_num##_powerdown, \
195 S_IRUGO | S_IWUSR, _show, _store, _addr)
196
197static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5504_read_dac_powerdown,
198 ad5504_write_dac_powerdown, 0);
199static IIO_DEV_ATTR_DAC_POWERDOWN(1, ad5504_read_dac_powerdown,
200 ad5504_write_dac_powerdown, 1);
201static IIO_DEV_ATTR_DAC_POWERDOWN(2, ad5504_read_dac_powerdown,
202 ad5504_write_dac_powerdown, 2);
203static IIO_DEV_ATTR_DAC_POWERDOWN(3, ad5504_read_dac_powerdown,
204 ad5504_write_dac_powerdown, 3);
205
206static struct attribute *ad5504_attributes[] = {
207 &iio_dev_attr_out0_raw.dev_attr.attr,
208 &iio_dev_attr_out1_raw.dev_attr.attr,
209 &iio_dev_attr_out2_raw.dev_attr.attr,
210 &iio_dev_attr_out3_raw.dev_attr.attr,
211 &iio_dev_attr_out0_powerdown.dev_attr.attr,
212 &iio_dev_attr_out1_powerdown.dev_attr.attr,
213 &iio_dev_attr_out2_powerdown.dev_attr.attr,
214 &iio_dev_attr_out3_powerdown.dev_attr.attr,
215 &iio_dev_attr_out_powerdown_mode.dev_attr.attr,
216 &iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
217 &iio_dev_attr_out_scale.dev_attr.attr,
218 NULL,
219};
220
221static const struct attribute_group ad5504_attribute_group = {
222 .attrs = ad5504_attributes,
223};
224
225static struct attribute *ad5501_attributes[] = {
226 &iio_dev_attr_out0_raw.dev_attr.attr,
227 &iio_dev_attr_out0_powerdown.dev_attr.attr,
228 &iio_dev_attr_out_powerdown_mode.dev_attr.attr,
229 &iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
230 &iio_dev_attr_out_scale.dev_attr.attr,
231 NULL,
232};
233
234static const struct attribute_group ad5501_attribute_group = {
235 .attrs = ad5501_attributes,
236};
237
238static IIO_CONST_ATTR(temp0_thresh_rising_value, "110000");
239static IIO_CONST_ATTR(temp0_thresh_rising_en, "1");
240
241static struct attribute *ad5504_ev_attributes[] = {
242 &iio_const_attr_temp0_thresh_rising_value.dev_attr.attr,
243 &iio_const_attr_temp0_thresh_rising_en.dev_attr.attr,
244 NULL,
245};
246
247static struct attribute_group ad5504_ev_attribute_group = {
248 .attrs = ad5504_ev_attributes,
249};
250
251static irqreturn_t ad5504_event_handler(int irq, void *private)
252{
253 iio_push_event(private, 0,
254 IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP,
255 0,
256 IIO_EV_TYPE_THRESH,
257 IIO_EV_DIR_RISING),
258 iio_get_time_ns());
259
260 return IRQ_HANDLED;
261}
262
263static const struct iio_info ad5504_info = {
264 .attrs = &ad5504_attribute_group,
265 .num_interrupt_lines = 1,
266 .event_attrs = &ad5504_ev_attribute_group,
267 .driver_module = THIS_MODULE,
268};
269
270static const struct iio_info ad5501_info = {
271 .attrs = &ad5501_attribute_group,
272 .num_interrupt_lines = 1,
273 .event_attrs = &ad5504_ev_attribute_group,
274 .driver_module = THIS_MODULE,
275};
276
277static int __devinit ad5504_probe(struct spi_device *spi)
278{
279 struct ad5504_platform_data *pdata = spi->dev.platform_data;
280 struct iio_dev *indio_dev;
281 struct ad5504_state *st;
282 struct regulator *reg;
283 int ret, voltage_uv = 0;
284
285 reg = regulator_get(&spi->dev, "vcc");
286 if (!IS_ERR(reg)) {
287 ret = regulator_enable(reg);
288 if (ret)
289 goto error_put_reg;
290
291 voltage_uv = regulator_get_voltage(reg);
292 }
293
294 indio_dev = iio_allocate_device(sizeof(*st));
295 if (indio_dev == NULL) {
296 ret = -ENOMEM;
297 goto error_disable_reg;
298 }
299 spi_set_drvdata(spi, indio_dev);
300 st = iio_priv(indio_dev);
301 if (voltage_uv)
302 st->vref_mv = voltage_uv / 1000;
303 else if (pdata)
304 st->vref_mv = pdata->vref_mv;
305 else
306 dev_warn(&spi->dev, "reference voltage unspecified\n");
307
308 st->reg = reg;
309 st->spi = spi;
310 indio_dev->dev.parent = &spi->dev;
311 indio_dev->name = spi_get_device_id(st->spi)->name;
312 if (spi_get_device_id(st->spi)->driver_data == ID_AD5501)
313 indio_dev->info = &ad5501_info;
314 else
315 indio_dev->info = &ad5504_info;
316 indio_dev->modes = INDIO_DIRECT_MODE;
317
318 ret = iio_device_register(indio_dev);
319 if (ret)
320 goto error_free_dev;
321
322 if (spi->irq) {
323 ret = request_threaded_irq(spi->irq,
324 NULL,
325 &ad5504_event_handler,
326 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
327 spi_get_device_id(st->spi)->name,
328 indio_dev);
329 if (ret)
330 goto error_unreg_iio_device;
331 }
332
333 return 0;
334
335error_unreg_iio_device:
336 iio_device_unregister(indio_dev);
337error_free_dev:
338 iio_free_device(indio_dev);
339error_disable_reg:
340 if (!IS_ERR(reg))
341 regulator_disable(st->reg);
342error_put_reg:
343 if (!IS_ERR(reg))
344 regulator_put(reg);
345
346 return ret;
347}
348
349static int __devexit ad5504_remove(struct spi_device *spi)
350{
351 struct iio_dev *indio_dev = spi_get_drvdata(spi);
352 struct ad5504_state *st = iio_priv(indio_dev);
353 struct regulator *reg = st->reg;
354 if (spi->irq)
355 free_irq(spi->irq, indio_dev);
356
357 iio_device_unregister(indio_dev);
358
359 if (!IS_ERR(reg)) {
360 regulator_disable(reg);
361 regulator_put(reg);
362 }
363
364 return 0;
365}
366
367static const struct spi_device_id ad5504_id[] = {
368 {"ad5504", ID_AD5504},
369 {"ad5501", ID_AD5501},
370 {}
371};
372
373static struct spi_driver ad5504_driver = {
374 .driver = {
375 .name = "ad5504",
376 .owner = THIS_MODULE,
377 },
378 .probe = ad5504_probe,
379 .remove = __devexit_p(ad5504_remove),
380 .id_table = ad5504_id,
381};
382
383static __init int ad5504_spi_init(void)
384{
385 return spi_register_driver(&ad5504_driver);
386}
387module_init(ad5504_spi_init);
388
389static __exit void ad5504_spi_exit(void)
390{
391 spi_unregister_driver(&ad5504_driver);
392}
393module_exit(ad5504_spi_exit);
394
395MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
396MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
397MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5504.h b/drivers/staging/iio/dac/ad5504.h
new file mode 100644
index 00000000000..85beb1dd29b
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5504.h
@@ -0,0 +1,68 @@
1/*
2 * AD5504 SPI DAC driver
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#ifndef SPI_AD5504_H_
10#define SPI_AD5504_H_
11
12#define AD5505_BITS 12
13#define AD5504_RES_MASK ((1 << (AD5505_BITS)) - 1)
14
15#define AD5504_CMD_READ (1 << 15)
16#define AD5504_CMD_WRITE (0 << 15)
17#define AD5504_ADDR(addr) ((addr) << 12)
18
19/* Registers */
20#define AD5504_ADDR_NOOP 0
21#define AD5504_ADDR_DAC0 1
22#define AD5504_ADDR_DAC1 2
23#define AD5504_ADDR_DAC2 3
24#define AD5504_ADDR_DAC3 4
25#define AD5504_ADDR_ALL_DAC 5
26#define AD5504_ADDR_CTRL 7
27
28/* Control Register */
29#define AD5504_DAC_PWR(ch) ((ch) << 2)
30#define AD5504_DAC_PWRDWN_MODE(mode) ((mode) << 6)
31#define AD5504_DAC_PWRDN_20K 0
32#define AD5504_DAC_PWRDN_3STATE 1
33
34/*
35 * TODO: struct ad5504_platform_data needs to go into include/linux/iio
36 */
37
38struct ad5504_platform_data {
39 u16 vref_mv;
40};
41
42/**
43 * struct ad5446_state - driver instance specific data
44 * @us: spi_device
45 * @reg: supply regulator
46 * @vref_mv: actual reference voltage used
47 * @pwr_down_mask power down mask
48 * @pwr_down_mode current power down mode
49 */
50
51struct ad5504_state {
52 struct spi_device *spi;
53 struct regulator *reg;
54 unsigned short vref_mv;
55 unsigned pwr_down_mask;
56 unsigned pwr_down_mode;
57};
58
59/**
60 * ad5504_supported_device_ids:
61 */
62
63enum ad5504_supported_device_ids {
64 ID_AD5504,
65 ID_AD5501,
66};
67
68#endif /* SPI_AD5504_H_ */
diff --git a/drivers/staging/iio/dac/ad5624r.h b/drivers/staging/iio/dac/ad5624r.h
new file mode 100644
index 00000000000..b71c6a03e78
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5624r.h
@@ -0,0 +1,79 @@
1/*
2 * AD5624R SPI DAC driver
3 *
4 * Copyright 2010-2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8#ifndef SPI_AD5624R_H_
9#define SPI_AD5624R_H_
10
11#define AD5624R_DAC_CHANNELS 4
12
13#define AD5624R_ADDR_DAC0 0x0
14#define AD5624R_ADDR_DAC1 0x1
15#define AD5624R_ADDR_DAC2 0x2
16#define AD5624R_ADDR_DAC3 0x3
17#define AD5624R_ADDR_ALL_DAC 0x7
18
19#define AD5624R_CMD_WRITE_INPUT_N 0x0
20#define AD5624R_CMD_UPDATE_DAC_N 0x1
21#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_ALL 0x2
22#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_N 0x3
23#define AD5624R_CMD_POWERDOWN_DAC 0x4
24#define AD5624R_CMD_RESET 0x5
25#define AD5624R_CMD_LDAC_SETUP 0x6
26#define AD5624R_CMD_INTERNAL_REFER_SETUP 0x7
27
28#define AD5624R_LDAC_PWRDN_NONE 0x0
29#define AD5624R_LDAC_PWRDN_1K 0x1
30#define AD5624R_LDAC_PWRDN_100K 0x2
31#define AD5624R_LDAC_PWRDN_3STATE 0x3
32
33/**
34 * struct ad5624r_chip_info - chip specific information
35 * @bits: accuracy of the DAC in bits
36 * @int_vref_mv: AD5620/40/60: the internal reference voltage
37 */
38
39struct ad5624r_chip_info {
40 u8 bits;
41 u16 int_vref_mv;
42};
43
44/**
45 * struct ad5446_state - driver instance specific data
46 * @indio_dev: the industrial I/O device
47 * @us: spi_device
48 * @chip_info: chip model specific constants, available modes etc
49 * @reg: supply regulator
50 * @vref_mv: actual reference voltage used
51 * @pwr_down_mask power down mask
52 * @pwr_down_mode current power down mode
53 */
54
55struct ad5624r_state {
56 struct spi_device *us;
57 const struct ad5624r_chip_info *chip_info;
58 struct regulator *reg;
59 unsigned short vref_mv;
60 unsigned pwr_down_mask;
61 unsigned pwr_down_mode;
62};
63
64/**
65 * ad5624r_supported_device_ids:
66 * The AD5624/44/64 parts are available in different
67 * fixed internal reference voltage options.
68 */
69
70enum ad5624r_supported_device_ids {
71 ID_AD5624R3,
72 ID_AD5644R3,
73 ID_AD5664R3,
74 ID_AD5624R5,
75 ID_AD5644R5,
76 ID_AD5664R5,
77};
78
79#endif /* SPI_AD5624R_H_ */
diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c
new file mode 100644
index 00000000000..a5b3776718e
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5624r_spi.c
@@ -0,0 +1,336 @@
1/*
2 * AD5624R, AD5644R, AD5664R Digital to analog convertors spi driver
3 *
4 * Copyright 2010-2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/interrupt.h>
10#include <linux/gpio.h>
11#include <linux/fs.h>
12#include <linux/device.h>
13#include <linux/kernel.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h>
16#include <linux/sysfs.h>
17#include <linux/regulator/consumer.h>
18
19#include "../iio.h"
20#include "../sysfs.h"
21#include "dac.h"
22#include "ad5624r.h"
23
24static const struct ad5624r_chip_info ad5624r_chip_info_tbl[] = {
25 [ID_AD5624R3] = {
26 .bits = 12,
27 .int_vref_mv = 1250,
28 },
29 [ID_AD5644R3] = {
30 .bits = 14,
31 .int_vref_mv = 1250,
32 },
33 [ID_AD5664R3] = {
34 .bits = 16,
35 .int_vref_mv = 1250,
36 },
37 [ID_AD5624R5] = {
38 .bits = 12,
39 .int_vref_mv = 2500,
40 },
41 [ID_AD5644R5] = {
42 .bits = 14,
43 .int_vref_mv = 2500,
44 },
45 [ID_AD5664R5] = {
46 .bits = 16,
47 .int_vref_mv = 2500,
48 },
49};
50
51static int ad5624r_spi_write(struct spi_device *spi,
52 u8 cmd, u8 addr, u16 val, u8 len)
53{
54 u32 data;
55 u8 msg[3];
56
57 /*
58 * The input shift register is 24 bits wide. The first two bits are
59 * don't care bits. The next three are the command bits, C2 to C0,
60 * followed by the 3-bit DAC address, A2 to A0, and then the
61 * 16-, 14-, 12-bit data-word. The data-word comprises the 16-,
62 * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits,
63 * for the AD5664R, AD5644R, and AD5624R, respectively.
64 */
65 data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << (16 - len));
66 msg[0] = data >> 16;
67 msg[1] = data >> 8;
68 msg[2] = data;
69
70 return spi_write(spi, msg, 3);
71}
72
73static ssize_t ad5624r_write_dac(struct device *dev,
74 struct device_attribute *attr,
75 const char *buf, size_t len)
76{
77 long readin;
78 int ret;
79 struct iio_dev *indio_dev = dev_get_drvdata(dev);
80 struct ad5624r_state *st = iio_priv(indio_dev);
81 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
82
83 ret = strict_strtol(buf, 10, &readin);
84 if (ret)
85 return ret;
86
87 ret = ad5624r_spi_write(st->us, AD5624R_CMD_WRITE_INPUT_N_UPDATE_N,
88 this_attr->address, readin,
89 st->chip_info->bits);
90 return ret ? ret : len;
91}
92
93static ssize_t ad5624r_read_powerdown_mode(struct device *dev,
94 struct device_attribute *attr, char *buf)
95{
96 struct iio_dev *indio_dev = dev_get_drvdata(dev);
97 struct ad5624r_state *st = iio_priv(indio_dev);
98
99 char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"};
100
101 return sprintf(buf, "%s\n", mode[st->pwr_down_mode]);
102}
103
104static ssize_t ad5624r_write_powerdown_mode(struct device *dev,
105 struct device_attribute *attr,
106 const char *buf, size_t len)
107{
108 struct iio_dev *indio_dev = dev_get_drvdata(dev);
109 struct ad5624r_state *st = iio_priv(indio_dev);
110 int ret;
111
112 if (sysfs_streq(buf, "1kohm_to_gnd"))
113 st->pwr_down_mode = AD5624R_LDAC_PWRDN_1K;
114 else if (sysfs_streq(buf, "100kohm_to_gnd"))
115 st->pwr_down_mode = AD5624R_LDAC_PWRDN_100K;
116 else if (sysfs_streq(buf, "three_state"))
117 st->pwr_down_mode = AD5624R_LDAC_PWRDN_3STATE;
118 else
119 ret = -EINVAL;
120
121 return ret ? ret : len;
122}
123
124static ssize_t ad5624r_read_dac_powerdown(struct device *dev,
125 struct device_attribute *attr,
126 char *buf)
127{
128 struct iio_dev *indio_dev = dev_get_drvdata(dev);
129 struct ad5624r_state *st = iio_priv(indio_dev);
130 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
131
132 return sprintf(buf, "%d\n",
133 !!(st->pwr_down_mask & (1 << this_attr->address)));
134}
135
136static ssize_t ad5624r_write_dac_powerdown(struct device *dev,
137 struct device_attribute *attr,
138 const char *buf, size_t len)
139{
140 long readin;
141 int ret;
142 struct iio_dev *indio_dev = dev_get_drvdata(dev);
143 struct ad5624r_state *st = iio_priv(indio_dev);
144 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
145
146 ret = strict_strtol(buf, 10, &readin);
147 if (ret)
148 return ret;
149
150 if (readin == 1)
151 st->pwr_down_mask |= (1 << this_attr->address);
152 else if (!readin)
153 st->pwr_down_mask &= ~(1 << this_attr->address);
154 else
155 ret = -EINVAL;
156
157 ret = ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0,
158 (st->pwr_down_mode << 4) |
159 st->pwr_down_mask, 16);
160
161 return ret ? ret : len;
162}
163
164static ssize_t ad5624r_show_scale(struct device *dev,
165 struct device_attribute *attr,
166 char *buf)
167{
168 struct iio_dev *indio_dev = dev_get_drvdata(dev);
169 struct ad5624r_state *st = iio_priv(indio_dev);
170 /* Corresponds to Vref / 2^(bits) */
171 unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits;
172
173 return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
174}
175static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5624r_show_scale, NULL, 0);
176
177static IIO_DEV_ATTR_OUT_RAW(0, ad5624r_write_dac, AD5624R_ADDR_DAC0);
178static IIO_DEV_ATTR_OUT_RAW(1, ad5624r_write_dac, AD5624R_ADDR_DAC1);
179static IIO_DEV_ATTR_OUT_RAW(2, ad5624r_write_dac, AD5624R_ADDR_DAC2);
180static IIO_DEV_ATTR_OUT_RAW(3, ad5624r_write_dac, AD5624R_ADDR_DAC3);
181
182static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO |
183 S_IWUSR, ad5624r_read_powerdown_mode,
184 ad5624r_write_powerdown_mode, 0);
185
186static IIO_CONST_ATTR(out_powerdown_mode_available,
187 "1kohm_to_gnd 100kohm_to_gnd three_state");
188
189#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr) \
190 IIO_DEVICE_ATTR(out##_num##_powerdown, \
191 S_IRUGO | S_IWUSR, _show, _store, _addr)
192
193static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5624r_read_dac_powerdown,
194 ad5624r_write_dac_powerdown, 0);
195static IIO_DEV_ATTR_DAC_POWERDOWN(1, ad5624r_read_dac_powerdown,
196 ad5624r_write_dac_powerdown, 1);
197static IIO_DEV_ATTR_DAC_POWERDOWN(2, ad5624r_read_dac_powerdown,
198 ad5624r_write_dac_powerdown, 2);
199static IIO_DEV_ATTR_DAC_POWERDOWN(3, ad5624r_read_dac_powerdown,
200 ad5624r_write_dac_powerdown, 3);
201
202static struct attribute *ad5624r_attributes[] = {
203 &iio_dev_attr_out0_raw.dev_attr.attr,
204 &iio_dev_attr_out1_raw.dev_attr.attr,
205 &iio_dev_attr_out2_raw.dev_attr.attr,
206 &iio_dev_attr_out3_raw.dev_attr.attr,
207 &iio_dev_attr_out0_powerdown.dev_attr.attr,
208 &iio_dev_attr_out1_powerdown.dev_attr.attr,
209 &iio_dev_attr_out2_powerdown.dev_attr.attr,
210 &iio_dev_attr_out3_powerdown.dev_attr.attr,
211 &iio_dev_attr_out_powerdown_mode.dev_attr.attr,
212 &iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
213 &iio_dev_attr_out_scale.dev_attr.attr,
214 NULL,
215};
216
217static const struct attribute_group ad5624r_attribute_group = {
218 .attrs = ad5624r_attributes,
219};
220
221static const struct iio_info ad5624r_info = {
222 .attrs = &ad5624r_attribute_group,
223 .driver_module = THIS_MODULE,
224};
225
226static int __devinit ad5624r_probe(struct spi_device *spi)
227{
228 struct ad5624r_state *st;
229 struct iio_dev *indio_dev;
230 struct regulator *reg;
231 int ret, voltage_uv = 0;
232
233 reg = regulator_get(&spi->dev, "vcc");
234 if (!IS_ERR(reg)) {
235 ret = regulator_enable(reg);
236 if (ret)
237 goto error_put_reg;
238
239 voltage_uv = regulator_get_voltage(reg);
240 }
241 indio_dev = iio_allocate_device(sizeof(*st));
242 if (indio_dev == NULL) {
243 ret = -ENOMEM;
244 goto error_disable_reg;
245 }
246 st = iio_priv(indio_dev);
247 st->reg = reg;
248 spi_set_drvdata(spi, indio_dev);
249 st->chip_info =
250 &ad5624r_chip_info_tbl[spi_get_device_id(spi)->driver_data];
251
252 if (voltage_uv)
253 st->vref_mv = voltage_uv / 1000;
254 else
255 st->vref_mv = st->chip_info->int_vref_mv;
256
257 st->us = spi;
258
259 indio_dev->dev.parent = &spi->dev;
260 indio_dev->name = spi_get_device_id(spi)->name;
261 indio_dev->info = &ad5624r_info;
262 indio_dev->modes = INDIO_DIRECT_MODE;
263
264 ret = iio_device_register(indio_dev);
265 if (ret)
266 goto error_free_dev;
267
268 ret = ad5624r_spi_write(spi, AD5624R_CMD_INTERNAL_REFER_SETUP, 0,
269 !!voltage_uv, 16);
270 if (ret)
271 goto error_free_dev;
272
273 return 0;
274
275error_free_dev:
276 iio_free_device(indio_dev);
277error_disable_reg:
278 if (!IS_ERR(reg))
279 regulator_disable(reg);
280error_put_reg:
281 if (!IS_ERR(reg))
282 regulator_put(reg);
283
284 return ret;
285}
286
287static int __devexit ad5624r_remove(struct spi_device *spi)
288{
289 struct iio_dev *indio_dev = spi_get_drvdata(spi);
290 struct ad5624r_state *st = iio_priv(indio_dev);
291 struct regulator *reg = st->reg;
292
293 iio_device_unregister(indio_dev);
294 if (!IS_ERR(reg)) {
295 regulator_disable(reg);
296 regulator_put(reg);
297 }
298
299 return 0;
300}
301
302static const struct spi_device_id ad5624r_id[] = {
303 {"ad5624r3", ID_AD5624R3},
304 {"ad5644r3", ID_AD5644R3},
305 {"ad5664r3", ID_AD5664R3},
306 {"ad5624r5", ID_AD5624R5},
307 {"ad5644r5", ID_AD5644R5},
308 {"ad5664r5", ID_AD5664R5},
309 {}
310};
311
312static struct spi_driver ad5624r_driver = {
313 .driver = {
314 .name = "ad5624r",
315 .owner = THIS_MODULE,
316 },
317 .probe = ad5624r_probe,
318 .remove = __devexit_p(ad5624r_remove),
319 .id_table = ad5624r_id,
320};
321
322static __init int ad5624r_spi_init(void)
323{
324 return spi_register_driver(&ad5624r_driver);
325}
326module_init(ad5624r_spi_init);
327
328static __exit void ad5624r_spi_exit(void)
329{
330 spi_unregister_driver(&ad5624r_driver);
331}
332module_exit(ad5624r_spi_exit);
333
334MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
335MODULE_DESCRIPTION("Analog Devices AD5624/44/64R DAC spi driver");
336MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c
new file mode 100644
index 00000000000..fd67cfa5edb
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5686.c
@@ -0,0 +1,497 @@
1/*
2 * AD5686R, AD5685R, AD5684R Digital to analog converters driver
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/interrupt.h>
10#include <linux/gpio.h>
11#include <linux/fs.h>
12#include <linux/device.h>
13#include <linux/kernel.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h>
16#include <linux/sysfs.h>
17#include <linux/regulator/consumer.h>
18
19#include "../iio.h"
20#include "../sysfs.h"
21#include "dac.h"
22
23#define AD5686_DAC_CHANNELS 4
24
25#define AD5686_ADDR(x) ((x) << 16)
26#define AD5686_CMD(x) ((x) << 20)
27
28#define AD5686_ADDR_DAC0 0x1
29#define AD5686_ADDR_DAC1 0x2
30#define AD5686_ADDR_DAC2 0x4
31#define AD5686_ADDR_DAC3 0x8
32#define AD5686_ADDR_ALL_DAC 0xF
33
34#define AD5686_CMD_NOOP 0x0
35#define AD5686_CMD_WRITE_INPUT_N 0x1
36#define AD5686_CMD_UPDATE_DAC_N 0x2
37#define AD5686_CMD_WRITE_INPUT_N_UPDATE_N 0x3
38#define AD5686_CMD_POWERDOWN_DAC 0x4
39#define AD5686_CMD_LDAC_MASK 0x5
40#define AD5686_CMD_RESET 0x6
41#define AD5686_CMD_INTERNAL_REFER_SETUP 0x7
42#define AD5686_CMD_DAISY_CHAIN_ENABLE 0x8
43#define AD5686_CMD_READBACK_ENABLE 0x9
44
45#define AD5686_LDAC_PWRDN_NONE 0x0
46#define AD5686_LDAC_PWRDN_1K 0x1
47#define AD5686_LDAC_PWRDN_100K 0x2
48#define AD5686_LDAC_PWRDN_3STATE 0x3
49
50/**
51 * struct ad5686_chip_info - chip specific information
52 * @int_vref_mv: AD5620/40/60: the internal reference voltage
53 * @channel: channel specification
54*/
55
56struct ad5686_chip_info {
57 u16 int_vref_mv;
58 struct iio_chan_spec channel[AD5686_DAC_CHANNELS];
59};
60
61/**
62 * struct ad5446_state - driver instance specific data
63 * @spi: spi_device
64 * @chip_info: chip model specific constants, available modes etc
65 * @reg: supply regulator
66 * @vref_mv: actual reference voltage used
67 * @pwr_down_mask: power down mask
68 * @pwr_down_mode: current power down mode
69 * @data: spi transfer buffers
70 */
71
72struct ad5686_state {
73 struct spi_device *spi;
74 const struct ad5686_chip_info *chip_info;
75 struct regulator *reg;
76 unsigned short vref_mv;
77 unsigned pwr_down_mask;
78 unsigned pwr_down_mode;
79 /*
80 * DMA (thus cache coherency maintenance) requires the
81 * transfer buffers to live in their own cache lines.
82 */
83
84 union {
85 u32 d32;
86 u8 d8[4];
87 } data[3] ____cacheline_aligned;
88};
89
90/**
91 * ad5686_supported_device_ids:
92 */
93
94enum ad5686_supported_device_ids {
95 ID_AD5684,
96 ID_AD5685,
97 ID_AD5686,
98};
99
100static const struct ad5686_chip_info ad5686_chip_info_tbl[] = {
101 [ID_AD5684] = {
102 .channel[0] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 0, 0,
103 (1 << IIO_CHAN_INFO_SCALE_SHARED),
104 AD5686_ADDR_DAC0,
105 0, IIO_ST('u', 12, 16, 4), 0),
106 .channel[1] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 1, 0,
107 (1 << IIO_CHAN_INFO_SCALE_SHARED),
108 AD5686_ADDR_DAC1,
109 1, IIO_ST('u', 12, 16, 4), 0),
110 .channel[2] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 2, 0,
111 (1 << IIO_CHAN_INFO_SCALE_SHARED),
112 AD5686_ADDR_DAC2,
113 2, IIO_ST('u', 12, 16, 4), 0),
114 .channel[3] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 3, 0,
115 (1 << IIO_CHAN_INFO_SCALE_SHARED),
116 AD5686_ADDR_DAC3,
117 3, IIO_ST('u', 12, 16, 4), 0),
118 .int_vref_mv = 2500,
119 },
120 [ID_AD5685] = {
121 .channel[0] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 0, 0,
122 (1 << IIO_CHAN_INFO_SCALE_SHARED),
123 AD5686_ADDR_DAC0,
124 0, IIO_ST('u', 14, 16, 2), 0),
125 .channel[1] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 1, 0,
126 (1 << IIO_CHAN_INFO_SCALE_SHARED),
127 AD5686_ADDR_DAC1,
128 1, IIO_ST('u', 14, 16, 2), 0),
129 .channel[2] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 2, 0,
130 (1 << IIO_CHAN_INFO_SCALE_SHARED),
131 AD5686_ADDR_DAC2,
132 2, IIO_ST('u', 14, 16, 2), 0),
133 .channel[3] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 3, 0,
134 (1 << IIO_CHAN_INFO_SCALE_SHARED),
135 AD5686_ADDR_DAC3,
136 3, IIO_ST('u', 14, 16, 2), 0),
137 .int_vref_mv = 2500,
138 },
139 [ID_AD5686] = {
140 .channel[0] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 0, 0,
141 (1 << IIO_CHAN_INFO_SCALE_SHARED),
142 AD5686_ADDR_DAC0,
143 0, IIO_ST('u', 16, 16, 0), 0),
144 .channel[1] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 1, 0,
145 (1 << IIO_CHAN_INFO_SCALE_SHARED),
146 AD5686_ADDR_DAC1,
147 1, IIO_ST('u', 16, 16, 0), 0),
148 .channel[2] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 2, 0,
149 (1 << IIO_CHAN_INFO_SCALE_SHARED),
150 AD5686_ADDR_DAC2,
151 2, IIO_ST('u', 16, 16, 0), 0),
152 .channel[3] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 3, 0,
153 (1 << IIO_CHAN_INFO_SCALE_SHARED),
154 AD5686_ADDR_DAC3,
155 3, IIO_ST('u', 16, 16, 0), 0),
156 .int_vref_mv = 2500,
157 },
158};
159
160static int ad5686_spi_write(struct ad5686_state *st,
161 u8 cmd, u8 addr, u16 val, u8 shift)
162{
163 val <<= shift;
164
165 st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
166 AD5686_ADDR(addr) |
167 val);
168
169 return spi_write(st->spi, &st->data[0].d8[1], 3);
170}
171
172static int ad5686_spi_read(struct ad5686_state *st, u8 addr)
173{
174 struct spi_transfer t[] = {
175 {
176 .tx_buf = &st->data[0].d8[1],
177 .len = 3,
178 .cs_change = 1,
179 }, {
180 .tx_buf = &st->data[1].d8[1],
181 .rx_buf = &st->data[2].d8[1],
182 .len = 3,
183 },
184 };
185 struct spi_message m;
186 int ret;
187
188 spi_message_init(&m);
189 spi_message_add_tail(&t[0], &m);
190 spi_message_add_tail(&t[1], &m);
191
192 st->data[0].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_READBACK_ENABLE) |
193 AD5686_ADDR(addr));
194 st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP));
195
196 ret = spi_sync(st->spi, &m);
197 if (ret < 0)
198 return ret;
199
200 return be32_to_cpu(st->data[2].d32);
201}
202
203static ssize_t ad5686_read_powerdown_mode(struct device *dev,
204 struct device_attribute *attr, char *buf)
205{
206 struct iio_dev *indio_dev = dev_get_drvdata(dev);
207 struct ad5686_state *st = iio_priv(indio_dev);
208 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
209
210 char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"};
211
212 return sprintf(buf, "%s\n", mode[(st->pwr_down_mode >>
213 (this_attr->address * 2)) & 0x3]);
214}
215
216static ssize_t ad5686_write_powerdown_mode(struct device *dev,
217 struct device_attribute *attr,
218 const char *buf, size_t len)
219{
220 struct iio_dev *indio_dev = dev_get_drvdata(dev);
221 struct ad5686_state *st = iio_priv(indio_dev);
222 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
223 unsigned mode;
224
225 if (sysfs_streq(buf, "1kohm_to_gnd"))
226 mode = AD5686_LDAC_PWRDN_1K;
227 else if (sysfs_streq(buf, "100kohm_to_gnd"))
228 mode = AD5686_LDAC_PWRDN_100K;
229 else if (sysfs_streq(buf, "three_state"))
230 mode = AD5686_LDAC_PWRDN_3STATE;
231 else
232 return -EINVAL;
233
234 st->pwr_down_mode &= ~(0x3 << (this_attr->address * 2));
235 st->pwr_down_mode |= (mode << (this_attr->address * 2));
236
237 return len;
238}
239
240static ssize_t ad5686_read_dac_powerdown(struct device *dev,
241 struct device_attribute *attr,
242 char *buf)
243{
244 struct iio_dev *indio_dev = dev_get_drvdata(dev);
245 struct ad5686_state *st = iio_priv(indio_dev);
246 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
247
248 return sprintf(buf, "%d\n", !!(st->pwr_down_mask &
249 (0x3 << (this_attr->address * 2))));
250}
251
252static ssize_t ad5686_write_dac_powerdown(struct device *dev,
253 struct device_attribute *attr,
254 const char *buf, size_t len)
255{
256 bool readin;
257 int ret;
258 struct iio_dev *indio_dev = dev_get_drvdata(dev);
259 struct ad5686_state *st = iio_priv(indio_dev);
260 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
261
262 ret = strtobool(buf, &readin);
263 if (ret)
264 return ret;
265
266 if (readin == true)
267 st->pwr_down_mask |= (0x3 << (this_attr->address * 2));
268 else
269 st->pwr_down_mask &= ~(0x3 << (this_attr->address * 2));
270
271 ret = ad5686_spi_write(st, AD5686_CMD_POWERDOWN_DAC, 0,
272 st->pwr_down_mask & st->pwr_down_mode, 0);
273
274 return ret ? ret : len;
275}
276
277static IIO_CONST_ATTR(out_powerdown_mode_available,
278 "1kohm_to_gnd 100kohm_to_gnd three_state");
279
280#define IIO_DEV_ATTR_DAC_POWERDOWN_MODE(_num) \
281 IIO_DEVICE_ATTR(out##_num##_powerdown_mode, S_IRUGO | S_IWUSR, \
282 ad5686_read_powerdown_mode, \
283 ad5686_write_powerdown_mode, _num)
284
285static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(0);
286static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(1);
287static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(2);
288static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(3);
289
290#define IIO_DEV_ATTR_DAC_POWERDOWN(_num) \
291 IIO_DEVICE_ATTR(out##_num##_powerdown, S_IRUGO | S_IWUSR, \
292 ad5686_read_dac_powerdown, \
293 ad5686_write_dac_powerdown, _num)
294
295static IIO_DEV_ATTR_DAC_POWERDOWN(0);
296static IIO_DEV_ATTR_DAC_POWERDOWN(1);
297static IIO_DEV_ATTR_DAC_POWERDOWN(2);
298static IIO_DEV_ATTR_DAC_POWERDOWN(3);
299
300static struct attribute *ad5686_attributes[] = {
301 &iio_dev_attr_out0_powerdown.dev_attr.attr,
302 &iio_dev_attr_out1_powerdown.dev_attr.attr,
303 &iio_dev_attr_out2_powerdown.dev_attr.attr,
304 &iio_dev_attr_out3_powerdown.dev_attr.attr,
305 &iio_dev_attr_out0_powerdown_mode.dev_attr.attr,
306 &iio_dev_attr_out1_powerdown_mode.dev_attr.attr,
307 &iio_dev_attr_out2_powerdown_mode.dev_attr.attr,
308 &iio_dev_attr_out3_powerdown_mode.dev_attr.attr,
309 &iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
310 NULL,
311};
312
313static const struct attribute_group ad5686_attribute_group = {
314 .attrs = ad5686_attributes,
315};
316
317static int ad5686_read_raw(struct iio_dev *indio_dev,
318 struct iio_chan_spec const *chan,
319 int *val,
320 int *val2,
321 long m)
322{
323 struct ad5686_state *st = iio_priv(indio_dev);
324 unsigned long scale_uv;
325 int ret;
326
327 switch (m) {
328 case 0:
329 mutex_lock(&indio_dev->mlock);
330 ret = ad5686_spi_read(st, chan->address);
331 mutex_unlock(&indio_dev->mlock);
332 if (ret < 0)
333 return ret;
334 *val = ret;
335 return IIO_VAL_INT;
336 break;
337 case (1 << IIO_CHAN_INFO_SCALE_SHARED):
338 scale_uv = (st->vref_mv * 100000)
339 >> (chan->scan_type.realbits);
340 *val = scale_uv / 100000;
341 *val2 = (scale_uv % 100000) * 10;
342 return IIO_VAL_INT_PLUS_MICRO;
343
344 }
345 return -EINVAL;
346}
347
348static int ad5686_write_raw(struct iio_dev *indio_dev,
349 struct iio_chan_spec const *chan,
350 int val,
351 int val2,
352 long mask)
353{
354 struct ad5686_state *st = iio_priv(indio_dev);
355 int ret;
356
357 switch (mask) {
358 case 0:
359 if (val > (1 << chan->scan_type.realbits))
360 return -EINVAL;
361
362 mutex_lock(&indio_dev->mlock);
363 ret = ad5686_spi_write(st,
364 AD5686_CMD_WRITE_INPUT_N_UPDATE_N,
365 chan->address,
366 val,
367 chan->scan_type.shift);
368 mutex_unlock(&indio_dev->mlock);
369 break;
370 default:
371 ret = -EINVAL;
372 }
373
374 return ret;
375}
376
377static const struct iio_info ad5686_info = {
378 .read_raw = ad5686_read_raw,
379 .write_raw = ad5686_write_raw,
380 .attrs = &ad5686_attribute_group,
381 .driver_module = THIS_MODULE,
382};
383
384static int __devinit ad5686_probe(struct spi_device *spi)
385{
386 struct ad5686_state *st;
387 struct iio_dev *indio_dev;
388 int ret, regdone = 0, voltage_uv = 0;
389
390 indio_dev = iio_allocate_device(sizeof(*st));
391 if (indio_dev == NULL)
392 return -ENOMEM;
393
394 st = iio_priv(indio_dev);
395 spi_set_drvdata(spi, indio_dev);
396
397 st->reg = regulator_get(&spi->dev, "vcc");
398 if (!IS_ERR(st->reg)) {
399 ret = regulator_enable(st->reg);
400 if (ret)
401 goto error_put_reg;
402
403 voltage_uv = regulator_get_voltage(st->reg);
404 }
405
406 st->chip_info =
407 &ad5686_chip_info_tbl[spi_get_device_id(spi)->driver_data];
408
409 if (voltage_uv)
410 st->vref_mv = voltage_uv / 1000;
411 else
412 st->vref_mv = st->chip_info->int_vref_mv;
413
414 st->spi = spi;
415
416 indio_dev->dev.parent = &spi->dev;
417 indio_dev->name = spi_get_device_id(spi)->name;
418 indio_dev->info = &ad5686_info;
419 indio_dev->modes = INDIO_DIRECT_MODE;
420 indio_dev->channels = st->chip_info->channel;
421 indio_dev->num_channels = AD5686_DAC_CHANNELS;
422
423 ret = iio_device_register(indio_dev);
424 if (ret)
425 goto error_disable_reg;
426
427 regdone = 1;
428 ret = ad5686_spi_write(st, AD5686_CMD_INTERNAL_REFER_SETUP, 0,
429 !!voltage_uv, 0);
430 if (ret)
431 goto error_disable_reg;
432
433 return 0;
434
435error_disable_reg:
436 if (!IS_ERR(st->reg))
437 regulator_disable(st->reg);
438error_put_reg:
439 if (!IS_ERR(st->reg))
440 regulator_put(st->reg);
441
442 if (regdone)
443 iio_device_unregister(indio_dev);
444 else
445 iio_free_device(indio_dev);
446
447 return ret;
448}
449
450static int __devexit ad5686_remove(struct spi_device *spi)
451{
452 struct iio_dev *indio_dev = spi_get_drvdata(spi);
453 struct ad5686_state *st = iio_priv(indio_dev);
454 struct regulator *reg = st->reg;
455
456 if (!IS_ERR(reg)) {
457 regulator_disable(reg);
458 regulator_put(reg);
459 }
460
461 iio_device_unregister(indio_dev);
462
463 return 0;
464}
465
466static const struct spi_device_id ad5686_id[] = {
467 {"ad5684", ID_AD5684},
468 {"ad5685", ID_AD5685},
469 {"ad5686", ID_AD5686},
470 {}
471};
472
473static struct spi_driver ad5686_driver = {
474 .driver = {
475 .name = "ad5686",
476 .owner = THIS_MODULE,
477 },
478 .probe = ad5686_probe,
479 .remove = __devexit_p(ad5686_remove),
480 .id_table = ad5686_id,
481};
482
483static __init int ad5686_spi_init(void)
484{
485 return spi_register_driver(&ad5686_driver);
486}
487module_init(ad5686_spi_init);
488
489static __exit void ad5686_spi_exit(void)
490{
491 spi_unregister_driver(&ad5686_driver);
492}
493module_exit(ad5686_spi_exit);
494
495MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
496MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC");
497MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c
new file mode 100644
index 00000000000..64770d2a1b4
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5791.c
@@ -0,0 +1,442 @@
1/*
2 * AD5760, AD5780, AD5781, AD5791 Voltage Output Digital to Analog Converter
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/interrupt.h>
10#include <linux/gpio.h>
11#include <linux/fs.h>
12#include <linux/device.h>
13#include <linux/kernel.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h>
16#include <linux/sysfs.h>
17#include <linux/regulator/consumer.h>
18
19#include "../iio.h"
20#include "../sysfs.h"
21#include "dac.h"
22#include "ad5791.h"
23
24static int ad5791_spi_write(struct spi_device *spi, u8 addr, u32 val)
25{
26 union {
27 u32 d32;
28 u8 d8[4];
29 } data;
30
31 data.d32 = cpu_to_be32(AD5791_CMD_WRITE |
32 AD5791_ADDR(addr) |
33 (val & AD5791_DAC_MASK));
34
35 return spi_write(spi, &data.d8[1], 3);
36}
37
38static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val)
39{
40 union {
41 u32 d32;
42 u8 d8[4];
43 } data[3];
44 int ret;
45 struct spi_message msg;
46 struct spi_transfer xfers[] = {
47 {
48 .tx_buf = &data[0].d8[1],
49 .bits_per_word = 8,
50 .len = 3,
51 .cs_change = 1,
52 }, {
53 .tx_buf = &data[1].d8[1],
54 .rx_buf = &data[2].d8[1],
55 .bits_per_word = 8,
56 .len = 3,
57 },
58 };
59
60 data[0].d32 = cpu_to_be32(AD5791_CMD_READ |
61 AD5791_ADDR(addr));
62 data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP));
63
64 spi_message_init(&msg);
65 spi_message_add_tail(&xfers[0], &msg);
66 spi_message_add_tail(&xfers[1], &msg);
67 ret = spi_sync(spi, &msg);
68
69 *val = be32_to_cpu(data[2].d32);
70
71 return ret;
72}
73
74static ssize_t ad5791_write_dac(struct device *dev,
75 struct device_attribute *attr,
76 const char *buf, size_t len)
77{
78 struct iio_dev *indio_dev = dev_get_drvdata(dev);
79 struct ad5791_state *st = iio_priv(indio_dev);
80 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
81 long readin;
82 int ret;
83
84 ret = strict_strtol(buf, 10, &readin);
85 if (ret)
86 return ret;
87
88 readin += (1 << (st->chip_info->bits - 1));
89 readin &= AD5791_RES_MASK(st->chip_info->bits);
90 readin <<= st->chip_info->left_shift;
91
92 ret = ad5791_spi_write(st->spi, this_attr->address, readin);
93 return ret ? ret : len;
94}
95
96static ssize_t ad5791_read_dac(struct device *dev,
97 struct device_attribute *attr,
98 char *buf)
99{
100 struct iio_dev *indio_dev = dev_get_drvdata(dev);
101 struct ad5791_state *st = iio_priv(indio_dev);
102 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
103 int ret;
104 int val;
105
106 ret = ad5791_spi_read(st->spi, this_attr->address, &val);
107 if (ret)
108 return ret;
109
110 val &= AD5791_DAC_MASK;
111 val >>= st->chip_info->left_shift;
112 val -= (1 << (st->chip_info->bits - 1));
113
114 return sprintf(buf, "%d\n", val);
115}
116
117static ssize_t ad5791_read_powerdown_mode(struct device *dev,
118 struct device_attribute *attr, char *buf)
119{
120 struct iio_dev *indio_dev = dev_get_drvdata(dev);
121 struct ad5791_state *st = iio_priv(indio_dev);
122
123 const char mode[][14] = {"6kohm_to_gnd", "three_state"};
124
125 return sprintf(buf, "%s\n", mode[st->pwr_down_mode]);
126}
127
128static ssize_t ad5791_write_powerdown_mode(struct device *dev,
129 struct device_attribute *attr,
130 const char *buf, size_t len)
131{
132 struct iio_dev *indio_dev = dev_get_drvdata(dev);
133 struct ad5791_state *st = iio_priv(indio_dev);
134 int ret;
135
136 if (sysfs_streq(buf, "6kohm_to_gnd"))
137 st->pwr_down_mode = AD5791_DAC_PWRDN_6K;
138 else if (sysfs_streq(buf, "three_state"))
139 st->pwr_down_mode = AD5791_DAC_PWRDN_3STATE;
140 else
141 ret = -EINVAL;
142
143 return ret ? ret : len;
144}
145
146static ssize_t ad5791_read_dac_powerdown(struct device *dev,
147 struct device_attribute *attr,
148 char *buf)
149{
150 struct iio_dev *indio_dev = dev_get_drvdata(dev);
151 struct ad5791_state *st = iio_priv(indio_dev);
152
153 return sprintf(buf, "%d\n", st->pwr_down);
154}
155
156static ssize_t ad5791_write_dac_powerdown(struct device *dev,
157 struct device_attribute *attr,
158 const char *buf, size_t len)
159{
160 long readin;
161 int ret;
162 struct iio_dev *indio_dev = dev_get_drvdata(dev);
163 struct ad5791_state *st = iio_priv(indio_dev);
164
165 ret = strict_strtol(buf, 10, &readin);
166 if (ret)
167 return ret;
168
169 if (readin == 0) {
170 st->pwr_down = false;
171 st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
172 } else if (readin == 1) {
173 st->pwr_down = true;
174 if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K)
175 st->ctrl |= AD5791_CTRL_OPGND;
176 else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE)
177 st->ctrl |= AD5791_CTRL_DACTRI;
178 } else
179 ret = -EINVAL;
180
181 ret = ad5791_spi_write(st->spi, AD5791_ADDR_CTRL, st->ctrl);
182
183 return ret ? ret : len;
184}
185
186static ssize_t ad5791_show_scale(struct device *dev,
187 struct device_attribute *attr,
188 char *buf)
189{
190 struct iio_dev *indio_dev = dev_get_drvdata(dev);
191 struct ad5791_state *st = iio_priv(indio_dev);
192 /* Corresponds to Vref / 2^(bits) */
193 unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits;
194
195 return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
196}
197static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5791_show_scale, NULL, 0);
198
199static ssize_t ad5791_show_name(struct device *dev,
200 struct device_attribute *attr,
201 char *buf)
202{
203 struct iio_dev *indio_dev = dev_get_drvdata(dev);
204 struct ad5791_state *st = iio_priv(indio_dev);
205
206 return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
207}
208static IIO_DEVICE_ATTR(name, S_IRUGO, ad5791_show_name, NULL, 0);
209
210#define IIO_DEV_ATTR_OUT_RW_RAW(_num, _show, _store, _addr) \
211 IIO_DEVICE_ATTR(out##_num##_raw, \
212 S_IRUGO | S_IWUSR, _show, _store, _addr)
213
214static IIO_DEV_ATTR_OUT_RW_RAW(0, ad5791_read_dac,
215 ad5791_write_dac, AD5791_ADDR_DAC0);
216
217static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO |
218 S_IWUSR, ad5791_read_powerdown_mode,
219 ad5791_write_powerdown_mode, 0);
220
221static IIO_CONST_ATTR(out_powerdown_mode_available,
222 "6kohm_to_gnd three_state");
223
224#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr) \
225 IIO_DEVICE_ATTR(out##_num##_powerdown, \
226 S_IRUGO | S_IWUSR, _show, _store, _addr)
227
228static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5791_read_dac_powerdown,
229 ad5791_write_dac_powerdown, 0);
230
231static struct attribute *ad5791_attributes[] = {
232 &iio_dev_attr_out0_raw.dev_attr.attr,
233 &iio_dev_attr_out0_powerdown.dev_attr.attr,
234 &iio_dev_attr_out_powerdown_mode.dev_attr.attr,
235 &iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
236 &iio_dev_attr_out_scale.dev_attr.attr,
237 &iio_dev_attr_name.dev_attr.attr,
238 NULL,
239};
240
241static const struct attribute_group ad5791_attribute_group = {
242 .attrs = ad5791_attributes,
243};
244
245static int ad5791_get_lin_comp(unsigned int span)
246{
247 if (span <= 10000)
248 return AD5791_LINCOMP_0_10;
249 else if (span <= 12000)
250 return AD5791_LINCOMP_10_12;
251 else if (span <= 16000)
252 return AD5791_LINCOMP_12_16;
253 else if (span <= 19000)
254 return AD5791_LINCOMP_16_19;
255 else
256 return AD5791_LINCOMP_19_20;
257}
258
259static int ad5780_get_lin_comp(unsigned int span)
260{
261 if (span <= 10000)
262 return AD5780_LINCOMP_0_10;
263 else
264 return AD5780_LINCOMP_10_20;
265}
266
267static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
268 [ID_AD5760] = {
269 .bits = 16,
270 .left_shift = 4,
271 .get_lin_comp = ad5780_get_lin_comp,
272 },
273 [ID_AD5780] = {
274 .bits = 18,
275 .left_shift = 2,
276 .get_lin_comp = ad5780_get_lin_comp,
277 },
278 [ID_AD5781] = {
279 .bits = 18,
280 .left_shift = 2,
281 .get_lin_comp = ad5791_get_lin_comp,
282 },
283 [ID_AD5791] = {
284 .bits = 20,
285 .left_shift = 0,
286 .get_lin_comp = ad5791_get_lin_comp,
287 },
288};
289
290static const struct iio_info ad5791_info = {
291 .attrs = &ad5791_attribute_group,
292 .driver_module = THIS_MODULE,
293};
294
295static int __devinit ad5791_probe(struct spi_device *spi)
296{
297 struct ad5791_platform_data *pdata = spi->dev.platform_data;
298 struct iio_dev *indio_dev;
299 struct regulator *reg_vdd, *reg_vss;
300 struct ad5791_state *st;
301 int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
302
303 reg_vdd = regulator_get(&spi->dev, "vdd");
304 if (!IS_ERR(reg_vdd)) {
305 ret = regulator_enable(reg_vdd);
306 if (ret)
307 goto error_put_reg_pos;
308
309 pos_voltage_uv = regulator_get_voltage(reg_vdd);
310 }
311
312 reg_vss = regulator_get(&spi->dev, "vss");
313 if (!IS_ERR(reg_vss)) {
314 ret = regulator_enable(reg_vss);
315 if (ret)
316 goto error_put_reg_neg;
317
318 neg_voltage_uv = regulator_get_voltage(reg_vss);
319 }
320
321 indio_dev = iio_allocate_device(sizeof(*st));
322 if (indio_dev == NULL) {
323 ret = -ENOMEM;
324 goto error_disable_reg_neg;
325 }
326 st = iio_priv(indio_dev);
327 st->pwr_down = true;
328 st->spi = spi;
329
330 if (!IS_ERR(reg_vss) && !IS_ERR(reg_vdd))
331 st->vref_mv = (pos_voltage_uv - neg_voltage_uv) / 1000;
332 else if (pdata)
333 st->vref_mv = pdata->vref_pos_mv - pdata->vref_neg_mv;
334 else
335 dev_warn(&spi->dev, "reference voltage unspecified\n");
336
337 ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
338 if (ret)
339 goto error_free_dev;
340
341 st->chip_info =
342 &ad5791_chip_info_tbl[spi_get_device_id(spi)->driver_data];
343
344
345 st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv))
346 | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) |
347 AD5791_CTRL_BIN2SC;
348
349 ret = ad5791_spi_write(spi, AD5791_ADDR_CTRL, st->ctrl |
350 AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
351 if (ret)
352 goto error_free_dev;
353
354 st->reg_vdd = reg_vdd;
355 st->reg_vss = reg_vss;
356
357 spi_set_drvdata(spi, indio_dev);
358 indio_dev->dev.parent = &spi->dev;
359 indio_dev->info = &ad5791_info;
360 indio_dev->modes = INDIO_DIRECT_MODE;
361
362 ret = iio_device_register(indio_dev);
363 if (ret)
364 goto error_free_dev;
365
366 return 0;
367
368error_free_dev:
369 iio_free_device(indio_dev);
370
371error_disable_reg_neg:
372 if (!IS_ERR(reg_vss))
373 regulator_disable(reg_vss);
374error_put_reg_neg:
375 if (!IS_ERR(reg_vss))
376 regulator_put(reg_vss);
377
378 if (!IS_ERR(reg_vdd))
379 regulator_disable(reg_vdd);
380error_put_reg_pos:
381 if (!IS_ERR(reg_vdd))
382 regulator_put(reg_vdd);
383
384error_ret:
385 return ret;
386}
387
388static int __devexit ad5791_remove(struct spi_device *spi)
389{
390 struct iio_dev *indio_dev = spi_get_drvdata(spi);
391 struct ad5791_state *st = iio_priv(indio_dev);
392 struct regulator *reg_vdd = st->reg_vdd;
393 struct regulator *reg_vss = st->reg_vss;
394
395 iio_device_unregister(indio_dev);
396
397 if (!IS_ERR(st->reg_vdd)) {
398 regulator_disable(reg_vdd);
399 regulator_put(reg_vdd);
400 }
401
402 if (!IS_ERR(st->reg_vss)) {
403 regulator_disable(reg_vss);
404 regulator_put(reg_vss);
405 }
406
407 return 0;
408}
409
410static const struct spi_device_id ad5791_id[] = {
411 {"ad5760", ID_AD5760},
412 {"ad5780", ID_AD5780},
413 {"ad5781", ID_AD5781},
414 {"ad5791", ID_AD5791},
415 {}
416};
417
418static struct spi_driver ad5791_driver = {
419 .driver = {
420 .name = "ad5791",
421 .owner = THIS_MODULE,
422 },
423 .probe = ad5791_probe,
424 .remove = __devexit_p(ad5791_remove),
425 .id_table = ad5791_id,
426};
427
428static __init int ad5791_spi_init(void)
429{
430 return spi_register_driver(&ad5791_driver);
431}
432module_init(ad5791_spi_init);
433
434static __exit void ad5791_spi_exit(void)
435{
436 spi_unregister_driver(&ad5791_driver);
437}
438module_exit(ad5791_spi_exit);
439
440MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
441MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5791 DAC");
442MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dac/ad5791.h b/drivers/staging/iio/dac/ad5791.h
new file mode 100644
index 00000000000..c807f26539d
--- /dev/null
+++ b/drivers/staging/iio/dac/ad5791.h
@@ -0,0 +1,114 @@
1/*
2 * AD5791 SPI DAC driver
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#ifndef SPI_AD5791_H_
10#define SPI_AD5791_H_
11
12#define AD5791_RES_MASK(x) ((1 << (x)) - 1)
13#define AD5791_DAC_MASK AD5791_RES_MASK(20)
14#define AD5791_DAC_MSB (1 << 19)
15
16#define AD5791_CMD_READ (1 << 23)
17#define AD5791_CMD_WRITE (0 << 23)
18#define AD5791_ADDR(addr) ((addr) << 20)
19
20/* Registers */
21#define AD5791_ADDR_NOOP 0
22#define AD5791_ADDR_DAC0 1
23#define AD5791_ADDR_CTRL 2
24#define AD5791_ADDR_CLRCODE 3
25#define AD5791_ADDR_SW_CTRL 4
26
27/* Control Register */
28#define AD5791_CTRL_RBUF (1 << 1)
29#define AD5791_CTRL_OPGND (1 << 2)
30#define AD5791_CTRL_DACTRI (1 << 3)
31#define AD5791_CTRL_BIN2SC (1 << 4)
32#define AD5791_CTRL_SDODIS (1 << 5)
33#define AD5761_CTRL_LINCOMP(x) ((x) << 6)
34
35#define AD5791_LINCOMP_0_10 0
36#define AD5791_LINCOMP_10_12 1
37#define AD5791_LINCOMP_12_16 2
38#define AD5791_LINCOMP_16_19 3
39#define AD5791_LINCOMP_19_20 12
40
41#define AD5780_LINCOMP_0_10 0
42#define AD5780_LINCOMP_10_20 12
43
44/* Software Control Register */
45#define AD5791_SWCTRL_LDAC (1 << 0)
46#define AD5791_SWCTRL_CLR (1 << 1)
47#define AD5791_SWCTRL_RESET (1 << 2)
48
49#define AD5791_DAC_PWRDN_6K 0
50#define AD5791_DAC_PWRDN_3STATE 1
51
52/*
53 * TODO: struct ad5791_platform_data needs to go into include/linux/iio
54 */
55
56/**
57 * struct ad5791_platform_data - platform specific information
58 * @vref_pos_mv: Vdd Positive Analog Supply Volatge (mV)
59 * @vref_neg_mv: Vdd Negative Analog Supply Volatge (mV)
60 * @use_rbuf_gain2: ext. amplifier connected in gain of two configuration
61 */
62
63struct ad5791_platform_data {
64 u16 vref_pos_mv;
65 u16 vref_neg_mv;
66 bool use_rbuf_gain2;
67};
68
69/**
70 * struct ad5791_chip_info - chip specific information
71 * @bits: accuracy of the DAC in bits
72 * @left_shift: number of bits the datum must be shifted
73 * @get_lin_comp: function pointer to the device specific function
74 */
75
76struct ad5791_chip_info {
77 u8 bits;
78 u8 left_shift;
79 int (*get_lin_comp) (unsigned int span);
80};
81
82/**
83 * struct ad5791_state - driver instance specific data
84 * @us: spi_device
85 * @reg_vdd: positive supply regulator
86 * @reg_vss: negative supply regulator
87 * @chip_info: chip model specific constants
88 * @vref_mv: actual reference voltage used
89 * @pwr_down_mode current power down mode
90 */
91
92struct ad5791_state {
93 struct spi_device *spi;
94 struct regulator *reg_vdd;
95 struct regulator *reg_vss;
96 const struct ad5791_chip_info *chip_info;
97 unsigned short vref_mv;
98 unsigned ctrl;
99 unsigned pwr_down_mode;
100 bool pwr_down;
101};
102
103/**
104 * ad5791_supported_device_ids:
105 */
106
107enum ad5791_supported_device_ids {
108 ID_AD5760,
109 ID_AD5780,
110 ID_AD5781,
111 ID_AD5791,
112};
113
114#endif /* SPI_AD5791_H_ */
diff --git a/drivers/staging/iio/dac/dac.h b/drivers/staging/iio/dac/dac.h
new file mode 100644
index 00000000000..1d82f353241
--- /dev/null
+++ b/drivers/staging/iio/dac/dac.h
@@ -0,0 +1,6 @@
1/*
2 * dac.h - sysfs attributes associated with DACs
3 */
4
5#define IIO_DEV_ATTR_OUT_RAW(_num, _store, _addr) \
6 IIO_DEVICE_ATTR(out##_num##_raw, S_IWUSR, NULL, _store, _addr)
diff --git a/drivers/staging/iio/dac/max517.c b/drivers/staging/iio/dac/max517.c
new file mode 100644
index 00000000000..ed5d351b238
--- /dev/null
+++ b/drivers/staging/iio/dac/max517.c
@@ -0,0 +1,295 @@
1/*
2 * max517.c - Support for Maxim MAX517, MAX518 and MAX519
3 *
4 * Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/jiffies.h>
25#include <linux/i2c.h>
26#include <linux/err.h>
27
28#include "../iio.h"
29#include "dac.h"
30
31#include "max517.h"
32
33#define MAX517_DRV_NAME "max517"
34
35/* Commands */
36#define COMMAND_CHANNEL0 0x00
37#define COMMAND_CHANNEL1 0x01 /* for MAX518 and MAX519 */
38#define COMMAND_PD 0x08 /* Power Down */
39
40enum max517_device_ids {
41 ID_MAX517,
42 ID_MAX518,
43 ID_MAX519,
44};
45
46struct max517_data {
47 struct iio_dev *indio_dev;
48 struct i2c_client *client;
49 unsigned short vref_mv[2];
50};
51
52/*
53 * channel: bit 0: channel 1
54 * bit 1: channel 2
55 * (this way, it's possible to set both channels at once)
56 */
57static ssize_t max517_set_value(struct device *dev,
58 struct device_attribute *attr,
59 const char *buf, size_t count, int channel)
60{
61 struct iio_dev *dev_info = dev_get_drvdata(dev);
62 struct max517_data *data = iio_priv(dev_info);
63 struct i2c_client *client = data->client;
64 u8 outbuf[4]; /* 1x or 2x command + value */
65 int outbuf_size = 0;
66 int res;
67 long val;
68
69 res = strict_strtol(buf, 10, &val);
70
71 if (res)
72 return res;
73
74 if (val < 0 || val > 255)
75 return -EINVAL;
76
77 if (channel & 1) {
78 outbuf[outbuf_size++] = COMMAND_CHANNEL0;
79 outbuf[outbuf_size++] = val;
80 }
81 if (channel & 2) {
82 outbuf[outbuf_size++] = COMMAND_CHANNEL1;
83 outbuf[outbuf_size++] = val;
84 }
85
86 /*
87 * At this point, there are always 1 or 2 two-byte commands in
88 * outbuf. With 2 commands, the device can set two outputs
89 * simultaneously, latching the values upon the end of the I2C
90 * transfer.
91 */
92
93 res = i2c_master_send(client, outbuf, outbuf_size);
94 if (res < 0)
95 return res;
96
97 return count;
98}
99
100static ssize_t max517_set_value_1(struct device *dev,
101 struct device_attribute *attr,
102 const char *buf, size_t count)
103{
104 return max517_set_value(dev, attr, buf, count, 1);
105}
106static IIO_DEV_ATTR_OUT_RAW(1, max517_set_value_1, 0);
107
108static ssize_t max517_set_value_2(struct device *dev,
109 struct device_attribute *attr,
110 const char *buf, size_t count)
111{
112 return max517_set_value(dev, attr, buf, count, 2);
113}
114static IIO_DEV_ATTR_OUT_RAW(2, max517_set_value_2, 1);
115
116static ssize_t max517_set_value_both(struct device *dev,
117 struct device_attribute *attr,
118 const char *buf, size_t count)
119{
120 return max517_set_value(dev, attr, buf, count, 3);
121}
122static IIO_DEVICE_ATTR_NAMED(out1and2_raw, out1&2_raw, S_IWUSR, NULL,
123 max517_set_value_both, -1);
124
125static ssize_t max517_show_scale(struct device *dev,
126 struct device_attribute *attr,
127 char *buf, int channel)
128{
129 struct iio_dev *dev_info = dev_get_drvdata(dev);
130 struct max517_data *data = iio_priv(dev_info);
131 /* Corresponds to Vref / 2^(bits) */
132 unsigned int scale_uv = (data->vref_mv[channel - 1] * 1000) >> 8;
133
134 return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
135}
136
137static ssize_t max517_show_scale1(struct device *dev,
138 struct device_attribute *attr,
139 char *buf)
140{
141 return max517_show_scale(dev, attr, buf, 1);
142}
143static IIO_DEVICE_ATTR(out1_scale, S_IRUGO, max517_show_scale1, NULL, 0);
144
145static ssize_t max517_show_scale2(struct device *dev,
146 struct device_attribute *attr,
147 char *buf)
148{
149 return max517_show_scale(dev, attr, buf, 2);
150}
151static IIO_DEVICE_ATTR(out2_scale, S_IRUGO, max517_show_scale2, NULL, 0);
152
153/* On MAX517 variant, we have one output */
154static struct attribute *max517_attributes[] = {
155 &iio_dev_attr_out1_raw.dev_attr.attr,
156 &iio_dev_attr_out1_scale.dev_attr.attr,
157 NULL
158};
159
160static struct attribute_group max517_attribute_group = {
161 .attrs = max517_attributes,
162};
163
164/* On MAX518 and MAX519 variant, we have two outputs */
165static struct attribute *max518_attributes[] = {
166 &iio_dev_attr_out1_raw.dev_attr.attr,
167 &iio_dev_attr_out1_scale.dev_attr.attr,
168 &iio_dev_attr_out2_raw.dev_attr.attr,
169 &iio_dev_attr_out2_scale.dev_attr.attr,
170 &iio_dev_attr_out1and2_raw.dev_attr.attr,
171 NULL
172};
173
174static struct attribute_group max518_attribute_group = {
175 .attrs = max518_attributes,
176};
177
178static int max517_suspend(struct i2c_client *client, pm_message_t mesg)
179{
180 u8 outbuf = COMMAND_PD;
181
182 return i2c_master_send(client, &outbuf, 1);
183}
184
185static int max517_resume(struct i2c_client *client)
186{
187 u8 outbuf = 0;
188
189 return i2c_master_send(client, &outbuf, 1);
190}
191
192static const struct iio_info max517_info = {
193 .attrs = &max517_attribute_group,
194 .driver_module = THIS_MODULE,
195};
196
197static const struct iio_info max518_info = {
198 .attrs = &max518_attribute_group,
199 .driver_module = THIS_MODULE,
200};
201
202static int max517_probe(struct i2c_client *client,
203 const struct i2c_device_id *id)
204{
205 struct max517_data *data;
206 struct iio_dev *indio_dev;
207 struct max517_platform_data *platform_data = client->dev.platform_data;
208 int err;
209
210 indio_dev = iio_allocate_device(sizeof(*data));
211 if (indio_dev == NULL) {
212 err = -ENOMEM;
213 goto exit;
214 }
215 data = iio_priv(indio_dev);
216 i2c_set_clientdata(client, indio_dev);
217 data->client = client;
218
219 /* establish that the iio_dev is a child of the i2c device */
220 indio_dev->dev.parent = &client->dev;
221
222 /* reduced attribute set for MAX517 */
223 if (id->driver_data == ID_MAX517)
224 indio_dev->info = &max517_info;
225 else
226 indio_dev->info = &max518_info;
227 indio_dev->modes = INDIO_DIRECT_MODE;
228
229 /*
230 * Reference voltage on MAX518 and default is 5V, else take vref_mv
231 * from platform_data
232 */
233 if (id->driver_data == ID_MAX518 || !platform_data) {
234 data->vref_mv[0] = data->vref_mv[1] = 5000; /* mV */
235 } else {
236 data->vref_mv[0] = platform_data->vref_mv[0];
237 data->vref_mv[1] = platform_data->vref_mv[1];
238 }
239
240 err = iio_device_register(indio_dev);
241 if (err)
242 goto exit_free_device;
243
244 dev_info(&client->dev, "DAC registered\n");
245
246 return 0;
247
248exit_free_device:
249 iio_free_device(indio_dev);
250exit:
251 return err;
252}
253
254static int max517_remove(struct i2c_client *client)
255{
256 iio_free_device(i2c_get_clientdata(client));
257
258 return 0;
259}
260
261static const struct i2c_device_id max517_id[] = {
262 { "max517", ID_MAX517 },
263 { "max518", ID_MAX518 },
264 { "max519", ID_MAX519 },
265 { }
266};
267MODULE_DEVICE_TABLE(i2c, max517_id);
268
269static struct i2c_driver max517_driver = {
270 .driver = {
271 .name = MAX517_DRV_NAME,
272 },
273 .probe = max517_probe,
274 .remove = max517_remove,
275 .suspend = max517_suspend,
276 .resume = max517_resume,
277 .id_table = max517_id,
278};
279
280static int __init max517_init(void)
281{
282 return i2c_add_driver(&max517_driver);
283}
284
285static void __exit max517_exit(void)
286{
287 i2c_del_driver(&max517_driver);
288}
289
290MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
291MODULE_DESCRIPTION("MAX517/MAX518/MAX519 8-bit DAC");
292MODULE_LICENSE("GPL");
293
294module_init(max517_init);
295module_exit(max517_exit);
diff --git a/drivers/staging/iio/dac/max517.h b/drivers/staging/iio/dac/max517.h
new file mode 100644
index 00000000000..8106cf24642
--- /dev/null
+++ b/drivers/staging/iio/dac/max517.h
@@ -0,0 +1,19 @@
1/*
2 * MAX517 DAC driver
3 *
4 * Copyright 2011 Roland Stigge <stigge@antcom.de>
5 *
6 * Licensed under the GPL-2 or later.
7 */
8#ifndef IIO_DAC_MAX517_H_
9#define IIO_DAC_MAX517_H_
10
11/*
12 * TODO: struct max517_platform_data needs to go into include/linux/iio
13 */
14
15struct max517_platform_data {
16 u16 vref_mv[2];
17};
18
19#endif /* IIO_DAC_MAX517_H_ */