Commit e764df67963940b4123325710536a9471d1e24ae

Authored by Michael Hennerich
Committed by Jonathan Cameron
1 parent 9404fa15f2

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>

Showing 2 changed files with 213 additions and 1 deletions Side-by-side Diff

Documentation/devicetree/bindings/iio/frequency/adf4350.txt
  1 +Analog Devices ADF4350/ADF4351 device driver
  2 +
  3 +Required properties:
  4 + - compatible: Should be one of
  5 + * "adi,adf4350": When using the ADF4350 device
  6 + * "adi,adf4351": When using the ADF4351 device
  7 + - reg: SPI chip select numbert for the device
  8 + - spi-max-frequency: Max SPI frequency to use (< 20000000)
  9 + - clocks: From common clock binding. Clock is phandle to clock for
  10 + ADF435x Reference Clock (CLKIN).
  11 +
  12 +Optional properties:
  13 + - gpios: GPIO Lock detect - If set with a valid phandle and GPIO number,
  14 + pll lock state is tested upon read.
  15 + - adi,channel-spacing: Channel spacing in Hz (influences MODULUS).
  16 + - adi,power-up-frequency: If set in Hz the PLL tunes to
  17 + the desired frequency on probe.
  18 + - adi,reference-div-factor: If set the driver skips dynamic calculation
  19 + and uses this default value instead.
  20 + - adi,reference-doubler-enable: Enables reference doubler.
  21 + - adi,reference-div2-enable: Enables reference divider.
  22 + - adi,phase-detector-polarity-positive-enable: Enables positive phase
  23 + detector polarity. Default = negative.
  24 + - adi,lock-detect-precision-6ns-enable: Enables 6ns lock detect precision.
  25 + Default = 10ns.
  26 + - adi,lock-detect-function-integer-n-enable: Enables lock detect
  27 + for integer-N mode. Default = factional-N mode.
  28 + - adi,charge-pump-current: Charge pump current in mA.
  29 + Default = 2500mA.
  30 + - adi,muxout-select: On chip multiplexer output selection.
  31 + Valid values for the multiplexer output are:
  32 + 0: Three-State Output (default)
  33 + 1: DVDD
  34 + 2: DGND
  35 + 3: R-Counter output
  36 + 4: N-Divider output
  37 + 5: Analog lock detect
  38 + 6: Digital lock detect
  39 + - adi,low-spur-mode-enable: Enables low spur mode.
  40 + Default = Low noise mode.
  41 + - adi,cycle-slip-reduction-enable: Enables cycle slip reduction.
  42 + - adi,charge-cancellation-enable: Enabled charge pump
  43 + charge cancellation for integer-N modes.
  44 + - adi,anti-backlash-3ns-enable: Enables 3ns antibacklash pulse width
  45 + for integer-N modes.
  46 + - adi,band-select-clock-mode-high-enable: Enables faster band
  47 + selection logic.
  48 + - adi,12bit-clk-divider: Clock divider value used when
  49 + adi,12bit-clkdiv-mode != 0
  50 + - adi,clk-divider-mode:
  51 + Valid values for the clkdiv mode are:
  52 + 0: Clock divider off (default)
  53 + 1: Fast lock enable
  54 + 2: Phase resync enable
  55 + - adi,aux-output-enable: Enables auxiliary RF output.
  56 + - adi,aux-output-fundamental-enable: Selects fundamental VCO output on
  57 + the auxiliary RF output. Default = Output of RF dividers.
  58 + - adi,mute-till-lock-enable: Enables Mute-Till-Lock-Detect function.
  59 + - adi,output-power: Output power selection.
  60 + Valid values for the power mode are:
  61 + 0: -4dBm (default)
  62 + 1: -1dBm
  63 + 2: +2dBm
  64 + 3: +5dBm
  65 + - adi,aux-output-power: Auxiliary output power selection.
  66 + Valid values for the power mode are:
  67 + 0: -4dBm (default)
  68 + 1: -1dBm
  69 + 2: +2dBm
  70 + 3: +5dBm
  71 +
  72 +
  73 +Example:
  74 + lo_pll0_rx_adf4351: adf4351-rx-lpc@4 {
  75 + compatible = "adi,adf4351";
  76 + reg = <4>;
  77 + spi-max-frequency = <10000000>;
  78 + clocks = <&clk0_ad9523 9>;
  79 + clock-names = "clkin";
  80 + adi,channel-spacing = <10000>;
  81 + adi,power-up-frequency = <2400000000>;
  82 + adi,phase-detector-polarity-positive-enable;
  83 + adi,charge-pump-current = <2500>;
  84 + adi,output-power = <3>;
  85 + adi,mute-till-lock-enable;
  86 + };
drivers/iio/frequency/adf4350.c
... ... @@ -18,6 +18,8 @@
18 18 #include <linux/gpio.h>
19 19 #include <asm/div64.h>
20 20 #include <linux/clk.h>
  21 +#include <linux/of.h>
  22 +#include <linux/of_gpio.h>
21 23  
22 24 #include <linux/iio/iio.h>
23 25 #include <linux/iio/sysfs.h>
24 26  
25 27  
... ... @@ -375,13 +377,137 @@
375 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 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 499 struct iio_dev *indio_dev;
382 500 struct adf4350_state *st;
383 501 struct clk *clk = NULL;
384 502 int ret;
  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 + }
385 511  
386 512 if (!pdata) {
387 513 dev_warn(&spi->dev, "no platform data? using default\n");