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.capri...@analog.com>
---
 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

Reply via email to