aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio-frequency-adf435021
-rw-r--r--drivers/iio/frequency/Kconfig18
-rw-r--r--drivers/iio/frequency/Makefile1
-rw-r--r--drivers/iio/frequency/adf4350.c478
-rw-r--r--include/linux/iio/frequency/adf4350.h126
5 files changed, 644 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 b/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350
new file mode 100644
index 000000000000..d89aded01c5a
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350
@@ -0,0 +1,21 @@
1What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_frequency_resolution
2KernelVersion: 3.4.0
3Contact: linux-iio@vger.kernel.org
4Description:
5 Stores channel Y frequency resolution/channel spacing in Hz.
6 The value given directly influences the MODULUS used by
7 the fractional-N PLL. It is assumed that the algorithm
8 that is used to compute the various dividers, is able to
9 generate proper values for multiples of channel spacing.
10
11What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_refin_frequency
12KernelVersion: 3.4.0
13Contact: linux-iio@vger.kernel.org
14Description:
15 Sets channel Y REFin frequency in Hz. In some clock chained
16 applications, the reference frequency used by the PLL may
17 change during runtime. This attribute allows the user to
18 adjust the reference frequency accordingly.
19 The value written has no effect until out_altvoltageY_frequency
20 is updated. Consider to use out_altvoltageY_powerdown to power
21 down the PLL and it's RFOut buffers during REFin changes.
diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig
index 0458c92464a3..6aaa33ef4544 100644
--- a/drivers/iio/frequency/Kconfig
+++ b/drivers/iio/frequency/Kconfig
@@ -20,4 +20,22 @@ config AD9523
20 module will be called ad9523. 20 module will be called ad9523.
21 21
22endmenu 22endmenu
23
24#
25# Phase-Locked Loop (PLL) frequency synthesizers
26#
27
28menu "Phase-Locked Loop (PLL) frequency synthesizers"
29
30config ADF4350
31 tristate "Analog Devices ADF4350/ADF4351 Wideband Synthesizers"
32 depends on SPI
33 help
34 Say yes here to build support for Analog Devices ADF4350/ADF4351
35 Wideband Synthesizers. The driver provides direct access via sysfs.
36
37 To compile this driver as a module, choose M here: the
38 module will be called adf4350.
39
40endmenu
23endmenu 41endmenu
diff --git a/drivers/iio/frequency/Makefile b/drivers/iio/frequency/Makefile
index 1b5b22417da1..00d26e5d1dc2 100644
--- a/drivers/iio/frequency/Makefile
+++ b/drivers/iio/frequency/Makefile
@@ -3,3 +3,4 @@
3# 3#
4 4
5obj-$(CONFIG_AD9523) += ad9523.o 5obj-$(CONFIG_AD9523) += ad9523.o
6obj-$(CONFIG_ADF4350) += adf4350.o
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c
new file mode 100644
index 000000000000..fd4c8501aba9
--- /dev/null
+++ b/drivers/iio/frequency/adf4350.c
@@ -0,0 +1,478 @@
1/*
2 * ADF4350/ADF4351 SPI Wideband Synthesizer driver
3 *
4 * Copyright 2012 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#include <linux/device.h>
10#include <linux/kernel.h>
11#include <linux/slab.h>
12#include <linux/sysfs.h>
13#include <linux/spi/spi.h>
14#include <linux/regulator/consumer.h>
15#include <linux/err.h>
16#include <linux/module.h>
17#include <linux/gcd.h>
18#include <linux/gpio.h>
19#include <asm/div64.h>
20
21#include <linux/iio/iio.h>
22#include <linux/iio/sysfs.h>
23#include <linux/iio/frequency/adf4350.h>
24
25enum {
26 ADF4350_FREQ,
27 ADF4350_FREQ_REFIN,
28 ADF4350_FREQ_RESOLUTION,
29 ADF4350_PWRDOWN,
30};
31
32struct adf4350_state {
33 struct spi_device *spi;
34 struct regulator *reg;
35 struct adf4350_platform_data *pdata;
36 unsigned long clkin;
37 unsigned long chspc; /* Channel Spacing */
38 unsigned long fpfd; /* Phase Frequency Detector */
39 unsigned long min_out_freq;
40 unsigned r0_fract;
41 unsigned r0_int;
42 unsigned r1_mod;
43 unsigned r4_rf_div_sel;
44 unsigned long regs[6];
45 unsigned long regs_hw[6];
46
47 /*
48 * DMA (thus cache coherency maintenance) requires the
49 * transfer buffers to live in their own cache lines.
50 */
51 __be32 val ____cacheline_aligned;
52};
53
54static struct adf4350_platform_data default_pdata = {
55 .clkin = 122880000,
56 .channel_spacing = 10000,
57 .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS,
58 ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500),
59 .r3_user_settings = ADF4350_REG3_12BIT_CLKDIV_MODE(0),
60 .r4_user_settings = ADF4350_REG4_OUTPUT_PWR(3) |
61 ADF4350_REG4_MUTE_TILL_LOCK_EN,
62 .gpio_lock_detect = -1,
63};
64
65static int adf4350_sync_config(struct adf4350_state *st)
66{
67 int ret, i, doublebuf = 0;
68
69 for (i = ADF4350_REG5; i >= ADF4350_REG0; i--) {
70 if ((st->regs_hw[i] != st->regs[i]) ||
71 ((i == ADF4350_REG0) && doublebuf)) {
72
73 switch (i) {
74 case ADF4350_REG1:
75 case ADF4350_REG4:
76 doublebuf = 1;
77 break;
78 }
79
80 st->val = cpu_to_be32(st->regs[i] | i);
81 ret = spi_write(st->spi, &st->val, 4);
82 if (ret < 0)
83 return ret;
84 st->regs_hw[i] = st->regs[i];
85 dev_dbg(&st->spi->dev, "[%d] 0x%X\n",
86 i, (u32)st->regs[i] | i);
87 }
88 }
89 return 0;
90}
91
92static int adf4350_reg_access(struct iio_dev *indio_dev,
93 unsigned reg, unsigned writeval,
94 unsigned *readval)
95{
96 struct adf4350_state *st = iio_priv(indio_dev);
97 int ret;
98
99 if (reg > ADF4350_REG5)
100 return -EINVAL;
101
102 mutex_lock(&indio_dev->mlock);
103 if (readval == NULL) {
104 st->regs[reg] = writeval & ~(BIT(0) | BIT(1) | BIT(2));
105 ret = adf4350_sync_config(st);
106 } else {
107 *readval = st->regs_hw[reg];
108 ret = 0;
109 }
110 mutex_unlock(&indio_dev->mlock);
111
112 return ret;
113}
114
115static int adf4350_tune_r_cnt(struct adf4350_state *st, unsigned short r_cnt)
116{
117 struct adf4350_platform_data *pdata = st->pdata;
118
119 do {
120 r_cnt++;
121 st->fpfd = (st->clkin * (pdata->ref_doubler_en ? 2 : 1)) /
122 (r_cnt * (pdata->ref_div2_en ? 2 : 1));
123 } while (st->fpfd > ADF4350_MAX_FREQ_PFD);
124
125 return r_cnt;
126}
127
128static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq)
129{
130 struct adf4350_platform_data *pdata = st->pdata;
131 u64 tmp;
132 u32 div_gcd, prescaler;
133 u16 mdiv, r_cnt = 0;
134 u8 band_sel_div;
135
136 if (freq > ADF4350_MAX_OUT_FREQ || freq < st->min_out_freq)
137 return -EINVAL;
138
139 if (freq > ADF4350_MAX_FREQ_45_PRESC) {
140 prescaler = ADF4350_REG1_PRESCALER;
141 mdiv = 75;
142 } else {
143 prescaler = 0;
144 mdiv = 23;
145 }
146
147 st->r4_rf_div_sel = 0;
148
149 while (freq < ADF4350_MIN_VCO_FREQ) {
150 freq <<= 1;
151 st->r4_rf_div_sel++;
152 }
153
154 /*
155 * Allow a predefined reference division factor
156 * if not set, compute our own
157 */
158 if (pdata->ref_div_factor)
159 r_cnt = pdata->ref_div_factor - 1;
160
161 do {
162 r_cnt = adf4350_tune_r_cnt(st, r_cnt);
163
164 st->r1_mod = st->fpfd / st->chspc;
165 while (st->r1_mod > ADF4350_MAX_MODULUS) {
166 r_cnt = adf4350_tune_r_cnt(st, r_cnt);
167 st->r1_mod = st->fpfd / st->chspc;
168 }
169
170 tmp = freq * (u64)st->r1_mod + (st->fpfd > 1);
171 do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */
172 st->r0_fract = do_div(tmp, st->r1_mod);
173 st->r0_int = tmp;
174 } while (mdiv > st->r0_int);
175
176 band_sel_div = DIV_ROUND_UP(st->fpfd, ADF4350_MAX_BANDSEL_CLK);
177
178 if (st->r0_fract && st->r1_mod) {
179 div_gcd = gcd(st->r1_mod, st->r0_fract);
180 st->r1_mod /= div_gcd;
181 st->r0_fract /= div_gcd;
182 } else {
183 st->r0_fract = 0;
184 st->r1_mod = 1;
185 }
186
187 dev_dbg(&st->spi->dev, "VCO: %llu Hz, PFD %lu Hz\n"
188 "REF_DIV %d, R0_INT %d, R0_FRACT %d\n"
189 "R1_MOD %d, RF_DIV %d\nPRESCALER %s, BAND_SEL_DIV %d\n",
190 freq, st->fpfd, r_cnt, st->r0_int, st->r0_fract, st->r1_mod,
191 1 << st->r4_rf_div_sel, prescaler ? "8/9" : "4/5",
192 band_sel_div);
193
194 st->regs[ADF4350_REG0] = ADF4350_REG0_INT(st->r0_int) |
195 ADF4350_REG0_FRACT(st->r0_fract);
196
197 st->regs[ADF4350_REG1] = ADF4350_REG1_PHASE(0) |
198 ADF4350_REG1_MOD(st->r1_mod) |
199 prescaler;
200
201 st->regs[ADF4350_REG2] =
202 ADF4350_REG2_10BIT_R_CNT(r_cnt) |
203 ADF4350_REG2_DOUBLE_BUFF_EN |
204 (pdata->ref_doubler_en ? ADF4350_REG2_RMULT2_EN : 0) |
205 (pdata->ref_div2_en ? ADF4350_REG2_RDIV2_EN : 0) |
206 (pdata->r2_user_settings & (ADF4350_REG2_PD_POLARITY_POS |
207 ADF4350_REG2_LDP_6ns | ADF4350_REG2_LDF_INT_N |
208 ADF4350_REG2_CHARGE_PUMP_CURR_uA(5000) |
209 ADF4350_REG2_MUXOUT(0x7) | ADF4350_REG2_NOISE_MODE(0x9)));
210
211 st->regs[ADF4350_REG3] = pdata->r3_user_settings &
212 (ADF4350_REG3_12BIT_CLKDIV(0xFFF) |
213 ADF4350_REG3_12BIT_CLKDIV_MODE(0x3) |
214 ADF4350_REG3_12BIT_CSR_EN |
215 ADF4351_REG3_CHARGE_CANCELLATION_EN |
216 ADF4351_REG3_ANTI_BACKLASH_3ns_EN |
217 ADF4351_REG3_BAND_SEL_CLOCK_MODE_HIGH);
218
219 st->regs[ADF4350_REG4] =
220 ADF4350_REG4_FEEDBACK_FUND |
221 ADF4350_REG4_RF_DIV_SEL(st->r4_rf_div_sel) |
222 ADF4350_REG4_8BIT_BAND_SEL_CLKDIV(band_sel_div) |
223 ADF4350_REG4_RF_OUT_EN |
224 (pdata->r4_user_settings &
225 (ADF4350_REG4_OUTPUT_PWR(0x3) |
226 ADF4350_REG4_AUX_OUTPUT_PWR(0x3) |
227 ADF4350_REG4_AUX_OUTPUT_EN |
228 ADF4350_REG4_AUX_OUTPUT_FUND |
229 ADF4350_REG4_MUTE_TILL_LOCK_EN));
230
231 st->regs[ADF4350_REG5] = ADF4350_REG5_LD_PIN_MODE_DIGITAL;
232
233 return adf4350_sync_config(st);
234}
235
236static ssize_t adf4350_write(struct iio_dev *indio_dev,
237 uintptr_t private,
238 const struct iio_chan_spec *chan,
239 const char *buf, size_t len)
240{
241 struct adf4350_state *st = iio_priv(indio_dev);
242 unsigned long long readin;
243 int ret;
244
245 ret = kstrtoull(buf, 10, &readin);
246 if (ret)
247 return ret;
248
249 mutex_lock(&indio_dev->mlock);
250 switch ((u32)private) {
251 case ADF4350_FREQ:
252 ret = adf4350_set_freq(st, readin);
253 break;
254 case ADF4350_FREQ_REFIN:
255 if (readin > ADF4350_MAX_FREQ_REFIN)
256 ret = -EINVAL;
257 else
258 st->clkin = readin;
259 break;
260 case ADF4350_FREQ_RESOLUTION:
261 if (readin == 0)
262 ret = -EINVAL;
263 else
264 st->chspc = readin;
265 break;
266 case ADF4350_PWRDOWN:
267 if (readin)
268 st->regs[ADF4350_REG2] |= ADF4350_REG2_POWER_DOWN_EN;
269 else
270 st->regs[ADF4350_REG2] &= ~ADF4350_REG2_POWER_DOWN_EN;
271
272 adf4350_sync_config(st);
273 break;
274 default:
275 ret = -ENODEV;
276 }
277 mutex_unlock(&indio_dev->mlock);
278
279 return ret ? ret : len;
280}
281
282static ssize_t adf4350_read(struct iio_dev *indio_dev,
283 uintptr_t private,
284 const struct iio_chan_spec *chan,
285 char *buf)
286{
287 struct adf4350_state *st = iio_priv(indio_dev);
288 unsigned long long val;
289 int ret = 0;
290
291 mutex_lock(&indio_dev->mlock);
292 switch ((u32)private) {
293 case ADF4350_FREQ:
294 val = (u64)((st->r0_int * st->r1_mod) + st->r0_fract) *
295 (u64)st->fpfd;
296 do_div(val, st->r1_mod * (1 << st->r4_rf_div_sel));
297 /* PLL unlocked? return error */
298 if (gpio_is_valid(st->pdata->gpio_lock_detect))
299 if (!gpio_get_value(st->pdata->gpio_lock_detect)) {
300 dev_dbg(&st->spi->dev, "PLL un-locked\n");
301 ret = -EBUSY;
302 }
303 break;
304 case ADF4350_FREQ_REFIN:
305 val = st->clkin;
306 break;
307 case ADF4350_FREQ_RESOLUTION:
308 val = st->chspc;
309 break;
310 case ADF4350_PWRDOWN:
311 val = !!(st->regs[ADF4350_REG2] & ADF4350_REG2_POWER_DOWN_EN);
312 break;
313 }
314 mutex_unlock(&indio_dev->mlock);
315
316 return ret < 0 ? ret : sprintf(buf, "%llu\n", val);
317}
318
319#define _ADF4350_EXT_INFO(_name, _ident) { \
320 .name = _name, \
321 .read = adf4350_read, \
322 .write = adf4350_write, \
323 .private = _ident, \
324}
325
326static const struct iio_chan_spec_ext_info adf4350_ext_info[] = {
327 /* Ideally we use IIO_CHAN_INFO_FREQUENCY, but there are
328 * values > 2^32 in order to support the entire frequency range
329 * in Hz. Using scale is a bit ugly.
330 */
331 _ADF4350_EXT_INFO("frequency", ADF4350_FREQ),
332 _ADF4350_EXT_INFO("frequency_resolution", ADF4350_FREQ_RESOLUTION),
333 _ADF4350_EXT_INFO("refin_frequency", ADF4350_FREQ_REFIN),
334 _ADF4350_EXT_INFO("powerdown", ADF4350_PWRDOWN),
335 { },
336};
337
338static const struct iio_chan_spec adf4350_chan = {
339 .type = IIO_ALTVOLTAGE,
340 .indexed = 1,
341 .output = 1,
342 .ext_info = adf4350_ext_info,
343};
344
345static const struct iio_info adf4350_info = {
346 .debugfs_reg_access = &adf4350_reg_access,
347 .driver_module = THIS_MODULE,
348};
349
350static int __devinit adf4350_probe(struct spi_device *spi)
351{
352 struct adf4350_platform_data *pdata = spi->dev.platform_data;
353 struct iio_dev *indio_dev;
354 struct adf4350_state *st;
355 int ret;
356
357 if (!pdata) {
358 dev_warn(&spi->dev, "no platform data? using default\n");
359
360 pdata = &default_pdata;
361 }
362
363 indio_dev = iio_device_alloc(sizeof(*st));
364 if (indio_dev == NULL)
365 return -ENOMEM;
366
367 st = iio_priv(indio_dev);
368
369 st->reg = regulator_get(&spi->dev, "vcc");
370 if (!IS_ERR(st->reg)) {
371 ret = regulator_enable(st->reg);
372 if (ret)
373 goto error_put_reg;
374 }
375
376 spi_set_drvdata(spi, indio_dev);
377 st->spi = spi;
378 st->pdata = pdata;
379
380 indio_dev->dev.parent = &spi->dev;
381 indio_dev->name = (pdata->name[0] != 0) ? pdata->name :
382 spi_get_device_id(spi)->name;
383
384 indio_dev->info = &adf4350_info;
385 indio_dev->modes = INDIO_DIRECT_MODE;
386 indio_dev->channels = &adf4350_chan;
387 indio_dev->num_channels = 1;
388
389 st->chspc = pdata->channel_spacing;
390 st->clkin = pdata->clkin;
391
392 st->min_out_freq = spi_get_device_id(spi)->driver_data == 4351 ?
393 ADF4351_MIN_OUT_FREQ : ADF4350_MIN_OUT_FREQ;
394
395 memset(st->regs_hw, 0xFF, sizeof(st->regs_hw));
396
397 if (gpio_is_valid(pdata->gpio_lock_detect)) {
398 ret = gpio_request(pdata->gpio_lock_detect, indio_dev->name);
399 if (ret) {
400 dev_err(&spi->dev, "fail to request lock detect GPIO-%d",
401 pdata->gpio_lock_detect);
402 goto error_disable_reg;
403 }
404 gpio_direction_input(pdata->gpio_lock_detect);
405 }
406
407 if (pdata->power_up_frequency) {
408 ret = adf4350_set_freq(st, pdata->power_up_frequency);
409 if (ret)
410 goto error_free_gpio;
411 }
412
413 ret = iio_device_register(indio_dev);
414 if (ret)
415 goto error_free_gpio;
416
417 return 0;
418
419error_free_gpio:
420 if (gpio_is_valid(pdata->gpio_lock_detect))
421 gpio_free(pdata->gpio_lock_detect);
422
423error_disable_reg:
424 if (!IS_ERR(st->reg))
425 regulator_disable(st->reg);
426error_put_reg:
427 if (!IS_ERR(st->reg))
428 regulator_put(st->reg);
429
430 iio_device_free(indio_dev);
431
432 return ret;
433}
434
435static int __devexit adf4350_remove(struct spi_device *spi)
436{
437 struct iio_dev *indio_dev = spi_get_drvdata(spi);
438 struct adf4350_state *st = iio_priv(indio_dev);
439 struct regulator *reg = st->reg;
440
441 st->regs[ADF4350_REG2] |= ADF4350_REG2_POWER_DOWN_EN;
442 adf4350_sync_config(st);
443
444 iio_device_unregister(indio_dev);
445
446 if (!IS_ERR(reg)) {
447 regulator_disable(reg);
448 regulator_put(reg);
449 }
450
451 if (gpio_is_valid(st->pdata->gpio_lock_detect))
452 gpio_free(st->pdata->gpio_lock_detect);
453
454 iio_device_free(indio_dev);
455
456 return 0;
457}
458
459static const struct spi_device_id adf4350_id[] = {
460 {"adf4350", 4350},
461 {"adf4351", 4351},
462 {}
463};
464
465static struct spi_driver adf4350_driver = {
466 .driver = {
467 .name = "adf4350",
468 .owner = THIS_MODULE,
469 },
470 .probe = adf4350_probe,
471 .remove = __devexit_p(adf4350_remove),
472 .id_table = adf4350_id,
473};
474module_spi_driver(adf4350_driver);
475
476MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
477MODULE_DESCRIPTION("Analog Devices ADF4350/ADF4351 PLL");
478MODULE_LICENSE("GPL v2");
diff --git a/include/linux/iio/frequency/adf4350.h b/include/linux/iio/frequency/adf4350.h
new file mode 100644
index 000000000000..b76b4a87065e
--- /dev/null
+++ b/include/linux/iio/frequency/adf4350.h
@@ -0,0 +1,126 @@
1/*
2 * ADF4350/ADF4351 SPI PLL driver
3 *
4 * Copyright 2012 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2.
7 */
8
9#ifndef IIO_PLL_ADF4350_H_
10#define IIO_PLL_ADF4350_H_
11
12/* Registers */
13#define ADF4350_REG0 0
14#define ADF4350_REG1 1
15#define ADF4350_REG2 2
16#define ADF4350_REG3 3
17#define ADF4350_REG4 4
18#define ADF4350_REG5 5
19
20/* REG0 Bit Definitions */
21#define ADF4350_REG0_FRACT(x) (((x) & 0xFFF) << 3)
22#define ADF4350_REG0_INT(x) (((x) & 0xFFFF) << 15)
23
24/* REG1 Bit Definitions */
25#define ADF4350_REG1_MOD(x) (((x) & 0xFFF) << 3)
26#define ADF4350_REG1_PHASE(x) (((x) & 0xFFF) << 15)
27#define ADF4350_REG1_PRESCALER (1 << 27)
28
29/* REG2 Bit Definitions */
30#define ADF4350_REG2_COUNTER_RESET_EN (1 << 3)
31#define ADF4350_REG2_CP_THREESTATE_EN (1 << 4)
32#define ADF4350_REG2_POWER_DOWN_EN (1 << 5)
33#define ADF4350_REG2_PD_POLARITY_POS (1 << 6)
34#define ADF4350_REG2_LDP_6ns (1 << 7)
35#define ADF4350_REG2_LDP_10ns (0 << 7)
36#define ADF4350_REG2_LDF_FRACT_N (0 << 8)
37#define ADF4350_REG2_LDF_INT_N (1 << 8)
38#define ADF4350_REG2_CHARGE_PUMP_CURR_uA(x) (((((x)-312) / 312) & 0xF) << 9)
39#define ADF4350_REG2_DOUBLE_BUFF_EN (1 << 13)
40#define ADF4350_REG2_10BIT_R_CNT(x) ((x) << 14)
41#define ADF4350_REG2_RDIV2_EN (1 << 24)
42#define ADF4350_REG2_RMULT2_EN (1 << 25)
43#define ADF4350_REG2_MUXOUT(x) ((x) << 26)
44#define ADF4350_REG2_NOISE_MODE(x) ((x) << 29)
45#define ADF4350_MUXOUT_THREESTATE 0
46#define ADF4350_MUXOUT_DVDD 1
47#define ADF4350_MUXOUT_GND 2
48#define ADF4350_MUXOUT_R_DIV_OUT 3
49#define ADF4350_MUXOUT_N_DIV_OUT 4
50#define ADF4350_MUXOUT_ANALOG_LOCK_DETECT 5
51#define ADF4350_MUXOUT_DIGITAL_LOCK_DETECT 6
52
53/* REG3 Bit Definitions */
54#define ADF4350_REG3_12BIT_CLKDIV(x) ((x) << 3)
55#define ADF4350_REG3_12BIT_CLKDIV_MODE(x) ((x) << 16)
56#define ADF4350_REG3_12BIT_CSR_EN (1 << 18)
57#define ADF4351_REG3_CHARGE_CANCELLATION_EN (1 << 21)
58#define ADF4351_REG3_ANTI_BACKLASH_3ns_EN (1 << 22)
59#define ADF4351_REG3_BAND_SEL_CLOCK_MODE_HIGH (1 << 23)
60
61/* REG4 Bit Definitions */
62#define ADF4350_REG4_OUTPUT_PWR(x) ((x) << 3)
63#define ADF4350_REG4_RF_OUT_EN (1 << 5)
64#define ADF4350_REG4_AUX_OUTPUT_PWR(x) ((x) << 6)
65#define ADF4350_REG4_AUX_OUTPUT_EN (1 << 8)
66#define ADF4350_REG4_AUX_OUTPUT_FUND (1 << 9)
67#define ADF4350_REG4_AUX_OUTPUT_DIV (0 << 9)
68#define ADF4350_REG4_MUTE_TILL_LOCK_EN (1 << 10)
69#define ADF4350_REG4_VCO_PWRDOWN_EN (1 << 11)
70#define ADF4350_REG4_8BIT_BAND_SEL_CLKDIV(x) ((x) << 12)
71#define ADF4350_REG4_RF_DIV_SEL(x) ((x) << 20)
72#define ADF4350_REG4_FEEDBACK_DIVIDED (0 << 23)
73#define ADF4350_REG4_FEEDBACK_FUND (1 << 23)
74
75/* REG5 Bit Definitions */
76#define ADF4350_REG5_LD_PIN_MODE_LOW (0 << 22)
77#define ADF4350_REG5_LD_PIN_MODE_DIGITAL (1 << 22)
78#define ADF4350_REG5_LD_PIN_MODE_HIGH (3 << 22)
79
80/* Specifications */
81#define ADF4350_MAX_OUT_FREQ 4400000000ULL /* Hz */
82#define ADF4350_MIN_OUT_FREQ 137500000 /* Hz */
83#define ADF4351_MIN_OUT_FREQ 34375000 /* Hz */
84#define ADF4350_MIN_VCO_FREQ 2200000000ULL /* Hz */
85#define ADF4350_MAX_FREQ_45_PRESC 3000000000ULL /* Hz */
86#define ADF4350_MAX_FREQ_PFD 32000000 /* Hz */
87#define ADF4350_MAX_BANDSEL_CLK 125000 /* Hz */
88#define ADF4350_MAX_FREQ_REFIN 250000000 /* Hz */
89#define ADF4350_MAX_MODULUS 4095
90
91/**
92 * struct adf4350_platform_data - platform specific information
93 * @name: Optional device name.
94 * @clkin: REFin frequency in Hz.
95 * @channel_spacing: Channel spacing in Hz (influences MODULUS).
96 * @power_up_frequency: Optional, If set in Hz the PLL tunes to the desired
97 * frequency on probe.
98 * @ref_div_factor: Optional, if set the driver skips dynamic calculation
99 * and uses this default value instead.
100 * @ref_doubler_en: Enables reference doubler.
101 * @ref_div2_en: Enables reference divider.
102 * @r2_user_settings: User defined settings for ADF4350/1 REGISTER_2.
103 * @r3_user_settings: User defined settings for ADF4350/1 REGISTER_3.
104 * @r4_user_settings: User defined settings for ADF4350/1 REGISTER_4.
105 * @gpio_lock_detect: Optional, if set with a valid GPIO number,
106 * pll lock state is tested upon read.
107 * If not used - set to -1.
108 */
109
110struct adf4350_platform_data {
111 char name[32];
112 unsigned long clkin;
113 unsigned long channel_spacing;
114 unsigned long long power_up_frequency;
115
116 unsigned short ref_div_factor; /* 10-bit R counter */
117 bool ref_doubler_en;
118 bool ref_div2_en;
119
120 unsigned r2_user_settings;
121 unsigned r3_user_settings;
122 unsigned r4_user_settings;
123 int gpio_lock_detect;
124};
125
126#endif /* IIO_PLL_ADF4350_H_ */