ad9834 driver needs some default properties. Currently these parameters are provided through platform_data. This patch adds a function to create this pdata based on device-tree node. Signed-off-by: Gwenhael Goavec-Merou <gwenhael.goavec-merou@xxxxxxxxxxxxxx> --- Changes v1 -> v2: - use clock bindings for input clock (Lars-Peter Clausen) - provides a default value for freq0/1 and phase0/1 (Lars-Peter Clausen) --- drivers/staging/iio/frequency/ad9834.c | 71 +++++++++++++++++++++++++++++++++- drivers/staging/iio/frequency/ad9834.h | 1 + 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 6366216..24a3e84 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -18,6 +18,7 @@ #include <linux/err.h> #include <linux/module.h> #include <asm/div64.h> +#include <linux/clk.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -316,24 +317,76 @@ static const struct iio_info ad9833_info = { .driver_module = THIS_MODULE, }; +#if defined(CONFIG_OF) +static struct ad9834_platform_data *ad9834_parse_dt(struct spi_device *spi) +{ + struct ad9834_platform_data *pdata; + struct device_node *np = spi->dev.of_node; + + pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + pdata->freq0 = 134000; + of_property_read_u32(np, "freq0", &pdata->freq0); + + pdata->freq1 = 134000; + of_property_read_u32(np, "freq1", &pdata->freq1); + + pdata->phase0 = 0; + of_property_read_u16(np, "phase0", &pdata->phase0); + + pdata->phase1 = 0; + of_property_read_u16(np, "phase1", &pdata->phase1); + + pdata->en_div2 = of_property_read_bool(np, "en_div2"); + pdata->en_signbit_msb_out = of_property_read_bool(np, + "en_signbit_msb_out"); + + return pdata; +} +#else +static struct ad9834_platform_data *ad9834_parse_dt(struct spi_device *spi) +{ + return NULL; +} +#endif + static int ad9834_probe(struct spi_device *spi) { struct ad9834_platform_data *pdata = dev_get_platdata(&spi->dev); struct ad9834_state *st; struct iio_dev *indio_dev; struct regulator *reg; + struct clk *clk = NULL; int ret; + if (!pdata && spi->dev.of_node) { + pdata = ad9834_parse_dt(spi); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + } + if (!pdata) { dev_dbg(&spi->dev, "no platform data?\n"); return -ENODEV; } + if (!pdata->mclk) { + clk = devm_clk_get(&spi->dev, NULL); + if (IS_ERR(clk)) + return -EPROBE_DEFER; + + ret = clk_prepare_enable(clk); + if (ret < 0) + return ret; + } + reg = devm_regulator_get(&spi->dev, "vcc"); if (!IS_ERR(reg)) { ret = regulator_enable(reg); if (ret) - return ret; + goto error_disable_clk; } indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); @@ -343,7 +396,14 @@ static int ad9834_probe(struct spi_device *spi) } spi_set_drvdata(spi, indio_dev); st = iio_priv(indio_dev); - st->mclk = pdata->mclk; + + if (clk) { + st->clk = clk; + st->mclk = clk_get_rate(clk); + } else { + st->mclk = pdata->mclk; + } + st->spi = spi; st->devid = spi_get_device_id(spi)->driver_data; st->reg = reg; @@ -418,6 +478,9 @@ static int ad9834_probe(struct spi_device *spi) error_disable_reg: if (!IS_ERR(reg)) regulator_disable(reg); +error_disable_clk: + if (clk) + clk_disable_unprepare(clk); return ret; } @@ -428,6 +491,10 @@ static int ad9834_remove(struct spi_device *spi) struct ad9834_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); + + if (st->clk) + clk_disable_unprepare(st->clk); + if (!IS_ERR(st->reg)) regulator_disable(st->reg); diff --git a/drivers/staging/iio/frequency/ad9834.h b/drivers/staging/iio/frequency/ad9834.h index 40fdd5d..fd9cccf 100644 --- a/drivers/staging/iio/frequency/ad9834.h +++ b/drivers/staging/iio/frequency/ad9834.h @@ -53,6 +53,7 @@ struct ad9834_state { struct spi_device *spi; struct regulator *reg; + struct clk *clk; unsigned int mclk; unsigned short control; unsigned short devid; -- 2.9.3 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel