]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/iio/frequency/ad9834.c
d02bb44fb8fc1bbec82882bf7a4910bc1b7f94c7
[karo-tx-linux.git] / drivers / staging / iio / frequency / ad9834.c
1 /*
2  * AD9833/AD9834/AD9837/AD9838 SPI DDS driver
3  *
4  * Copyright 2010-2011 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2.
7  */
8
9 #include <linux/interrupt.h>
10 #include <linux/workqueue.h>
11 #include <linux/device.h>
12 #include <linux/kernel.h>
13 #include <linux/slab.h>
14 #include <linux/sysfs.h>
15 #include <linux/list.h>
16 #include <linux/spi/spi.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/err.h>
19 #include <linux/module.h>
20 #include <asm/div64.h>
21
22 #include <linux/iio/iio.h>
23 #include <linux/iio/sysfs.h>
24 #include "dds.h"
25
26 #include "ad9834.h"
27
28 static unsigned int ad9834_calc_freqreg(unsigned long mclk, unsigned long fout)
29 {
30         unsigned long long freqreg = (u64)fout * (u64)BIT(AD9834_FREQ_BITS);
31
32         do_div(freqreg, mclk);
33         return freqreg;
34 }
35
36 static int ad9834_write_frequency(struct ad9834_state *st,
37                                   unsigned long addr, unsigned long fout)
38 {
39         unsigned long regval;
40
41         if (fout > (st->mclk / 2))
42                 return -EINVAL;
43
44         regval = ad9834_calc_freqreg(st->mclk, fout);
45
46         st->freq_data[0] = cpu_to_be16(addr | (regval &
47                                        RES_MASK(AD9834_FREQ_BITS / 2)));
48         st->freq_data[1] = cpu_to_be16(addr | ((regval >>
49                                        (AD9834_FREQ_BITS / 2)) &
50                                        RES_MASK(AD9834_FREQ_BITS / 2)));
51
52         return spi_sync(st->spi, &st->freq_msg);
53 }
54
55 static int ad9834_write_phase(struct ad9834_state *st,
56                               unsigned long addr, unsigned long phase)
57 {
58         if (phase > BIT(AD9834_PHASE_BITS))
59                 return -EINVAL;
60         st->data = cpu_to_be16(addr | phase);
61
62         return spi_sync(st->spi, &st->msg);
63 }
64
65 static ssize_t ad9834_write(struct device *dev,
66                             struct device_attribute *attr,
67                             const char *buf,
68                             size_t len)
69 {
70         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
71         struct ad9834_state *st = iio_priv(indio_dev);
72         struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
73         int ret;
74         unsigned long val;
75
76         ret = kstrtoul(buf, 10, &val);
77         if (ret)
78                 goto error_ret;
79
80         mutex_lock(&indio_dev->mlock);
81         switch ((u32)this_attr->address) {
82         case AD9834_REG_FREQ0:
83         case AD9834_REG_FREQ1:
84                 ret = ad9834_write_frequency(st, this_attr->address, val);
85                 break;
86         case AD9834_REG_PHASE0:
87         case AD9834_REG_PHASE1:
88                 ret = ad9834_write_phase(st, this_attr->address, val);
89                 break;
90         case AD9834_OPBITEN:
91                 if (st->control & AD9834_MODE) {
92                         ret = -EINVAL;  /* AD9843 reserved mode */
93                         break;
94                 }
95
96                 if (val)
97                         st->control |= AD9834_OPBITEN;
98                 else
99                         st->control &= ~AD9834_OPBITEN;
100
101                 st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
102                 ret = spi_sync(st->spi, &st->msg);
103                 break;
104         case AD9834_PIN_SW:
105                 if (val)
106                         st->control |= AD9834_PIN_SW;
107                 else
108                         st->control &= ~AD9834_PIN_SW;
109                 st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
110                 ret = spi_sync(st->spi, &st->msg);
111                 break;
112         case AD9834_FSEL:
113         case AD9834_PSEL:
114                 if (val == 0) {
115                         st->control &= ~(this_attr->address | AD9834_PIN_SW);
116                 } else if (val == 1) {
117                         st->control |= this_attr->address;
118                         st->control &= ~AD9834_PIN_SW;
119                 } else {
120                         ret = -EINVAL;
121                         break;
122                 }
123                 st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
124                 ret = spi_sync(st->spi, &st->msg);
125                 break;
126         case AD9834_RESET:
127                 if (val)
128                         st->control &= ~AD9834_RESET;
129                 else
130                         st->control |= AD9834_RESET;
131
132                 st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
133                 ret = spi_sync(st->spi, &st->msg);
134                 break;
135         default:
136                 ret = -ENODEV;
137         }
138         mutex_unlock(&indio_dev->mlock);
139
140 error_ret:
141         return ret ? ret : len;
142 }
143
144 static ssize_t ad9834_store_wavetype(struct device *dev,
145                                      struct device_attribute *attr,
146                                      const char *buf,
147                                      size_t len)
148 {
149         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
150         struct ad9834_state *st = iio_priv(indio_dev);
151         struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
152         int ret = 0;
153         bool is_ad9833_7 = (st->devid == ID_AD9833) || (st->devid == ID_AD9837);
154
155         mutex_lock(&indio_dev->mlock);
156
157         switch ((u32)this_attr->address) {
158         case 0:
159                 if (sysfs_streq(buf, "sine")) {
160                         st->control &= ~AD9834_MODE;
161                         if (is_ad9833_7)
162                                 st->control &= ~AD9834_OPBITEN;
163                 } else if (sysfs_streq(buf, "triangle")) {
164                         if (is_ad9833_7) {
165                                 st->control &= ~AD9834_OPBITEN;
166                                 st->control |= AD9834_MODE;
167                         } else if (st->control & AD9834_OPBITEN) {
168                                 ret = -EINVAL;  /* AD9843 reserved mode */
169                         } else {
170                                 st->control |= AD9834_MODE;
171                         }
172                 } else if (is_ad9833_7 && sysfs_streq(buf, "square")) {
173                         st->control &= ~AD9834_MODE;
174                         st->control |= AD9834_OPBITEN;
175                 } else {
176                         ret = -EINVAL;
177                 }
178
179                 break;
180         case 1:
181                 if (sysfs_streq(buf, "square") &&
182                     !(st->control & AD9834_MODE)) {
183                         st->control &= ~AD9834_MODE;
184                         st->control |= AD9834_OPBITEN;
185                 } else {
186                         ret = -EINVAL;
187                 }
188                 break;
189         default:
190                 ret = -EINVAL;
191                 break;
192         }
193
194         if (!ret) {
195                 st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
196                 ret = spi_sync(st->spi, &st->msg);
197         }
198         mutex_unlock(&indio_dev->mlock);
199
200         return ret ? ret : len;
201 }
202
203 static
204 ssize_t ad9834_show_out0_wavetype_available(struct device *dev,
205                                             struct device_attribute *attr,
206                                             char *buf)
207 {
208         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
209         struct ad9834_state *st = iio_priv(indio_dev);
210         char *str;
211
212         if ((st->devid == ID_AD9833) || (st->devid == ID_AD9837))
213                 str = "sine triangle square";
214         else if (st->control & AD9834_OPBITEN)
215                 str = "sine";
216         else
217                 str = "sine triangle";
218
219         return sprintf(buf, "%s\n", str);
220 }
221
222 static IIO_DEVICE_ATTR(out_altvoltage0_out0_wavetype_available, S_IRUGO,
223                        ad9834_show_out0_wavetype_available, NULL, 0);
224
225 static
226 ssize_t ad9834_show_out1_wavetype_available(struct device *dev,
227                                             struct device_attribute *attr,
228                                             char *buf)
229 {
230         struct iio_dev *indio_dev = dev_to_iio_dev(dev);
231         struct ad9834_state *st = iio_priv(indio_dev);
232         char *str;
233
234         if (st->control & AD9834_MODE)
235                 str = "";
236         else
237                 str = "square";
238
239         return sprintf(buf, "%s\n", str);
240 }
241
242 static IIO_DEVICE_ATTR(out_altvoltage0_out1_wavetype_available, S_IRUGO,
243                        ad9834_show_out1_wavetype_available, NULL, 0);
244
245 /**
246  * see dds.h for further information
247  */
248
249 static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ0);
250 static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ1);
251 static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_FSEL);
252 static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */
253
254 static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE0);
255 static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE1);
256 static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_PSEL);
257 static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/
258
259 static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL,
260         ad9834_write, AD9834_PIN_SW);
261 static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, ad9834_write, AD9834_RESET);
262 static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, S_IWUSR, NULL,
263         ad9834_write, AD9834_OPBITEN);
264 static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0);
265 static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1);
266
267 static struct attribute *ad9834_attributes[] = {
268         &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr,
269         &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr,
270         &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr,
271         &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr,
272         &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr,
273         &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr,
274         &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr,
275         &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr,
276         &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr,
277         &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr,
278         &iio_dev_attr_out_altvoltage0_out1_enable.dev_attr.attr,
279         &iio_dev_attr_out_altvoltage0_out0_wavetype.dev_attr.attr,
280         &iio_dev_attr_out_altvoltage0_out1_wavetype.dev_attr.attr,
281         &iio_dev_attr_out_altvoltage0_out0_wavetype_available.dev_attr.attr,
282         &iio_dev_attr_out_altvoltage0_out1_wavetype_available.dev_attr.attr,
283         NULL,
284 };
285
286 static struct attribute *ad9833_attributes[] = {
287         &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr,
288         &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr,
289         &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr,
290         &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr,
291         &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr,
292         &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr,
293         &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr,
294         &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr,
295         &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr,
296         &iio_dev_attr_out_altvoltage0_out0_wavetype.dev_attr.attr,
297         &iio_dev_attr_out_altvoltage0_out0_wavetype_available.dev_attr.attr,
298         NULL,
299 };
300
301 static const struct attribute_group ad9834_attribute_group = {
302         .attrs = ad9834_attributes,
303 };
304
305 static const struct attribute_group ad9833_attribute_group = {
306         .attrs = ad9833_attributes,
307 };
308
309 static const struct iio_info ad9834_info = {
310         .attrs = &ad9834_attribute_group,
311         .driver_module = THIS_MODULE,
312 };
313
314 static const struct iio_info ad9833_info = {
315         .attrs = &ad9833_attribute_group,
316         .driver_module = THIS_MODULE,
317 };
318
319 static int ad9834_probe(struct spi_device *spi)
320 {
321         struct ad9834_platform_data *pdata = spi->dev.platform_data;
322         struct ad9834_state *st;
323         struct iio_dev *indio_dev;
324         struct regulator *reg;
325         int ret;
326
327         if (!pdata) {
328                 dev_dbg(&spi->dev, "no platform data?\n");
329                 return -ENODEV;
330         }
331
332         reg = devm_regulator_get(&spi->dev, "vcc");
333         if (!IS_ERR(reg)) {
334                 ret = regulator_enable(reg);
335                 if (ret)
336                         return ret;
337         }
338
339         indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
340         if (!indio_dev) {
341                 ret = -ENOMEM;
342                 goto error_disable_reg;
343         }
344         spi_set_drvdata(spi, indio_dev);
345         st = iio_priv(indio_dev);
346         st->mclk = pdata->mclk;
347         st->spi = spi;
348         st->devid = spi_get_device_id(spi)->driver_data;
349         st->reg = reg;
350         indio_dev->dev.parent = &spi->dev;
351         indio_dev->name = spi_get_device_id(spi)->name;
352         switch (st->devid) {
353         case ID_AD9833:
354         case ID_AD9837:
355                 indio_dev->info = &ad9833_info;
356                 break;
357         default:
358                 indio_dev->info = &ad9834_info;
359                 break;
360         }
361         indio_dev->modes = INDIO_DIRECT_MODE;
362
363         /* Setup default messages */
364
365         st->xfer.tx_buf = &st->data;
366         st->xfer.len = 2;
367
368         spi_message_init(&st->msg);
369         spi_message_add_tail(&st->xfer, &st->msg);
370
371         st->freq_xfer[0].tx_buf = &st->freq_data[0];
372         st->freq_xfer[0].len = 2;
373         st->freq_xfer[0].cs_change = 1;
374         st->freq_xfer[1].tx_buf = &st->freq_data[1];
375         st->freq_xfer[1].len = 2;
376
377         spi_message_init(&st->freq_msg);
378         spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg);
379         spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg);
380
381         st->control = AD9834_B28 | AD9834_RESET;
382
383         if (!pdata->en_div2)
384                 st->control |= AD9834_DIV2;
385
386         if (!pdata->en_signbit_msb_out && (st->devid == ID_AD9834))
387                 st->control |= AD9834_SIGN_PIB;
388
389         st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
390         ret = spi_sync(st->spi, &st->msg);
391         if (ret) {
392                 dev_err(&spi->dev, "device init failed\n");
393                 goto error_disable_reg;
394         }
395
396         ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0);
397         if (ret)
398                 goto error_disable_reg;
399
400         ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1);
401         if (ret)
402                 goto error_disable_reg;
403
404         ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0);
405         if (ret)
406                 goto error_disable_reg;
407
408         ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1);
409         if (ret)
410                 goto error_disable_reg;
411
412         ret = iio_device_register(indio_dev);
413         if (ret)
414                 goto error_disable_reg;
415
416         return 0;
417
418 error_disable_reg:
419         if (!IS_ERR(reg))
420                 regulator_disable(reg);
421
422         return ret;
423 }
424
425 static int ad9834_remove(struct spi_device *spi)
426 {
427         struct iio_dev *indio_dev = spi_get_drvdata(spi);
428         struct ad9834_state *st = iio_priv(indio_dev);
429
430         iio_device_unregister(indio_dev);
431         if (!IS_ERR(st->reg))
432                 regulator_disable(st->reg);
433
434         return 0;
435 }
436
437 static const struct spi_device_id ad9834_id[] = {
438         {"ad9833", ID_AD9833},
439         {"ad9834", ID_AD9834},
440         {"ad9837", ID_AD9837},
441         {"ad9838", ID_AD9838},
442         {}
443 };
444 MODULE_DEVICE_TABLE(spi, ad9834_id);
445
446 static struct spi_driver ad9834_driver = {
447         .driver = {
448                 .name   = "ad9834",
449                 .owner  = THIS_MODULE,
450         },
451         .probe          = ad9834_probe,
452         .remove         = ad9834_remove,
453         .id_table       = ad9834_id,
454 };
455 module_spi_driver(ad9834_driver);
456
457 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
458 MODULE_DESCRIPTION("Analog Devices AD9833/AD9834/AD9837/AD9838 DDS");
459 MODULE_LICENSE("GPL v2");