linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23@kernel.org>
To: Mircea Caprioru <mircea.caprioru@analog.com>
Cc: <Michael.Hennerich@analog.com>, <knaack.h@gmx.de>,
	<lars@metafoo.de>, <pmeerw@pmeerw.net>,
	<gregkh@linuxfoundation.org>, <linux-kernel@vger.kernel.org>,
	<linux-iio@vger.kernel.org>, <devel@driverdev.osuosl.org>,
	Rob Herring <robh+dt@kernel.org>,
	linux-clk@vger.kernel.org
Subject: Re: [PATCH 1/2] staging: iio: adc: ad7192: Add clock for external clock reference
Date: Sat, 8 Dec 2018 15:29:54 +0000	[thread overview]
Message-ID: <20181208152954.596529f8@archlinux> (raw)
In-Reply-To: <20181206091052.7644-1-mircea.caprioru@analog.com>

On Thu, 6 Dec 2018 11:10:51 +0200
Mircea Caprioru <mircea.caprioru@analog.com> wrote:

> This patch adds a clock to the state structure of ad7192 for getting the
> external clock frequency. This modifications is in accordance with clock
> framework dt bindings documentation.
> 
> Signed-off-by: Mircea Caprioru <mircea.caprioru@analog.com>

+cc Rob and the clk list for advise on how to do the binding for this one.

It is basically 2 pins, you can put a clock in on one of them or connect
a crystal across them.  The driver has to set a register to say which is
the case.  

Current proposal is two optional clocks (fall back to internal oscillator)
but that doesn't seem to be commonly done, so I'm wondering if there
is a 'standard' way to handle this sort of thing.

Thanks,

Jonathan

> ---
>  drivers/staging/iio/adc/ad7192.c | 74 +++++++++++++++++++++-----------
>  drivers/staging/iio/adc/ad7192.h |  2 -
>  2 files changed, 50 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
> index acdbc07fd259..8a4e6ede42b3 100644
> --- a/drivers/staging/iio/adc/ad7192.c
> +++ b/drivers/staging/iio/adc/ad7192.c
> @@ -6,6 +6,7 @@
>   * Licensed under the GPL-2.
>   */
>  
> +#include <linux/clk.h>
>  #include <linux/interrupt.h>
>  #include <linux/device.h>
>  #include <linux/kernel.h>
> @@ -156,8 +157,9 @@
>  struct ad7192_state {
>  	struct regulator		*avdd;
>  	struct regulator		*dvdd;
> +	struct clk			*mclk;
>  	u16				int_vref_mv;
> -	u32				mclk;
> +	u32				fclk;
>  	u32				f_order;
>  	u32				mode;
>  	u32				conf;
> @@ -165,6 +167,7 @@ struct ad7192_state {
>  	u8				gpocon;
>  	u8				devid;
>  	struct mutex			lock;	/* protect sensor state */
> +	u8				clock_sel;
>  
>  	struct ad_sigma_delta		sd;
>  };
> @@ -250,28 +253,8 @@ static int ad7192_setup(struct ad7192_state *st,
>  		dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X)\n",
>  			 id);
>  
> -	switch (pdata->clock_source_sel) {
> -	case AD7192_CLK_INT:
> -	case AD7192_CLK_INT_CO:
> -		st->mclk = AD7192_INT_FREQ_MHZ;
> -		break;
> -	case AD7192_CLK_EXT_MCLK1_2:
> -	case AD7192_CLK_EXT_MCLK2:
> -		if (ad7192_valid_external_frequency(pdata->ext_clk_hz)) {
> -			st->mclk = pdata->ext_clk_hz;
> -			break;
> -		}
> -		dev_err(&st->sd.spi->dev, "Invalid frequency setting %u\n",
> -			pdata->ext_clk_hz);
> -		ret = -EINVAL;
> -		goto out;
> -	default:
> -		ret = -EINVAL;
> -		goto out;
> -	}
> -
>  	st->mode = AD7192_MODE_SEL(AD7192_MODE_IDLE) |
> -		AD7192_MODE_CLKSRC(pdata->clock_source_sel) |
> +		AD7192_MODE_CLKSRC(st->clock_sel) |
>  		AD7192_MODE_RATE(480);
>  
>  	st->conf = AD7192_CONF_GAIN(0);
> @@ -499,7 +482,7 @@ static int ad7192_read_raw(struct iio_dev *indio_dev,
>  			*val -= 273 * ad7192_get_temp_scale(unipolar);
>  		return IIO_VAL_INT;
>  	case IIO_CHAN_INFO_SAMP_FREQ:
> -		*val = st->mclk /
> +		*val = st->fclk /
>  			(st->f_order * 1024 * AD7192_MODE_RATE(st->mode));
>  		return IIO_VAL_INT;
>  	}
> @@ -546,7 +529,7 @@ static int ad7192_write_raw(struct iio_dev *indio_dev,
>  			break;
>  		}
>  
> -		div = st->mclk / (val * st->f_order * 1024);
> +		div = st->fclk / (val * st->f_order * 1024);
>  		if (div < 1 || div > 1023) {
>  			ret = -EINVAL;
>  			break;
> @@ -625,6 +608,42 @@ static const struct iio_chan_spec ad7193_channels[] = {
>  	IIO_CHAN_SOFT_TIMESTAMP(14),
>  };
>  
> +static int ad7192_clock_select(struct spi_device *spi, struct ad7192_state *st)
> +{
> +	int ret;
> +
> +	st->clock_sel = AD7192_CLK_EXT_MCLK2;
> +	st->mclk = devm_clk_get(&spi->dev, "clk");
> +	if (IS_ERR(st->mclk)) {
> +		if (PTR_ERR(st->mclk) != -ENOENT)
> +			return PTR_ERR(st->mclk);
> +
> +		/* try xtal option */
> +		st->mclk = devm_clk_get(&spi->dev, "xtal");

I'm not seeing any other driver using clock naming to distinguish
between different clock options. 

Which does raise the question of how to do this? 

I think it's probably going to be a single clock as both the external
clock and the crystal would be connected to the same pins.


> +		st->clock_sel = AD7192_CLK_EXT_MCLK1_2;
> +		if (IS_ERR(st->mclk)) {
> +			if (PTR_ERR(st->mclk) != -ENOENT)
> +				return PTR_ERR(st->mclk);
> +
> +			/* use internal clock */
> +			st->clock_sel = AD7192_CLK_INT;
> +			st->fclk = AD7192_INT_FREQ_MHZ;
> +		}
> +	}
> +	if (st->clock_sel == AD7192_CLK_EXT_MCLK2 ||
> +	    st->clock_sel == AD7192_CLK_EXT_MCLK1_2) {
> +		ret = clk_prepare_enable(st->mclk);
> +		if (ret < 0)
> +			return ret;
> +
> +		st->fclk = clk_get_rate(st->mclk);
> +		if (!ad7192_valid_external_frequency(st->fclk))
> +			return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>  static int ad7192_probe(struct spi_device *spi)
>  {
>  	const struct ad7192_platform_data *pdata = dev_get_platdata(&spi->dev);
> @@ -672,6 +691,10 @@ static int ad7192_probe(struct spi_device *spi)
>  		goto error_disable_avdd;
>  	}
>  
> +	ret = ad7192_clock_select(spi, st);
> +	if (ret < 0)
> +		goto error_clk_disable_unprepare;
> +
>  	voltage_uv = regulator_get_voltage(st->avdd);
>  
>  	if (pdata->vref_mv)
> @@ -720,6 +743,8 @@ static int ad7192_probe(struct spi_device *spi)
>  
>  error_remove_trigger:
>  	ad_sd_cleanup_buffer_and_trigger(indio_dev);
> +error_clk_disable_unprepare:
> +	clk_disable_unprepare(st->mclk);
>  error_disable_dvdd:
>  	regulator_disable(st->dvdd);
>  error_disable_avdd:
> @@ -735,6 +760,7 @@ static int ad7192_remove(struct spi_device *spi)
>  
>  	iio_device_unregister(indio_dev);
>  	ad_sd_cleanup_buffer_and_trigger(indio_dev);
> +	clk_disable_unprepare(st->mclk);
>  
>  	regulator_disable(st->dvdd);
>  	regulator_disable(st->avdd);
> diff --git a/drivers/staging/iio/adc/ad7192.h b/drivers/staging/iio/adc/ad7192.h
> index 7433a43c2611..3be3ee269ed5 100644
> --- a/drivers/staging/iio/adc/ad7192.h
> +++ b/drivers/staging/iio/adc/ad7192.h
> @@ -33,8 +33,6 @@
>  
>  struct ad7192_platform_data {
>  	u16		vref_mv;
> -	u8		clock_source_sel;
> -	u32		ext_clk_hz;
>  	bool		refin2_en;
>  	bool		rej60_en;
>  	bool		sinc3_en;


       reply	other threads:[~2018-12-08 15:30 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20181206091052.7644-1-mircea.caprioru@analog.com>
2018-12-08 15:29 ` Jonathan Cameron [this message]
2018-12-14  1:39   ` [PATCH 1/2] staging: iio: adc: ad7192: Add clock for external clock reference Stephen Boyd
2018-12-16 10:07     ` Jonathan Cameron
2019-01-24 22:41       ` Stephen Boyd
2019-01-25  8:16         ` Alexandru Ardelean

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=20181208152954.596529f8@archlinux \
    --to=jic23@kernel.org \
    --cc=Michael.Hennerich@analog.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=knaack.h@gmx.de \
    --cc=lars@metafoo.de \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mircea.caprioru@analog.com \
    --cc=pmeerw@pmeerw.net \
    --cc=robh+dt@kernel.org \
    /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).