2 * Driver for ADI Direct Digital Synthesis ad9910
4 * Copyright (c) 2010 Analog Devices Inc.
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.
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>
22 #define DRV_NAME "ad9910"
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
46 #define RAM_ENABLE (1 << 7)
48 #define MANUAL_OSK (1 << 7)
49 #define INVSIC (1 << 6)
50 #define DDS_SINEOP (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)
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)
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)
77 #define TX_ENA (1 << 1)
78 #define PDCLK_INV (1 << 2)
79 #define PDCLK_ENB (1 << 3)
81 #define PARA_ENA (1 << 4)
82 #define SYNC_DIS (1 << 5)
83 #define DATA_ASS (1 << 6)
84 #define MATCH_ENA (1 << 7)
87 #define PFD_RST (1 << 2)
88 #define REFCLK_RST (1 << 6)
89 #define REFCLK_BYP (1 << 7)
91 /* Register format: 1 byte addr + value */
92 struct ad9910_config
{
112 struct ad9910_state
{
114 struct spi_device
*sdev
;
117 static ssize_t
ad9910_set_parameter(struct device
*dev
,
118 struct device_attribute
*attr
,
122 struct spi_message msg
;
123 struct spi_transfer xfer
;
125 struct ad9910_config
*config
= (struct ad9910_config
*)buf
;
126 struct iio_dev
*idev
= dev_get_drvdata(dev
);
127 struct ad9910_state
*st
= iio_priv(idev
);
130 xfer
.tx_buf
= &config
->auxdac
[0];
131 mutex_lock(&st
->lock
);
133 spi_message_init(&msg
);
134 spi_message_add_tail(&xfer
, &msg
);
135 ret
= spi_sync(st
->sdev
, &msg
);
140 xfer
.tx_buf
= &config
->ioupd
[0];
142 spi_message_init(&msg
);
143 spi_message_add_tail(&xfer
, &msg
);
144 ret
= spi_sync(st
->sdev
, &msg
);
149 xfer
.tx_buf
= &config
->ftw
[0];
151 spi_message_init(&msg
);
152 spi_message_add_tail(&xfer
, &msg
);
153 ret
= spi_sync(st
->sdev
, &msg
);
158 xfer
.tx_buf
= &config
->pow
[0];
160 spi_message_init(&msg
);
161 spi_message_add_tail(&xfer
, &msg
);
162 ret
= spi_sync(st
->sdev
, &msg
);
167 xfer
.tx_buf
= &config
->asf
[0];
169 spi_message_init(&msg
);
170 spi_message_add_tail(&xfer
, &msg
);
171 ret
= spi_sync(st
->sdev
, &msg
);
176 xfer
.tx_buf
= &config
->multc
[0];
178 spi_message_init(&msg
);
179 spi_message_add_tail(&xfer
, &msg
);
180 ret
= spi_sync(st
->sdev
, &msg
);
185 xfer
.tx_buf
= &config
->dig_rampl
[0];
187 spi_message_init(&msg
);
188 spi_message_add_tail(&xfer
, &msg
);
189 ret
= spi_sync(st
->sdev
, &msg
);
194 xfer
.tx_buf
= &config
->dig_ramps
[0];
196 spi_message_init(&msg
);
197 spi_message_add_tail(&xfer
, &msg
);
198 ret
= spi_sync(st
->sdev
, &msg
);
203 xfer
.tx_buf
= &config
->dig_rampr
[0];
205 spi_message_init(&msg
);
206 spi_message_add_tail(&xfer
, &msg
);
207 ret
= spi_sync(st
->sdev
, &msg
);
212 xfer
.tx_buf
= &config
->sin_tonep0
[0];
214 spi_message_init(&msg
);
215 spi_message_add_tail(&xfer
, &msg
);
216 ret
= spi_sync(st
->sdev
, &msg
);
221 xfer
.tx_buf
= &config
->sin_tonep1
[0];
223 spi_message_init(&msg
);
224 spi_message_add_tail(&xfer
, &msg
);
225 ret
= spi_sync(st
->sdev
, &msg
);
230 xfer
.tx_buf
= &config
->sin_tonep2
[0];
232 spi_message_init(&msg
);
233 spi_message_add_tail(&xfer
, &msg
);
234 ret
= spi_sync(st
->sdev
, &msg
);
238 xfer
.tx_buf
= &config
->sin_tonep3
[0];
240 spi_message_init(&msg
);
241 spi_message_add_tail(&xfer
, &msg
);
242 ret
= spi_sync(st
->sdev
, &msg
);
247 xfer
.tx_buf
= &config
->sin_tonep4
[0];
249 spi_message_init(&msg
);
250 spi_message_add_tail(&xfer
, &msg
);
251 ret
= spi_sync(st
->sdev
, &msg
);
256 xfer
.tx_buf
= &config
->sin_tonep5
[0];
258 spi_message_init(&msg
);
259 spi_message_add_tail(&xfer
, &msg
);
260 ret
= spi_sync(st
->sdev
, &msg
);
265 xfer
.tx_buf
= &config
->sin_tonep6
[0];
267 spi_message_init(&msg
);
268 spi_message_add_tail(&xfer
, &msg
);
269 ret
= spi_sync(st
->sdev
, &msg
);
274 xfer
.tx_buf
= &config
->sin_tonep7
[0];
276 spi_message_init(&msg
);
277 spi_message_add_tail(&xfer
, &msg
);
278 ret
= spi_sync(st
->sdev
, &msg
);
282 mutex_unlock(&st
->lock
);
284 return ret
? ret
: len
;
287 static IIO_DEVICE_ATTR(dds
, S_IWUSR
, NULL
, ad9910_set_parameter
, 0);
289 static void ad9910_init(struct ad9910_state
*st
)
291 struct spi_message msg
;
292 struct spi_transfer xfer
;
298 cfr
[2] = MANUAL_OSK
| INVSIC
| DDS_SINEOP
;
299 cfr
[3] = AUTO_OSK
| OSKEN
| ACLR_PHA
| ACLR_DIG
| LOAD_LRR
;
302 mutex_lock(&st
->lock
);
307 spi_message_init(&msg
);
308 spi_message_add_tail(&xfer
, &msg
);
309 ret
= spi_sync(st
->sdev
, &msg
);
315 cfr
[2] = READ_FTW
| DIGR_ENA
| ITER_IOUPD
;
316 cfr
[3] = TX_ENA
| PDCLK_INV
| PDCLK_ENB
;
322 spi_message_init(&msg
);
323 spi_message_add_tail(&xfer
, &msg
);
324 ret
= spi_sync(st
->sdev
, &msg
);
331 cfr
[3] = REFCLK_RST
| REFCLK_BYP
;
337 spi_message_init(&msg
);
338 spi_message_add_tail(&xfer
, &msg
);
339 ret
= spi_sync(st
->sdev
, &msg
);
344 mutex_unlock(&st
->lock
);
350 static struct attribute
*ad9910_attributes
[] = {
351 &iio_dev_attr_dds
.dev_attr
.attr
,
355 static const struct attribute_group ad9910_attribute_group
= {
356 .attrs
= ad9910_attributes
,
359 static const struct iio_info ad9910_info
= {
360 .attrs
= &ad9910_attribute_group
,
361 .driver_module
= THIS_MODULE
,
364 static int __devinit
ad9910_probe(struct spi_device
*spi
)
366 struct ad9910_state
*st
;
367 struct iio_dev
*idev
;
370 idev
= iio_allocate_device(sizeof(*st
));
375 spi_set_drvdata(spi
, idev
);
377 mutex_init(&st
->lock
);
380 idev
->dev
.parent
= &spi
->dev
;
381 idev
->info
= &ad9910_info
;
382 idev
->modes
= INDIO_DIRECT_MODE
;
384 ret
= iio_device_register(idev
);
387 spi
->max_speed_hz
= 2000000;
388 spi
->mode
= SPI_MODE_3
;
389 spi
->bits_per_word
= 8;
395 iio_free_device(idev
);
400 static int __devexit
ad9910_remove(struct spi_device
*spi
)
402 iio_device_unregister(spi_get_drvdata(spi
));
403 iio_free_device(spi_get_drvdata(spi
));
408 static struct spi_driver ad9910_driver
= {
411 .owner
= THIS_MODULE
,
413 .probe
= ad9910_probe
,
414 .remove
= __devexit_p(ad9910_remove
),
416 module_spi_driver(ad9910_driver
);
418 MODULE_AUTHOR("Cliff Cai");
419 MODULE_DESCRIPTION("Analog Devices ad9910 driver");
420 MODULE_LICENSE("GPL v2");
421 MODULE_ALIAS("spi:" DRV_NAME
);