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