1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * AD9833/AD9834/AD9837/AD9838 SPI DDS driver |
4 | * |
5 | * Copyright 2010-2011 Analog Devices Inc. |
6 | */ |
7 | |
8 | #include <linux/clk.h> |
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 | /* Registers */ |
29 | |
30 | #define AD9834_REG_CMD 0 |
31 | #define AD9834_REG_FREQ0 BIT(14) |
32 | #define AD9834_REG_FREQ1 BIT(15) |
33 | #define AD9834_REG_PHASE0 (BIT(15) | BIT(14)) |
34 | #define AD9834_REG_PHASE1 (BIT(15) | BIT(14) | BIT(13)) |
35 | |
36 | /* Command Control Bits */ |
37 | |
38 | #define AD9834_B28 BIT(13) |
39 | #define AD9834_HLB BIT(12) |
40 | #define AD9834_FSEL BIT(11) |
41 | #define AD9834_PSEL BIT(10) |
42 | #define AD9834_PIN_SW BIT(9) |
43 | #define AD9834_RESET BIT(8) |
44 | #define AD9834_SLEEP1 BIT(7) |
45 | #define AD9834_SLEEP12 BIT(6) |
46 | #define AD9834_OPBITEN BIT(5) |
47 | #define AD9834_SIGN_PIB BIT(4) |
48 | #define AD9834_DIV2 BIT(3) |
49 | #define AD9834_MODE BIT(1) |
50 | |
51 | #define AD9834_FREQ_BITS 28 |
52 | #define AD9834_PHASE_BITS 12 |
53 | |
54 | #define RES_MASK(bits) (BIT(bits) - 1) |
55 | |
56 | /** |
57 | * struct ad9834_state - driver instance specific data |
58 | * @spi: spi_device |
59 | * @mclk: external master clock |
60 | * @control: cached control word |
61 | * @devid: device id |
62 | * @xfer: default spi transfer |
63 | * @msg: default spi message |
64 | * @freq_xfer: tuning word spi transfer |
65 | * @freq_msg: tuning word spi message |
66 | * @lock: protect sensor state |
67 | * @data: spi transmit buffer |
68 | * @freq_data: tuning word spi transmit buffer |
69 | */ |
70 | |
71 | struct ad9834_state { |
72 | struct spi_device *spi; |
73 | struct clk *mclk; |
74 | unsigned short control; |
75 | unsigned short devid; |
76 | struct spi_transfer xfer; |
77 | struct spi_message msg; |
78 | struct spi_transfer freq_xfer[2]; |
79 | struct spi_message freq_msg; |
80 | struct mutex lock; /* protect sensor state */ |
81 | |
82 | /* |
83 | * DMA (thus cache coherency maintenance) requires the |
84 | * transfer buffers to live in their own cache lines. |
85 | */ |
86 | __be16 data __aligned(IIO_DMA_MINALIGN); |
87 | __be16 freq_data[2]; |
88 | }; |
89 | |
90 | /* |
91 | * ad9834_supported_device_ids: |
92 | */ |
93 | |
94 | enum ad9834_supported_device_ids { |
95 | ID_AD9833, |
96 | ID_AD9834, |
97 | ID_AD9837, |
98 | ID_AD9838, |
99 | }; |
100 | |
101 | static unsigned int ad9834_calc_freqreg(unsigned long mclk, unsigned long fout) |
102 | { |
103 | unsigned long long freqreg = (u64)fout * (u64)BIT(AD9834_FREQ_BITS); |
104 | |
105 | do_div(freqreg, mclk); |
106 | return freqreg; |
107 | } |
108 | |
109 | static int ad9834_write_frequency(struct ad9834_state *st, |
110 | unsigned long addr, unsigned long fout) |
111 | { |
112 | unsigned long clk_freq; |
113 | unsigned long regval; |
114 | |
115 | clk_freq = clk_get_rate(clk: st->mclk); |
116 | |
117 | if (fout > (clk_freq / 2)) |
118 | return -EINVAL; |
119 | |
120 | regval = ad9834_calc_freqreg(mclk: clk_freq, fout); |
121 | |
122 | st->freq_data[0] = cpu_to_be16(addr | (regval & |
123 | RES_MASK(AD9834_FREQ_BITS / 2))); |
124 | st->freq_data[1] = cpu_to_be16(addr | ((regval >> |
125 | (AD9834_FREQ_BITS / 2)) & |
126 | RES_MASK(AD9834_FREQ_BITS / 2))); |
127 | |
128 | return spi_sync(spi: st->spi, message: &st->freq_msg); |
129 | } |
130 | |
131 | static int ad9834_write_phase(struct ad9834_state *st, |
132 | unsigned long addr, unsigned long phase) |
133 | { |
134 | if (phase > BIT(AD9834_PHASE_BITS)) |
135 | return -EINVAL; |
136 | st->data = cpu_to_be16(addr | phase); |
137 | |
138 | return spi_sync(spi: st->spi, message: &st->msg); |
139 | } |
140 | |
141 | static ssize_t ad9834_write(struct device *dev, |
142 | struct device_attribute *attr, |
143 | const char *buf, |
144 | size_t len) |
145 | { |
146 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
147 | struct ad9834_state *st = iio_priv(indio_dev); |
148 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
149 | int ret; |
150 | unsigned long val; |
151 | |
152 | ret = kstrtoul(s: buf, base: 10, res: &val); |
153 | if (ret) |
154 | return ret; |
155 | |
156 | mutex_lock(&st->lock); |
157 | switch ((u32)this_attr->address) { |
158 | case AD9834_REG_FREQ0: |
159 | case AD9834_REG_FREQ1: |
160 | ret = ad9834_write_frequency(st, addr: this_attr->address, fout: val); |
161 | break; |
162 | case AD9834_REG_PHASE0: |
163 | case AD9834_REG_PHASE1: |
164 | ret = ad9834_write_phase(st, addr: this_attr->address, phase: val); |
165 | break; |
166 | case AD9834_OPBITEN: |
167 | if (st->control & AD9834_MODE) { |
168 | ret = -EINVAL; /* AD9843 reserved mode */ |
169 | break; |
170 | } |
171 | |
172 | if (val) |
173 | st->control |= AD9834_OPBITEN; |
174 | else |
175 | st->control &= ~AD9834_OPBITEN; |
176 | |
177 | st->data = cpu_to_be16(AD9834_REG_CMD | st->control); |
178 | ret = spi_sync(spi: st->spi, message: &st->msg); |
179 | break; |
180 | case AD9834_PIN_SW: |
181 | if (val) |
182 | st->control |= AD9834_PIN_SW; |
183 | else |
184 | st->control &= ~AD9834_PIN_SW; |
185 | st->data = cpu_to_be16(AD9834_REG_CMD | st->control); |
186 | ret = spi_sync(spi: st->spi, message: &st->msg); |
187 | break; |
188 | case AD9834_FSEL: |
189 | case AD9834_PSEL: |
190 | if (!val) { |
191 | st->control &= ~(this_attr->address | AD9834_PIN_SW); |
192 | } else if (val == 1) { |
193 | st->control |= this_attr->address; |
194 | st->control &= ~AD9834_PIN_SW; |
195 | } else { |
196 | ret = -EINVAL; |
197 | break; |
198 | } |
199 | st->data = cpu_to_be16(AD9834_REG_CMD | st->control); |
200 | ret = spi_sync(spi: st->spi, message: &st->msg); |
201 | break; |
202 | case AD9834_RESET: |
203 | if (val) |
204 | st->control &= ~AD9834_RESET; |
205 | else |
206 | st->control |= AD9834_RESET; |
207 | |
208 | st->data = cpu_to_be16(AD9834_REG_CMD | st->control); |
209 | ret = spi_sync(spi: st->spi, message: &st->msg); |
210 | break; |
211 | default: |
212 | ret = -ENODEV; |
213 | } |
214 | mutex_unlock(lock: &st->lock); |
215 | |
216 | return ret ? ret : len; |
217 | } |
218 | |
219 | static ssize_t ad9834_store_wavetype(struct device *dev, |
220 | struct device_attribute *attr, |
221 | const char *buf, |
222 | size_t len) |
223 | { |
224 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
225 | struct ad9834_state *st = iio_priv(indio_dev); |
226 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
227 | int ret = 0; |
228 | bool is_ad9833_7 = (st->devid == ID_AD9833) || (st->devid == ID_AD9837); |
229 | |
230 | mutex_lock(&st->lock); |
231 | |
232 | switch ((u32)this_attr->address) { |
233 | case 0: |
234 | if (sysfs_streq(s1: buf, s2: "sine" )) { |
235 | st->control &= ~AD9834_MODE; |
236 | if (is_ad9833_7) |
237 | st->control &= ~AD9834_OPBITEN; |
238 | } else if (sysfs_streq(s1: buf, s2: "triangle" )) { |
239 | if (is_ad9833_7) { |
240 | st->control &= ~AD9834_OPBITEN; |
241 | st->control |= AD9834_MODE; |
242 | } else if (st->control & AD9834_OPBITEN) { |
243 | ret = -EINVAL; /* AD9843 reserved mode */ |
244 | } else { |
245 | st->control |= AD9834_MODE; |
246 | } |
247 | } else if (is_ad9833_7 && sysfs_streq(s1: buf, s2: "square" )) { |
248 | st->control &= ~AD9834_MODE; |
249 | st->control |= AD9834_OPBITEN; |
250 | } else { |
251 | ret = -EINVAL; |
252 | } |
253 | |
254 | break; |
255 | case 1: |
256 | if (sysfs_streq(s1: buf, s2: "square" ) && |
257 | !(st->control & AD9834_MODE)) { |
258 | st->control &= ~AD9834_MODE; |
259 | st->control |= AD9834_OPBITEN; |
260 | } else { |
261 | ret = -EINVAL; |
262 | } |
263 | break; |
264 | default: |
265 | ret = -EINVAL; |
266 | break; |
267 | } |
268 | |
269 | if (!ret) { |
270 | st->data = cpu_to_be16(AD9834_REG_CMD | st->control); |
271 | ret = spi_sync(spi: st->spi, message: &st->msg); |
272 | } |
273 | mutex_unlock(lock: &st->lock); |
274 | |
275 | return ret ? ret : len; |
276 | } |
277 | |
278 | static |
279 | ssize_t ad9834_show_out0_wavetype_available(struct device *dev, |
280 | struct device_attribute *attr, |
281 | char *buf) |
282 | { |
283 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
284 | struct ad9834_state *st = iio_priv(indio_dev); |
285 | char *str; |
286 | |
287 | if (st->devid == ID_AD9833 || st->devid == ID_AD9837) |
288 | str = "sine triangle square" ; |
289 | else if (st->control & AD9834_OPBITEN) |
290 | str = "sine" ; |
291 | else |
292 | str = "sine triangle" ; |
293 | |
294 | return sprintf(buf, fmt: "%s\n" , str); |
295 | } |
296 | |
297 | static IIO_DEVICE_ATTR(out_altvoltage0_out0_wavetype_available, 0444, |
298 | ad9834_show_out0_wavetype_available, NULL, 0); |
299 | |
300 | static |
301 | ssize_t ad9834_show_out1_wavetype_available(struct device *dev, |
302 | struct device_attribute *attr, |
303 | char *buf) |
304 | { |
305 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
306 | struct ad9834_state *st = iio_priv(indio_dev); |
307 | char *str; |
308 | |
309 | if (st->control & AD9834_MODE) |
310 | str = "" ; |
311 | else |
312 | str = "square" ; |
313 | |
314 | return sprintf(buf, fmt: "%s\n" , str); |
315 | } |
316 | |
317 | static IIO_DEVICE_ATTR(out_altvoltage0_out1_wavetype_available, 0444, |
318 | ad9834_show_out1_wavetype_available, NULL, 0); |
319 | |
320 | /* |
321 | * see dds.h for further information |
322 | */ |
323 | |
324 | static IIO_DEV_ATTR_FREQ(0, 0, 0200, NULL, ad9834_write, AD9834_REG_FREQ0); |
325 | static IIO_DEV_ATTR_FREQ(0, 1, 0200, NULL, ad9834_write, AD9834_REG_FREQ1); |
326 | static IIO_DEV_ATTR_FREQSYMBOL(0, 0200, NULL, ad9834_write, AD9834_FSEL); |
327 | static IIO_CONST_ATTR_FREQ_SCALE(0, "1" ); /* 1Hz */ |
328 | |
329 | static IIO_DEV_ATTR_PHASE(0, 0, 0200, NULL, ad9834_write, AD9834_REG_PHASE0); |
330 | static IIO_DEV_ATTR_PHASE(0, 1, 0200, NULL, ad9834_write, AD9834_REG_PHASE1); |
331 | static IIO_DEV_ATTR_PHASESYMBOL(0, 0200, NULL, ad9834_write, AD9834_PSEL); |
332 | static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808" ); /* 2PI/2^12 rad*/ |
333 | |
334 | static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL, ad9834_write, AD9834_PIN_SW); |
335 | static IIO_DEV_ATTR_OUT_ENABLE(0, 0200, NULL, ad9834_write, AD9834_RESET); |
336 | static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, 0200, NULL, ad9834_write, AD9834_OPBITEN); |
337 | static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0); |
338 | static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1); |
339 | |
340 | static struct attribute *ad9834_attributes[] = { |
341 | &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, |
342 | &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr, |
343 | &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr, |
344 | &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr, |
345 | &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr, |
346 | &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr, |
347 | &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr, |
348 | &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, |
349 | &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, |
350 | &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, |
351 | &iio_dev_attr_out_altvoltage0_out1_enable.dev_attr.attr, |
352 | &iio_dev_attr_out_altvoltage0_out0_wavetype.dev_attr.attr, |
353 | &iio_dev_attr_out_altvoltage0_out1_wavetype.dev_attr.attr, |
354 | &iio_dev_attr_out_altvoltage0_out0_wavetype_available.dev_attr.attr, |
355 | &iio_dev_attr_out_altvoltage0_out1_wavetype_available.dev_attr.attr, |
356 | NULL, |
357 | }; |
358 | |
359 | static struct attribute *ad9833_attributes[] = { |
360 | &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, |
361 | &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr, |
362 | &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr, |
363 | &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr, |
364 | &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr, |
365 | &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr, |
366 | &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, |
367 | &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, |
368 | &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, |
369 | &iio_dev_attr_out_altvoltage0_out0_wavetype.dev_attr.attr, |
370 | &iio_dev_attr_out_altvoltage0_out0_wavetype_available.dev_attr.attr, |
371 | NULL, |
372 | }; |
373 | |
374 | static const struct attribute_group ad9834_attribute_group = { |
375 | .attrs = ad9834_attributes, |
376 | }; |
377 | |
378 | static const struct attribute_group ad9833_attribute_group = { |
379 | .attrs = ad9833_attributes, |
380 | }; |
381 | |
382 | static const struct iio_info ad9834_info = { |
383 | .attrs = &ad9834_attribute_group, |
384 | }; |
385 | |
386 | static const struct iio_info ad9833_info = { |
387 | .attrs = &ad9833_attribute_group, |
388 | }; |
389 | |
390 | static void ad9834_disable_reg(void *data) |
391 | { |
392 | struct regulator *reg = data; |
393 | |
394 | regulator_disable(regulator: reg); |
395 | } |
396 | |
397 | static int ad9834_probe(struct spi_device *spi) |
398 | { |
399 | struct ad9834_state *st; |
400 | struct iio_dev *indio_dev; |
401 | struct regulator *reg; |
402 | int ret; |
403 | |
404 | reg = devm_regulator_get(dev: &spi->dev, id: "avdd" ); |
405 | if (IS_ERR(ptr: reg)) |
406 | return PTR_ERR(ptr: reg); |
407 | |
408 | ret = regulator_enable(regulator: reg); |
409 | if (ret) { |
410 | dev_err(&spi->dev, "Failed to enable specified AVDD supply\n" ); |
411 | return ret; |
412 | } |
413 | |
414 | ret = devm_add_action_or_reset(&spi->dev, ad9834_disable_reg, reg); |
415 | if (ret) |
416 | return ret; |
417 | |
418 | indio_dev = devm_iio_device_alloc(parent: &spi->dev, sizeof_priv: sizeof(*st)); |
419 | if (!indio_dev) { |
420 | ret = -ENOMEM; |
421 | return ret; |
422 | } |
423 | st = iio_priv(indio_dev); |
424 | mutex_init(&st->lock); |
425 | st->mclk = devm_clk_get_enabled(dev: &spi->dev, NULL); |
426 | if (IS_ERR(ptr: st->mclk)) { |
427 | dev_err(&spi->dev, "Failed to enable master clock\n" ); |
428 | return PTR_ERR(ptr: st->mclk); |
429 | } |
430 | |
431 | st->spi = spi; |
432 | st->devid = spi_get_device_id(sdev: spi)->driver_data; |
433 | indio_dev->name = spi_get_device_id(sdev: spi)->name; |
434 | switch (st->devid) { |
435 | case ID_AD9833: |
436 | case ID_AD9837: |
437 | indio_dev->info = &ad9833_info; |
438 | break; |
439 | default: |
440 | indio_dev->info = &ad9834_info; |
441 | break; |
442 | } |
443 | indio_dev->modes = INDIO_DIRECT_MODE; |
444 | |
445 | /* Setup default messages */ |
446 | |
447 | st->xfer.tx_buf = &st->data; |
448 | st->xfer.len = 2; |
449 | |
450 | spi_message_init(m: &st->msg); |
451 | spi_message_add_tail(t: &st->xfer, m: &st->msg); |
452 | |
453 | st->freq_xfer[0].tx_buf = &st->freq_data[0]; |
454 | st->freq_xfer[0].len = 2; |
455 | st->freq_xfer[0].cs_change = 1; |
456 | st->freq_xfer[1].tx_buf = &st->freq_data[1]; |
457 | st->freq_xfer[1].len = 2; |
458 | |
459 | spi_message_init(m: &st->freq_msg); |
460 | spi_message_add_tail(t: &st->freq_xfer[0], m: &st->freq_msg); |
461 | spi_message_add_tail(t: &st->freq_xfer[1], m: &st->freq_msg); |
462 | |
463 | st->control = AD9834_B28 | AD9834_RESET; |
464 | st->control |= AD9834_DIV2; |
465 | |
466 | if (st->devid == ID_AD9834) |
467 | st->control |= AD9834_SIGN_PIB; |
468 | |
469 | st->data = cpu_to_be16(AD9834_REG_CMD | st->control); |
470 | ret = spi_sync(spi: st->spi, message: &st->msg); |
471 | if (ret) { |
472 | dev_err(&spi->dev, "device init failed\n" ); |
473 | return ret; |
474 | } |
475 | |
476 | ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, fout: 1000000); |
477 | if (ret) |
478 | return ret; |
479 | |
480 | ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, fout: 5000000); |
481 | if (ret) |
482 | return ret; |
483 | |
484 | ret = ad9834_write_phase(st, AD9834_REG_PHASE0, phase: 512); |
485 | if (ret) |
486 | return ret; |
487 | |
488 | ret = ad9834_write_phase(st, AD9834_REG_PHASE1, phase: 1024); |
489 | if (ret) |
490 | return ret; |
491 | |
492 | return devm_iio_device_register(&spi->dev, indio_dev); |
493 | } |
494 | |
495 | static const struct spi_device_id ad9834_id[] = { |
496 | {"ad9833" , ID_AD9833}, |
497 | {"ad9834" , ID_AD9834}, |
498 | {"ad9837" , ID_AD9837}, |
499 | {"ad9838" , ID_AD9838}, |
500 | {} |
501 | }; |
502 | MODULE_DEVICE_TABLE(spi, ad9834_id); |
503 | |
504 | static const struct of_device_id ad9834_of_match[] = { |
505 | {.compatible = "adi,ad9833" }, |
506 | {.compatible = "adi,ad9834" }, |
507 | {.compatible = "adi,ad9837" }, |
508 | {.compatible = "adi,ad9838" }, |
509 | {} |
510 | }; |
511 | |
512 | MODULE_DEVICE_TABLE(of, ad9834_of_match); |
513 | |
514 | static struct spi_driver ad9834_driver = { |
515 | .driver = { |
516 | .name = "ad9834" , |
517 | .of_match_table = ad9834_of_match |
518 | }, |
519 | .probe = ad9834_probe, |
520 | .id_table = ad9834_id, |
521 | }; |
522 | module_spi_driver(ad9834_driver); |
523 | |
524 | MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>" ); |
525 | MODULE_DESCRIPTION("Analog Devices AD9833/AD9834/AD9837/AD9838 DDS" ); |
526 | MODULE_LICENSE("GPL v2" ); |
527 | |