diff options
author | Michael Hennerich <michael.hennerich@analog.com> | 2013-06-03 09:30:00 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2013-06-09 14:15:43 -0400 |
commit | e764df67963940b4123325710536a9471d1e24ae (patch) | |
tree | 86cb05a11b7ec622afc136c6e464a21c87c8144e /drivers/iio | |
parent | 9404fa15f20e89b415cdcbe2649709a8d46c513c (diff) |
iio: frequency: adf4350: Add support for dt bindings
Per review feedback from Lars-Peter Clausen <lars@metafoo.de>
Changes since V1:
Fix return value handling of adf4350_parse_dt()
Use of_get_gpio
Avoid abbreviations in devicetree properties
Fix typo in docs
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>
Diffstat (limited to 'drivers/iio')
-rw-r--r-- | drivers/iio/frequency/adf4350.c | 128 |
1 files changed, 127 insertions, 1 deletions
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index f6849c8b6a90..a4157cdb314d 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
19 | #include <asm/div64.h> | 19 | #include <asm/div64.h> |
20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
21 | #include <linux/of.h> | ||
22 | #include <linux/of_gpio.h> | ||
21 | 23 | ||
22 | #include <linux/iio/iio.h> | 24 | #include <linux/iio/iio.h> |
23 | #include <linux/iio/sysfs.h> | 25 | #include <linux/iio/sysfs.h> |
@@ -375,14 +377,138 @@ static const struct iio_info adf4350_info = { | |||
375 | .driver_module = THIS_MODULE, | 377 | .driver_module = THIS_MODULE, |
376 | }; | 378 | }; |
377 | 379 | ||
380 | #ifdef CONFIG_OF | ||
381 | static struct adf4350_platform_data *adf4350_parse_dt(struct device *dev) | ||
382 | { | ||
383 | struct device_node *np = dev->of_node; | ||
384 | struct adf4350_platform_data *pdata; | ||
385 | unsigned int tmp; | ||
386 | int ret; | ||
387 | |||
388 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
389 | if (!pdata) { | ||
390 | dev_err(dev, "could not allocate memory for platform data\n"); | ||
391 | return NULL; | ||
392 | } | ||
393 | |||
394 | strncpy(&pdata->name[0], np->name, SPI_NAME_SIZE - 1); | ||
395 | |||
396 | tmp = 10000; | ||
397 | of_property_read_u32(np, "adi,channel-spacing", &tmp); | ||
398 | pdata->channel_spacing = tmp; | ||
399 | |||
400 | tmp = 0; | ||
401 | of_property_read_u32(np, "adi,power-up-frequency", &tmp); | ||
402 | pdata->power_up_frequency = tmp; | ||
403 | |||
404 | tmp = 0; | ||
405 | of_property_read_u32(np, "adi,reference-div-factor", &tmp); | ||
406 | pdata->ref_div_factor = tmp; | ||
407 | |||
408 | ret = of_get_gpio(np, 0); | ||
409 | if (ret < 0) | ||
410 | pdata->gpio_lock_detect = -1; | ||
411 | else | ||
412 | pdata->gpio_lock_detect = ret; | ||
413 | |||
414 | pdata->ref_doubler_en = of_property_read_bool(np, | ||
415 | "adi,reference-doubler-enable"); | ||
416 | pdata->ref_div2_en = of_property_read_bool(np, | ||
417 | "adi,reference-div2-enable"); | ||
418 | |||
419 | /* r2_user_settings */ | ||
420 | pdata->r2_user_settings = of_property_read_bool(np, | ||
421 | "adi,phase-detector-polarity-positive-enable") ? | ||
422 | ADF4350_REG2_PD_POLARITY_POS : 0; | ||
423 | pdata->r2_user_settings |= of_property_read_bool(np, | ||
424 | "adi,lock-detect-precision-6ns-enable") ? | ||
425 | ADF4350_REG2_LDP_6ns : 0; | ||
426 | pdata->r2_user_settings |= of_property_read_bool(np, | ||
427 | "adi,lock-detect-function-integer-n-enable") ? | ||
428 | ADF4350_REG2_LDF_INT_N : 0; | ||
429 | |||
430 | tmp = 2500; | ||
431 | of_property_read_u32(np, "adi,charge-pump-current", &tmp); | ||
432 | pdata->r2_user_settings |= ADF4350_REG2_CHARGE_PUMP_CURR_uA(tmp); | ||
433 | |||
434 | tmp = 0; | ||
435 | of_property_read_u32(np, "adi,muxout-select", &tmp); | ||
436 | pdata->r2_user_settings |= ADF4350_REG2_MUXOUT(tmp); | ||
437 | |||
438 | pdata->r2_user_settings |= of_property_read_bool(np, | ||
439 | "adi,low-spur-mode-enable") ? | ||
440 | ADF4350_REG2_NOISE_MODE(0x3) : 0; | ||
441 | |||
442 | /* r3_user_settings */ | ||
443 | |||
444 | pdata->r3_user_settings = of_property_read_bool(np, | ||
445 | "adi,cycle-slip-reduction-enable") ? | ||
446 | ADF4350_REG3_12BIT_CSR_EN : 0; | ||
447 | pdata->r3_user_settings |= of_property_read_bool(np, | ||
448 | "adi,charge-cancellation-enable") ? | ||
449 | ADF4351_REG3_CHARGE_CANCELLATION_EN : 0; | ||
450 | |||
451 | pdata->r3_user_settings |= of_property_read_bool(np, | ||
452 | "adi,anti-backlash-3ns-enable") ? | ||
453 | ADF4351_REG3_ANTI_BACKLASH_3ns_EN : 0; | ||
454 | pdata->r3_user_settings |= of_property_read_bool(np, | ||
455 | "adi,band-select-clock-mode-high-enable") ? | ||
456 | ADF4351_REG3_BAND_SEL_CLOCK_MODE_HIGH : 0; | ||
457 | |||
458 | tmp = 0; | ||
459 | of_property_read_u32(np, "adi,12bit-clk-divider", &tmp); | ||
460 | pdata->r3_user_settings |= ADF4350_REG3_12BIT_CLKDIV(tmp); | ||
461 | |||
462 | tmp = 0; | ||
463 | of_property_read_u32(np, "adi,clk-divider-mode", &tmp); | ||
464 | pdata->r3_user_settings |= ADF4350_REG3_12BIT_CLKDIV_MODE(tmp); | ||
465 | |||
466 | /* r4_user_settings */ | ||
467 | |||
468 | pdata->r4_user_settings = of_property_read_bool(np, | ||
469 | "adi,aux-output-enable") ? | ||
470 | ADF4350_REG4_AUX_OUTPUT_EN : 0; | ||
471 | pdata->r4_user_settings |= of_property_read_bool(np, | ||
472 | "adi,aux-output-fundamental-enable") ? | ||
473 | ADF4350_REG4_AUX_OUTPUT_FUND : 0; | ||
474 | pdata->r4_user_settings |= of_property_read_bool(np, | ||
475 | "adi,mute-till-lock-enable") ? | ||
476 | ADF4350_REG4_MUTE_TILL_LOCK_EN : 0; | ||
477 | |||
478 | tmp = 0; | ||
479 | of_property_read_u32(np, "adi,output-power", &tmp); | ||
480 | pdata->r4_user_settings |= ADF4350_REG4_OUTPUT_PWR(tmp); | ||
481 | |||
482 | tmp = 0; | ||
483 | of_property_read_u32(np, "adi,aux-output-power", &tmp); | ||
484 | pdata->r4_user_settings |= ADF4350_REG4_AUX_OUTPUT_PWR(tmp); | ||
485 | |||
486 | return pdata; | ||
487 | } | ||
488 | #else | ||
489 | static | ||
490 | struct adf4350_platform_data *adf4350_parse_dt(struct device *dev) | ||
491 | { | ||
492 | return NULL; | ||
493 | } | ||
494 | #endif | ||
495 | |||
378 | static int adf4350_probe(struct spi_device *spi) | 496 | static int adf4350_probe(struct spi_device *spi) |
379 | { | 497 | { |
380 | struct adf4350_platform_data *pdata = spi->dev.platform_data; | 498 | struct adf4350_platform_data *pdata; |
381 | struct iio_dev *indio_dev; | 499 | struct iio_dev *indio_dev; |
382 | struct adf4350_state *st; | 500 | struct adf4350_state *st; |
383 | struct clk *clk = NULL; | 501 | struct clk *clk = NULL; |
384 | int ret; | 502 | int ret; |
385 | 503 | ||
504 | if (spi->dev.of_node) { | ||
505 | pdata = adf4350_parse_dt(&spi->dev); | ||
506 | if (pdata == NULL) | ||
507 | return -EINVAL; | ||
508 | } else { | ||
509 | pdata = spi->dev.platform_data; | ||
510 | } | ||
511 | |||
386 | if (!pdata) { | 512 | if (!pdata) { |
387 | dev_warn(&spi->dev, "no platform data? using default\n"); | 513 | dev_warn(&spi->dev, "no platform data? using default\n"); |
388 | pdata = &default_pdata; | 514 | pdata = &default_pdata; |