Commit 9404fa15f20e89b415cdcbe2649709a8d46c513c
Committed by
Jonathan Cameron
1 parent
5f43264c53
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
iio: frequency: adf4350: Add support for clock consumer framework
Preferably get clkin (PLL reference clock) from clock framework Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Showing 1 changed file with 49 additions and 9 deletions Side-by-side Diff
drivers/iio/frequency/adf4350.c
1 | 1 | /* |
2 | 2 | * ADF4350/ADF4351 SPI Wideband Synthesizer driver |
3 | 3 | * |
4 | - * Copyright 2012 Analog Devices Inc. | |
4 | + * Copyright 2012-2013 Analog Devices Inc. | |
5 | 5 | * |
6 | 6 | * Licensed under the GPL-2. |
7 | 7 | */ |
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 | #include <linux/gcd.h> |
18 | 18 | #include <linux/gpio.h> |
19 | 19 | #include <asm/div64.h> |
20 | +#include <linux/clk.h> | |
20 | 21 | |
21 | 22 | #include <linux/iio/iio.h> |
22 | 23 | #include <linux/iio/sysfs.h> |
... | ... | @@ -33,6 +34,7 @@ |
33 | 34 | struct spi_device *spi; |
34 | 35 | struct regulator *reg; |
35 | 36 | struct adf4350_platform_data *pdata; |
37 | + struct clk *clk; | |
36 | 38 | unsigned long clkin; |
37 | 39 | unsigned long chspc; /* Channel Spacing */ |
38 | 40 | unsigned long fpfd; /* Phase Frequency Detector */ |
... | ... | @@ -43,7 +45,7 @@ |
43 | 45 | unsigned r4_rf_div_sel; |
44 | 46 | unsigned long regs[6]; |
45 | 47 | unsigned long regs_hw[6]; |
46 | - | |
48 | + unsigned long long freq_req; | |
47 | 49 | /* |
48 | 50 | * DMA (thus cache coherency maintenance) requires the |
49 | 51 | * transfer buffers to live in their own cache lines. |
... | ... | @@ -52,7 +54,6 @@ |
52 | 54 | }; |
53 | 55 | |
54 | 56 | static struct adf4350_platform_data default_pdata = { |
55 | - .clkin = 122880000, | |
56 | 57 | .channel_spacing = 10000, |
57 | 58 | .r2_user_settings = ADF4350_REG2_PD_POLARITY_POS | |
58 | 59 | ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500), |
... | ... | @@ -235,6 +236,7 @@ |
235 | 236 | ADF4350_REG4_MUTE_TILL_LOCK_EN)); |
236 | 237 | |
237 | 238 | st->regs[ADF4350_REG5] = ADF4350_REG5_LD_PIN_MODE_DIGITAL; |
239 | + st->freq_req = freq; | |
238 | 240 | |
239 | 241 | return adf4350_sync_config(st); |
240 | 242 | } |
... | ... | @@ -246,6 +248,7 @@ |
246 | 248 | { |
247 | 249 | struct adf4350_state *st = iio_priv(indio_dev); |
248 | 250 | unsigned long long readin; |
251 | + unsigned long tmp; | |
249 | 252 | int ret; |
250 | 253 | |
251 | 254 | ret = kstrtoull(buf, 10, &readin); |
252 | 255 | |
... | ... | @@ -258,10 +261,23 @@ |
258 | 261 | ret = adf4350_set_freq(st, readin); |
259 | 262 | break; |
260 | 263 | case ADF4350_FREQ_REFIN: |
261 | - if (readin > ADF4350_MAX_FREQ_REFIN) | |
264 | + if (readin > ADF4350_MAX_FREQ_REFIN) { | |
262 | 265 | ret = -EINVAL; |
263 | - else | |
264 | - st->clkin = readin; | |
266 | + break; | |
267 | + } | |
268 | + | |
269 | + if (st->clk) { | |
270 | + tmp = clk_round_rate(st->clk, readin); | |
271 | + if (tmp != readin) { | |
272 | + ret = -EINVAL; | |
273 | + break; | |
274 | + } | |
275 | + ret = clk_set_rate(st->clk, tmp); | |
276 | + if (ret < 0) | |
277 | + break; | |
278 | + } | |
279 | + st->clkin = readin; | |
280 | + ret = adf4350_set_freq(st, st->freq_req); | |
265 | 281 | break; |
266 | 282 | case ADF4350_FREQ_RESOLUTION: |
267 | 283 | if (readin == 0) |
... | ... | @@ -308,6 +324,9 @@ |
308 | 324 | } |
309 | 325 | break; |
310 | 326 | case ADF4350_FREQ_REFIN: |
327 | + if (st->clk) | |
328 | + st->clkin = clk_get_rate(st->clk); | |
329 | + | |
311 | 330 | val = st->clkin; |
312 | 331 | break; |
313 | 332 | case ADF4350_FREQ_RESOLUTION: |
... | ... | @@ -318,6 +337,7 @@ |
318 | 337 | break; |
319 | 338 | default: |
320 | 339 | ret = -EINVAL; |
340 | + val = 0; | |
321 | 341 | } |
322 | 342 | mutex_unlock(&indio_dev->mlock); |
323 | 343 | |
324 | 344 | |
325 | 345 | |
... | ... | @@ -360,14 +380,24 @@ |
360 | 380 | struct adf4350_platform_data *pdata = spi->dev.platform_data; |
361 | 381 | struct iio_dev *indio_dev; |
362 | 382 | struct adf4350_state *st; |
383 | + struct clk *clk = NULL; | |
363 | 384 | int ret; |
364 | 385 | |
365 | 386 | if (!pdata) { |
366 | 387 | dev_warn(&spi->dev, "no platform data? using default\n"); |
367 | - | |
368 | 388 | pdata = &default_pdata; |
369 | 389 | } |
370 | 390 | |
391 | + if (!pdata->clkin) { | |
392 | + clk = clk_get(&spi->dev, "clkin"); | |
393 | + if (IS_ERR(clk)) | |
394 | + return -EPROBE_DEFER; | |
395 | + | |
396 | + ret = clk_prepare_enable(clk); | |
397 | + if (ret < 0) | |
398 | + return ret; | |
399 | + } | |
400 | + | |
371 | 401 | indio_dev = iio_device_alloc(sizeof(*st)); |
372 | 402 | if (indio_dev == NULL) |
373 | 403 | return -ENOMEM; |
... | ... | @@ -395,7 +425,12 @@ |
395 | 425 | indio_dev->num_channels = 1; |
396 | 426 | |
397 | 427 | st->chspc = pdata->channel_spacing; |
398 | - st->clkin = pdata->clkin; | |
428 | + if (clk) { | |
429 | + st->clk = clk; | |
430 | + st->clkin = clk_get_rate(clk); | |
431 | + } else { | |
432 | + st->clkin = pdata->clkin; | |
433 | + } | |
399 | 434 | |
400 | 435 | st->min_out_freq = spi_get_device_id(spi)->driver_data == 4351 ? |
401 | 436 | ADF4351_MIN_OUT_FREQ : ADF4350_MIN_OUT_FREQ; |
... | ... | @@ -435,6 +470,8 @@ |
435 | 470 | if (!IS_ERR(st->reg)) |
436 | 471 | regulator_put(st->reg); |
437 | 472 | |
473 | + if (clk) | |
474 | + clk_disable_unprepare(clk); | |
438 | 475 | iio_device_free(indio_dev); |
439 | 476 | |
440 | 477 | return ret; |
... | ... | @@ -451,6 +488,9 @@ |
451 | 488 | |
452 | 489 | iio_device_unregister(indio_dev); |
453 | 490 | |
491 | + if (st->clk) | |
492 | + clk_disable_unprepare(st->clk); | |
493 | + | |
454 | 494 | if (!IS_ERR(reg)) { |
455 | 495 | regulator_disable(reg); |
456 | 496 | regulator_put(reg); |
... | ... | @@ -481,7 +521,7 @@ |
481 | 521 | }; |
482 | 522 | module_spi_driver(adf4350_driver); |
483 | 523 | |
484 | -MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | |
524 | +MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); | |
485 | 525 | MODULE_DESCRIPTION("Analog Devices ADF4350/ADF4351 PLL"); |
486 | 526 | MODULE_LICENSE("GPL v2"); |