Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ad9910.c
Go to the documentation of this file.
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];
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_message msg;
123  struct spi_transfer xfer;
124  int ret;
125  struct ad9910_config *config = (struct ad9910_config *)buf;
126  struct iio_dev *idev = dev_to_iio_dev(dev);
127  struct ad9910_state *st = iio_priv(idev);
128 
129  xfer.len = 5;
130  xfer.tx_buf = &config->auxdac[0];
131  mutex_lock(&st->lock);
132 
133  spi_message_init(&msg);
134  spi_message_add_tail(&xfer, &msg);
135  ret = spi_sync(st->sdev, &msg);
136  if (ret)
137  goto error_ret;
138 
139  xfer.len = 5;
140  xfer.tx_buf = &config->ioupd[0];
141 
142  spi_message_init(&msg);
143  spi_message_add_tail(&xfer, &msg);
144  ret = spi_sync(st->sdev, &msg);
145  if (ret)
146  goto error_ret;
147 
148  xfer.len = 5;
149  xfer.tx_buf = &config->ftw[0];
150 
151  spi_message_init(&msg);
152  spi_message_add_tail(&xfer, &msg);
153  ret = spi_sync(st->sdev, &msg);
154  if (ret)
155  goto error_ret;
156 
157  xfer.len = 3;
158  xfer.tx_buf = &config->pow[0];
159 
160  spi_message_init(&msg);
161  spi_message_add_tail(&xfer, &msg);
162  ret = spi_sync(st->sdev, &msg);
163  if (ret)
164  goto error_ret;
165 
166  xfer.len = 5;
167  xfer.tx_buf = &config->asf[0];
168 
169  spi_message_init(&msg);
170  spi_message_add_tail(&xfer, &msg);
171  ret = spi_sync(st->sdev, &msg);
172  if (ret)
173  goto error_ret;
174 
175  xfer.len = 5;
176  xfer.tx_buf = &config->multc[0];
177 
178  spi_message_init(&msg);
179  spi_message_add_tail(&xfer, &msg);
180  ret = spi_sync(st->sdev, &msg);
181  if (ret)
182  goto error_ret;
183 
184  xfer.len = 9;
185  xfer.tx_buf = &config->dig_rampl[0];
186 
187  spi_message_init(&msg);
188  spi_message_add_tail(&xfer, &msg);
189  ret = spi_sync(st->sdev, &msg);
190  if (ret)
191  goto error_ret;
192 
193  xfer.len = 9;
194  xfer.tx_buf = &config->dig_ramps[0];
195 
196  spi_message_init(&msg);
197  spi_message_add_tail(&xfer, &msg);
198  ret = spi_sync(st->sdev, &msg);
199  if (ret)
200  goto error_ret;
201 
202  xfer.len = 5;
203  xfer.tx_buf = &config->dig_rampr[0];
204 
205  spi_message_init(&msg);
206  spi_message_add_tail(&xfer, &msg);
207  ret = spi_sync(st->sdev, &msg);
208  if (ret)
209  goto error_ret;
210 
211  xfer.len = 9;
212  xfer.tx_buf = &config->sin_tonep0[0];
213 
214  spi_message_init(&msg);
215  spi_message_add_tail(&xfer, &msg);
216  ret = spi_sync(st->sdev, &msg);
217  if (ret)
218  goto error_ret;
219 
220  xfer.len = 9;
221  xfer.tx_buf = &config->sin_tonep1[0];
222 
223  spi_message_init(&msg);
224  spi_message_add_tail(&xfer, &msg);
225  ret = spi_sync(st->sdev, &msg);
226  if (ret)
227  goto error_ret;
228 
229  xfer.len = 9;
230  xfer.tx_buf = &config->sin_tonep2[0];
231 
232  spi_message_init(&msg);
233  spi_message_add_tail(&xfer, &msg);
234  ret = spi_sync(st->sdev, &msg);
235  if (ret)
236  goto error_ret;
237  xfer.len = 9;
238  xfer.tx_buf = &config->sin_tonep3[0];
239 
240  spi_message_init(&msg);
241  spi_message_add_tail(&xfer, &msg);
242  ret = spi_sync(st->sdev, &msg);
243  if (ret)
244  goto error_ret;
245 
246  xfer.len = 9;
247  xfer.tx_buf = &config->sin_tonep4[0];
248 
249  spi_message_init(&msg);
250  spi_message_add_tail(&xfer, &msg);
251  ret = spi_sync(st->sdev, &msg);
252  if (ret)
253  goto error_ret;
254 
255  xfer.len = 9;
256  xfer.tx_buf = &config->sin_tonep5[0];
257 
258  spi_message_init(&msg);
259  spi_message_add_tail(&xfer, &msg);
260  ret = spi_sync(st->sdev, &msg);
261  if (ret)
262  goto error_ret;
263 
264  xfer.len = 9;
265  xfer.tx_buf = &config->sin_tonep6[0];
266 
267  spi_message_init(&msg);
268  spi_message_add_tail(&xfer, &msg);
269  ret = spi_sync(st->sdev, &msg);
270  if (ret)
271  goto error_ret;
272 
273  xfer.len = 9;
274  xfer.tx_buf = &config->sin_tonep7[0];
275 
276  spi_message_init(&msg);
277  spi_message_add_tail(&xfer, &msg);
278  ret = spi_sync(st->sdev, &msg);
279  if (ret)
280  goto error_ret;
281 error_ret:
282  mutex_unlock(&st->lock);
283 
284  return ret ? ret : len;
285 }
286 
287 static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0);
288 
289 static void ad9910_init(struct ad9910_state *st)
290 {
291  struct spi_message msg;
292  struct spi_transfer xfer;
293  int ret;
294  u8 cfr[5];
295 
296  cfr[0] = CFR1;
297  cfr[1] = 0;
298  cfr[2] = MANUAL_OSK | INVSIC | DDS_SINEOP;
299  cfr[3] = AUTO_OSK | OSKEN | ACLR_PHA | ACLR_DIG | LOAD_LRR;
300  cfr[4] = 0;
301 
302  mutex_lock(&st->lock);
303 
304  xfer.len = 5;
305  xfer.tx_buf = &cfr;
306 
307  spi_message_init(&msg);
308  spi_message_add_tail(&xfer, &msg);
309  ret = spi_sync(st->sdev, &msg);
310  if (ret)
311  goto error_ret;
312 
313  cfr[0] = CFR2;
314  cfr[1] = ENA_AMP;
315  cfr[2] = READ_FTW | DIGR_ENA | ITER_IOUPD;
316  cfr[3] = TX_ENA | PDCLK_INV | PDCLK_ENB;
317  cfr[4] = PARA_ENA;
318 
319  xfer.len = 5;
320  xfer.tx_buf = &cfr;
321 
322  spi_message_init(&msg);
323  spi_message_add_tail(&xfer, &msg);
324  ret = spi_sync(st->sdev, &msg);
325  if (ret)
326  goto error_ret;
327 
328  cfr[0] = CFR3;
329  cfr[1] = PLL_ENA;
330  cfr[2] = 0;
331  cfr[3] = REFCLK_RST | REFCLK_BYP;
332  cfr[4] = 0;
333 
334  xfer.len = 5;
335  xfer.tx_buf = &cfr;
336 
337  spi_message_init(&msg);
338  spi_message_add_tail(&xfer, &msg);
339  ret = spi_sync(st->sdev, &msg);
340  if (ret)
341  goto error_ret;
342 
343 error_ret:
344  mutex_unlock(&st->lock);
345 
346 
347 
348 }
349 
350 static struct attribute *ad9910_attributes[] = {
351  &iio_dev_attr_dds.dev_attr.attr,
352  NULL,
353 };
354 
355 static const struct attribute_group ad9910_attribute_group = {
356  .attrs = ad9910_attributes,
357 };
358 
359 static const struct iio_info ad9910_info = {
360  .attrs = &ad9910_attribute_group,
361  .driver_module = THIS_MODULE,
362 };
363 
364 static 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_device_alloc(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 
394 error_free_dev:
395  iio_device_free(idev);
396 error_ret:
397  return ret;
398 }
399 
400 static int __devexit ad9910_remove(struct spi_device *spi)
401 {
402  iio_device_unregister(spi_get_drvdata(spi));
403  iio_device_free(spi_get_drvdata(spi));
404 
405  return 0;
406 }
407 
408 static struct spi_driver ad9910_driver = {
409  .driver = {
410  .name = DRV_NAME,
411  .owner = THIS_MODULE,
412  },
413  .probe = ad9910_probe,
414  .remove = __devexit_p(ad9910_remove),
415 };
416 module_spi_driver(ad9910_driver);
417 
418 MODULE_AUTHOR("Cliff Cai");
419 MODULE_DESCRIPTION("Analog Devices ad9910 driver");
420 MODULE_LICENSE("GPL v2");
421 MODULE_ALIAS("spi:" DRV_NAME);