aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/iio/dds
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/iio/dds')
-rw-r--r--drivers/staging/iio/dds/Kconfig59
-rw-r--r--drivers/staging/iio/dds/Makefile11
-rw-r--r--drivers/staging/iio/dds/ad5930.c159
-rw-r--r--drivers/staging/iio/dds/ad9832.c372
-rw-r--r--drivers/staging/iio/dds/ad9832.h126
-rw-r--r--drivers/staging/iio/dds/ad9834.c464
-rw-r--r--drivers/staging/iio/dds/ad9834.h112
-rw-r--r--drivers/staging/iio/dds/ad9850.c145
-rw-r--r--drivers/staging/iio/dds/ad9852.c297
-rw-r--r--drivers/staging/iio/dds/ad9910.c430
-rw-r--r--drivers/staging/iio/dds/ad9951.c241
-rw-r--r--drivers/staging/iio/dds/dds.h110
12 files changed, 2526 insertions, 0 deletions
diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig
new file mode 100644
index 00000000000..e07431d8009
--- /dev/null
+++ b/drivers/staging/iio/dds/Kconfig
@@ -0,0 +1,59 @@
1#
2# Direct Digital Synthesis drivers
3#
4comment "Direct Digital Synthesis"
5
6config AD5930
7 tristate "Analog Devices ad5930/5932 driver"
8 depends on SPI
9 help
10 Say yes here to build support for Analog Devices DDS chip
11 ad5930/ad5932, provides direct access via sysfs.
12
13config AD9832
14 tristate "Analog Devices ad9832/5 driver"
15 depends on SPI
16 help
17 Say yes here to build support for Analog Devices DDS chip
18 AD9832 and AD9835, provides direct access via sysfs.
19
20 To compile this driver as a module, choose M here: the
21 module will be called ad9832.
22
23config AD9834
24 tristate "Analog Devices AD9833/4/7/8 driver"
25 depends on SPI
26 help
27 Say yes here to build support for Analog Devices DDS chip
28 AD9833, AD9834, AD9837 and AD9838, provides direct access via sysfs.
29
30 To compile this driver as a module, choose M here: the
31 module will be called ad9834.
32
33config AD9850
34 tristate "Analog Devices ad9850/1 driver"
35 depends on SPI
36 help
37 Say yes here to build support for Analog Devices DDS chip
38 ad9850/1, provides direct access via sysfs.
39
40config AD9852
41 tristate "Analog Devices ad9852/4 driver"
42 depends on SPI
43 help
44 Say yes here to build support for Analog Devices DDS chip
45 ad9852/4, provides direct access via sysfs.
46
47config AD9910
48 tristate "Analog Devices ad9910 driver"
49 depends on SPI
50 help
51 Say yes here to build support for Analog Devices DDS chip
52 ad9910, provides direct access via sysfs.
53
54config AD9951
55 tristate "Analog Devices ad9951 driver"
56 depends on SPI
57 help
58 Say yes here to build support for Analog Devices DDS chip
59 ad9951, provides direct access via sysfs.
diff --git a/drivers/staging/iio/dds/Makefile b/drivers/staging/iio/dds/Makefile
new file mode 100644
index 00000000000..147746176b9
--- /dev/null
+++ b/drivers/staging/iio/dds/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile for Direct Digital Synthesis drivers
3#
4
5obj-$(CONFIG_AD5930) += ad5930.o
6obj-$(CONFIG_AD9832) += ad9832.o
7obj-$(CONFIG_AD9834) += ad9834.o
8obj-$(CONFIG_AD9850) += ad9850.o
9obj-$(CONFIG_AD9852) += ad9852.o
10obj-$(CONFIG_AD9910) += ad9910.o
11obj-$(CONFIG_AD9951) += ad9951.o
diff --git a/drivers/staging/iio/dds/ad5930.c b/drivers/staging/iio/dds/ad5930.c
new file mode 100644
index 00000000000..0b2aa4cafdd
--- /dev/null
+++ b/drivers/staging/iio/dds/ad5930.c
@@ -0,0 +1,159 @@
1/*
2 * Driver for ADI Direct Digital Synthesis ad5930
3 *
4 * Copyright (c) 2010-2010 Analog Devices Inc.
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 version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11#include <linux/types.h>
12#include <linux/mutex.h>
13#include <linux/device.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h>
16#include <linux/sysfs.h>
17
18#include "../iio.h"
19#include "../sysfs.h"
20
21#define DRV_NAME "ad5930"
22
23#define value_mask (u16)0xf000
24#define addr_shift 12
25
26/* Register format: 4 bits addr + 12 bits value */
27struct ad5903_config {
28 u16 control;
29 u16 incnum;
30 u16 frqdelt[2];
31 u16 incitvl;
32 u16 buritvl;
33 u16 strtfrq[2];
34};
35
36struct ad5930_state {
37 struct mutex lock;
38 struct spi_device *sdev;
39};
40
41static ssize_t ad5930_set_parameter(struct device *dev,
42 struct device_attribute *attr,
43 const char *buf,
44 size_t len)
45{
46 struct spi_message msg;
47 struct spi_transfer xfer;
48 int ret;
49 struct ad5903_config *config = (struct ad5903_config *)buf;
50 struct iio_dev *idev = dev_get_drvdata(dev);
51 struct ad5930_state *st = iio_priv(idev);
52
53 config->control = (config->control & ~value_mask);
54 config->incnum = (config->control & ~value_mask) | (1 << addr_shift);
55 config->frqdelt[0] = (config->control & ~value_mask) | (2 << addr_shift);
56 config->frqdelt[1] = (config->control & ~value_mask) | 3 << addr_shift;
57 config->incitvl = (config->control & ~value_mask) | 4 << addr_shift;
58 config->buritvl = (config->control & ~value_mask) | 8 << addr_shift;
59 config->strtfrq[0] = (config->control & ~value_mask) | 0xc << addr_shift;
60 config->strtfrq[1] = (config->control & ~value_mask) | 0xd << addr_shift;
61
62 xfer.len = len;
63 xfer.tx_buf = config;
64 mutex_lock(&st->lock);
65
66 spi_message_init(&msg);
67 spi_message_add_tail(&xfer, &msg);
68 ret = spi_sync(st->sdev, &msg);
69 if (ret)
70 goto error_ret;
71error_ret:
72 mutex_unlock(&st->lock);
73
74 return ret ? ret : len;
75}
76
77static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad5930_set_parameter, 0);
78
79static struct attribute *ad5930_attributes[] = {
80 &iio_dev_attr_dds.dev_attr.attr,
81 NULL,
82};
83
84static const struct attribute_group ad5930_attribute_group = {
85 .attrs = ad5930_attributes,
86};
87
88static const struct iio_info ad5930_info = {
89 .attrs = &ad5930_attribute_group,
90 .driver_module = THIS_MODULE,
91};
92
93static int __devinit ad5930_probe(struct spi_device *spi)
94{
95 struct ad5930_state *st;
96 struct iio_dev *idev;
97 int ret = 0;
98
99 idev = iio_allocate_device(sizeof(*st));
100 if (idev == NULL) {
101 ret = -ENOMEM;
102 goto error_ret;
103 }
104 spi_set_drvdata(spi, idev);
105 st = iio_priv(idev);
106
107 mutex_init(&st->lock);
108 st->sdev = spi;
109 idev->dev.parent = &spi->dev;
110 idev->info = &ad5930_info;
111 idev->modes = INDIO_DIRECT_MODE;
112
113 ret = iio_device_register(idev);
114 if (ret)
115 goto error_free_dev;
116 spi->max_speed_hz = 2000000;
117 spi->mode = SPI_MODE_3;
118 spi->bits_per_word = 16;
119 spi_setup(spi);
120
121 return 0;
122
123error_free_dev:
124 iio_free_device(idev);
125error_ret:
126 return ret;
127}
128
129static int __devexit ad5930_remove(struct spi_device *spi)
130{
131 iio_device_unregister(spi_get_drvdata(spi));
132
133 return 0;
134}
135
136static struct spi_driver ad5930_driver = {
137 .driver = {
138 .name = DRV_NAME,
139 .owner = THIS_MODULE,
140 },
141 .probe = ad5930_probe,
142 .remove = __devexit_p(ad5930_remove),
143};
144
145static __init int ad5930_spi_init(void)
146{
147 return spi_register_driver(&ad5930_driver);
148}
149module_init(ad5930_spi_init);
150
151static __exit void ad5930_spi_exit(void)
152{
153 spi_unregister_driver(&ad5930_driver);
154}
155module_exit(ad5930_spi_exit);
156
157MODULE_AUTHOR("Cliff Cai");
158MODULE_DESCRIPTION("Analog Devices ad5930 driver");
159MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c
new file mode 100644
index 00000000000..e3e61a469bb
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9832.c
@@ -0,0 +1,372 @@
1/*
2 * AD9832 SPI DDS driver
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/device.h>
10#include <linux/kernel.h>
11#include <linux/slab.h>
12#include <linux/sysfs.h>
13#include <linux/spi/spi.h>
14#include <linux/regulator/consumer.h>
15#include <linux/err.h>
16#include <asm/div64.h>
17
18#include "../iio.h"
19#include "../sysfs.h"
20#include "dds.h"
21
22#include "ad9832.h"
23
24static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout)
25{
26 unsigned long long freqreg = (u64) fout *
27 (u64) ((u64) 1L << AD9832_FREQ_BITS);
28 do_div(freqreg, mclk);
29 return freqreg;
30}
31
32static int ad9832_write_frequency(struct ad9832_state *st,
33 unsigned addr, unsigned long fout)
34{
35 unsigned long regval;
36
37 if (fout > (st->mclk / 2))
38 return -EINVAL;
39
40 regval = ad9832_calc_freqreg(st->mclk, fout);
41
42 st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) |
43 (addr << ADD_SHIFT) |
44 ((regval >> 24) & 0xFF));
45 st->freq_data[1] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) |
46 ((addr - 1) << ADD_SHIFT) |
47 ((regval >> 16) & 0xFF));
48 st->freq_data[2] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) |
49 ((addr - 2) << ADD_SHIFT) |
50 ((regval >> 8) & 0xFF));
51 st->freq_data[3] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) |
52 ((addr - 3) << ADD_SHIFT) |
53 ((regval >> 0) & 0xFF));
54
55 return spi_sync(st->spi, &st->freq_msg);;
56}
57
58static int ad9832_write_phase(struct ad9832_state *st,
59 unsigned long addr, unsigned long phase)
60{
61 if (phase > (1 << AD9832_PHASE_BITS))
62 return -EINVAL;
63
64 st->phase_data[0] = cpu_to_be16((AD9832_CMD_PHA8BITSW << CMD_SHIFT) |
65 (addr << ADD_SHIFT) |
66 ((phase >> 8) & 0xFF));
67 st->phase_data[1] = cpu_to_be16((AD9832_CMD_PHA16BITSW << CMD_SHIFT) |
68 ((addr - 1) << ADD_SHIFT) |
69 (phase & 0xFF));
70
71 return spi_sync(st->spi, &st->phase_msg);
72}
73
74static ssize_t ad9832_write(struct device *dev,
75 struct device_attribute *attr,
76 const char *buf,
77 size_t len)
78{
79 struct iio_dev *dev_info = dev_get_drvdata(dev);
80 struct ad9832_state *st = iio_priv(dev_info);
81 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
82 int ret;
83 long val;
84
85 ret = strict_strtoul(buf, 10, &val);
86 if (ret)
87 goto error_ret;
88
89 mutex_lock(&dev_info->mlock);
90 switch (this_attr->address) {
91 case AD9832_FREQ0HM:
92 case AD9832_FREQ1HM:
93 ret = ad9832_write_frequency(st, this_attr->address, val);
94 break;
95 case AD9832_PHASE0H:
96 case AD9832_PHASE1H:
97 case AD9832_PHASE2H:
98 case AD9832_PHASE3H:
99 ret = ad9832_write_phase(st, this_attr->address, val);
100 break;
101 case AD9832_PINCTRL_EN:
102 if (val)
103 st->ctrl_ss &= ~AD9832_SELSRC;
104 else
105 st->ctrl_ss |= AD9832_SELSRC;
106 st->data = cpu_to_be16((AD9832_CMD_SYNCSELSRC << CMD_SHIFT) |
107 st->ctrl_ss);
108 ret = spi_sync(st->spi, &st->msg);
109 break;
110 case AD9832_FREQ_SYM:
111 if (val == 1)
112 st->ctrl_fp |= AD9832_FREQ;
113 else if (val == 0)
114 st->ctrl_fp &= ~AD9832_FREQ;
115 else {
116 ret = -EINVAL;
117 break;
118 }
119 st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) |
120 st->ctrl_fp);
121 ret = spi_sync(st->spi, &st->msg);
122 break;
123 case AD9832_PHASE_SYM:
124 if (val < 0 || val > 3) {
125 ret = -EINVAL;
126 break;
127 }
128
129 st->ctrl_fp &= ~AD9832_PHASE(3);
130 st->ctrl_fp |= AD9832_PHASE(val);
131
132 st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) |
133 st->ctrl_fp);
134 ret = spi_sync(st->spi, &st->msg);
135 break;
136 case AD9832_OUTPUT_EN:
137 if (val)
138 st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP |
139 AD9832_CLR);
140 else
141 st->ctrl_src |= AD9832_RESET;
142
143 st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) |
144 st->ctrl_src);
145 ret = spi_sync(st->spi, &st->msg);
146 break;
147 default:
148 ret = -ENODEV;
149 }
150 mutex_unlock(&dev_info->mlock);
151
152error_ret:
153 return ret ? ret : len;
154}
155
156/**
157 * see dds.h for further information
158 */
159
160static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9832_write, AD9832_FREQ0HM);
161static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9832_write, AD9832_FREQ1HM);
162static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9832_write, AD9832_FREQ_SYM);
163static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */
164
165static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9832_write, AD9832_PHASE0H);
166static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9832_write, AD9832_PHASE1H);
167static IIO_DEV_ATTR_PHASE(0, 2, S_IWUSR, NULL, ad9832_write, AD9832_PHASE2H);
168static IIO_DEV_ATTR_PHASE(0, 3, S_IWUSR, NULL, ad9832_write, AD9832_PHASE3H);
169static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL,
170 ad9832_write, AD9832_PHASE_SYM);
171static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/
172
173static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL,
174 ad9832_write, AD9832_PINCTRL_EN);
175static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL,
176 ad9832_write, AD9832_OUTPUT_EN);
177
178static struct attribute *ad9832_attributes[] = {
179 &iio_dev_attr_dds0_freq0.dev_attr.attr,
180 &iio_dev_attr_dds0_freq1.dev_attr.attr,
181 &iio_const_attr_dds0_freq_scale.dev_attr.attr,
182 &iio_dev_attr_dds0_phase0.dev_attr.attr,
183 &iio_dev_attr_dds0_phase1.dev_attr.attr,
184 &iio_dev_attr_dds0_phase2.dev_attr.attr,
185 &iio_dev_attr_dds0_phase3.dev_attr.attr,
186 &iio_const_attr_dds0_phase_scale.dev_attr.attr,
187 &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr,
188 &iio_dev_attr_dds0_freqsymbol.dev_attr.attr,
189 &iio_dev_attr_dds0_phasesymbol.dev_attr.attr,
190 &iio_dev_attr_dds0_out_enable.dev_attr.attr,
191 NULL,
192};
193
194static const struct attribute_group ad9832_attribute_group = {
195 .attrs = ad9832_attributes,
196};
197
198static const struct iio_info ad9832_info = {
199 .attrs = &ad9832_attribute_group,
200 .driver_module = THIS_MODULE,
201};
202
203static int __devinit ad9832_probe(struct spi_device *spi)
204{
205 struct ad9832_platform_data *pdata = spi->dev.platform_data;
206 struct iio_dev *indio_dev;
207 struct ad9832_state *st;
208 struct regulator *reg;
209 int ret;
210
211 if (!pdata) {
212 dev_dbg(&spi->dev, "no platform data?\n");
213 return -ENODEV;
214 }
215
216 reg = regulator_get(&spi->dev, "vcc");
217 if (!IS_ERR(reg)) {
218 ret = regulator_enable(reg);
219 if (ret)
220 goto error_put_reg;
221 }
222
223 indio_dev = iio_allocate_device(sizeof(*st));
224 if (indio_dev == NULL) {
225 ret = -ENOMEM;
226 goto error_disable_reg;
227 }
228 spi_set_drvdata(spi, indio_dev);
229 st = iio_priv(indio_dev);
230 st->reg = reg;
231 st->mclk = pdata->mclk;
232 st->spi = spi;
233
234 indio_dev->dev.parent = &spi->dev;
235 indio_dev->name = spi_get_device_id(spi)->name;
236 indio_dev->info = &ad9832_info;
237 indio_dev->modes = INDIO_DIRECT_MODE;
238
239 /* Setup default messages */
240
241 st->xfer.tx_buf = &st->data;
242 st->xfer.len = 2;
243
244 spi_message_init(&st->msg);
245 spi_message_add_tail(&st->xfer, &st->msg);
246
247 st->freq_xfer[0].tx_buf = &st->freq_data[0];
248 st->freq_xfer[0].len = 2;
249 st->freq_xfer[0].cs_change = 1;
250 st->freq_xfer[1].tx_buf = &st->freq_data[1];
251 st->freq_xfer[1].len = 2;
252 st->freq_xfer[1].cs_change = 1;
253 st->freq_xfer[2].tx_buf = &st->freq_data[2];
254 st->freq_xfer[2].len = 2;
255 st->freq_xfer[2].cs_change = 1;
256 st->freq_xfer[3].tx_buf = &st->freq_data[3];
257 st->freq_xfer[3].len = 2;
258
259 spi_message_init(&st->freq_msg);
260 spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg);
261 spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg);
262 spi_message_add_tail(&st->freq_xfer[2], &st->freq_msg);
263 spi_message_add_tail(&st->freq_xfer[3], &st->freq_msg);
264
265 st->phase_xfer[0].tx_buf = &st->phase_data[0];
266 st->phase_xfer[0].len = 2;
267 st->phase_xfer[0].cs_change = 1;
268 st->phase_xfer[1].tx_buf = &st->phase_data[1];
269 st->phase_xfer[1].len = 2;
270
271 spi_message_init(&st->phase_msg);
272 spi_message_add_tail(&st->phase_xfer[0], &st->phase_msg);
273 spi_message_add_tail(&st->phase_xfer[1], &st->phase_msg);
274
275 st->ctrl_src = AD9832_SLEEP | AD9832_RESET | AD9832_CLR;
276 st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) |
277 st->ctrl_src);
278 ret = spi_sync(st->spi, &st->msg);
279 if (ret) {
280 dev_err(&spi->dev, "device init failed\n");
281 goto error_free_device;
282 }
283
284 ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0);
285 if (ret)
286 goto error_free_device;
287
288 ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1);
289 if (ret)
290 goto error_free_device;
291
292 ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0);
293 if (ret)
294 goto error_free_device;
295
296 ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1);
297 if (ret)
298 goto error_free_device;
299
300 ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2);
301 if (ret)
302 goto error_free_device;
303
304 ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3);
305 if (ret)
306 goto error_free_device;
307
308 ret = iio_device_register(indio_dev);
309 if (ret)
310 goto error_free_device;
311
312 return 0;
313
314error_free_device:
315 iio_free_device(indio_dev);
316error_disable_reg:
317 if (!IS_ERR(reg))
318 regulator_disable(reg);
319error_put_reg:
320 if (!IS_ERR(reg))
321 regulator_put(reg);
322
323 return ret;
324}
325
326static int __devexit ad9832_remove(struct spi_device *spi)
327{
328 struct iio_dev *indio_dev = spi_get_drvdata(spi);
329 struct ad9832_state *st = iio_priv(indio_dev);
330 struct regulator *reg = st->reg;
331
332 iio_device_unregister(indio_dev);
333 if (!IS_ERR(reg)) {
334 regulator_disable(reg);
335 regulator_put(reg);
336 }
337 return 0;
338}
339
340static const struct spi_device_id ad9832_id[] = {
341 {"ad9832", 0},
342 {"ad9835", 0},
343 {}
344};
345
346static struct spi_driver ad9832_driver = {
347 .driver = {
348 .name = "ad9832",
349 .bus = &spi_bus_type,
350 .owner = THIS_MODULE,
351 },
352 .probe = ad9832_probe,
353 .remove = __devexit_p(ad9832_remove),
354 .id_table = ad9832_id,
355};
356
357static int __init ad9832_init(void)
358{
359 return spi_register_driver(&ad9832_driver);
360}
361module_init(ad9832_init);
362
363static void __exit ad9832_exit(void)
364{
365 spi_unregister_driver(&ad9832_driver);
366}
367module_exit(ad9832_exit);
368
369MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
370MODULE_DESCRIPTION("Analog Devices AD9832/AD9835 DDS");
371MODULE_LICENSE("GPL v2");
372MODULE_ALIAS("spi:ad9832");
diff --git a/drivers/staging/iio/dds/ad9832.h b/drivers/staging/iio/dds/ad9832.h
new file mode 100644
index 00000000000..c5b701f8aab
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9832.h
@@ -0,0 +1,126 @@
1/*
2 * AD9832 SPI DDS driver
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8#ifndef IIO_DDS_AD9832_H_
9#define IIO_DDS_AD9832_H_
10
11/* Registers */
12
13#define AD9832_FREQ0LL 0x0
14#define AD9832_FREQ0HL 0x1
15#define AD9832_FREQ0LM 0x2
16#define AD9832_FREQ0HM 0x3
17#define AD9832_FREQ1LL 0x4
18#define AD9832_FREQ1HL 0x5
19#define AD9832_FREQ1LM 0x6
20#define AD9832_FREQ1HM 0x7
21#define AD9832_PHASE0L 0x8
22#define AD9832_PHASE0H 0x9
23#define AD9832_PHASE1L 0xA
24#define AD9832_PHASE1H 0xB
25#define AD9832_PHASE2L 0xC
26#define AD9832_PHASE2H 0xD
27#define AD9832_PHASE3L 0xE
28#define AD9832_PHASE3H 0xF
29
30#define AD9832_PHASE_SYM 0x10
31#define AD9832_FREQ_SYM 0x11
32#define AD9832_PINCTRL_EN 0x12
33#define AD9832_OUTPUT_EN 0x13
34
35/* Command Control Bits */
36
37#define AD9832_CMD_PHA8BITSW 0x1
38#define AD9832_CMD_PHA16BITSW 0x0
39#define AD9832_CMD_FRE8BITSW 0x3
40#define AD9832_CMD_FRE16BITSW 0x2
41#define AD9832_CMD_FPSELECT 0x6
42#define AD9832_CMD_SYNCSELSRC 0x8
43#define AD9832_CMD_SLEEPRESCLR 0xC
44
45#define AD9832_FREQ (1 << 11)
46#define AD9832_PHASE(x) (((x) & 3) << 9)
47#define AD9832_SYNC (1 << 13)
48#define AD9832_SELSRC (1 << 12)
49#define AD9832_SLEEP (1 << 13)
50#define AD9832_RESET (1 << 12)
51#define AD9832_CLR (1 << 11)
52#define CMD_SHIFT 12
53#define ADD_SHIFT 8
54#define AD9832_FREQ_BITS 32
55#define AD9832_PHASE_BITS 12
56#define RES_MASK(bits) ((1 << (bits)) - 1)
57
58/**
59 * struct ad9832_state - driver instance specific data
60 * @spi: spi_device
61 * @reg: supply regulator
62 * @mclk: external master clock
63 * @ctrl_fp: cached frequency/phase control word
64 * @ctrl_ss: cached sync/selsrc control word
65 * @ctrl_src: cached sleep/reset/clr word
66 * @xfer: default spi transfer
67 * @msg: default spi message
68 * @freq_xfer: tuning word spi transfer
69 * @freq_msg: tuning word spi message
70 * @phase_xfer: tuning word spi transfer
71 * @phase_msg: tuning word spi message
72 * @data: spi transmit buffer
73 * @phase_data: tuning word spi transmit buffer
74 * @freq_data: tuning word spi transmit buffer
75 */
76
77struct ad9832_state {
78 struct spi_device *spi;
79 struct regulator *reg;
80 unsigned long mclk;
81 unsigned short ctrl_fp;
82 unsigned short ctrl_ss;
83 unsigned short ctrl_src;
84 struct spi_transfer xfer;
85 struct spi_message msg;
86 struct spi_transfer freq_xfer[4];
87 struct spi_message freq_msg;
88 struct spi_transfer phase_xfer[2];
89 struct spi_message phase_msg;
90 /*
91 * DMA (thus cache coherency maintenance) requires the
92 * transfer buffers to live in their own cache lines.
93 */
94 union {
95 unsigned short freq_data[4]____cacheline_aligned;
96 unsigned short phase_data[2];
97 unsigned short data;
98 };
99};
100
101/*
102 * TODO: struct ad9832_platform_data needs to go into include/linux/iio
103 */
104
105/**
106 * struct ad9832_platform_data - platform specific information
107 * @mclk: master clock in Hz
108 * @freq0: power up freq0 tuning word in Hz
109 * @freq1: power up freq1 tuning word in Hz
110 * @phase0: power up phase0 value [0..4095] correlates with 0..2PI
111 * @phase1: power up phase1 value [0..4095] correlates with 0..2PI
112 * @phase2: power up phase2 value [0..4095] correlates with 0..2PI
113 * @phase3: power up phase3 value [0..4095] correlates with 0..2PI
114 */
115
116struct ad9832_platform_data {
117 unsigned long mclk;
118 unsigned long freq0;
119 unsigned long freq1;
120 unsigned short phase0;
121 unsigned short phase1;
122 unsigned short phase2;
123 unsigned short phase3;
124};
125
126#endif /* IIO_DDS_AD9832_H_ */
diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c
new file mode 100644
index 00000000000..e6454d58fe4
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9834.c
@@ -0,0 +1,464 @@
1/*
2 * AD9833/AD9834/AD9837/AD9838 SPI DDS 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/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#include <asm/div64.h>
20
21#include "../iio.h"
22#include "../sysfs.h"
23#include "dds.h"
24
25#include "ad9834.h"
26
27static unsigned int ad9834_calc_freqreg(unsigned long mclk, unsigned long fout)
28{
29 unsigned long long freqreg = (u64) fout * (u64) (1 << AD9834_FREQ_BITS);
30 do_div(freqreg, mclk);
31 return freqreg;
32}
33
34static int ad9834_write_frequency(struct ad9834_state *st,
35 unsigned long addr, unsigned long fout)
36{
37 unsigned long regval;
38
39 if (fout > (st->mclk / 2))
40 return -EINVAL;
41
42 regval = ad9834_calc_freqreg(st->mclk, fout);
43
44 st->freq_data[0] = cpu_to_be16(addr | (regval &
45 RES_MASK(AD9834_FREQ_BITS / 2)));
46 st->freq_data[1] = cpu_to_be16(addr | ((regval >>
47 (AD9834_FREQ_BITS / 2)) &
48 RES_MASK(AD9834_FREQ_BITS / 2)));
49
50 return spi_sync(st->spi, &st->freq_msg);
51}
52
53static int ad9834_write_phase(struct ad9834_state *st,
54 unsigned long addr, unsigned long phase)
55{
56 if (phase > (1 << AD9834_PHASE_BITS))
57 return -EINVAL;
58 st->data = cpu_to_be16(addr | phase);
59
60 return spi_sync(st->spi, &st->msg);
61}
62
63static ssize_t ad9834_write(struct device *dev,
64 struct device_attribute *attr,
65 const char *buf,
66 size_t len)
67{
68 struct iio_dev *dev_info = dev_get_drvdata(dev);
69 struct ad9834_state *st = iio_priv(dev_info);
70 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
71 int ret;
72 long val;
73
74 ret = strict_strtoul(buf, 10, &val);
75 if (ret)
76 goto error_ret;
77
78 mutex_lock(&dev_info->mlock);
79 switch (this_attr->address) {
80 case AD9834_REG_FREQ0:
81 case AD9834_REG_FREQ1:
82 ret = ad9834_write_frequency(st, this_attr->address, val);
83 break;
84 case AD9834_REG_PHASE0:
85 case AD9834_REG_PHASE1:
86 ret = ad9834_write_phase(st, this_attr->address, val);
87 break;
88 case AD9834_OPBITEN:
89 if (st->control & AD9834_MODE) {
90 ret = -EINVAL; /* AD9843 reserved mode */
91 break;
92 }
93
94 if (val)
95 st->control |= AD9834_OPBITEN;
96 else
97 st->control &= ~AD9834_OPBITEN;
98
99 st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
100 ret = spi_sync(st->spi, &st->msg);
101 break;
102 case AD9834_PIN_SW:
103 if (val)
104 st->control |= AD9834_PIN_SW;
105 else
106 st->control &= ~AD9834_PIN_SW;
107 st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
108 ret = spi_sync(st->spi, &st->msg);
109 break;
110 case AD9834_FSEL:
111 case AD9834_PSEL:
112 if (val == 0)
113 st->control &= ~(this_attr->address | AD9834_PIN_SW);
114 else if (val == 1) {
115 st->control |= this_attr->address;
116 st->control &= ~AD9834_PIN_SW;
117 } else {
118 ret = -EINVAL;
119 break;
120 }
121 st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
122 ret = spi_sync(st->spi, &st->msg);
123 break;
124 case AD9834_RESET:
125 if (val)
126 st->control &= ~AD9834_RESET;
127 else
128 st->control |= AD9834_RESET;
129
130 st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
131 ret = spi_sync(st->spi, &st->msg);
132 break;
133 default:
134 ret = -ENODEV;
135 }
136 mutex_unlock(&dev_info->mlock);
137
138error_ret:
139 return ret ? ret : len;
140}
141
142static ssize_t ad9834_store_wavetype(struct device *dev,
143 struct device_attribute *attr,
144 const char *buf,
145 size_t len)
146{
147 struct iio_dev *dev_info = dev_get_drvdata(dev);
148 struct ad9834_state *st = iio_priv(dev_info);
149 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
150 int ret = 0;
151 bool is_ad9833_7 = (st->devid == ID_AD9833) || (st->devid == ID_AD9837);
152
153 mutex_lock(&dev_info->mlock);
154
155 switch (this_attr->address) {
156 case 0:
157 if (sysfs_streq(buf, "sine")) {
158 st->control &= ~AD9834_MODE;
159 if (is_ad9833_7)
160 st->control &= ~AD9834_OPBITEN;
161 } else if (sysfs_streq(buf, "triangle")) {
162 if (is_ad9833_7) {
163 st->control &= ~AD9834_OPBITEN;
164 st->control |= AD9834_MODE;
165 } else if (st->control & AD9834_OPBITEN) {
166 ret = -EINVAL; /* AD9843 reserved mode */
167 } else {
168 st->control |= AD9834_MODE;
169 }
170 } else if (is_ad9833_7 && sysfs_streq(buf, "square")) {
171 st->control &= ~AD9834_MODE;
172 st->control |= AD9834_OPBITEN;
173 } else {
174 ret = -EINVAL;
175 }
176
177 break;
178 case 1:
179 if (sysfs_streq(buf, "square") &&
180 !(st->control & AD9834_MODE)) {
181 st->control &= ~AD9834_MODE;
182 st->control |= AD9834_OPBITEN;
183 } else {
184 ret = -EINVAL;
185 }
186 break;
187 default:
188 ret = -EINVAL;
189 break;
190 }
191
192 if (!ret) {
193 st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
194 ret = spi_sync(st->spi, &st->msg);
195 }
196 mutex_unlock(&dev_info->mlock);
197
198 return ret ? ret : len;
199}
200
201static ssize_t ad9834_show_out0_wavetype_available(struct device *dev,
202 struct device_attribute *attr,
203 char *buf)
204{
205 struct iio_dev *dev_info = dev_get_drvdata(dev);
206 struct ad9834_state *st = iio_priv(dev_info);
207 char *str;
208
209 if ((st->devid == ID_AD9833) || (st->devid == ID_AD9837))
210 str = "sine triangle square";
211 else if (st->control & AD9834_OPBITEN)
212 str = "sine";
213 else
214 str = "sine triangle";
215
216 return sprintf(buf, "%s\n", str);
217}
218
219
220static IIO_DEVICE_ATTR(dds0_out0_wavetype_available, S_IRUGO,
221 ad9834_show_out0_wavetype_available, NULL, 0);
222
223static ssize_t ad9834_show_out1_wavetype_available(struct device *dev,
224 struct device_attribute *attr,
225 char *buf)
226{
227 struct iio_dev *dev_info = dev_get_drvdata(dev);
228 struct ad9834_state *st = iio_priv(dev_info);
229 char *str;
230
231 if (st->control & AD9834_MODE)
232 str = "";
233 else
234 str = "square";
235
236 return sprintf(buf, "%s\n", str);
237}
238
239static IIO_DEVICE_ATTR(dds0_out1_wavetype_available, S_IRUGO,
240 ad9834_show_out1_wavetype_available, NULL, 0);
241
242/**
243 * see dds.h for further information
244 */
245
246static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ0);
247static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ1);
248static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_FSEL);
249static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */
250
251static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE0);
252static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE1);
253static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_PSEL);
254static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/
255
256static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL,
257 ad9834_write, AD9834_PIN_SW);
258static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, ad9834_write, AD9834_RESET);
259static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, S_IWUSR, NULL,
260 ad9834_write, AD9834_OPBITEN);
261static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0);
262static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1);
263
264static struct attribute *ad9834_attributes[] = {
265 &iio_dev_attr_dds0_freq0.dev_attr.attr,
266 &iio_dev_attr_dds0_freq1.dev_attr.attr,
267 &iio_const_attr_dds0_freq_scale.dev_attr.attr,
268 &iio_dev_attr_dds0_phase0.dev_attr.attr,
269 &iio_dev_attr_dds0_phase1.dev_attr.attr,
270 &iio_const_attr_dds0_phase_scale.dev_attr.attr,
271 &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr,
272 &iio_dev_attr_dds0_freqsymbol.dev_attr.attr,
273 &iio_dev_attr_dds0_phasesymbol.dev_attr.attr,
274 &iio_dev_attr_dds0_out_enable.dev_attr.attr,
275 &iio_dev_attr_dds0_out1_enable.dev_attr.attr,
276 &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr,
277 &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr,
278 &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr,
279 &iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr,
280 NULL,
281};
282
283static mode_t ad9834_attr_is_visible(struct kobject *kobj,
284 struct attribute *attr, int n)
285{
286 struct device *dev = container_of(kobj, struct device, kobj);
287 struct iio_dev *dev_info = dev_get_drvdata(dev);
288 struct ad9834_state *st = iio_priv(dev_info);
289
290 mode_t mode = attr->mode;
291
292 if (((st->devid == ID_AD9833) || (st->devid == ID_AD9837)) &&
293 ((attr == &iio_dev_attr_dds0_out1_enable.dev_attr.attr) ||
294 (attr == &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr) ||
295 (attr ==
296 &iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr) ||
297 (attr == &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr)))
298 mode = 0;
299
300 return mode;
301}
302
303static const struct attribute_group ad9834_attribute_group = {
304 .attrs = ad9834_attributes,
305 .is_visible = ad9834_attr_is_visible,
306};
307
308static const struct iio_info ad9834_info = {
309 .attrs = &ad9834_attribute_group,
310 .driver_module = THIS_MODULE,
311};
312
313static int __devinit ad9834_probe(struct spi_device *spi)
314{
315 struct ad9834_platform_data *pdata = spi->dev.platform_data;
316 struct ad9834_state *st;
317 struct iio_dev *indio_dev;
318 struct regulator *reg;
319 int ret;
320
321 if (!pdata) {
322 dev_dbg(&spi->dev, "no platform data?\n");
323 return -ENODEV;
324 }
325
326 reg = regulator_get(&spi->dev, "vcc");
327 if (!IS_ERR(reg)) {
328 ret = regulator_enable(reg);
329 if (ret)
330 goto error_put_reg;
331 }
332
333 indio_dev = iio_allocate_device(sizeof(*st));
334 if (indio_dev == NULL) {
335 ret = -ENOMEM;
336 goto error_disable_reg;
337 }
338 spi_set_drvdata(spi, indio_dev);
339 st = iio_priv(indio_dev);
340 st->mclk = pdata->mclk;
341 st->spi = spi;
342 st->devid = spi_get_device_id(spi)->driver_data;
343 st->reg = reg;
344 indio_dev->dev.parent = &spi->dev;
345 indio_dev->name = spi_get_device_id(spi)->name;
346 indio_dev->info = &ad9834_info;
347 indio_dev->modes = INDIO_DIRECT_MODE;
348
349 /* Setup default messages */
350
351 st->xfer.tx_buf = &st->data;
352 st->xfer.len = 2;
353
354 spi_message_init(&st->msg);
355 spi_message_add_tail(&st->xfer, &st->msg);
356
357 st->freq_xfer[0].tx_buf = &st->freq_data[0];
358 st->freq_xfer[0].len = 2;
359 st->freq_xfer[0].cs_change = 1;
360 st->freq_xfer[1].tx_buf = &st->freq_data[1];
361 st->freq_xfer[1].len = 2;
362
363 spi_message_init(&st->freq_msg);
364 spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg);
365 spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg);
366
367 st->control = AD9834_B28 | AD9834_RESET;
368
369 if (!pdata->en_div2)
370 st->control |= AD9834_DIV2;
371
372 if (!pdata->en_signbit_msb_out && (st->devid == ID_AD9834))
373 st->control |= AD9834_SIGN_PIB;
374
375 st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
376 ret = spi_sync(st->spi, &st->msg);
377 if (ret) {
378 dev_err(&spi->dev, "device init failed\n");
379 goto error_free_device;
380 }
381
382 ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0);
383 if (ret)
384 goto error_free_device;
385
386 ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1);
387 if (ret)
388 goto error_free_device;
389
390 ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0);
391 if (ret)
392 goto error_free_device;
393
394 ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1);
395 if (ret)
396 goto error_free_device;
397
398 ret = iio_device_register(indio_dev);
399 if (ret)
400 goto error_free_device;
401
402 return 0;
403
404error_free_device:
405 iio_free_device(indio_dev);
406error_disable_reg:
407 if (!IS_ERR(reg))
408 regulator_disable(reg);
409error_put_reg:
410 if (!IS_ERR(reg))
411 regulator_put(reg);
412 return ret;
413}
414
415static int __devexit ad9834_remove(struct spi_device *spi)
416{
417 struct iio_dev *indio_dev = spi_get_drvdata(spi);
418 struct ad9834_state *st = iio_priv(indio_dev);
419 struct regulator *reg = st->reg;
420
421 iio_device_unregister(indio_dev);
422 if (!IS_ERR(reg)) {
423 regulator_disable(reg);
424 regulator_put(reg);
425 }
426
427 return 0;
428}
429
430static const struct spi_device_id ad9834_id[] = {
431 {"ad9833", ID_AD9833},
432 {"ad9834", ID_AD9834},
433 {"ad9837", ID_AD9837},
434 {"ad9838", ID_AD9838},
435 {}
436};
437
438static struct spi_driver ad9834_driver = {
439 .driver = {
440 .name = "ad9834",
441 .bus = &spi_bus_type,
442 .owner = THIS_MODULE,
443 },
444 .probe = ad9834_probe,
445 .remove = __devexit_p(ad9834_remove),
446 .id_table = ad9834_id,
447};
448
449static int __init ad9834_init(void)
450{
451 return spi_register_driver(&ad9834_driver);
452}
453module_init(ad9834_init);
454
455static void __exit ad9834_exit(void)
456{
457 spi_unregister_driver(&ad9834_driver);
458}
459module_exit(ad9834_exit);
460
461MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
462MODULE_DESCRIPTION("Analog Devices AD9833/AD9834/AD9837/AD9838 DDS");
463MODULE_LICENSE("GPL v2");
464MODULE_ALIAS("spi:ad9834");
diff --git a/drivers/staging/iio/dds/ad9834.h b/drivers/staging/iio/dds/ad9834.h
new file mode 100644
index 00000000000..ed5ed8d0007
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9834.h
@@ -0,0 +1,112 @@
1/*
2 * AD9833/AD9834/AD9837/AD9838 SPI DDS driver
3 *
4 * Copyright 2010-2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8#ifndef IIO_DDS_AD9834_H_
9#define IIO_DDS_AD9834_H_
10
11/* Registers */
12
13#define AD9834_REG_CMD (0 << 14)
14#define AD9834_REG_FREQ0 (1 << 14)
15#define AD9834_REG_FREQ1 (2 << 14)
16#define AD9834_REG_PHASE0 (6 << 13)
17#define AD9834_REG_PHASE1 (7 << 13)
18
19/* Command Control Bits */
20
21#define AD9834_B28 (1 << 13)
22#define AD9834_HLB (1 << 12)
23#define AD9834_FSEL (1 << 11)
24#define AD9834_PSEL (1 << 10)
25#define AD9834_PIN_SW (1 << 9)
26#define AD9834_RESET (1 << 8)
27#define AD9834_SLEEP1 (1 << 7)
28#define AD9834_SLEEP12 (1 << 6)
29#define AD9834_OPBITEN (1 << 5)
30#define AD9834_SIGN_PIB (1 << 4)
31#define AD9834_DIV2 (1 << 3)
32#define AD9834_MODE (1 << 1)
33
34#define AD9834_FREQ_BITS 28
35#define AD9834_PHASE_BITS 12
36
37#define RES_MASK(bits) ((1 << (bits)) - 1)
38
39/**
40 * struct ad9834_state - driver instance specific data
41 * @spi: spi_device
42 * @reg: supply regulator
43 * @mclk: external master clock
44 * @control: cached control word
45 * @xfer: default spi transfer
46 * @msg: default spi message
47 * @freq_xfer: tuning word spi transfer
48 * @freq_msg: tuning word spi message
49 * @data: spi transmit buffer
50 * @freq_data: tuning word spi transmit buffer
51 */
52
53struct ad9834_state {
54 struct spi_device *spi;
55 struct regulator *reg;
56 unsigned int mclk;
57 unsigned short control;
58 unsigned short devid;
59 struct spi_transfer xfer;
60 struct spi_message msg;
61 struct spi_transfer freq_xfer[2];
62 struct spi_message freq_msg;
63
64 /*
65 * DMA (thus cache coherency maintenance) requires the
66 * transfer buffers to live in their own cache lines.
67 */
68 unsigned short data ____cacheline_aligned;
69 unsigned short freq_data[2] ;
70};
71
72
73/*
74 * TODO: struct ad7887_platform_data needs to go into include/linux/iio
75 */
76
77/**
78 * struct ad9834_platform_data - platform specific information
79 * @mclk: master clock in Hz
80 * @freq0: power up freq0 tuning word in Hz
81 * @freq1: power up freq1 tuning word in Hz
82 * @phase0: power up phase0 value [0..4095] correlates with 0..2PI
83 * @phase1: power up phase1 value [0..4095] correlates with 0..2PI
84 * @en_div2: digital output/2 is passed to the SIGN BIT OUT pin
85 * @en_signbit_msb_out: the MSB (or MSB/2) of the DAC data is connected to the
86 * SIGN BIT OUT pin. en_div2 controls whether it is the MSB
87 * or MSB/2 that is output. if en_signbit_msb_out=false,
88 * the on-board comparator is connected to SIGN BIT OUT
89 */
90
91struct ad9834_platform_data {
92 unsigned int mclk;
93 unsigned int freq0;
94 unsigned int freq1;
95 unsigned short phase0;
96 unsigned short phase1;
97 bool en_div2;
98 bool en_signbit_msb_out;
99};
100
101/**
102 * ad9834_supported_device_ids:
103 */
104
105enum ad9834_supported_device_ids {
106 ID_AD9833,
107 ID_AD9834,
108 ID_AD9837,
109 ID_AD9838,
110};
111
112#endif /* IIO_DDS_AD9834_H_ */
diff --git a/drivers/staging/iio/dds/ad9850.c b/drivers/staging/iio/dds/ad9850.c
new file mode 100644
index 00000000000..d7c9d05f635
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9850.c
@@ -0,0 +1,145 @@
1/*
2 * Driver for ADI Direct Digital Synthesis ad9850
3 *
4 * Copyright (c) 2010-2010 Analog Devices Inc.
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 version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11#include <linux/types.h>
12#include <linux/mutex.h>
13#include <linux/device.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h>
16#include <linux/sysfs.h>
17
18#include "../iio.h"
19#include "../sysfs.h"
20
21#define DRV_NAME "ad9850"
22
23#define value_mask (u16)0xf000
24#define addr_shift 12
25
26/* Register format: 4 bits addr + 12 bits value */
27struct ad9850_config {
28 u8 control[5];
29};
30
31struct ad9850_state {
32 struct mutex lock;
33 struct spi_device *sdev;
34};
35
36static ssize_t ad9850_set_parameter(struct device *dev,
37 struct device_attribute *attr,
38 const char *buf,
39 size_t len)
40{
41 struct spi_message msg;
42 struct spi_transfer xfer;
43 int ret;
44 struct ad9850_config *config = (struct ad9850_config *)buf;
45 struct iio_dev *idev = dev_get_drvdata(dev);
46 struct ad9850_state *st = iio_priv(idev);
47
48 xfer.len = len;
49 xfer.tx_buf = config;
50 mutex_lock(&st->lock);
51
52 spi_message_init(&msg);
53 spi_message_add_tail(&xfer, &msg);
54 ret = spi_sync(st->sdev, &msg);
55 if (ret)
56 goto error_ret;
57error_ret:
58 mutex_unlock(&st->lock);
59
60 return ret ? ret : len;
61}
62
63static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9850_set_parameter, 0);
64
65static struct attribute *ad9850_attributes[] = {
66 &iio_dev_attr_dds.dev_attr.attr,
67 NULL,
68};
69
70static const struct attribute_group ad9850_attribute_group = {
71 .attrs = ad9850_attributes,
72};
73
74static const struct iio_info ad9850_info = {
75 .attrs = &ad9850_attribute_group,
76 .driver_module = THIS_MODULE,
77};
78
79static int __devinit ad9850_probe(struct spi_device *spi)
80{
81 struct ad9850_state *st;
82 struct iio_dev *idev;
83 int ret = 0;
84
85 idev = iio_allocate_device(sizeof(*st));
86 if (idev == NULL) {
87 ret = -ENOMEM;
88 goto error_ret;
89 }
90 spi_set_drvdata(spi, idev);
91 st = iio_priv(idev);
92 mutex_init(&st->lock);
93 st->sdev = spi;
94
95 idev->dev.parent = &spi->dev;
96 idev->info = &ad9850_info;
97 idev->modes = INDIO_DIRECT_MODE;
98
99 ret = iio_device_register(idev);
100 if (ret)
101 goto error_free_dev;
102 spi->max_speed_hz = 2000000;
103 spi->mode = SPI_MODE_3;
104 spi->bits_per_word = 16;
105 spi_setup(spi);
106
107 return 0;
108
109error_free_dev:
110 iio_free_device(idev);
111error_ret:
112 return ret;
113}
114
115static int __devexit ad9850_remove(struct spi_device *spi)
116{
117 iio_device_unregister(spi_get_drvdata(spi));
118
119 return 0;
120}
121
122static struct spi_driver ad9850_driver = {
123 .driver = {
124 .name = DRV_NAME,
125 .owner = THIS_MODULE,
126 },
127 .probe = ad9850_probe,
128 .remove = __devexit_p(ad9850_remove),
129};
130
131static __init int ad9850_spi_init(void)
132{
133 return spi_register_driver(&ad9850_driver);
134}
135module_init(ad9850_spi_init);
136
137static __exit void ad9850_spi_exit(void)
138{
139 spi_unregister_driver(&ad9850_driver);
140}
141module_exit(ad9850_spi_exit);
142
143MODULE_AUTHOR("Cliff Cai");
144MODULE_DESCRIPTION("Analog Devices ad9850 driver");
145MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/dds/ad9852.c
new file mode 100644
index 00000000000..0184585425d
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9852.c
@@ -0,0 +1,297 @@
1/*
2 * Driver for ADI Direct Digital Synthesis ad9852
3 *
4 * Copyright (c) 2010 Analog Devices Inc.
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 version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11#include <linux/types.h>
12#include <linux/mutex.h>
13#include <linux/device.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h>
16#include <linux/sysfs.h>
17
18#include "../iio.h"
19#include "../sysfs.h"
20
21#define DRV_NAME "ad9852"
22
23#define addr_phaad1 0x0
24#define addr_phaad2 0x1
25#define addr_fretu1 0x2
26#define addr_fretu2 0x3
27#define addr_delfre 0x4
28#define addr_updclk 0x5
29#define addr_ramclk 0x6
30#define addr_contrl 0x7
31#define addr_optskm 0x8
32#define addr_optskr 0xa
33#define addr_dacctl 0xb
34
35#define COMPPD (1 << 4)
36#define REFMULT2 (1 << 2)
37#define BYPPLL (1 << 5)
38#define PLLRANG (1 << 6)
39#define IEUPCLK (1)
40#define OSKEN (1 << 5)
41
42#define read_bit (1 << 7)
43
44/* Register format: 1 byte addr + value */
45struct ad9852_config {
46 u8 phajst0[3];
47 u8 phajst1[3];
48 u8 fretun1[6];
49 u8 fretun2[6];
50 u8 dltafre[6];
51 u8 updtclk[5];
52 u8 ramprat[4];
53 u8 control[5];
54 u8 outpskm[3];
55 u8 outpskr[2];
56 u8 daccntl[3];
57};
58
59struct ad9852_state {
60 struct mutex lock;
61 struct spi_device *sdev;
62};
63
64static ssize_t ad9852_set_parameter(struct device *dev,
65 struct device_attribute *attr,
66 const char *buf,
67 size_t len)
68{
69 struct spi_message msg;
70 struct spi_transfer xfer;
71 int ret;
72 struct ad9852_config *config = (struct ad9852_config *)buf;
73 struct iio_dev *idev = dev_get_drvdata(dev);
74 struct ad9852_state *st = iio_priv(idev);
75
76 xfer.len = 3;
77 xfer.tx_buf = &config->phajst0[0];
78 mutex_lock(&st->lock);
79
80 spi_message_init(&msg);
81 spi_message_add_tail(&xfer, &msg);
82 ret = spi_sync(st->sdev, &msg);
83 if (ret)
84 goto error_ret;
85
86 xfer.len = 3;
87 xfer.tx_buf = &config->phajst1[0];
88
89 spi_message_init(&msg);
90 spi_message_add_tail(&xfer, &msg);
91 ret = spi_sync(st->sdev, &msg);
92 if (ret)
93 goto error_ret;
94
95 xfer.len = 6;
96 xfer.tx_buf = &config->fretun1[0];
97
98 spi_message_init(&msg);
99 spi_message_add_tail(&xfer, &msg);
100 ret = spi_sync(st->sdev, &msg);
101 if (ret)
102 goto error_ret;
103
104 xfer.len = 6;
105 xfer.tx_buf = &config->fretun2[0];
106
107 spi_message_init(&msg);
108 spi_message_add_tail(&xfer, &msg);
109 ret = spi_sync(st->sdev, &msg);
110 if (ret)
111 goto error_ret;
112
113 xfer.len = 6;
114 xfer.tx_buf = &config->dltafre[0];
115
116 spi_message_init(&msg);
117 spi_message_add_tail(&xfer, &msg);
118 ret = spi_sync(st->sdev, &msg);
119 if (ret)
120 goto error_ret;
121
122 xfer.len = 5;
123 xfer.tx_buf = &config->updtclk[0];
124
125 spi_message_init(&msg);
126 spi_message_add_tail(&xfer, &msg);
127 ret = spi_sync(st->sdev, &msg);
128 if (ret)
129 goto error_ret;
130
131 xfer.len = 4;
132 xfer.tx_buf = &config->ramprat[0];
133
134 spi_message_init(&msg);
135 spi_message_add_tail(&xfer, &msg);
136 ret = spi_sync(st->sdev, &msg);
137 if (ret)
138 goto error_ret;
139
140 xfer.len = 5;
141 xfer.tx_buf = &config->control[0];
142
143 spi_message_init(&msg);
144 spi_message_add_tail(&xfer, &msg);
145 ret = spi_sync(st->sdev, &msg);
146 if (ret)
147 goto error_ret;
148
149 xfer.len = 3;
150 xfer.tx_buf = &config->outpskm[0];
151
152 spi_message_init(&msg);
153 spi_message_add_tail(&xfer, &msg);
154 ret = spi_sync(st->sdev, &msg);
155 if (ret)
156 goto error_ret;
157
158 xfer.len = 2;
159 xfer.tx_buf = &config->outpskr[0];
160
161 spi_message_init(&msg);
162 spi_message_add_tail(&xfer, &msg);
163 ret = spi_sync(st->sdev, &msg);
164 if (ret)
165 goto error_ret;
166
167 xfer.len = 3;
168 xfer.tx_buf = &config->daccntl[0];
169
170 spi_message_init(&msg);
171 spi_message_add_tail(&xfer, &msg);
172 ret = spi_sync(st->sdev, &msg);
173 if (ret)
174 goto error_ret;
175error_ret:
176 mutex_unlock(&st->lock);
177
178 return ret ? ret : len;
179}
180
181static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9852_set_parameter, 0);
182
183static void ad9852_init(struct ad9852_state *st)
184{
185 struct spi_message msg;
186 struct spi_transfer xfer;
187 int ret;
188 u8 config[5];
189
190 config[0] = addr_contrl;
191 config[1] = COMPPD;
192 config[2] = REFMULT2 | BYPPLL | PLLRANG;
193 config[3] = IEUPCLK;
194 config[4] = OSKEN;
195
196 mutex_lock(&st->lock);
197
198 xfer.len = 5;
199 xfer.tx_buf = &config;
200
201 spi_message_init(&msg);
202 spi_message_add_tail(&xfer, &msg);
203 ret = spi_sync(st->sdev, &msg);
204 if (ret)
205 goto error_ret;
206
207error_ret:
208 mutex_unlock(&st->lock);
209
210
211
212}
213
214static struct attribute *ad9852_attributes[] = {
215 &iio_dev_attr_dds.dev_attr.attr,
216 NULL,
217};
218
219static const struct attribute_group ad9852_attribute_group = {
220 .name = DRV_NAME,
221 .attrs = ad9852_attributes,
222};
223
224static const struct iio_info ad9852_info = {
225 .attrs = &ad9852_attribute_group,
226 .driver_module = THIS_MODULE,
227};
228
229static int __devinit ad9852_probe(struct spi_device *spi)
230{
231 struct ad9852_state *st;
232 struct iio_dev *idev;
233 int ret = 0;
234
235 idev = iio_allocate_device(sizeof(*st));
236 if (idev == NULL) {
237 ret = -ENOMEM;
238 goto error_ret;
239 }
240 st = iio_priv(idev);
241 spi_set_drvdata(spi, idev);
242 mutex_init(&st->lock);
243 st->sdev = spi;
244
245 idev->dev.parent = &spi->dev;
246 idev->info = &ad9852_info;
247 idev->modes = INDIO_DIRECT_MODE;
248
249 ret = iio_device_register(idev);
250 if (ret)
251 goto error_free_dev;
252 spi->max_speed_hz = 2000000;
253 spi->mode = SPI_MODE_3;
254 spi->bits_per_word = 8;
255 spi_setup(spi);
256 ad9852_init(st);
257
258 return 0;
259
260error_free_dev:
261 iio_free_device(idev);
262
263error_ret:
264 return ret;
265}
266
267static int __devexit ad9852_remove(struct spi_device *spi)
268{
269 iio_device_unregister(spi_get_drvdata(spi));
270
271 return 0;
272}
273
274static struct spi_driver ad9852_driver = {
275 .driver = {
276 .name = DRV_NAME,
277 .owner = THIS_MODULE,
278 },
279 .probe = ad9852_probe,
280 .remove = __devexit_p(ad9852_remove),
281};
282
283static __init int ad9852_spi_init(void)
284{
285 return spi_register_driver(&ad9852_driver);
286}
287module_init(ad9852_spi_init);
288
289static __exit void ad9852_spi_exit(void)
290{
291 spi_unregister_driver(&ad9852_driver);
292}
293module_exit(ad9852_spi_exit);
294
295MODULE_AUTHOR("Cliff Cai");
296MODULE_DESCRIPTION("Analog Devices ad9852 driver");
297MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/dds/ad9910.c
new file mode 100644
index 00000000000..0fa217f7b90
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9910.c
@@ -0,0 +1,430 @@
1/*
2 * Driver for ADI Direct Digital Synthesis ad9910
3 *
4 * Copyright (c) 2010 Analog Devices Inc.
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 version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11#include <linux/types.h>
12#include <linux/mutex.h>
13#include <linux/device.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h>
16#include <linux/sysfs.h>
17
18#include "../iio.h"
19#include "../sysfs.h"
20
21#define DRV_NAME "ad9910"
22
23#define CFR1 0x0
24#define CFR2 0x1
25#define CFR3 0x2
26
27#define AUXDAC 0x3
28#define IOUPD 0x4
29#define FTW 0x7
30#define POW 0x8
31#define ASF 0x9
32#define MULTC 0x0A
33#define DIG_RAMPL 0x0B
34#define DIG_RAMPS 0x0C
35#define DIG_RAMPR 0x0D
36#define SIN_TONEP0 0x0E
37#define SIN_TONEP1 0x0F
38#define SIN_TONEP2 0x10
39#define SIN_TONEP3 0x11
40#define SIN_TONEP4 0x12
41#define SIN_TONEP5 0x13
42#define SIN_TONEP6 0x14
43#define SIN_TONEP7 0x15
44
45#define RAM_ENABLE (1 << 7)
46
47#define MANUAL_OSK (1 << 7)
48#define INVSIC (1 << 6)
49#define DDS_SINEOP (1)
50
51#define AUTO_OSK (1)
52#define OSKEN (1 << 1)
53#define LOAD_ARR (1 << 2)
54#define CLR_PHA (1 << 3)
55#define CLR_DIG (1 << 4)
56#define ACLR_PHA (1 << 5)
57#define ACLR_DIG (1 << 6)
58#define LOAD_LRR (1 << 7)
59
60#define LSB_FST (1)
61#define SDIO_IPT (1 << 1)
62#define EXT_PWD (1 << 3)
63#define ADAC_PWD (1 << 4)
64#define REFCLK_PWD (1 << 5)
65#define DAC_PWD (1 << 6)
66#define DIG_PWD (1 << 7)
67
68#define ENA_AMP (1)
69#define READ_FTW (1)
70#define DIGR_LOW (1 << 1)
71#define DIGR_HIGH (1 << 2)
72#define DIGR_ENA (1 << 3)
73#define SYNCCLK_ENA (1 << 6)
74#define ITER_IOUPD (1 << 7)
75
76#define TX_ENA (1 << 1)
77#define PDCLK_INV (1 << 2)
78#define PDCLK_ENB (1 << 3)
79
80#define PARA_ENA (1 << 4)
81#define SYNC_DIS (1 << 5)
82#define DATA_ASS (1 << 6)
83#define MATCH_ENA (1 << 7)
84
85#define PLL_ENA (1)
86#define PFD_RST (1 << 2)
87#define REFCLK_RST (1 << 6)
88#define REFCLK_BYP (1 << 7)
89
90/* Register format: 1 byte addr + value */
91struct ad9910_config {
92 u8 auxdac[5];
93 u8 ioupd[5];
94 u8 ftw[5];
95 u8 pow[3];
96 u8 asf[5];
97 u8 multc[5];
98 u8 dig_rampl[9];
99 u8 dig_ramps[9];
100 u8 dig_rampr[5];
101 u8 sin_tonep0[9];
102 u8 sin_tonep1[9];
103 u8 sin_tonep2[9];
104 u8 sin_tonep3[9];
105 u8 sin_tonep4[9];
106 u8 sin_tonep5[9];
107 u8 sin_tonep6[9];
108 u8 sin_tonep7[9];
109};
110
111struct ad9910_state {
112 struct mutex lock;
113 struct spi_device *sdev;
114};
115
116static ssize_t ad9910_set_parameter(struct device *dev,
117 struct device_attribute *attr,
118 const char *buf,
119 size_t len)
120{
121 struct spi_message msg;
122 struct spi_transfer xfer;
123 int ret;
124 struct ad9910_config *config = (struct ad9910_config *)buf;
125 struct iio_dev *idev = dev_get_drvdata(dev);
126 struct ad9910_state *st = iio_priv(idev);
127
128 xfer.len = 5;
129 xfer.tx_buf = &config->auxdac[0];
130 mutex_lock(&st->lock);
131
132 spi_message_init(&msg);
133 spi_message_add_tail(&xfer, &msg);
134 ret = spi_sync(st->sdev, &msg);
135 if (ret)
136 goto error_ret;
137
138 xfer.len = 5;
139 xfer.tx_buf = &config->ioupd[0];
140
141 spi_message_init(&msg);
142 spi_message_add_tail(&xfer, &msg);
143 ret = spi_sync(st->sdev, &msg);
144 if (ret)
145 goto error_ret;
146
147 xfer.len = 5;
148 xfer.tx_buf = &config->ftw[0];
149
150 spi_message_init(&msg);
151 spi_message_add_tail(&xfer, &msg);
152 ret = spi_sync(st->sdev, &msg);
153 if (ret)
154 goto error_ret;
155
156 xfer.len = 3;
157 xfer.tx_buf = &config->pow[0];
158
159 spi_message_init(&msg);
160 spi_message_add_tail(&xfer, &msg);
161 ret = spi_sync(st->sdev, &msg);
162 if (ret)
163 goto error_ret;
164
165 xfer.len = 5;
166 xfer.tx_buf = &config->asf[0];
167
168 spi_message_init(&msg);
169 spi_message_add_tail(&xfer, &msg);
170 ret = spi_sync(st->sdev, &msg);
171 if (ret)
172 goto error_ret;
173
174 xfer.len = 5;
175 xfer.tx_buf = &config->multc[0];
176
177 spi_message_init(&msg);
178 spi_message_add_tail(&xfer, &msg);
179 ret = spi_sync(st->sdev, &msg);
180 if (ret)
181 goto error_ret;
182
183 xfer.len = 9;
184 xfer.tx_buf = &config->dig_rampl[0];
185
186 spi_message_init(&msg);
187 spi_message_add_tail(&xfer, &msg);
188 ret = spi_sync(st->sdev, &msg);
189 if (ret)
190 goto error_ret;
191
192 xfer.len = 9;
193 xfer.tx_buf = &config->dig_ramps[0];
194
195 spi_message_init(&msg);
196 spi_message_add_tail(&xfer, &msg);
197 ret = spi_sync(st->sdev, &msg);
198 if (ret)
199 goto error_ret;
200
201 xfer.len = 5;
202 xfer.tx_buf = &config->dig_rampr[0];
203
204 spi_message_init(&msg);
205 spi_message_add_tail(&xfer, &msg);
206 ret = spi_sync(st->sdev, &msg);
207 if (ret)
208 goto error_ret;
209
210 xfer.len = 9;
211 xfer.tx_buf = &config->sin_tonep0[0];
212
213 spi_message_init(&msg);
214 spi_message_add_tail(&xfer, &msg);
215 ret = spi_sync(st->sdev, &msg);
216 if (ret)
217 goto error_ret;
218
219 xfer.len = 9;
220 xfer.tx_buf = &config->sin_tonep1[0];
221
222 spi_message_init(&msg);
223 spi_message_add_tail(&xfer, &msg);
224 ret = spi_sync(st->sdev, &msg);
225 if (ret)
226 goto error_ret;
227
228 xfer.len = 9;
229 xfer.tx_buf = &config->sin_tonep2[0];
230
231 spi_message_init(&msg);
232 spi_message_add_tail(&xfer, &msg);
233 ret = spi_sync(st->sdev, &msg);
234 if (ret)
235 goto error_ret;
236 xfer.len = 9;
237 xfer.tx_buf = &config->sin_tonep3[0];
238
239 spi_message_init(&msg);
240 spi_message_add_tail(&xfer, &msg);
241 ret = spi_sync(st->sdev, &msg);
242 if (ret)
243 goto error_ret;
244
245 xfer.len = 9;
246 xfer.tx_buf = &config->sin_tonep4[0];
247
248 spi_message_init(&msg);
249 spi_message_add_tail(&xfer, &msg);
250 ret = spi_sync(st->sdev, &msg);
251 if (ret)
252 goto error_ret;
253
254 xfer.len = 9;
255 xfer.tx_buf = &config->sin_tonep5[0];
256
257 spi_message_init(&msg);
258 spi_message_add_tail(&xfer, &msg);
259 ret = spi_sync(st->sdev, &msg);
260 if (ret)
261 goto error_ret;
262
263 xfer.len = 9;
264 xfer.tx_buf = &config->sin_tonep6[0];
265
266 spi_message_init(&msg);
267 spi_message_add_tail(&xfer, &msg);
268 ret = spi_sync(st->sdev, &msg);
269 if (ret)
270 goto error_ret;
271
272 xfer.len = 9;
273 xfer.tx_buf = &config->sin_tonep7[0];
274
275 spi_message_init(&msg);
276 spi_message_add_tail(&xfer, &msg);
277 ret = spi_sync(st->sdev, &msg);
278 if (ret)
279 goto error_ret;
280error_ret:
281 mutex_unlock(&st->lock);
282
283 return ret ? ret : len;
284}
285
286static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0);
287
288static void ad9910_init(struct ad9910_state *st)
289{
290 struct spi_message msg;
291 struct spi_transfer xfer;
292 int ret;
293 u8 cfr[5];
294
295 cfr[0] = CFR1;
296 cfr[1] = 0;
297 cfr[2] = MANUAL_OSK | INVSIC | DDS_SINEOP;
298 cfr[3] = AUTO_OSK | OSKEN | ACLR_PHA | ACLR_DIG | LOAD_LRR;
299 cfr[4] = 0;
300
301 mutex_lock(&st->lock);
302
303 xfer.len = 5;
304 xfer.tx_buf = &cfr;
305
306 spi_message_init(&msg);
307 spi_message_add_tail(&xfer, &msg);
308 ret = spi_sync(st->sdev, &msg);
309 if (ret)
310 goto error_ret;
311
312 cfr[0] = CFR2;
313 cfr[1] = ENA_AMP;
314 cfr[2] = READ_FTW | DIGR_ENA | ITER_IOUPD;
315 cfr[3] = TX_ENA | PDCLK_INV | PDCLK_ENB;
316 cfr[4] = PARA_ENA;
317
318 xfer.len = 5;
319 xfer.tx_buf = &cfr;
320
321 spi_message_init(&msg);
322 spi_message_add_tail(&xfer, &msg);
323 ret = spi_sync(st->sdev, &msg);
324 if (ret)
325 goto error_ret;
326
327 cfr[0] = CFR3;
328 cfr[1] = PLL_ENA;
329 cfr[2] = 0;
330 cfr[3] = REFCLK_RST | REFCLK_BYP;
331 cfr[4] = 0;
332
333 xfer.len = 5;
334 xfer.tx_buf = &cfr;
335
336 spi_message_init(&msg);
337 spi_message_add_tail(&xfer, &msg);
338 ret = spi_sync(st->sdev, &msg);
339 if (ret)
340 goto error_ret;
341
342error_ret:
343 mutex_unlock(&st->lock);
344
345
346
347}
348
349static struct attribute *ad9910_attributes[] = {
350 &iio_dev_attr_dds.dev_attr.attr,
351 NULL,
352};
353
354static const struct attribute_group ad9910_attribute_group = {
355 .name = DRV_NAME,
356 .attrs = ad9910_attributes,
357};
358
359static const struct iio_info ad9910_info = {
360 .attrs = &ad9910_attribute_group,
361 .driver_module = THIS_MODULE,
362};
363
364static int __devinit ad9910_probe(struct spi_device *spi)
365{
366 struct ad9910_state *st;
367 struct iio_dev *idev;
368 int ret = 0;
369
370 idev = iio_allocate_device(sizeof(*st));
371 if (idev == NULL) {
372 ret = -ENOMEM;
373 goto error_ret;
374 }
375 spi_set_drvdata(spi, idev);
376 st = iio_priv(idev);
377 mutex_init(&st->lock);
378 st->sdev = spi;
379
380 idev->dev.parent = &spi->dev;
381 idev->info = &ad9910_info;
382 idev->modes = INDIO_DIRECT_MODE;
383
384 ret = iio_device_register(idev);
385 if (ret)
386 goto error_free_dev;
387 spi->max_speed_hz = 2000000;
388 spi->mode = SPI_MODE_3;
389 spi->bits_per_word = 8;
390 spi_setup(spi);
391 ad9910_init(st);
392 return 0;
393
394error_free_dev:
395 iio_free_device(idev);
396error_ret:
397 return ret;
398}
399
400static int __devexit ad9910_remove(struct spi_device *spi)
401{
402 iio_device_unregister(spi_get_drvdata(spi));
403
404 return 0;
405}
406
407static struct spi_driver ad9910_driver = {
408 .driver = {
409 .name = DRV_NAME,
410 .owner = THIS_MODULE,
411 },
412 .probe = ad9910_probe,
413 .remove = __devexit_p(ad9910_remove),
414};
415
416static __init int ad9910_spi_init(void)
417{
418 return spi_register_driver(&ad9910_driver);
419}
420module_init(ad9910_spi_init);
421
422static __exit void ad9910_spi_exit(void)
423{
424 spi_unregister_driver(&ad9910_driver);
425}
426module_exit(ad9910_spi_exit);
427
428MODULE_AUTHOR("Cliff Cai");
429MODULE_DESCRIPTION("Analog Devices ad9910 driver");
430MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/dds/ad9951.c
new file mode 100644
index 00000000000..d361d1f125d
--- /dev/null
+++ b/drivers/staging/iio/dds/ad9951.c
@@ -0,0 +1,241 @@
1/*
2 * Driver for ADI Direct Digital Synthesis ad9951
3 *
4 * Copyright (c) 2010 Analog Devices Inc.
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 version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11#include <linux/types.h>
12#include <linux/mutex.h>
13#include <linux/device.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h>
16#include <linux/sysfs.h>
17
18#include "../iio.h"
19#include "../sysfs.h"
20
21#define DRV_NAME "ad9951"
22
23#define CFR1 0x0
24#define CFR2 0x1
25
26#define AUTO_OSK (1)
27#define OSKEN (1 << 1)
28#define LOAD_ARR (1 << 2)
29
30#define AUTO_SYNC (1 << 7)
31
32#define LSB_FST (1)
33#define SDIO_IPT (1 << 1)
34#define CLR_PHA (1 << 2)
35#define SINE_OPT (1 << 4)
36#define ACLR_PHA (1 << 5)
37
38#define VCO_RANGE (1 << 2)
39
40#define CRS_OPT (1 << 1)
41#define HMANU_SYNC (1 << 2)
42#define HSPD_SYNC (1 << 3)
43
44/* Register format: 1 byte addr + value */
45struct ad9951_config {
46 u8 asf[3];
47 u8 arr[2];
48 u8 ftw0[5];
49 u8 ftw1[3];
50};
51
52struct ad9951_state {
53 struct mutex lock;
54 struct spi_device *sdev;
55};
56
57static ssize_t ad9951_set_parameter(struct device *dev,
58 struct device_attribute *attr,
59 const char *buf,
60 size_t len)
61{
62 struct spi_message msg;
63 struct spi_transfer xfer;
64 int ret;
65 struct ad9951_config *config = (struct ad9951_config *)buf;
66 struct iio_dev *idev = dev_get_drvdata(dev);
67 struct ad9951_state *st = iio_priv(idev);
68
69 xfer.len = 3;
70 xfer.tx_buf = &config->asf[0];
71 mutex_lock(&st->lock);
72
73 spi_message_init(&msg);
74 spi_message_add_tail(&xfer, &msg);
75 ret = spi_sync(st->sdev, &msg);
76 if (ret)
77 goto error_ret;
78
79 xfer.len = 2;
80 xfer.tx_buf = &config->arr[0];
81
82 spi_message_init(&msg);
83 spi_message_add_tail(&xfer, &msg);
84 ret = spi_sync(st->sdev, &msg);
85 if (ret)
86 goto error_ret;
87
88 xfer.len = 5;
89 xfer.tx_buf = &config->ftw0[0];
90
91 spi_message_init(&msg);
92 spi_message_add_tail(&xfer, &msg);
93 ret = spi_sync(st->sdev, &msg);
94 if (ret)
95 goto error_ret;
96
97 xfer.len = 3;
98 xfer.tx_buf = &config->ftw1[0];
99
100 spi_message_init(&msg);
101 spi_message_add_tail(&xfer, &msg);
102 ret = spi_sync(st->sdev, &msg);
103 if (ret)
104 goto error_ret;
105error_ret:
106 mutex_unlock(&st->lock);
107
108 return ret ? ret : len;
109}
110
111static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0);
112
113static void ad9951_init(struct ad9951_state *st)
114{
115 struct spi_message msg;
116 struct spi_transfer xfer;
117 int ret;
118 u8 cfr[5];
119
120 cfr[0] = CFR1;
121 cfr[1] = 0;
122 cfr[2] = LSB_FST | CLR_PHA | SINE_OPT | ACLR_PHA;
123 cfr[3] = AUTO_OSK | OSKEN | LOAD_ARR;
124 cfr[4] = 0;
125
126 mutex_lock(&st->lock);
127
128 xfer.len = 5;
129 xfer.tx_buf = &cfr;
130
131 spi_message_init(&msg);
132 spi_message_add_tail(&xfer, &msg);
133 ret = spi_sync(st->sdev, &msg);
134 if (ret)
135 goto error_ret;
136
137 cfr[0] = CFR2;
138 cfr[1] = VCO_RANGE;
139 cfr[2] = HSPD_SYNC;
140 cfr[3] = 0;
141
142 xfer.len = 4;
143 xfer.tx_buf = &cfr;
144
145 spi_message_init(&msg);
146 spi_message_add_tail(&xfer, &msg);
147 ret = spi_sync(st->sdev, &msg);
148 if (ret)
149 goto error_ret;
150
151error_ret:
152 mutex_unlock(&st->lock);
153
154
155
156}
157
158static struct attribute *ad9951_attributes[] = {
159 &iio_dev_attr_dds.dev_attr.attr,
160 NULL,
161};
162
163static const struct attribute_group ad9951_attribute_group = {
164 .name = DRV_NAME,
165 .attrs = ad9951_attributes,
166};
167
168static const struct iio_info ad9951_info = {
169 .attrs = &ad9951_attribute_group,
170 .driver_module = THIS_MODULE,
171};
172
173static int __devinit ad9951_probe(struct spi_device *spi)
174{
175 struct ad9951_state *st;
176 struct iio_dev *idev;
177 int ret = 0;
178
179 idev = iio_allocate_device(sizeof(*st));
180 if (idev == NULL) {
181 ret = -ENOMEM;
182 goto error_ret;
183 }
184 spi_set_drvdata(spi, idev);
185 st = iio_priv(idev);
186 mutex_init(&st->lock);
187 st->sdev = spi;
188
189 idev->dev.parent = &spi->dev;
190
191 idev->info = &ad9951_info;
192 idev->modes = INDIO_DIRECT_MODE;
193
194 ret = iio_device_register(idev);
195 if (ret)
196 goto error_free_dev;
197 spi->max_speed_hz = 2000000;
198 spi->mode = SPI_MODE_3;
199 spi->bits_per_word = 8;
200 spi_setup(spi);
201 ad9951_init(st);
202 return 0;
203
204error_free_dev:
205 iio_free_device(idev);
206
207error_ret:
208 return ret;
209}
210
211static int __devexit ad9951_remove(struct spi_device *spi)
212{
213 iio_device_unregister(spi_get_drvdata(spi));
214
215 return 0;
216}
217
218static struct spi_driver ad9951_driver = {
219 .driver = {
220 .name = DRV_NAME,
221 .owner = THIS_MODULE,
222 },
223 .probe = ad9951_probe,
224 .remove = __devexit_p(ad9951_remove),
225};
226
227static __init int ad9951_spi_init(void)
228{
229 return spi_register_driver(&ad9951_driver);
230}
231module_init(ad9951_spi_init);
232
233static __exit void ad9951_spi_exit(void)
234{
235 spi_unregister_driver(&ad9951_driver);
236}
237module_exit(ad9951_spi_exit);
238
239MODULE_AUTHOR("Cliff Cai");
240MODULE_DESCRIPTION("Analog Devices ad9951 driver");
241MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/dds/dds.h b/drivers/staging/iio/dds/dds.h
new file mode 100644
index 00000000000..d8ac3a93baf
--- /dev/null
+++ b/drivers/staging/iio/dds/dds.h
@@ -0,0 +1,110 @@
1/*
2 * dds.h - sysfs attributes associated with DDS devices
3 *
4 * Copyright (c) 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9/**
10 * /sys/bus/iio/devices/.../ddsX_freqY
11 */
12
13#define IIO_DEV_ATTR_FREQ(_channel, _num, _mode, _show, _store, _addr) \
14 IIO_DEVICE_ATTR(dds##_channel##_freq##_num, \
15 _mode, _show, _store, _addr)
16
17/**
18 * /sys/bus/iio/devices/.../ddsX_freqY_scale
19 */
20
21#define IIO_CONST_ATTR_FREQ_SCALE(_channel, _string) \
22 IIO_CONST_ATTR(dds##_channel##_freq_scale, _string)
23
24/**
25 * /sys/bus/iio/devices/.../ddsX_freqsymbol
26 */
27
28#define IIO_DEV_ATTR_FREQSYMBOL(_channel, _mode, _show, _store, _addr) \
29 IIO_DEVICE_ATTR(dds##_channel##_freqsymbol, \
30 _mode, _show, _store, _addr);
31
32/**
33 * /sys/bus/iio/devices/.../ddsX_phaseY
34 */
35
36#define IIO_DEV_ATTR_PHASE(_channel, _num, _mode, _show, _store, _addr) \
37 IIO_DEVICE_ATTR(dds##_channel##_phase##_num, \
38 _mode, _show, _store, _addr)
39
40/**
41 * /sys/bus/iio/devices/.../ddsX_phaseY_scale
42 */
43
44#define IIO_CONST_ATTR_PHASE_SCALE(_channel, _string) \
45 IIO_CONST_ATTR(dds##_channel##_phase_scale, _string)
46
47/**
48 * /sys/bus/iio/devices/.../ddsX_phasesymbol
49 */
50
51#define IIO_DEV_ATTR_PHASESYMBOL(_channel, _mode, _show, _store, _addr) \
52 IIO_DEVICE_ATTR(dds##_channel##_phasesymbol, \
53 _mode, _show, _store, _addr);
54
55/**
56 * /sys/bus/iio/devices/.../ddsX_pincontrol_en
57 */
58
59#define IIO_DEV_ATTR_PINCONTROL_EN(_channel, _mode, _show, _store, _addr)\
60 IIO_DEVICE_ATTR(dds##_channel##_pincontrol_en, \
61 _mode, _show, _store, _addr);
62
63/**
64 * /sys/bus/iio/devices/.../ddsX_pincontrol_freq_en
65 */
66
67#define IIO_DEV_ATTR_PINCONTROL_FREQ_EN(_channel, _mode, _show, _store, _addr)\
68 IIO_DEVICE_ATTR(dds##_channel##_pincontrol_freq_en, \
69 _mode, _show, _store, _addr);
70
71/**
72 * /sys/bus/iio/devices/.../ddsX_pincontrol_phase_en
73 */
74
75#define IIO_DEV_ATTR_PINCONTROL_PHASE_EN(_channel, _mode, _show, _store, _addr)\
76 IIO_DEVICE_ATTR(dds##_channel##_pincontrol_phase_en, \
77 _mode, _show, _store, _addr);
78
79/**
80 * /sys/bus/iio/devices/.../ddsX_out_enable
81 */
82
83#define IIO_DEV_ATTR_OUT_ENABLE(_channel, _mode, _show, _store, _addr) \
84 IIO_DEVICE_ATTR(dds##_channel##_out_enable, \
85 _mode, _show, _store, _addr);
86
87/**
88 * /sys/bus/iio/devices/.../ddsX_outY_enable
89 */
90
91#define IIO_DEV_ATTR_OUTY_ENABLE(_channel, _output, \
92 _mode, _show, _store, _addr) \
93 IIO_DEVICE_ATTR(dds##_channel##_out##_output##_enable, \
94 _mode, _show, _store, _addr);
95
96/**
97 * /sys/bus/iio/devices/.../ddsX_outY_wavetype
98 */
99
100#define IIO_DEV_ATTR_OUT_WAVETYPE(_channel, _output, _store, _addr) \
101 IIO_DEVICE_ATTR(dds##_channel##_out##_output##_wavetype, \
102 S_IWUSR, NULL, _store, _addr);
103
104/**
105 * /sys/bus/iio/devices/.../ddsX_outY_wavetype_available
106 */
107
108#define IIO_CONST_ATTR_OUT_WAVETYPES_AVAILABLE(_channel, _output, _modes)\
109 IIO_CONST_ATTR(dds##_channel##_out##_output##_wavetype_available,\
110 _modes);