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>
21 #define DRV_NAME "ad9910"
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
45 #define RAM_ENABLE (1 << 7)
47 #define MANUAL_OSK (1 << 7)
48 #define INVSIC (1 << 6)
49 #define DDS_SINEOP (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)
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)
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)
76 #define TX_ENA (1 << 1)
77 #define PDCLK_INV (1 << 2)
78 #define PDCLK_ENB (1 << 3)
80 #define PARA_ENA (1 << 4)
81 #define SYNC_DIS (1 << 5)
82 #define DATA_ASS (1 << 6)
83 #define MATCH_ENA (1 << 7)
86 #define PFD_RST (1 << 2)
87 #define REFCLK_RST (1 << 6)
88 #define REFCLK_BYP (1 << 7)
90 /* Register format: 1 byte addr + value */
91 struct ad9910_config
{
111 struct ad9910_state
{
113 struct iio_dev
*idev
;
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
= idev
->dev_data
;
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
= {
357 .attrs
= ad9910_attributes
,
360 static int __devinit
ad9910_probe(struct spi_device
*spi
)
362 struct ad9910_state
*st
;
365 st
= kzalloc(sizeof(*st
), GFP_KERNEL
);
370 spi_set_drvdata(spi
, st
);
372 mutex_init(&st
->lock
);
375 st
->idev
= iio_allocate_device();
376 if (st
->idev
== NULL
) {
380 st
->idev
->dev
.parent
= &spi
->dev
;
381 st
->idev
->num_interrupt_lines
= 0;
382 st
->idev
->event_attrs
= NULL
;
384 st
->idev
->attrs
= &ad9910_attribute_group
;
385 st
->idev
->dev_data
= (void *)(st
);
386 st
->idev
->driver_module
= THIS_MODULE
;
387 st
->idev
->modes
= INDIO_DIRECT_MODE
;
389 ret
= iio_device_register(st
->idev
);
392 spi
->max_speed_hz
= 2000000;
393 spi
->mode
= SPI_MODE_3
;
394 spi
->bits_per_word
= 8;
400 iio_free_device(st
->idev
);
407 static int __devexit
ad9910_remove(struct spi_device
*spi
)
409 struct ad9910_state
*st
= spi_get_drvdata(spi
);
411 iio_device_unregister(st
->idev
);
417 static struct spi_driver ad9910_driver
= {
420 .owner
= THIS_MODULE
,
422 .probe
= ad9910_probe
,
423 .remove
= __devexit_p(ad9910_remove
),
426 static __init
int ad9910_spi_init(void)
428 return spi_register_driver(&ad9910_driver
);
430 module_init(ad9910_spi_init
);
432 static __exit
void ad9910_spi_exit(void)
434 spi_unregister_driver(&ad9910_driver
);
436 module_exit(ad9910_spi_exit
);
438 MODULE_AUTHOR("Cliff Cai");
439 MODULE_DESCRIPTION("Analog Devices ad9910 driver");
440 MODULE_LICENSE("GPL v2");