RE: [PATCH v3 2/2] iio: frequency: adf4377: add support for ADF4377

From: Sa, Nuno
Date: Fri Nov 18 2022 - 05:33:22 EST


> From: Antoniu Miclaus <antoniu.miclaus@xxxxxxxxxx>
> Sent: Tuesday, November 15, 2022 12:01 PM
> To: jic23@xxxxxxxxxx; robh+dt@xxxxxxxxxx;
> krzysztof.kozlowski+dt@xxxxxxxxxx; linux-iio@xxxxxxxxxxxxxxx;
> devicetree@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx
> Cc: Miclaus, Antoniu <Antoniu.Miclaus@xxxxxxxxxx>
> Subject: [PATCH v3 2/2] iio: frequency: adf4377: add support for ADF4377
>
> [External]
>
> The ADF4377 is a high performance, ultralow jitter, dual output integer-N
> phased locked loop (PLL) with integrated voltage controlled oscillator
> (VCO) ideally suited for data converter and mixed signal front end (MxFE)
> clock applications.
>
> Datasheet: https://www.analog.com/media/en/technical-
> documentation/data-sheets/adf4377.pdf
> Signed-off-by: Antoniu Miclaus <antoniu.miclaus@xxxxxxxxxx>
> ---
> changes in v3:
> - add register name/value for the macro definitions
> - use `__aligned(IIO_DMA_MINALIGN)`
> - add extra spacing for `reg_sequence` structure
> - check frequency value before reg writes in `adf4377_set_freq` function
> - remove ternary operators inside `adf4377_write` and `adf4377_read`
> - remove comma after null terminator
> drivers/iio/frequency/Kconfig | 10 +
> drivers/iio/frequency/Makefile | 1 +
> drivers/iio/frequency/adf4377.c | 994
> ++++++++++++++++++++++++++++++++
> 3 files changed, 1005 insertions(+)
> create mode 100644 drivers/iio/frequency/adf4377.c
>
> diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig
> index f3702f36436c..9e85dfa58508 100644
> --- a/drivers/iio/frequency/Kconfig
> +++ b/drivers/iio/frequency/Kconfig
> @@ -50,6 +50,16 @@ config ADF4371
> To compile this driver as a module, choose M here: the
> module will be called adf4371.
>
> +config ADF4377
> + tristate "Analog Devices ADF4377 Microwave Wideband Synthesizer"
> + depends on SPI && COMMON_CLK
> + help
> + Say yes here to build support for Analog Devices ADF4377
> Microwave
> + Wideband Synthesizer.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called adf4377.
> +
> config ADMV1013
> tristate "Analog Devices ADMV1013 Microwave Upconverter"
> depends on SPI && COMMON_CLK
> diff --git a/drivers/iio/frequency/Makefile b/drivers/iio/frequency/Makefile
> index 48add732f1d3..b616c29b4a08 100644
> --- a/drivers/iio/frequency/Makefile
> +++ b/drivers/iio/frequency/Makefile
> @@ -7,6 +7,7 @@
> obj-$(CONFIG_AD9523) += ad9523.o
> obj-$(CONFIG_ADF4350) += adf4350.o
> obj-$(CONFIG_ADF4371) += adf4371.o
> +obj-$(CONFIG_ADF4377) += adf4377.o
> obj-$(CONFIG_ADMV1013) += admv1013.o
> obj-$(CONFIG_ADMV1014) += admv1014.o
> obj-$(CONFIG_ADMV4420) += admv4420.o
> diff --git a/drivers/iio/frequency/adf4377.c
> b/drivers/iio/frequency/adf4377.c
> new file mode 100644
> index 000000000000..26abecbd51e0
> --- /dev/null
> +++ b/drivers/iio/frequency/adf4377.c
> @@ -0,0 +1,994 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * ADF4377 driver
> + *
> + * Copyright 2022 Analog Devices Inc.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/module.h>
> +#include <linux/notifier.h>
> +#include <linux/property.h>
> +#include <linux/spi/spi.h>
> +#include <linux/iio/iio.h>
> +#include <linux/regmap.h>
> +#include <linux/units.h>
> +
> +#include <asm/unaligned.h>
> +

...

> +
> +/* Specifications */
> +#define ADF4377_SPI_READ_CMD BIT(7)
> +#define ADF4377_MAX_VCO_FREQ (12800ULL *
> HZ_PER_MHZ)
> +#define ADF4377_MIN_VCO_FREQ (6400ULL *
> HZ_PER_MHZ)
> +#define ADF4377_MAX_REFIN_FREQ (1000 *
> HZ_PER_MHZ)
> +#define ADF4377_MIN_REFIN_FREQ (10 * HZ_PER_MHZ)
> +#define ADF4377_MAX_FREQ_PFD (500 * HZ_PER_MHZ)
> +#define ADF4377_MIN_FREQ_PFD (3 * HZ_PER_MHZ)
> +#define ADF4377_MAX_CLKPN_FREQ
> ADF4377_MAX_VCO_FREQ

Well, I think we are more than fine in using s64 :). Anyways, as the write
side is still a bit weird, let's stay with extended attr.

...

> +static int adf4377_get_freq(struct adf4377_state *st, u64 *freq)
> +{
> + unsigned int ref_div_factor, n_int;
> + u64 clkin_freq;
> + int ret;
> +
> + mutex_lock(&st->lock);
> + ret = regmap_read(st->regmap, 0x12, &ref_div_factor);
> + if (ret)
> + goto exit;
> +
> + ret = regmap_bulk_read(st->regmap, 0x10, st->buf, sizeof(st->buf));
> + if (ret)
> + goto exit;
> +
> + clkin_freq = clk_get_rate(st->clkin);
> + ref_div_factor = FIELD_GET(ADF4377_0012_R_DIV_MSK,
> ref_div_factor);
> + n_int = FIELD_GET(ADF4377_0010_N_INT_LSB_MSK |
> ADF4377_0011_N_INT_MSB_MSK,
> + get_unaligned_le16(&st->buf));
> +
> + *freq = div_u64(clkin_freq, ref_div_factor) * n_int;
> +exit:
> + mutex_unlock(&st->lock);
> +
> + return ret;
> +}
> +
> +static int adf4377_set_freq(struct adf4377_state *st, u64 freq)
> +{
> + unsigned int read_val;
> + u64 f_vco;
> + int ret;

Could initialize ret to -EINVAL and save one line of code :)...

Anyways...

Reviewed-by: Nuno Sá <nuno.sa@xxxxxxxxxx>