Linux-libre 3.16.41-gnu
[librecmc/linux-libre.git] / drivers / staging / iio / frequency / ad9910.c
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 #include <linux/module.h>
18
19 #include <linux/iio/iio.h>
20 #include <linux/iio/sysfs.h>
21
22 #define DRV_NAME "ad9910"
23
24 #define CFR1 0x0
25 #define CFR2 0x1
26 #define CFR3 0x2
27
28 #define AUXDAC 0x3
29 #define IOUPD 0x4
30 #define FTW 0x7
31 #define POW 0x8
32 #define ASF 0x9
33 #define MULTC 0x0A
34 #define DIG_RAMPL 0x0B
35 #define DIG_RAMPS 0x0C
36 #define DIG_RAMPR 0x0D
37 #define SIN_TONEP0 0x0E
38 #define SIN_TONEP1 0x0F
39 #define SIN_TONEP2 0x10
40 #define SIN_TONEP3 0x11
41 #define SIN_TONEP4 0x12
42 #define SIN_TONEP5 0x13
43 #define SIN_TONEP6 0x14
44 #define SIN_TONEP7 0x15
45
46 #define RAM_ENABLE      (1 << 7)
47
48 #define MANUAL_OSK      (1 << 7)
49 #define INVSIC          (1 << 6)
50 #define DDS_SINEOP      (1)
51
52 #define AUTO_OSK        (1)
53 #define OSKEN           (1 << 1)
54 #define LOAD_ARR        (1 << 2)
55 #define CLR_PHA         (1 << 3)
56 #define CLR_DIG         (1 << 4)
57 #define ACLR_PHA        (1 << 5)
58 #define ACLR_DIG        (1 << 6)
59 #define LOAD_LRR        (1 << 7)
60
61 #define LSB_FST         (1)
62 #define SDIO_IPT        (1 << 1)
63 #define EXT_PWD         (1 << 3)
64 #define ADAC_PWD        (1 << 4)
65 #define REFCLK_PWD      (1 << 5)
66 #define DAC_PWD         (1 << 6)
67 #define DIG_PWD         (1 << 7)
68
69 #define ENA_AMP         (1)
70 #define READ_FTW        (1)
71 #define DIGR_LOW        (1 << 1)
72 #define DIGR_HIGH       (1 << 2)
73 #define DIGR_ENA        (1 << 3)
74 #define SYNCCLK_ENA     (1 << 6)
75 #define ITER_IOUPD      (1 << 7)
76
77 #define TX_ENA          (1 << 1)
78 #define PDCLK_INV       (1 << 2)
79 #define PDCLK_ENB       (1 << 3)
80
81 #define PARA_ENA        (1 << 4)
82 #define SYNC_DIS        (1 << 5)
83 #define DATA_ASS        (1 << 6)
84 #define MATCH_ENA       (1 << 7)
85
86 #define PLL_ENA         (1)
87 #define PFD_RST         (1 << 2)
88 #define REFCLK_RST      (1 << 6)
89 #define REFCLK_BYP      (1 << 7)
90
91 /* Register format: 1 byte addr + value */
92 struct ad9910_config {
93         u8 auxdac[5];
94         u8 ioupd[5];
95         u8 ftw[5];
96         u8 pow[3];
97         u8 asf[5];
98         u8 multc[5];
99         u8 dig_rampl[9];
100         u8 dig_ramps[9];
101         u8 dig_rampr[5];
102         u8 sin_tonep0[9];
103         u8 sin_tonep1[9];
104         u8 sin_tonep2[9];
105         u8 sin_tonep3[9];
106         u8 sin_tonep4[9];
107         u8 sin_tonep5[9];
108         u8 sin_tonep6[9];
109         u8 sin_tonep7[9];
110 };
111
112 struct ad9910_state {
113         struct mutex lock;
114         struct spi_device *sdev;
115 };
116
117 static ssize_t ad9910_set_parameter(struct device *dev,
118                                         struct device_attribute *attr,
119                                         const char *buf,
120                                         size_t len)
121 {
122         struct spi_transfer xfer;
123         int ret;
124         struct ad9910_config *config = (struct ad9910_config *)buf;
125         struct iio_dev *idev = dev_to_iio_dev(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         ret = spi_sync_transfer(st->sdev, &xfer, 1);
133         if (ret)
134                 goto error_ret;
135
136         xfer.len = 5;
137         xfer.tx_buf = &config->ioupd[0];
138
139         ret = spi_sync_transfer(st->sdev, &xfer, 1);
140         if (ret)
141                 goto error_ret;
142
143         xfer.len = 5;
144         xfer.tx_buf = &config->ftw[0];
145
146         ret = spi_sync_transfer(st->sdev, &xfer, 1);
147         if (ret)
148                 goto error_ret;
149
150         xfer.len = 3;
151         xfer.tx_buf = &config->pow[0];
152
153         ret = spi_sync_transfer(st->sdev, &xfer, 1);
154         if (ret)
155                 goto error_ret;
156
157         xfer.len = 5;
158         xfer.tx_buf = &config->asf[0];
159
160         ret = spi_sync_transfer(st->sdev, &xfer, 1);
161         if (ret)
162                 goto error_ret;
163
164         xfer.len = 5;
165         xfer.tx_buf = &config->multc[0];
166
167         ret = spi_sync_transfer(st->sdev, &xfer, 1);
168         if (ret)
169                 goto error_ret;
170
171         xfer.len = 9;
172         xfer.tx_buf = &config->dig_rampl[0];
173
174         ret = spi_sync_transfer(st->sdev, &xfer, 1);
175         if (ret)
176                 goto error_ret;
177
178         xfer.len = 9;
179         xfer.tx_buf = &config->dig_ramps[0];
180
181         ret = spi_sync_transfer(st->sdev, &xfer, 1);
182         if (ret)
183                 goto error_ret;
184
185         xfer.len = 5;
186         xfer.tx_buf = &config->dig_rampr[0];
187
188         ret = spi_sync_transfer(st->sdev, &xfer, 1);
189         if (ret)
190                 goto error_ret;
191
192         xfer.len = 9;
193         xfer.tx_buf = &config->sin_tonep0[0];
194
195         ret = spi_sync_transfer(st->sdev, &xfer, 1);
196         if (ret)
197                 goto error_ret;
198
199         xfer.len = 9;
200         xfer.tx_buf = &config->sin_tonep1[0];
201
202         ret = spi_sync_transfer(st->sdev, &xfer, 1);
203         if (ret)
204                 goto error_ret;
205
206         xfer.len = 9;
207         xfer.tx_buf = &config->sin_tonep2[0];
208
209         ret = spi_sync_transfer(st->sdev, &xfer, 1);
210         if (ret)
211                 goto error_ret;
212         xfer.len = 9;
213         xfer.tx_buf = &config->sin_tonep3[0];
214
215         ret = spi_sync_transfer(st->sdev, &xfer, 1);
216         if (ret)
217                 goto error_ret;
218
219         xfer.len = 9;
220         xfer.tx_buf = &config->sin_tonep4[0];
221
222         ret = spi_sync_transfer(st->sdev, &xfer, 1);
223         if (ret)
224                 goto error_ret;
225
226         xfer.len = 9;
227         xfer.tx_buf = &config->sin_tonep5[0];
228
229         ret = spi_sync_transfer(st->sdev, &xfer, 1);
230         if (ret)
231                 goto error_ret;
232
233         xfer.len = 9;
234         xfer.tx_buf = &config->sin_tonep6[0];
235
236         ret = spi_sync_transfer(st->sdev, &xfer, 1);
237         if (ret)
238                 goto error_ret;
239
240         xfer.len = 9;
241         xfer.tx_buf = &config->sin_tonep7[0];
242
243         ret = spi_sync_transfer(st->sdev, &xfer, 1);
244         if (ret)
245                 goto error_ret;
246 error_ret:
247         mutex_unlock(&st->lock);
248
249         return ret ? ret : len;
250 }
251
252 static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0);
253
254 static void ad9910_init(struct ad9910_state *st)
255 {
256         struct spi_transfer xfer;
257         int ret;
258         u8 cfr[5];
259
260         cfr[0] = CFR1;
261         cfr[1] = 0;
262         cfr[2] = MANUAL_OSK | INVSIC | DDS_SINEOP;
263         cfr[3] = AUTO_OSK | OSKEN | ACLR_PHA | ACLR_DIG | LOAD_LRR;
264         cfr[4] = 0;
265
266         mutex_lock(&st->lock);
267
268         xfer.len = 5;
269         xfer.tx_buf = &cfr;
270
271         ret = spi_sync_transfer(st->sdev, &xfer, 1);
272         if (ret)
273                 goto error_ret;
274
275         cfr[0] = CFR2;
276         cfr[1] = ENA_AMP;
277         cfr[2] = READ_FTW | DIGR_ENA | ITER_IOUPD;
278         cfr[3] = TX_ENA | PDCLK_INV | PDCLK_ENB;
279         cfr[4] = PARA_ENA;
280
281         xfer.len = 5;
282         xfer.tx_buf = &cfr;
283
284         ret = spi_sync_transfer(st->sdev, &xfer, 1);
285         if (ret)
286                 goto error_ret;
287
288         cfr[0] = CFR3;
289         cfr[1] = PLL_ENA;
290         cfr[2] = 0;
291         cfr[3] = REFCLK_RST | REFCLK_BYP;
292         cfr[4] = 0;
293
294         xfer.len = 5;
295         xfer.tx_buf = &cfr;
296
297         ret = spi_sync_transfer(st->sdev, &xfer, 1);
298         if (ret)
299                 goto error_ret;
300
301 error_ret:
302         mutex_unlock(&st->lock);
303
304
305
306 }
307
308 static struct attribute *ad9910_attributes[] = {
309         &iio_dev_attr_dds.dev_attr.attr,
310         NULL,
311 };
312
313 static const struct attribute_group ad9910_attribute_group = {
314         .attrs = ad9910_attributes,
315 };
316
317 static const struct iio_info ad9910_info = {
318         .attrs = &ad9910_attribute_group,
319         .driver_module = THIS_MODULE,
320 };
321
322 static int ad9910_probe(struct spi_device *spi)
323 {
324         struct ad9910_state *st;
325         struct iio_dev *idev;
326         int ret = 0;
327
328         idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
329         if (!idev)
330                 return -ENOMEM;
331         spi_set_drvdata(spi, idev);
332         st = iio_priv(idev);
333         mutex_init(&st->lock);
334         st->sdev = spi;
335
336         idev->dev.parent = &spi->dev;
337         idev->info = &ad9910_info;
338         idev->modes = INDIO_DIRECT_MODE;
339
340         ret = iio_device_register(idev);
341         if (ret)
342                 return ret;
343         spi->max_speed_hz = 2000000;
344         spi->mode = SPI_MODE_3;
345         spi->bits_per_word = 8;
346         spi_setup(spi);
347         ad9910_init(st);
348         return 0;
349 }
350
351 static int ad9910_remove(struct spi_device *spi)
352 {
353         iio_device_unregister(spi_get_drvdata(spi));
354
355         return 0;
356 }
357
358 static struct spi_driver ad9910_driver = {
359         .driver = {
360                 .name = DRV_NAME,
361                 .owner = THIS_MODULE,
362         },
363         .probe = ad9910_probe,
364         .remove = ad9910_remove,
365 };
366 module_spi_driver(ad9910_driver);
367
368 MODULE_AUTHOR("Cliff Cai");
369 MODULE_DESCRIPTION("Analog Devices ad9910 driver");
370 MODULE_LICENSE("GPL v2");
371 MODULE_ALIAS("spi:" DRV_NAME);