Commit e01670e3 authored by Antoniu Miclaus's avatar Antoniu Miclaus Committed by Jonathan Cameron
Browse files

iio: frequency: adf4371: add refin mode



Add support for single-ended/differential reference input mode.

Reviewed-by: default avatarNuno Sa <nuno.sa@analog.com>
Signed-off-by: default avatarAntoniu Miclaus <antoniu.miclaus@analog.com>
Link: https://patch.msgid.link/20250127101026.5320-3-antoniu.miclaus@analog.com


Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent e8279e66
Loading
Loading
Loading
Loading
+26 −3
Original line number Diff line number Diff line
@@ -42,6 +42,10 @@
#define ADF4371_MOD2WORD_MSK		GENMASK(5, 0)
#define ADF4371_MOD2WORD(x)		FIELD_PREP(ADF4371_MOD2WORD_MSK, x)

/* ADF4371_REG22 */
#define ADF4371_REFIN_MODE_MASK		BIT(6)
#define ADF4371_REFIN_MODE(x)		FIELD_PREP(ADF4371_REFIN_MODE_MASK, x)

/* ADF4371_REG24 */
#define ADF4371_RF_DIV_SEL_MSK		GENMASK(6, 4)
#define ADF4371_RF_DIV_SEL(x)		FIELD_PREP(ADF4371_RF_DIV_SEL_MSK, x)
@@ -70,6 +74,7 @@

#define ADF4371_MAX_FREQ_PFD		250000000UL /* Hz */
#define ADF4371_MAX_FREQ_REFIN		600000000UL /* Hz */
#define ADF4371_MAX_FREQ_REFIN_SE	500000000UL /* Hz */

/* MOD1 is a 24-bit primary modulus with fixed value of 2^25 */
#define ADF4371_MODULUS1		33554432ULL
@@ -176,6 +181,7 @@ struct adf4371_state {
	unsigned int mod2;
	unsigned int rf_div_sel;
	unsigned int ref_div_factor;
	bool ref_diff_en;
	u8 buf[10] __aligned(IIO_DMA_MINALIGN);
};

@@ -505,6 +511,17 @@ static int adf4371_setup(struct adf4371_state *st)
				 ADF4371_ADDR_ASC(1) | ADF4371_ADDR_ASC_R(1));
	if (ret < 0)
		return ret;

	if ((st->ref_diff_en && st->clkin_freq > ADF4371_MAX_FREQ_REFIN) ||
	    (!st->ref_diff_en && st->clkin_freq > ADF4371_MAX_FREQ_REFIN_SE))
		return -EINVAL;

	ret = regmap_update_bits(st->regmap,  ADF4371_REG(0x22),
				 ADF4371_REFIN_MODE_MASK,
				 ADF4371_REFIN_MODE(st->ref_diff_en));
	if (ret < 0)
		return ret;

	/*
	 * Calculate and maximize PFD frequency
	 * fPFD = REFIN × ((1 + D)/(R × (1 + T)))
@@ -574,10 +591,16 @@ static int adf4371_probe(struct spi_device *spi)
	indio_dev->channels = st->chip_info->channels;
	indio_dev->num_channels = st->chip_info->num_channels;

	st->ref_diff_en = false;

	clkin = devm_clk_get_enabled(&spi->dev, "clkin");
	if (IS_ERR(clkin)) {
		clkin = devm_clk_get_enabled(&spi->dev, "clkin-diff");
		if (IS_ERR(clkin))
			return dev_err_probe(&spi->dev, PTR_ERR(clkin),
				     "Failed to get clkin\n");
				     "Failed to get clkin/clkin-diff\n");
		st->ref_diff_en = true;
	}

	st->clkin_freq = clk_get_rate(clkin);