summaryrefslogtreecommitdiff
path: root/drivers/iio/adc/ad7476.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-06-07 10:45:08 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-06-07 10:45:08 -0700
commit80ef846e9909f22ccdc2a4a6d931266cecce8b2c (patch)
tree0dd29cff6e6b4ee38452fb73ad292203c3ddeabf /drivers/iio/adc/ad7476.c
parent081096d98bb23946f16215357b141c5616b234bf (diff)
parent77f55d1305c11fb729b88f2c3f7881ba0831fa6f (diff)
Merge tag 'staging-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging/IIO driver updates from Greg KH: "Here is the large set of staging and IIO driver changes for 5.8-rc1 Nothing major, but a lot of new IIO drivers are included in here, along with other core iio cleanups and changes. On the staging driver front, again, nothing noticable. No new deletions or additions, just a ton of tiny cleanups all over the tree done by a lot of different people. Most coding style, but many actual real fixes and cleanups that are nice to see. All of these have been in linux-next for a while with no reported issues" * tag 'staging-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (618 commits) staging: rtl8723bs: Use common packet header constants staging: sm750fb: Add names to proc_setBLANK args staging: most: usb: init return value in default path of switch/case expression staging: vchiq: Get rid of VCHIQ_SERVICE_OPENEND callback reason staging: vchiq: move vchiq_release_message() into vchiq staging: vchi: Get rid of C++ guards staging: vchi: Get rid of not implemented function declarations staging: vchi: Get rid of vchiq_status_to_vchi() staging: vchi: Get rid of vchi_service_set_option() staging: vchi: Merge vchi_msg_queue() into vchi_queue_kernel_message() staging: vchiq: Move copy callback handling into vchiq staging: vchi: Get rid of vchi_queue_user_message() staging: vchi: Get rid of vchi_service_destroy() staging: most: usb: use function sysfs_streq staging: most: usb: add missing put_device calls staging: most: usb: use correct error codes staging: most: usb: replace code to calculate array index staging: most: usb: don't use error path to exit function on success staging: most: usb: move allocation of URB out of critical section staging: most: usb: return 0 instead of variable ...
Diffstat (limited to 'drivers/iio/adc/ad7476.c')
-rw-r--r--drivers/iio/adc/ad7476.c59
1 files changed, 46 insertions, 13 deletions
diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c
index 76747488044b..4e816d714ad2 100644
--- a/drivers/iio/adc/ad7476.c
+++ b/drivers/iio/adc/ad7476.c
@@ -12,9 +12,11 @@
#include <linux/sysfs.h>
#include <linux/spi/spi.h>
#include <linux/regulator/consumer.h>
+#include <linux/gpio/consumer.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/bitops.h>
+#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@@ -27,6 +29,8 @@ struct ad7476_state;
struct ad7476_chip_info {
unsigned int int_vref_uv;
struct iio_chan_spec channel[2];
+ /* channels used when convst gpio is defined */
+ struct iio_chan_spec convst_channel[2];
void (*reset)(struct ad7476_state *);
};
@@ -34,6 +38,7 @@ struct ad7476_state {
struct spi_device *spi;
const struct ad7476_chip_info *chip_info;
struct regulator *reg;
+ struct gpio_desc *convst_gpio;
struct spi_transfer xfer;
struct spi_message msg;
/*
@@ -64,6 +69,17 @@ enum ad7476_supported_device_ids {
ID_ADS7868,
};
+static void ad7091_convst(struct ad7476_state *st)
+{
+ if (!st->convst_gpio)
+ return;
+
+ gpiod_set_value(st->convst_gpio, 0);
+ udelay(1); /* CONVST pulse width: 10 ns min */
+ gpiod_set_value(st->convst_gpio, 1);
+ udelay(1); /* Conversion time: 650 ns max */
+}
+
static irqreturn_t ad7476_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
@@ -71,6 +87,8 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p)
struct ad7476_state *st = iio_priv(indio_dev);
int b_sent;
+ ad7091_convst(st);
+
b_sent = spi_sync(st->spi, &st->msg);
if (b_sent < 0)
goto done;
@@ -93,6 +111,8 @@ static int ad7476_scan_direct(struct ad7476_state *st)
{
int ret;
+ ad7091_convst(st);
+
ret = spi_sync(st->spi, &st->msg);
if (ret)
return ret;
@@ -160,6 +180,8 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
#define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \
BIT(IIO_CHAN_INFO_RAW))
#define AD7091R_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), 0)
+#define AD7091R_CONVST_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), \
+ BIT(IIO_CHAN_INFO_RAW))
#define ADS786X_CHAN(bits) _AD7476_CHAN((bits), 12 - (bits), \
BIT(IIO_CHAN_INFO_RAW))
@@ -167,6 +189,8 @@ static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
[ID_AD7091R] = {
.channel[0] = AD7091R_CHAN(12),
.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
+ .convst_channel[0] = AD7091R_CONVST_CHAN(12),
+ .convst_channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
.reset = ad7091_reset,
},
[ID_AD7276] = {
@@ -232,6 +256,13 @@ static const struct iio_info ad7476_info = {
.read_raw = &ad7476_read_raw,
};
+static void ad7476_reg_disable(void *data)
+{
+ struct ad7476_state *st = data;
+
+ regulator_disable(st->reg);
+}
+
static int ad7476_probe(struct spi_device *spi)
{
struct ad7476_state *st;
@@ -254,6 +285,17 @@ static int ad7476_probe(struct spi_device *spi)
if (ret)
return ret;
+ ret = devm_add_action_or_reset(&spi->dev, ad7476_reg_disable,
+ st);
+ if (ret)
+ return ret;
+
+ st->convst_gpio = devm_gpiod_get_optional(&spi->dev,
+ "adi,conversion-start",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(st->convst_gpio))
+ return PTR_ERR(st->convst_gpio);
+
spi_set_drvdata(spi, indio_dev);
st->spi = spi;
@@ -266,6 +308,9 @@ static int ad7476_probe(struct spi_device *spi)
indio_dev->channels = st->chip_info->channel;
indio_dev->num_channels = 2;
indio_dev->info = &ad7476_info;
+
+ if (st->convst_gpio)
+ indio_dev->channels = st->chip_info->convst_channel;
/* Setup default message */
st->xfer.rx_buf = &st->data;
@@ -295,19 +340,8 @@ error_disable_reg:
return ret;
}
-static int ad7476_remove(struct spi_device *spi)
-{
- struct iio_dev *indio_dev = spi_get_drvdata(spi);
- struct ad7476_state *st = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- iio_triggered_buffer_cleanup(indio_dev);
- regulator_disable(st->reg);
-
- return 0;
-}
-
static const struct spi_device_id ad7476_id[] = {
+ {"ad7091", ID_AD7091R},
{"ad7091r", ID_AD7091R},
{"ad7273", ID_AD7277},
{"ad7274", ID_AD7276},
@@ -343,7 +377,6 @@ static struct spi_driver ad7476_driver = {
.name = "ad7476",
},
.probe = ad7476_probe,
- .remove = ad7476_remove,
.id_table = ad7476_id,
};
module_spi_driver(ad7476_driver);