[PATCH 4/4] iio: frequency: adf4350: Add support for dt bindings

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Michael Hennerich <michael.hennerich@xxxxxxxxxx>

Signed-off-by: Michael Hennerich <michael.hennerich@xxxxxxxxxx>
---
 .../devicetree/bindings/iio/frequency/adf4350.txt  |   84 ++++++++++++++
 drivers/iio/frequency/adf4350.c                    |  122 +++++++++++++++++++-
 2 files changed, 205 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/iio/frequency/adf4350.txt

diff --git a/Documentation/devicetree/bindings/iio/frequency/adf4350.txt b/Documentation/devicetree/bindings/iio/frequency/adf4350.txt
new file mode 100644
index 0000000..ab99cfd
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/frequency/adf4350.txt
@@ -0,0 +1,84 @@
+Analog Devices ADF4350/ADF4351 device driver
+
+Required properties:
+	- compatible: Should be one of
+		* "adi,adf4350": When using the ADF4350 device
+		* "adi,adf4351": When using the ADF4351 device
+	- reg: SPI chip select numbert for the device
+	- spi-max-frequency: Max SPI frequency to use (< 20000000)
+	- clocks: From common clock binding. Clock is phandle to clock for
+		ADF435x Reference Clock (CLKIN).
+
+Optional properties:
+	- adi,channel-spacing: Channel spacing in Hz (influences MODULUS).
+	- adi,power-up-frequency:	If set in Hz the PLL tunes to
+			the desired frequency on probe.
+	- adi,ref-div-factor: If set the driver skips dynamic calculation
+			and uses this default value instead.
+	- adi,ref-doubler-en: Enables reference doubler.
+	- adi,ref-div2-en: Enables reference divider.
+	- adi,gpio-lock-detect:	If set with a valid GPIO number, pll lock state
+			is tested upon read.
+	- adi,reg2-pd-polarity-pos-en: Enables positive phase
+			detector polarity. Default = negative.
+	- adi,reg2-ldp-6ns-en: Enables 6ns lock detect precision.
+			Default = 10ns.
+	- adi,reg2-ldf-int-n-en: Enables lock detect for integer-N mode.
+			Default = factional-N mode.
+	- adi,reg2-charge-pump-curr-ua: Charge pump current in mA.
+			Default = 2500mA.
+	- adi,reg2-muxout: On chip multiplexer output selection.
+			Valid values for the multiplexer output are:
+			0: Three-State Output (default)
+			1: DVDD
+			2: DGND
+			3: R-Counter output
+			4: N-Divider output
+			5: Analog lock detect
+			6: Digital lock detect
+	- adi,reg2-noise-mode: Enables low noise mode. Default = Low spur mode.
+	- adi,reg3-csr-en: Enables cycle slip reduction.
+	- adi,reg3-charge-cancellation-en: Enabled charge pump
+			charge cancellation for integer-N modes.
+	- adi,reg3-anti-backlash-3ns-en: Enables 3ns antibacklash pulse width
+			 for integer-N modes.
+	- adi,reg3-band-sel-clock-mode-high-en: Enables faster band selection logic.
+	- adi,reg3-12bit-clkdiv: Clock divider value used when
+			adi,reg3-12bit-clkdiv-mode != 0
+	- adi,reg3-12bit-clkdiv-mode:
+			Valid values for the clkdiv mode are:
+			0: Clock divider off (default)
+			1: Fast lock enable
+			2: Phase resync enable
+	- adi,reg4-aux-output-en: Enables auxiliary RF output.
+	- adi,reg4-aux-output-fund-en: Selects fundamental VCO output on the
+			auxiliary RF output. Default = Output of RF dividers.
+	- adi,reg4-mute-till-lock-en: Enables Mute-Till-Lock-Detect function.
+	- adi,reg4-output-pwr: Output power selection.
+			Valid values for the power mode are:
+			0: -4dBM (default)
+			1: -1dBM
+			2: +2dBM
+			3: +5dBM
+	- adi,reg4-aux-output-pwr: Auxiliary output power selection.
+			Valid values for the power mode are:
+			0: -4dBM (default)
+			1: -1dBM
+			2: +2dBM
+			3: +5dBM
+
+
+Example:
+		lo_pll0_rx_adf4351: adf4351-rx-lpc@4 {
+			compatible = "adi,adf4351";
+			reg = <4>;
+			spi-max-frequency = <10000000>;
+			clocks = <&clk0_ad9523 9>;
+			clock-names = "clkin";
+			adi,channel-spacing = <10000>;
+			adi,power-up-frequency = <2400000000>;
+			adi,reg2-pd-polarity-pos-en;
+			adi,reg2-charge-pump-curr-ua = <2500>;
+			adi,reg4-output-pwr = <3>;
+			adi,reg4-mute-till-lock-en;
+		};
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c
index f6849c8..828ce3e1 100644
--- a/drivers/iio/frequency/adf4350.c
+++ b/drivers/iio/frequency/adf4350.c
@@ -18,6 +18,7 @@
 #include <linux/gpio.h>
 #include <asm/div64.h>
 #include <linux/clk.h>
+#include <linux/of.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -375,14 +376,133 @@ static const struct iio_info adf4350_info = {
 	.driver_module = THIS_MODULE,
 };
 
