1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * AD9832 SPI DDS driver |
4 | * |
5 | * Copyright 2011 Analog Devices Inc. |
6 | */ |
7 | |
8 | #include <asm/div64.h> |
9 | |
10 | #include <linux/clk.h> |
11 | #include <linux/device.h> |
12 | #include <linux/err.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/module.h> |
15 | #include <linux/regulator/consumer.h> |
16 | #include <linux/slab.h> |
17 | #include <linux/spi/spi.h> |
18 | #include <linux/sysfs.h> |
19 | |
20 | #include <linux/iio/iio.h> |
21 | #include <linux/iio/sysfs.h> |
22 | |
23 | #include "ad9832.h" |
24 | |
25 | #include "dds.h" |
26 | |
27 | /* Registers */ |
28 | |
29 | #define AD9832_FREQ0LL 0x0 |
30 | #define AD9832_FREQ0HL 0x1 |
31 | #define AD9832_FREQ0LM 0x2 |
32 | #define AD9832_FREQ0HM 0x3 |
33 | #define AD9832_FREQ1LL 0x4 |
34 | #define AD9832_FREQ1HL 0x5 |
35 | #define AD9832_FREQ1LM 0x6 |
36 | #define AD9832_FREQ1HM 0x7 |
37 | #define AD9832_PHASE0L 0x8 |
38 | #define AD9832_PHASE0H 0x9 |
39 | #define AD9832_PHASE1L 0xA |
40 | #define AD9832_PHASE1H 0xB |
41 | #define AD9832_PHASE2L 0xC |
42 | #define AD9832_PHASE2H 0xD |
43 | #define AD9832_PHASE3L 0xE |
44 | #define AD9832_PHASE3H 0xF |
45 | |
46 | #define AD9832_PHASE_SYM 0x10 |
47 | #define AD9832_FREQ_SYM 0x11 |
48 | #define AD9832_PINCTRL_EN 0x12 |
49 | #define AD9832_OUTPUT_EN 0x13 |
50 | |
51 | /* Command Control Bits */ |
52 | |
53 | #define AD9832_CMD_PHA8BITSW 0x1 |
54 | #define AD9832_CMD_PHA16BITSW 0x0 |
55 | #define AD9832_CMD_FRE8BITSW 0x3 |
56 | #define AD9832_CMD_FRE16BITSW 0x2 |
57 | #define AD9832_CMD_FPSELECT 0x6 |
58 | #define AD9832_CMD_SYNCSELSRC 0x8 |
59 | #define AD9832_CMD_SLEEPRESCLR 0xC |
60 | |
61 | #define AD9832_FREQ BIT(11) |
62 | #define AD9832_PHASE(x) (((x) & 3) << 9) |
63 | #define AD9832_SYNC BIT(13) |
64 | #define AD9832_SELSRC BIT(12) |
65 | #define AD9832_SLEEP BIT(13) |
66 | #define AD9832_RESET BIT(12) |
67 | #define AD9832_CLR BIT(11) |
68 | #define CMD_SHIFT 12 |
69 | #define ADD_SHIFT 8 |
70 | #define AD9832_FREQ_BITS 32 |
71 | #define AD9832_PHASE_BITS 12 |
72 | #define RES_MASK(bits) ((1 << (bits)) - 1) |
73 | |
74 | /** |
75 | * struct ad9832_state - driver instance specific data |
76 | * @spi: spi_device |
77 | * @avdd: supply regulator for the analog section |
78 | * @dvdd: supply regulator for the digital section |
79 | * @mclk: external master clock |
80 | * @ctrl_fp: cached frequency/phase control word |
81 | * @ctrl_ss: cached sync/selsrc control word |
82 | * @ctrl_src: cached sleep/reset/clr word |
83 | * @xfer: default spi transfer |
84 | * @msg: default spi message |
85 | * @freq_xfer: tuning word spi transfer |
86 | * @freq_msg: tuning word spi message |
87 | * @phase_xfer: tuning word spi transfer |
88 | * @phase_msg: tuning word spi message |
89 | * @lock: protect sensor state |
90 | * @data: spi transmit buffer |
91 | * @phase_data: tuning word spi transmit buffer |
92 | * @freq_data: tuning word spi transmit buffer |
93 | */ |
94 | |
95 | struct ad9832_state { |
96 | struct spi_device *spi; |
97 | struct regulator *avdd; |
98 | struct regulator *dvdd; |
99 | struct clk *mclk; |
100 | unsigned short ctrl_fp; |
101 | unsigned short ctrl_ss; |
102 | unsigned short ctrl_src; |
103 | struct spi_transfer xfer; |
104 | struct spi_message msg; |
105 | struct spi_transfer freq_xfer[4]; |
106 | struct spi_message freq_msg; |
107 | struct spi_transfer phase_xfer[2]; |
108 | struct spi_message phase_msg; |
109 | struct mutex lock; /* protect sensor state */ |
110 | /* |
111 | * DMA (thus cache coherency maintenance) requires the |
112 | * transfer buffers to live in their own cache lines. |
113 | */ |
114 | union { |
115 | __be16 freq_data[4]; |
116 | __be16 phase_data[2]; |
117 | __be16 data; |
118 | } __aligned(IIO_DMA_MINALIGN); |
119 | }; |
120 | |
121 | static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout) |
122 | { |
123 | unsigned long long freqreg = (u64)fout * |
124 | (u64)((u64)1L << AD9832_FREQ_BITS); |
125 | do_div(freqreg, mclk); |
126 | return freqreg; |
127 | } |
128 | |
129 | static int ad9832_write_frequency(struct ad9832_state *st, |
130 | unsigned int addr, unsigned long fout) |
131 | { |
132 | unsigned long regval; |
133 | |
134 | if (fout > (clk_get_rate(clk: st->mclk) / 2)) |
135 | return -EINVAL; |
136 | |
137 | regval = ad9832_calc_freqreg(mclk: clk_get_rate(clk: st->mclk), fout); |
138 | |
139 | st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | |
140 | (addr << ADD_SHIFT) | |
141 | ((regval >> 24) & 0xFF)); |
142 | st->freq_data[1] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | |
143 | ((addr - 1) << ADD_SHIFT) | |
144 | ((regval >> 16) & 0xFF)); |
145 | st->freq_data[2] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | |
146 | ((addr - 2) << ADD_SHIFT) | |
147 | ((regval >> 8) & 0xFF)); |
148 | st->freq_data[3] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | |
149 | ((addr - 3) << ADD_SHIFT) | |
150 | ((regval >> 0) & 0xFF)); |
151 | |
152 | return spi_sync(spi: st->spi, message: &st->freq_msg); |
153 | } |
154 | |
155 | static int ad9832_write_phase(struct ad9832_state *st, |
156 | unsigned long addr, unsigned long phase) |
157 | { |
158 | if (phase > BIT(AD9832_PHASE_BITS)) |
159 | return -EINVAL; |
160 | |
161 | st->phase_data[0] = cpu_to_be16((AD9832_CMD_PHA8BITSW << CMD_SHIFT) | |
162 | (addr << ADD_SHIFT) | |
163 | ((phase >> 8) & 0xFF)); |
164 | st->phase_data[1] = cpu_to_be16((AD9832_CMD_PHA16BITSW << CMD_SHIFT) | |
165 | ((addr - 1) << ADD_SHIFT) | |
166 | (phase & 0xFF)); |
167 | |
168 | return spi_sync(spi: st->spi, message: &st->phase_msg); |
169 | } |
170 | |
171 | static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, |
172 | const char *buf, size_t len) |
173 | { |
174 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
175 | struct ad9832_state *st = iio_priv(indio_dev); |
176 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
177 | int ret; |
178 | unsigned long val; |
179 | |
180 | ret = kstrtoul(s: buf, base: 10, res: &val); |
181 | if (ret) |
182 | goto error_ret; |
183 | |
184 | mutex_lock(&st->lock); |
185 | switch ((u32)this_attr->address) { |
186 | case AD9832_FREQ0HM: |
187 | case AD9832_FREQ1HM: |
188 | ret = ad9832_write_frequency(st, addr: this_attr->address, fout: val); |
189 | break; |
190 | case AD9832_PHASE0H: |
191 | case AD9832_PHASE1H: |
192 | case AD9832_PHASE2H: |
193 | case AD9832_PHASE3H: |
194 | ret = ad9832_write_phase(st, addr: this_attr->address, phase: val); |
195 | break; |
196 | case AD9832_PINCTRL_EN: |
197 | if (val) |
198 | st->ctrl_ss &= ~AD9832_SELSRC; |
199 | else |
200 | st->ctrl_ss |= AD9832_SELSRC; |
201 | st->data = cpu_to_be16((AD9832_CMD_SYNCSELSRC << CMD_SHIFT) | |
202 | st->ctrl_ss); |
203 | ret = spi_sync(spi: st->spi, message: &st->msg); |
204 | break; |
205 | case AD9832_FREQ_SYM: |
206 | if (val == 1) { |
207 | st->ctrl_fp |= AD9832_FREQ; |
208 | } else if (val == 0) { |
209 | st->ctrl_fp &= ~AD9832_FREQ; |
210 | } else { |
211 | ret = -EINVAL; |
212 | break; |
213 | } |
214 | st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | |
215 | st->ctrl_fp); |
216 | ret = spi_sync(spi: st->spi, message: &st->msg); |
217 | break; |
218 | case AD9832_PHASE_SYM: |
219 | if (val > 3) { |
220 | ret = -EINVAL; |
221 | break; |
222 | } |
223 | |
224 | st->ctrl_fp &= ~AD9832_PHASE(3); |
225 | st->ctrl_fp |= AD9832_PHASE(val); |
226 | |
227 | st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | |
228 | st->ctrl_fp); |
229 | ret = spi_sync(spi: st->spi, message: &st->msg); |
230 | break; |
231 | case AD9832_OUTPUT_EN: |
232 | if (val) |
233 | st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | |
234 | AD9832_CLR); |
235 | else |
236 | st->ctrl_src |= AD9832_RESET; |
237 | |
238 | st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) | |
239 | st->ctrl_src); |
240 | ret = spi_sync(spi: st->spi, message: &st->msg); |
241 | break; |
242 | default: |
243 | ret = -ENODEV; |
244 | } |
245 | mutex_unlock(lock: &st->lock); |
246 | |
247 | error_ret: |
248 | return ret ? ret : len; |
249 | } |
250 | |
251 | /* |
252 | * see dds.h for further information |
253 | */ |
254 | |
255 | static IIO_DEV_ATTR_FREQ(0, 0, 0200, NULL, ad9832_write, AD9832_FREQ0HM); |
256 | static IIO_DEV_ATTR_FREQ(0, 1, 0200, NULL, ad9832_write, AD9832_FREQ1HM); |
257 | static IIO_DEV_ATTR_FREQSYMBOL(0, 0200, NULL, ad9832_write, AD9832_FREQ_SYM); |
258 | static IIO_CONST_ATTR_FREQ_SCALE(0, "1" ); /* 1Hz */ |
259 | |
260 | static IIO_DEV_ATTR_PHASE(0, 0, 0200, NULL, ad9832_write, AD9832_PHASE0H); |
261 | static IIO_DEV_ATTR_PHASE(0, 1, 0200, NULL, ad9832_write, AD9832_PHASE1H); |
262 | static IIO_DEV_ATTR_PHASE(0, 2, 0200, NULL, ad9832_write, AD9832_PHASE2H); |
263 | static IIO_DEV_ATTR_PHASE(0, 3, 0200, NULL, ad9832_write, AD9832_PHASE3H); |
264 | static IIO_DEV_ATTR_PHASESYMBOL(0, 0200, NULL, |
265 | ad9832_write, AD9832_PHASE_SYM); |
266 | static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808" ); /* 2PI/2^12 rad*/ |
267 | |
268 | static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL, |
269 | ad9832_write, AD9832_PINCTRL_EN); |
270 | static IIO_DEV_ATTR_OUT_ENABLE(0, 0200, NULL, |
271 | ad9832_write, AD9832_OUTPUT_EN); |
272 | |
273 | static struct attribute *ad9832_attributes[] = { |
274 | &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, |
275 | &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr, |
276 | &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr, |
277 | &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr, |
278 | &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr, |
279 | &iio_dev_attr_out_altvoltage0_phase2.dev_attr.attr, |
280 | &iio_dev_attr_out_altvoltage0_phase3.dev_attr.attr, |
281 | &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr, |
282 | &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr, |
283 | &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, |
284 | &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, |
285 | &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, |
286 | NULL, |
287 | }; |
288 | |
289 | static const struct attribute_group ad9832_attribute_group = { |
290 | .attrs = ad9832_attributes, |
291 | }; |
292 | |
293 | static const struct iio_info ad9832_info = { |
294 | .attrs = &ad9832_attribute_group, |
295 | }; |
296 | |
297 | static void ad9832_reg_disable(void *reg) |
298 | { |
299 | regulator_disable(regulator: reg); |
300 | } |
301 | |
302 | static int ad9832_probe(struct spi_device *spi) |
303 | { |
304 | struct ad9832_platform_data *pdata = dev_get_platdata(dev: &spi->dev); |
305 | struct iio_dev *indio_dev; |
306 | struct ad9832_state *st; |
307 | int ret; |
308 | |
309 | if (!pdata) { |
310 | dev_dbg(&spi->dev, "no platform data?\n" ); |
311 | return -ENODEV; |
312 | } |
313 | |
314 | indio_dev = devm_iio_device_alloc(parent: &spi->dev, sizeof_priv: sizeof(*st)); |
315 | if (!indio_dev) |
316 | return -ENOMEM; |
317 | |
318 | st = iio_priv(indio_dev); |
319 | |
320 | st->avdd = devm_regulator_get(dev: &spi->dev, id: "avdd" ); |
321 | if (IS_ERR(ptr: st->avdd)) |
322 | return PTR_ERR(ptr: st->avdd); |
323 | |
324 | ret = regulator_enable(regulator: st->avdd); |
325 | if (ret) { |
326 | dev_err(&spi->dev, "Failed to enable specified AVDD supply\n" ); |
327 | return ret; |
328 | } |
329 | |
330 | ret = devm_add_action_or_reset(&spi->dev, ad9832_reg_disable, st->avdd); |
331 | if (ret) |
332 | return ret; |
333 | |
334 | st->dvdd = devm_regulator_get(dev: &spi->dev, id: "dvdd" ); |
335 | if (IS_ERR(ptr: st->dvdd)) |
336 | return PTR_ERR(ptr: st->dvdd); |
337 | |
338 | ret = regulator_enable(regulator: st->dvdd); |
339 | if (ret) { |
340 | dev_err(&spi->dev, "Failed to enable specified DVDD supply\n" ); |
341 | return ret; |
342 | } |
343 | |
344 | ret = devm_add_action_or_reset(&spi->dev, ad9832_reg_disable, st->dvdd); |
345 | if (ret) |
346 | return ret; |
347 | |
348 | st->mclk = devm_clk_get_enabled(dev: &spi->dev, id: "mclk" ); |
349 | if (IS_ERR(ptr: st->mclk)) |
350 | return PTR_ERR(ptr: st->mclk); |
351 | |
352 | st->spi = spi; |
353 | mutex_init(&st->lock); |
354 | |
355 | indio_dev->name = spi_get_device_id(sdev: spi)->name; |
356 | indio_dev->info = &ad9832_info; |
357 | indio_dev->modes = INDIO_DIRECT_MODE; |
358 | |
359 | /* Setup default messages */ |
360 | |
361 | st->xfer.tx_buf = &st->data; |
362 | st->xfer.len = 2; |
363 | |
364 | spi_message_init(m: &st->msg); |
365 | spi_message_add_tail(t: &st->xfer, m: &st->msg); |
366 | |
367 | st->freq_xfer[0].tx_buf = &st->freq_data[0]; |
368 | st->freq_xfer[0].len = 2; |
369 | st->freq_xfer[0].cs_change = 1; |
370 | st->freq_xfer[1].tx_buf = &st->freq_data[1]; |
371 | st->freq_xfer[1].len = 2; |
372 | st->freq_xfer[1].cs_change = 1; |
373 | st->freq_xfer[2].tx_buf = &st->freq_data[2]; |
374 | st->freq_xfer[2].len = 2; |
375 | st->freq_xfer[2].cs_change = 1; |
376 | st->freq_xfer[3].tx_buf = &st->freq_data[3]; |
377 | st->freq_xfer[3].len = 2; |
378 | |
379 | spi_message_init(m: &st->freq_msg); |
380 | spi_message_add_tail(t: &st->freq_xfer[0], m: &st->freq_msg); |
381 | spi_message_add_tail(t: &st->freq_xfer[1], m: &st->freq_msg); |
382 | spi_message_add_tail(t: &st->freq_xfer[2], m: &st->freq_msg); |
383 | spi_message_add_tail(t: &st->freq_xfer[3], m: &st->freq_msg); |
384 | |
385 | st->phase_xfer[0].tx_buf = &st->phase_data[0]; |
386 | st->phase_xfer[0].len = 2; |
387 | st->phase_xfer[0].cs_change = 1; |
388 | st->phase_xfer[1].tx_buf = &st->phase_data[1]; |
389 | st->phase_xfer[1].len = 2; |
390 | |
391 | spi_message_init(m: &st->phase_msg); |
392 | spi_message_add_tail(t: &st->phase_xfer[0], m: &st->phase_msg); |
393 | spi_message_add_tail(t: &st->phase_xfer[1], m: &st->phase_msg); |
394 | |
395 | st->ctrl_src = AD9832_SLEEP | AD9832_RESET | AD9832_CLR; |
396 | st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) | |
397 | st->ctrl_src); |
398 | ret = spi_sync(spi: st->spi, message: &st->msg); |
399 | if (ret) { |
400 | dev_err(&spi->dev, "device init failed\n" ); |
401 | return ret; |
402 | } |
403 | |
404 | ret = ad9832_write_frequency(st, AD9832_FREQ0HM, fout: pdata->freq0); |
405 | if (ret) |
406 | return ret; |
407 | |
408 | ret = ad9832_write_frequency(st, AD9832_FREQ1HM, fout: pdata->freq1); |
409 | if (ret) |
410 | return ret; |
411 | |
412 | ret = ad9832_write_phase(st, AD9832_PHASE0H, phase: pdata->phase0); |
413 | if (ret) |
414 | return ret; |
415 | |
416 | ret = ad9832_write_phase(st, AD9832_PHASE1H, phase: pdata->phase1); |
417 | if (ret) |
418 | return ret; |
419 | |
420 | ret = ad9832_write_phase(st, AD9832_PHASE2H, phase: pdata->phase2); |
421 | if (ret) |
422 | return ret; |
423 | |
424 | ret = ad9832_write_phase(st, AD9832_PHASE3H, phase: pdata->phase3); |
425 | if (ret) |
426 | return ret; |
427 | |
428 | return devm_iio_device_register(&spi->dev, indio_dev); |
429 | } |
430 | |
431 | static const struct spi_device_id ad9832_id[] = { |
432 | {"ad9832" , 0}, |
433 | {"ad9835" , 0}, |
434 | {} |
435 | }; |
436 | MODULE_DEVICE_TABLE(spi, ad9832_id); |
437 | |
438 | static struct spi_driver ad9832_driver = { |
439 | .driver = { |
440 | .name = "ad9832" , |
441 | }, |
442 | .probe = ad9832_probe, |
443 | .id_table = ad9832_id, |
444 | }; |
445 | module_spi_driver(ad9832_driver); |
446 | |
447 | MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>" ); |
448 | MODULE_DESCRIPTION("Analog Devices AD9832/AD9835 DDS" ); |
449 | MODULE_LICENSE("GPL v2" ); |
450 | |