Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ad9951.c
Go to the documentation of this file.
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 #include <linux/module.h>
18 
19 #include <linux/iio/iio.h>
20 #include <linux/iio/sysfs.h>
21 
22 #define DRV_NAME "ad9951"
23 
24 #define CFR1 0x0
25 #define CFR2 0x1
26 
27 #define AUTO_OSK (1)
28 #define OSKEN (1 << 1)
29 #define LOAD_ARR (1 << 2)
30 
31 #define AUTO_SYNC (1 << 7)
32 
33 #define LSB_FST (1)
34 #define SDIO_IPT (1 << 1)
35 #define CLR_PHA (1 << 2)
36 #define SINE_OPT (1 << 4)
37 #define ACLR_PHA (1 << 5)
38 
39 #define VCO_RANGE (1 << 2)
40 
41 #define CRS_OPT (1 << 1)
42 #define HMANU_SYNC (1 << 2)
43 #define HSPD_SYNC (1 << 3)
44 
45 /* Register format: 1 byte addr + value */
46 struct ad9951_config {
47  u8 asf[3];
48  u8 arr[2];
49  u8 ftw0[5];
50  u8 ftw1[3];
51 };
52 
53 struct ad9951_state {
54  struct mutex lock;
55  struct spi_device *sdev;
56 };
57 
58 static ssize_t ad9951_set_parameter(struct device *dev,
59  struct device_attribute *attr,
60  const char *buf,
61  size_t len)
62 {
63  struct spi_message msg;
64  struct spi_transfer xfer;
65  int ret;
66  struct ad9951_config *config = (struct ad9951_config *)buf;
67  struct iio_dev *idev = dev_to_iio_dev(dev);
68  struct ad9951_state *st = iio_priv(idev);
69 
70  xfer.len = 3;
71  xfer.tx_buf = &config->asf[0];
72  mutex_lock(&st->lock);
73 
74  spi_message_init(&msg);
75  spi_message_add_tail(&xfer, &msg);
76  ret = spi_sync(st->sdev, &msg);
77  if (ret)
78  goto error_ret;
79 
80  xfer.len = 2;
81  xfer.tx_buf = &config->arr[0];
82 
83  spi_message_init(&msg);
84  spi_message_add_tail(&xfer, &msg);
85  ret = spi_sync(st->sdev, &msg);
86  if (ret)
87  goto error_ret;
88 
89  xfer.len = 5;
90  xfer.tx_buf = &config->ftw0[0];
91 
92  spi_message_init(&msg);
93  spi_message_add_tail(&xfer, &msg);
94  ret = spi_sync(st->sdev, &msg);
95  if (ret)
96  goto error_ret;
97 
98  xfer.len = 3;
99  xfer.tx_buf = &config->ftw1[0];
100 
101  spi_message_init(&msg);
102  spi_message_add_tail(&xfer, &msg);
103  ret = spi_sync(st->sdev, &msg);
104  if (ret)
105  goto error_ret;
106 error_ret:
107  mutex_unlock(&st->lock);
108 
109  return ret ? ret : len;
110 }
111 
112 static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0);
113 
114 static void ad9951_init(struct ad9951_state *st)
115 {
116  struct spi_message msg;
117  struct spi_transfer xfer;
118  int ret;
119  u8 cfr[5];
120 
121  cfr[0] = CFR1;
122  cfr[1] = 0;
123  cfr[2] = LSB_FST | CLR_PHA | SINE_OPT | ACLR_PHA;
124  cfr[3] = AUTO_OSK | OSKEN | LOAD_ARR;
125  cfr[4] = 0;
126 
127  mutex_lock(&st->lock);
128 
129  xfer.len = 5;
130  xfer.tx_buf = &cfr;
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  cfr[0] = CFR2;
139  cfr[1] = VCO_RANGE;
140  cfr[2] = HSPD_SYNC;
141  cfr[3] = 0;
142 
143  xfer.len = 4;
144  xfer.tx_buf = &cfr;
145 
146  spi_message_init(&msg);
147  spi_message_add_tail(&xfer, &msg);
148  ret = spi_sync(st->sdev, &msg);
149  if (ret)
150  goto error_ret;
151 
152 error_ret:
153  mutex_unlock(&st->lock);
154 
155 
156 
157 }
158 
159 static struct attribute *ad9951_attributes[] = {
160  &iio_dev_attr_dds.dev_attr.attr,
161  NULL,
162 };
163 
164 static const struct attribute_group ad9951_attribute_group = {
165  .attrs = ad9951_attributes,
166 };
167 
168 static const struct iio_info ad9951_info = {
169  .attrs = &ad9951_attribute_group,
170  .driver_module = THIS_MODULE,
171 };
172 
173 static 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_device_alloc(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 
204 error_free_dev:
205  iio_device_free(idev);
206 
207 error_ret:
208  return ret;
209 }
210 
211 static int __devexit ad9951_remove(struct spi_device *spi)
212 {
213  iio_device_unregister(spi_get_drvdata(spi));
214  iio_device_free(spi_get_drvdata(spi));
215 
216  return 0;
217 }
218 
219 static struct spi_driver ad9951_driver = {
220  .driver = {
221  .name = DRV_NAME,
222  .owner = THIS_MODULE,
223  },
224  .probe = ad9951_probe,
225  .remove = __devexit_p(ad9951_remove),
226 };
227 module_spi_driver(ad9951_driver);
228 
229 MODULE_AUTHOR("Cliff Cai");
230 MODULE_DESCRIPTION("Analog Devices ad9951 driver");
231 MODULE_LICENSE("GPL v2");
232 MODULE_ALIAS("spi:" DRV_NAME);