+#ifdef CONFIG_OF
+static struct adf4350_platform_data *adf4350_parse_dt(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct adf4350_platform_data *pdata;
+	unsigned int tmp;
+	int ret;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "could not allocate memory for platform data\n");
+		return NULL;
+	}
+
+	strncpy(&pdata->name[0], np->name, SPI_NAME_SIZE - 1);
+
+	tmp = 10000;
+	of_property_read_u32(np, "adi,channel-spacing", &tmp);
+	pdata->channel_spacing = tmp;
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,power-up-frequency", &tmp);
+	pdata->power_up_frequency = tmp;
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,ref-div-factor", &tmp);
+	pdata->ref_div_factor = tmp;
+
+	ret = of_property_read_u32(np, "adi,gpio-lock-detect",
+				   &pdata->gpio_lock_detect);
+	if (ret < 0)
+		pdata->gpio_lock_detect = -1;
+
+	pdata->ref_doubler_en = of_property_read_bool(np, "adi,ref-doubler-en");
+	pdata->ref_div2_en = of_property_read_bool(np, "adi,ref-div2-en");
+
+	/* r2_user_settings */
+	pdata->r2_user_settings =
+		of_property_read_bool(np, "adi,reg2-pd-polarity-pos-en") ?
+					ADF4350_REG2_PD_POLARITY_POS : 0;
+	pdata->r2_user_settings |=
+		of_property_read_bool(np, "adi,reg2-ldp-6ns-en") ?
+					ADF4350_REG2_LDP_6ns : 0;
+	pdata->r2_user_settings |=
+		of_property_read_bool(np, "adi,reg2-ldf-int-n-en") ?
+					ADF4350_REG2_LDF_INT_N : 0;
+	tmp = 2500;
+	of_property_read_u32(np, "adi,reg2-charge-pump-curr-ua", &tmp);
+	pdata->r2_user_settings |= ADF4350_REG2_CHARGE_PUMP_CURR_uA(tmp);
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,reg2-muxout", &tmp);
+	pdata->r2_user_settings |= ADF4350_REG2_MUXOUT(tmp);
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,reg2-noise-mode", &tmp);
+	pdata->r2_user_settings |= ADF4350_REG2_NOISE_MODE(tmp);
+
+	/* r3_user_settings */
+
+	pdata->r3_user_settings =
+		of_property_read_bool(np, "adi,reg3-csr-en") ?
+					ADF4350_REG3_12BIT_CSR_EN : 0;
+	pdata->r3_user_settings |=
+		of_property_read_bool(np, "adi,reg3-charge-cancellation-en") ?
+					ADF4351_REG3_CHARGE_CANCELLATION_EN : 0;
+	pdata->r3_user_settings |=
+		of_property_read_bool(np, "adi,reg3-anti-backlash-3ns-en") ?
+					ADF4351_REG3_ANTI_BACKLASH_3ns_EN : 0;
+	pdata->r3_user_settings |=
+		of_property_read_bool(np,
+				      "adi,reg3-band-sel-clock-mode-high-en") ?
+				      ADF4351_REG3_BAND_SEL_CLOCK_MODE_HIGH : 0;
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,reg3-12bit-clkdiv", &tmp);
+	pdata->r3_user_settings |= ADF4350_REG3_12BIT_CLKDIV(tmp);
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,reg3-12bit-clkdiv-mode", &tmp);
+	pdata->r3_user_settings |= ADF4350_REG3_12BIT_CLKDIV_MODE(tmp);
+
+	/* r4_user_settings */
+
+	pdata->r4_user_settings =
+		of_property_read_bool(np, "adi,reg4-aux-output-en") ?
+					ADF4350_REG4_AUX_OUTPUT_EN : 0;
+	pdata->r4_user_settings |=
+		of_property_read_bool(np, "adi,reg4-aux-output-fund-en") ?
+					ADF4350_REG4_AUX_OUTPUT_FUND : 0;
+	pdata->r4_user_settings |=
+		of_property_read_bool(np, "adi,reg4-mute-till-lock-en") ?
+					ADF4350_REG4_MUTE_TILL_LOCK_EN : 0;
+	tmp = 0;
+	of_property_read_u32(np, "adi,reg4-output-pwr", &tmp);
+	pdata->r4_user_settings |= ADF4350_REG4_OUTPUT_PWR(tmp);
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,reg4-aux-output-pwr", &tmp);
+	pdata->r4_user_settings |= ADF4350_REG4_AUX_OUTPUT_PWR(tmp);
+
+	return pdata;
+}
+#else
+static
+struct adf4350_platform_data *adf4350_parse_dt(struct device *dev)
+{
+	return NULL;
+}
+#endif
+
 static int adf4350_probe(struct spi_device *spi)
 {
-	struct adf4350_platform_data *pdata = spi->dev.platform_data;
+	struct adf4350_platform_data *pdata;
 	struct iio_dev *indio_dev;
 	struct adf4350_state *st;
 	struct clk *clk = NULL;
 	int ret;
 
+	if (spi->dev.of_node) {
+		pdata = adf4350_parse_dt(&spi->dev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+	} else {
+		pdata = spi->dev.platform_data;
+	}
+
 	if (!pdata) {
 		dev_warn(&spi->dev, "no platform data? using default\n");
 		pdata = &default_pdata;
-- 
1.7.9.5


--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux