devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23@kernel.org>
To: Beniamin Bia <beniamin.bia@analog.com>
Cc: <knaack.h@gmx.de>, <lars@metafoo.de>, <pmeerw@pmeerw.net>,
	<robh+dt@kernel.org>, <mark.rutland@arm.com>,
	<Michael.Hennerich@analog.com>, <linux-iio@vger.kernel.org>,
	<devicetree@vger.kernel.org>, <biabeniamin@outlook.com>,
	Stefan Popa <stefan.popa@analog.com>
Subject: Re: [PATCH 2/3] iio: frequency: adf4371: Introduce channel child nodes
Date: Mon, 23 Dec 2019 11:02:46 +0000	[thread overview]
Message-ID: <20191223110246.39e008c3@archlinux> (raw)
In-Reply-To: <20191219133755.26109-2-beniamin.bia@analog.com>

On Thu, 19 Dec 2019 15:37:54 +0200
Beniamin Bia <beniamin.bia@analog.com> wrote:

> From: Stefan Popa <stefan.popa@analog.com>
> 
> The ADF4371/ADF4372 devices support individual configurations for the
> output channels. Each child node represents a channel for which
> "power-up-frequency" and "output-enable" optional properties are currently
> supported.
> 
> If the "power-up-frequency" is specified for a channel, the driver checks
> if the value provided is in sync with the frequencies set on the other
> channels. This limitation is due to the fact that all the channel
> frequencies are derived from the VCO fundamental frequency.
> 
> If the "output-enable" property is specified, then the channel will be
> enabled, otherwise, the driver will initialize the defaults (RF8x will
> be the only enabled channel).
> 
> Signed-off-by: Stefan Popa <stefan.popa@analog.com>
> Signed-off-by: Beniamin Bia <beniamin.bia@analog.com>
The code looks good.  Question outstanding is the one I raised in review
of the binding doc.  What's this for?

Thanks,

Jonathan

> ---
>  drivers/iio/frequency/adf4371.c | 79 ++++++++++++++++++++++++++++++++-
>  1 file changed, 77 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/frequency/adf4371.c b/drivers/iio/frequency/adf4371.c
> index 7d77ebdbea82..e2a599b912e5 100644
> --- a/drivers/iio/frequency/adf4371.c
> +++ b/drivers/iio/frequency/adf4371.c
> @@ -154,10 +154,16 @@ struct adf4371_chip_info {
>  	const struct iio_chan_spec *channels;
>  };
>  
> +struct adf4371_channel_config {
> +	bool enable;
> +	unsigned long long freq;
> +};
> +
>  struct adf4371_state {
>  	struct spi_device *spi;
>  	struct regmap *regmap;
>  	struct clk *clkin;
> +	struct adf4371_channel_config channel_cfg[4];
>  	/*
>  	 * Lock for accessing device registers. Some operations require
>  	 * multiple consecutive R/W operations, during which the device
> @@ -175,6 +181,7 @@ struct adf4371_state {
>  	unsigned int mod2;
>  	unsigned int rf_div_sel;
>  	unsigned int ref_div_factor;
> +	bool mute_till_lock_en;
>  	u8 buf[10] ____cacheline_aligned;
>  };
>  
> @@ -480,6 +487,36 @@ static const struct iio_info adf4371_info = {
>  	.debugfs_reg_access = &adf4371_reg_access,
>  };
>  
> +static int adf4371_channel_config(struct adf4371_state *st)
> +{
> +	unsigned long long rate;
> +	int i, ret;
> +
> +	for (i = 0; i < st->chip_info->num_channels; i++) {
> +		if (st->channel_cfg[i].freq == 0)
> +			continue;
> +
> +		rate = adf4371_pll_fract_n_get_rate(st, i);
> +		if (rate == 0) {
> +			ret = adf4371_set_freq(st, st->channel_cfg[i].freq, i);
> +			if (ret < 0)
> +				return ret;
> +		} else if (rate != st->channel_cfg[i].freq) {
> +			dev_err(&st->spi->dev,
> +				"Clock rate for chanel %d is not in sync\n", i);
> +			return -EINVAL;
> +		}
> +		/* Powerup channel if the property was specified in the dt */
> +		if (st->channel_cfg[i].enable) {
> +			ret = adf4371_channel_power_down(st, i, false);
> +			if (ret < 0)
> +				return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static int adf4371_setup(struct adf4371_state *st)
>  {
>  	unsigned int synth_timeout = 2, timeout = 1, vco_alc_timeout = 1;
> @@ -497,7 +534,7 @@ static int adf4371_setup(struct adf4371_state *st)
>  		return ret;
>  
>  	/* Mute to Lock Detect */
> -	if (device_property_read_bool(&st->spi->dev, "adi,mute-till-lock-en")) {
> +	if (st->mute_till_lock_en) {
>  		ret = regmap_update_bits(st->regmap, ADF4371_REG(0x25),
>  					 ADF4371_MUTE_LD_MSK,
>  					 ADF4371_MUTE_LD(1));
> @@ -545,7 +582,11 @@ static int adf4371_setup(struct adf4371_state *st)
>  	st->buf[3] = synth_timeout;
>  	st->buf[4] = ADF4371_VCO_ALC_TOUT(vco_alc_timeout);
>  
> -	return regmap_bulk_write(st->regmap, ADF4371_REG(0x30), st->buf, 5);
> +	ret = regmap_bulk_write(st->regmap, ADF4371_REG(0x30), st->buf, 5);
> +	if (ret < 0)
> +		return 0;
> +
> +	return adf4371_channel_config(st);
>  }
>  
>  static void adf4371_clk_disable(void *data)
> @@ -555,6 +596,36 @@ static void adf4371_clk_disable(void *data)
>  	clk_disable_unprepare(st->clkin);
>  }
>  
> +static int adf4371_parse_dt(struct adf4371_state *st)
> +{
> +	unsigned char num_channels;
> +	unsigned int channel;
> +	struct fwnode_handle *child;
> +	int ret;
> +
> +	if (device_property_read_bool(&st->spi->dev, "adi,mute-till-lock-en"))
> +		st->mute_till_lock_en = true;
> +
> +	num_channels = device_get_child_node_count(&st->spi->dev);
> +	if (num_channels > st->chip_info->num_channels)
> +		return -EINVAL;
> +
> +	device_for_each_child_node(&st->spi->dev, child) {
> +		ret = fwnode_property_read_u32(child, "reg", &channel);
> +		if (ret)
> +			return ret;
> +
> +		ret = fwnode_property_present(child, "adi,output-enable");
> +		st->channel_cfg[channel].enable = ret;
> +
> +		fwnode_property_read_u64(child,
> +					 "adi,power-up-frequency",
> +					 &st->channel_cfg[channel].freq);
> +	}
> +
> +	return 0;
> +}
> +
>  static int adf4371_probe(struct spi_device *spi)
>  {
>  	const struct spi_device_id *id = spi_get_device_id(spi);
> @@ -602,6 +673,10 @@ static int adf4371_probe(struct spi_device *spi)
>  
>  	st->clkin_freq = clk_get_rate(st->clkin);
>  
> +	ret = adf4371_parse_dt(st);
> +	if (ret < 0)
> +		return ret;
> +
>  	ret = adf4371_setup(st);
>  	if (ret < 0) {
>  		dev_err(&spi->dev, "ADF4371 setup failed\n");


  reply	other threads:[~2019-12-23 11:02 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-19 13:37 [PATCH 1/3] iio: frequency: adf4371: Create a power down/up function Beniamin Bia
2019-12-19 13:37 ` [PATCH 2/3] iio: frequency: adf4371: Introduce channel child nodes Beniamin Bia
2019-12-23 11:02   ` Jonathan Cameron [this message]
2019-12-19 13:37 ` [PATCH 3/3] dt-binding: iio: Add documentation for ADF4371 channel child notes Beniamin Bia
2019-12-23 11:00   ` Jonathan Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191223110246.39e008c3@archlinux \
    --to=jic23@kernel.org \
    --cc=Michael.Hennerich@analog.com \
    --cc=beniamin.bia@analog.com \
    --cc=biabeniamin@outlook.com \
    --cc=devicetree@vger.kernel.org \
    --cc=knaack.h@gmx.de \
    --cc=lars@metafoo.de \
    --cc=linux-iio@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=pmeerw@pmeerw.net \
    --cc=robh+dt@kernel.org \
    --cc=stefan.popa@analog.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).