From 9920ed25eccc9b494926be5372ba745db83481ab Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 14 Aug 2018 13:23:17 +0200 Subject: drivers: iio: Update MODULE AUTHOR email address no functional changes Signed-off-by: Michael Hennerich Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5446.c | 2 +- drivers/iio/dac/ad5504.c | 2 +- drivers/iio/dac/ad5686.c | 2 +- drivers/iio/dac/ad5791.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/iio/dac') diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index fd26a4272fc5..c3426708b6b5 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -628,6 +628,6 @@ static void __exit ad5446_exit(void) } module_exit(ad5446_exit); -MODULE_AUTHOR("Michael Hennerich "); +MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c index d9037ea59168..0ae23a268017 100644 --- a/drivers/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c @@ -369,6 +369,6 @@ static struct spi_driver ad5504_driver = { }; module_spi_driver(ad5504_driver); -MODULE_AUTHOR("Michael Hennerich "); +MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 2ddbfc3fdbae..0e134b13967a 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -470,6 +470,6 @@ int ad5686_remove(struct device *dev) } EXPORT_SYMBOL_GPL(ad5686_remove); -MODULE_AUTHOR("Michael Hennerich "); +MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c index 7569bf6868c2..84ce5e6ecf3f 100644 --- a/drivers/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c @@ -467,6 +467,6 @@ static struct spi_driver ad5791_driver = { }; module_spi_driver(ad5791_driver); -MODULE_AUTHOR("Michael Hennerich "); +MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC"); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From fe8a5420749f5d1e1bd1be15942281bf1b6e3d4e Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sat, 11 Aug 2018 10:47:09 +0200 Subject: iio: dac: max517: avoid using CONFIG_PM_SLEEP This is already handled by SIMPLE_DEV_PM_OPS(). Signed-off-by: Marcus Folkesson Signed-off-by: Jonathan Cameron --- drivers/iio/dac/max517.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers/iio/dac') diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c index 1d853247a205..451d10e323cf 100644 --- a/drivers/iio/dac/max517.c +++ b/drivers/iio/dac/max517.c @@ -113,15 +113,14 @@ static int max517_write_raw(struct iio_dev *indio_dev, return ret; } -#ifdef CONFIG_PM_SLEEP -static int max517_suspend(struct device *dev) +static int __maybe_unused max517_suspend(struct device *dev) { u8 outbuf = COMMAND_PD; return i2c_master_send(to_i2c_client(dev), &outbuf, 1); } -static int max517_resume(struct device *dev) +static int __maybe_unused max517_resume(struct device *dev) { u8 outbuf = 0; @@ -129,10 +128,6 @@ static int max517_resume(struct device *dev) } static SIMPLE_DEV_PM_OPS(max517_pm_ops, max517_suspend, max517_resume); -#define MAX517_PM_OPS (&max517_pm_ops) -#else -#define MAX517_PM_OPS NULL -#endif static const struct iio_info max517_info = { .read_raw = max517_read_raw, @@ -229,7 +224,7 @@ MODULE_DEVICE_TABLE(i2c, max517_id); static struct i2c_driver max517_driver = { .driver = { .name = MAX517_DRV_NAME, - .pm = MAX517_PM_OPS, + .pm = &max517_pm_ops, }, .probe = max517_probe, .remove = max517_remove, -- cgit v1.2.3 From b6ec220c28268872cad624aa824463a52c50ed47 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sat, 11 Aug 2018 10:47:18 +0200 Subject: iio: dac: max5821: avoid using CONFIG_PM_SLEEP This is already handled by SIMPLE_DEV_PM_OPS(). Signed-off-by: Marcus Folkesson Signed-off-by: Jonathan Cameron --- drivers/iio/dac/max5821.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers/iio/dac') diff --git a/drivers/iio/dac/max5821.c b/drivers/iio/dac/max5821.c index d0ecc1fdd8fc..f0cf6903dcd2 100644 --- a/drivers/iio/dac/max5821.c +++ b/drivers/iio/dac/max5821.c @@ -270,8 +270,7 @@ static int max5821_write_raw(struct iio_dev *indio_dev, } } -#ifdef CONFIG_PM_SLEEP -static int max5821_suspend(struct device *dev) +static int __maybe_unused max5821_suspend(struct device *dev) { u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE, MAX5821_EXTENDED_DAC_A | @@ -281,7 +280,7 @@ static int max5821_suspend(struct device *dev) return i2c_master_send(to_i2c_client(dev), outbuf, 2); } -static int max5821_resume(struct device *dev) +static int __maybe_unused max5821_resume(struct device *dev) { u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE, MAX5821_EXTENDED_DAC_A | @@ -292,10 +291,6 @@ static int max5821_resume(struct device *dev) } static SIMPLE_DEV_PM_OPS(max5821_pm_ops, max5821_suspend, max5821_resume); -#define MAX5821_PM_OPS (&max5821_pm_ops) -#else -#define MAX5821_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ static const struct iio_info max5821_info = { .read_raw = max5821_read_raw, @@ -392,7 +387,7 @@ static struct i2c_driver max5821_driver = { .driver = { .name = "max5821", .of_match_table = max5821_of_match, - .pm = MAX5821_PM_OPS, + .pm = &max5821_pm_ops, }, .probe = max5821_probe, .remove = max5821_remove, -- cgit v1.2.3 From 1a5bc41a3d23745577fa26f1ee34d50c205e2926 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Sat, 11 Aug 2018 10:47:25 +0200 Subject: iio: dac: mcp4725: avoid using CONFIG_PM_SLEEP This is already handled by SIMPLE_DEV_PM_OPS(). Signed-off-by: Marcus Folkesson Signed-off-by: Jonathan Cameron --- drivers/iio/dac/mcp4725.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers/iio/dac') diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index 8b5aad4c32d9..6d71fd905e29 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -45,7 +45,7 @@ struct mcp4725_data { struct regulator *vref_reg; }; -static int mcp4725_suspend(struct device *dev) +static int __maybe_unused mcp4725_suspend(struct device *dev) { struct mcp4725_data *data = iio_priv(i2c_get_clientdata( to_i2c_client(dev))); @@ -58,7 +58,7 @@ static int mcp4725_suspend(struct device *dev) return i2c_master_send(data->client, outbuf, 2); } -static int mcp4725_resume(struct device *dev) +static int __maybe_unused mcp4725_resume(struct device *dev) { struct mcp4725_data *data = iio_priv(i2c_get_clientdata( to_i2c_client(dev))); @@ -71,13 +71,7 @@ static int mcp4725_resume(struct device *dev) return i2c_master_send(data->client, outbuf, 2); } - -#ifdef CONFIG_PM_SLEEP static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume); -#define MCP4725_PM_OPS (&mcp4725_pm_ops) -#else -#define MCP4725_PM_OPS NULL -#endif static ssize_t mcp4725_store_eeprom(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) @@ -547,7 +541,7 @@ static struct i2c_driver mcp4725_driver = { .driver = { .name = MCP4725_DRV_NAME, .of_match_table = of_match_ptr(mcp4725_of_match), - .pm = MCP4725_PM_OPS, + .pm = &mcp4725_pm_ops, }, .probe = mcp4725_probe, .remove = mcp4725_remove, -- cgit v1.2.3 From 3c4b0f4ddf462bd713ce53d1b95e782dcba5298e Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Mon, 20 Aug 2018 12:01:13 +0200 Subject: iio: dpot-dac: switch to SPDX license identifier Drop the boilerplate license text. Signed-off-by: Peter Rosin Signed-off-by: Jonathan Cameron --- drivers/iio/dac/dpot-dac.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/iio/dac') diff --git a/drivers/iio/dac/dpot-dac.c b/drivers/iio/dac/dpot-dac.c index aaa2103d7c2b..a791d0a09d3b 100644 --- a/drivers/iio/dac/dpot-dac.c +++ b/drivers/iio/dac/dpot-dac.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * IIO DAC emulation driver using a digital potentiometer * * Copyright (C) 2016 Axentia Technologies AB * * Author: Peter Rosin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ /* -- cgit v1.2.3 From 8316cebd1e59823872d10799ce91f67c7c06968e Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Tue, 21 Aug 2018 21:31:24 +0200 Subject: iio: dac: add support for ltc1660 LTC1665/LTC1660 is a 8/10-bit Digital-to-Analog Converter (DAC) with eight individual channels. Signed-off-by: Marcus Folkesson Signed-off-by: Jonathan Cameron --- drivers/iio/dac/Kconfig | 10 ++ drivers/iio/dac/Makefile | 1 + drivers/iio/dac/ltc1660.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 261 insertions(+) create mode 100644 drivers/iio/dac/ltc1660.c (limited to 'drivers/iio/dac') diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 80beb64e9e0c..bb2057fd1b6f 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -120,6 +120,16 @@ config AD5624R_SPI Say yes here to build support for Analog Devices AD5624R, AD5644R and AD5664R converters (DAC). This driver uses the common SPI interface. +config LTC1660 + tristate "Linear Technology LTC1660/LTC1665 DAC SPI driver" + depends on SPI + help + Say yes here to build support for Linear Technology + LTC1660 and LTC1665 Digital to Analog Converters. + + To compile this driver as a module, choose M here: the + module will be called ltc1660. + config LTC2632 tristate "Linear Technology LTC2632-12/10/8 DAC spi driver" depends on SPI diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index a1b37cf99441..2ac93cc4a389 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_CIO_DAC) += cio-dac.o obj-$(CONFIG_DPOT_DAC) += dpot-dac.o obj-$(CONFIG_DS4424) += ds4424.o obj-$(CONFIG_LPC18XX_DAC) += lpc18xx_dac.o +obj-$(CONFIG_LTC1660) += ltc1660.o obj-$(CONFIG_LTC2632) += ltc2632.o obj-$(CONFIG_M62332) += m62332.o obj-$(CONFIG_MAX517) += max517.o diff --git a/drivers/iio/dac/ltc1660.c b/drivers/iio/dac/ltc1660.c new file mode 100644 index 000000000000..10866838c72a --- /dev/null +++ b/drivers/iio/dac/ltc1660.c @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for Linear Technology LTC1665/LTC1660, 8 channels DAC + * + * Copyright (C) 2018 Marcus Folkesson + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define LTC1660_REG_WAKE 0x0 +#define LTC1660_REG_DAC_A 0x1 +#define LTC1660_REG_DAC_B 0x2 +#define LTC1660_REG_DAC_C 0x3 +#define LTC1660_REG_DAC_D 0x4 +#define LTC1660_REG_DAC_E 0x5 +#define LTC1660_REG_DAC_F 0x6 +#define LTC1660_REG_DAC_G 0x7 +#define LTC1660_REG_DAC_H 0x8 +#define LTC1660_REG_SLEEP 0xe + +#define LTC1660_NUM_CHANNELS 8 + +static const struct regmap_config ltc1660_regmap_config = { + .reg_bits = 4, + .val_bits = 12, +}; + +enum ltc1660_supported_device_ids { + ID_LTC1660, + ID_LTC1665, +}; + +struct ltc1660_priv { + struct spi_device *spi; + struct regmap *regmap; + struct regulator *vref_reg; + unsigned int value[LTC1660_NUM_CHANNELS]; + unsigned int vref_mv; +}; + +static int ltc1660_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + struct ltc1660_priv *priv = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + *val = priv->value[chan->channel]; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = regulator_get_voltage(priv->vref_reg); + if (*val < 0) { + dev_err(&priv->spi->dev, "failed to read vref regulator: %d\n", + *val); + return *val; + } + + /* Convert to mV */ + *val /= 1000; + *val2 = chan->scan_type.realbits; + return IIO_VAL_FRACTIONAL_LOG2; + default: + return -EINVAL; + } +} + +static int ltc1660_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct ltc1660_priv *priv = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (val2 != 0) + return -EINVAL; + + if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0)) + return -EINVAL; + + ret = regmap_write(priv->regmap, chan->channel, + (val << chan->scan_type.shift)); + if (!ret) + priv->value[chan->channel] = val; + + return ret; + default: + return -EINVAL; + } +} + +#define LTC1660_CHAN(chan, bits) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .channel = chan, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 16, \ + .shift = 12 - (bits), \ + }, \ +} + +#define LTC1660_OCTAL_CHANNELS(bits) { \ + LTC1660_CHAN(LTC1660_REG_DAC_A, bits), \ + LTC1660_CHAN(LTC1660_REG_DAC_B, bits), \ + LTC1660_CHAN(LTC1660_REG_DAC_C, bits), \ + LTC1660_CHAN(LTC1660_REG_DAC_D, bits), \ + LTC1660_CHAN(LTC1660_REG_DAC_E, bits), \ + LTC1660_CHAN(LTC1660_REG_DAC_F, bits), \ + LTC1660_CHAN(LTC1660_REG_DAC_G, bits), \ + LTC1660_CHAN(LTC1660_REG_DAC_H, bits), \ +} + +static const struct iio_chan_spec ltc1660_channels[][LTC1660_NUM_CHANNELS] = { + [ID_LTC1660] = LTC1660_OCTAL_CHANNELS(10), + [ID_LTC1665] = LTC1660_OCTAL_CHANNELS(8), +}; + +static const struct iio_info ltc1660_info = { + .read_raw = <c1660_read_raw, + .write_raw = <c1660_write_raw, +}; + +static int __maybe_unused ltc1660_suspend(struct device *dev) +{ + struct ltc1660_priv *priv = iio_priv(spi_get_drvdata( + to_spi_device(dev))); + return regmap_write(priv->regmap, LTC1660_REG_SLEEP, 0x00); +} + +static int __maybe_unused ltc1660_resume(struct device *dev) +{ + struct ltc1660_priv *priv = iio_priv(spi_get_drvdata( + to_spi_device(dev))); + return regmap_write(priv->regmap, LTC1660_REG_WAKE, 0x00); +} +static SIMPLE_DEV_PM_OPS(ltc1660_pm_ops, ltc1660_suspend, ltc1660_resume); + +static int ltc1660_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct ltc1660_priv *priv; + const struct spi_device_id *id = spi_get_device_id(spi); + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*priv)); + if (indio_dev == NULL) + return -ENOMEM; + + priv = iio_priv(indio_dev); + priv->regmap = devm_regmap_init_spi(spi, <c1660_regmap_config); + if (IS_ERR(priv->regmap)) { + dev_err(&spi->dev, "failed to register spi regmap %ld\n", + PTR_ERR(priv->regmap)); + return PTR_ERR(priv->regmap); + } + + priv->vref_reg = devm_regulator_get(&spi->dev, "vref"); + if (IS_ERR(priv->vref_reg)) { + dev_err(&spi->dev, "vref regulator not specified\n"); + return PTR_ERR(priv->vref_reg); + } + + ret = regulator_enable(priv->vref_reg); + if (ret) { + dev_err(&spi->dev, "failed to enable vref regulator: %d\n", + ret); + return ret; + } + + priv->spi = spi; + spi_set_drvdata(spi, indio_dev); + indio_dev->dev.parent = &spi->dev; + indio_dev->info = <c1660_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ltc1660_channels[id->driver_data]; + indio_dev->num_channels = LTC1660_NUM_CHANNELS; + indio_dev->name = id->name; + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&spi->dev, "failed to register iio device: %d\n", + ret); + goto error_disable_reg; + } + + return 0; + +error_disable_reg: + regulator_disable(priv->vref_reg); + + return ret; +} + +static int ltc1660_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ltc1660_priv *priv = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + regulator_disable(priv->vref_reg); + + return 0; +} + +static const struct of_device_id ltc1660_dt_ids[] = { + { .compatible = "lltc,ltc1660", .data = (void *)ID_LTC1660 }, + { .compatible = "lltc,ltc1665", .data = (void *)ID_LTC1665 }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ltc1660_dt_ids); + +static const struct spi_device_id ltc1660_id[] = { + {"ltc1660", ID_LTC1660}, + {"ltc1665", ID_LTC1665}, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(spi, ltc1660_id); + +static struct spi_driver ltc1660_driver = { + .driver = { + .name = "ltc1660", + .of_match_table = ltc1660_dt_ids, + .pm = <c1660_pm_ops, + }, + .probe = ltc1660_probe, + .remove = ltc1660_remove, + .id_table = ltc1660_id, +}; +module_spi_driver(ltc1660_driver); + +MODULE_AUTHOR("Marcus Folkesson "); +MODULE_DESCRIPTION("Linear Technology LTC1660/LTC1665 DAC"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 0833627fc3f757a0dca11e2a9c46c96335a900ee Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Fri, 24 Aug 2018 22:24:40 +0200 Subject: iio: dac: mcp4922: fix error handling in mcp4922_write_raw Do not try to write negative values and make sure that the write goes well. Signed-off-by: Marcus Folkesson Signed-off-by: Jonathan Cameron --- drivers/iio/dac/mcp4922.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/iio/dac') diff --git a/drivers/iio/dac/mcp4922.c b/drivers/iio/dac/mcp4922.c index bf9aa3fc0534..b5190d1dae8e 100644 --- a/drivers/iio/dac/mcp4922.c +++ b/drivers/iio/dac/mcp4922.c @@ -94,17 +94,22 @@ static int mcp4922_write_raw(struct iio_dev *indio_dev, long mask) { struct mcp4922_state *state = iio_priv(indio_dev); + int ret; if (val2 != 0) return -EINVAL; switch (mask) { case IIO_CHAN_INFO_RAW: - if (val > GENMASK(chan->scan_type.realbits-1, 0)) + if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0)) return -EINVAL; val <<= chan->scan_type.shift; - state->value[chan->channel] = val; - return mcp4922_spi_write(state, chan->channel, val); + + ret = mcp4922_spi_write(state, chan->channel, val); + if (!ret) + state->value[chan->channel] = val; + return ret; + default: return -EINVAL; } -- cgit v1.2.3 From 91d05d7639f388bbed90076299867e85e983f298 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Fri, 24 Aug 2018 22:24:59 +0200 Subject: iio: dac: ti-dac5571: provide of_match_table to driver Use the created list of of_device_id's as a match table. Signed-off-by: Marcus Folkesson Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ti-dac5571.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/iio/dac') diff --git a/drivers/iio/dac/ti-dac5571.c b/drivers/iio/dac/ti-dac5571.c index e39d1e901353..f6dcd8bce2b0 100644 --- a/drivers/iio/dac/ti-dac5571.c +++ b/drivers/iio/dac/ti-dac5571.c @@ -421,6 +421,7 @@ MODULE_DEVICE_TABLE(i2c, dac5571_id); static struct i2c_driver dac5571_driver = { .driver = { .name = "ti-dac5571", + .of_match_table = of_match_ptr(dac5571_of_id), }, .probe = dac5571_probe, .remove = dac5571_remove, -- cgit v1.2.3 From ff5059302642d349596a7ebc3282a978a78144bd Mon Sep 17 00:00:00 2001 From: Stefan Popa Date: Wed, 29 Aug 2018 17:58:42 +0300 Subject: iio: dac: ad5758: Add support for hard reset The ad5758 has a hardware reset active low input pin. This patch adds a devicetree entry for a reset GPIO and a new ad5758_reset() function. During initialization, it is checked if the reset property is specified and the the GPIO is being asserted, therefore the device will become active. When the reset function is called, if the gpio_reset var is set, then the GPIO will be toggled, otherwise a software reset is performed. Signed-off-by: Stefan Popa Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5758.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'drivers/iio/dac') diff --git a/drivers/iio/dac/ad5758.c b/drivers/iio/dac/ad5758.c index bd36333257af..ef41f12bf262 100644 --- a/drivers/iio/dac/ad5758.c +++ b/drivers/iio/dac/ad5758.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -108,6 +109,7 @@ struct ad5758_range { struct ad5758_state { struct spi_device *spi; struct mutex lock; + struct gpio_desc *gpio_reset; struct ad5758_range out_range; unsigned int dc_dc_mode; unsigned int dc_dc_ilim; @@ -474,6 +476,21 @@ static int ad5758_internal_buffers_en(struct ad5758_state *st, bool enable) AD5758_CAL_MEM_UNREFRESHED_MSK); } +static int ad5758_reset(struct ad5758_state *st) +{ + if (st->gpio_reset) { + gpiod_set_value(st->gpio_reset, 0); + usleep_range(100, 1000); + gpiod_set_value(st->gpio_reset, 1); + usleep_range(100, 1000); + + return 0; + } else { + /* Perform a software reset */ + return ad5758_soft_reset(st); + } +} + static int ad5758_reg_access(struct iio_dev *indio_dev, unsigned int reg, unsigned int writeval, @@ -768,13 +785,18 @@ static int ad5758_init(struct ad5758_state *st) { int regval, ret; + st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(st->gpio_reset)) + return PTR_ERR(st->gpio_reset); + /* Disable CRC checks */ ret = ad5758_crc_disable(st); if (ret < 0) return ret; - /* Perform a software reset */ - ret = ad5758_soft_reset(st); + /* Perform a reset */ + ret = ad5758_reset(st); if (ret < 0) return ret; -- cgit v1.2.3