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@xxxxxxxxxx> --- 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"); + 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; -- 2.17.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel