All of lore.kernel.org
 help / color / mirror / Atom feed
From: Linus Walleij <linus.walleij@linaro.org>
To: Jonathan Cameron <jic23@kernel.org>,
	linux-iio@vger.kernel.org, Akinobu Mita <akinobu.mita@gmail.com>,
	"H. Nikolaus Schaller" <hns@goldelico.com>,
	Matt Ranostay <mranostay@gmail.com>,
	Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Cc: Christoph Mair <christoph.mair@gmail.com>,
	Vlad Dogaru <vlad.dogaru@intel.com>,
	Hartmut Knaack <knaack.h@gmx.de>,
	Marek Belisko <marek@goldelico.com>,
	Eric Andersson <eric.andersson@unixphere.com>,
	Neil Brown <neilb@suse.de>,
	Linus Walleij <linus.walleij@linaro.org>
Subject: [PATCH 08/10 v4] iio: pressure: bmp280: add support for BMP085 EOC interrupt
Date: Thu, 30 Jun 2016 03:48:52 +0200	[thread overview]
Message-ID: <1467251334-30594-9-git-send-email-linus.walleij@linaro.org> (raw)
In-Reply-To: <1467251334-30594-1-git-send-email-linus.walleij@linaro.org>

The first version of this sensor, BMP085, supports sending an
End-of-Conversion (EOC) interrupt. Add code to support this using
a completion, in a similar vein as drivers/misc/bmp085.c does.

Make sure to check that we are given a rising edge, because the
EOC line goes from low-to-high when the conversion is ready.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v3->v4:
- Fix a few 058/085 typos
ChangeLog v2->v3:
- Fetch interrupt before registering IIO device
- Factor out a separate BMP058 IRQ fetch function
ChangeLog v1->v2:
- Fix spelling mistakes
- Rebase on all other stuff like changes in probe() etc
---
 drivers/iio/pressure/bmp280-core.c | 92 ++++++++++++++++++++++++++++++++++----
 drivers/iio/pressure/bmp280-i2c.c  |  3 +-
 drivers/iio/pressure/bmp280-spi.c  |  3 +-
 drivers/iio/pressure/bmp280.h      |  3 +-
 4 files changed, 89 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index 89ed608035f8..b2858fbc1049 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -27,6 +27,9 @@
 #include <linux/iio/sysfs.h>
 #include <linux/gpio/consumer.h>
 #include <linux/regulator/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h> /* For irq_get_irq_data() */
+#include <linux/completion.h>
 
 #include "bmp280.h"
 
@@ -34,6 +37,8 @@ struct bmp280_data {
 	struct device *dev;
 	struct mutex lock;
 	struct regmap *regmap;
+	struct completion done;
+	bool use_eoc;
 	const struct bmp280_chip_info *chip_info;
 	struct regulator *vddd;
 	struct regulator *vdda;
@@ -595,16 +600,32 @@ static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas)
 	unsigned int delay_us;
 	unsigned int ctrl;
 
+	if (data->use_eoc)
+		init_completion(&data->done);
+
 	ret = regmap_write(data->regmap, BMP280_REG_CTRL_MEAS, ctrl_meas);
 	if (ret)
 		return ret;
 
-	if (ctrl_meas == BMP180_MEAS_TEMP)
-		delay_us = 4500;
-	else
-		delay_us = conversion_time_max[data->oversampling_press];
-
-	usleep_range(delay_us, delay_us + 1000);
+	if (data->use_eoc) {
+		/*
+		 * If we have a completion interrupt, use it, wait up to
+		 * 100ms. The longest conversion time listed is 76.5 ms for
+		 * advanced resolution mode.
+		 */
+		ret = wait_for_completion_timeout(&data->done,
+						  1 + msecs_to_jiffies(100));
+		if (!ret)
+			dev_err(data->dev, "timeout waiting for completion\n");
+	} else {
+		if (ctrl_meas == BMP180_MEAS_TEMP)
+			delay_us = 4500;
+		else
+			delay_us =
+				conversion_time_max[data->oversampling_press];
+
+		usleep_range(delay_us, delay_us + 1000);
+	}
 
 	ret = regmap_read(data->regmap, BMP280_REG_CTRL_MEAS, &ctrl);
 	if (ret)
@@ -846,10 +867,51 @@ static const struct bmp280_chip_info bmp180_chip_info = {
 	.read_press = bmp180_read_press,
 };
 
+static irqreturn_t bmp085_eoc_irq(int irq, void *d)
+{
+	struct bmp280_data *data = d;
+
+	complete(&data->done);
+
+	return IRQ_HANDLED;
+}
+
+int bmp085_fetch_eoc_irq(struct device *dev,
+			 const char *name,
+			 int irq,
+			 struct bmp280_data *data)
+{
+	unsigned long irq_trig;
+	int ret;
+
+	irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq));
+	if (irq_trig != IRQF_TRIGGER_RISING) {
+		dev_err(dev, "non-rising trigger given for EOC interrupt, "
+			"trying to enforce it\n");
+		irq_trig = IRQF_TRIGGER_RISING;
+	}
+	ret = devm_request_threaded_irq(dev,
+			irq,
+			bmp085_eoc_irq,
+			NULL,
+			irq_trig,
+			name,
+			data);
+	if (ret) {
+		/* Bail out without IRQ but keep the driver in place */
+		dev_err(dev, "unable to request DRDY IRQ\n");
+		return 0;
+	}
+
+	data->use_eoc = true;
+	return 0;
+}
+
 int bmp280_common_probe(struct device *dev,
 			struct regmap *regmap,
 			unsigned int chip,
-			const char *name)
+			const char *name,
+			int irq)
 {
 	int ret;
 	struct iio_dev *indio_dev;
@@ -948,10 +1010,22 @@ int bmp280_common_probe(struct device *dev,
 
 	dev_set_drvdata(dev, data);
 
+	/*
+	 * Attempt to grab an optional EOC IRQ - only the BMP085 has this
+	 * however as it happens, the BMP085 shares the chip ID of BMP180
+	 * so we look for an IRQ if we have that.
+	 */
+	if (irq > 0 || (chip_id  == BMP180_CHIP_ID)) {
+		ret = bmp085_fetch_eoc_irq(dev, name, irq, data);
+		if (ret)
+			goto out_disable_vdda;
+	}
+
 	ret = devm_iio_device_register(dev, indio_dev);
-	if (ret)
+	if (ret) {
+		dev_err(dev, "unable to register IIO device\n");
 		goto out_disable_vdda;
-
+	}
 	return 0;
 
 out_disable_vdda:
diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c
index 7c70ee172bba..8cf8a900bdaa 100644
--- a/drivers/iio/pressure/bmp280-i2c.c
+++ b/drivers/iio/pressure/bmp280-i2c.c
@@ -33,7 +33,8 @@ static int bmp280_i2c_probe(struct i2c_client *client,
 	return bmp280_common_probe(&client->dev,
 				   regmap,
 				   id->driver_data,
-				   id->name);
+				   id->name,
+				   client->irq);
 }
 
 static int bmp280_i2c_remove(struct i2c_client *client)
diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c
index 216e64b682bf..cd365ba74b68 100644
--- a/drivers/iio/pressure/bmp280-spi.c
+++ b/drivers/iio/pressure/bmp280-spi.c
@@ -81,7 +81,8 @@ static int bmp280_spi_probe(struct spi_device *spi)
 	return bmp280_common_probe(&spi->dev,
 				   regmap,
 				   id->driver_data,
-				   id->name);
+				   id->name,
+				   spi->irq);
 }
 
 static int bmp280_spi_remove(struct spi_device *spi)
diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
index b9fc28ce9428..573334b8e93b 100644
--- a/drivers/iio/pressure/bmp280.h
+++ b/drivers/iio/pressure/bmp280.h
@@ -104,5 +104,6 @@ extern const struct regmap_config bmp280_regmap_config;
 int bmp280_common_probe(struct device *dev,
 			struct regmap *regmap,
 			unsigned int chip,
-			const char *name);
+			const char *name,
+			int irq);
 int bmp280_common_remove(struct device *dev);
-- 
2.4.11

  parent reply	other threads:[~2016-06-30  1:48 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-30  1:48 [PATCH 00/10] Improve the BMP280 driver v4 Linus Walleij
     [not found] ` <1467251334-30594-1-git-send-email-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-06-30  1:48   ` [PATCH 01/10 v4] iio: pressure: bmp280: augment DT bindings Linus Walleij
2016-06-30  1:48     ` Linus Walleij
     [not found]     ` <1467251334-30594-2-git-send-email-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-06-30 19:23       ` Jonathan Cameron
2016-06-30 19:23         ` Jonathan Cameron
2016-06-30  1:48 ` [PATCH 02/10 v4] iio: pressure: bmp280: support device tree initialization Linus Walleij
2016-06-30 19:24   ` Jonathan Cameron
2016-06-30  1:48 ` [PATCH 03/10 v4] iio: pressure: bmp280: add reset GPIO line handling Linus Walleij
2016-06-30 19:25   ` Jonathan Cameron
2016-06-30  1:48 ` [PATCH 04/10 v4] iio: pressure: bmp280: support supply regulators Linus Walleij
2016-06-30 19:30   ` Jonathan Cameron
2016-07-03  9:54     ` Jonathan Cameron
2016-06-30  1:48 ` [PATCH 05/10 v4] iio: pressure: bmp280: split driver in logical parts Linus Walleij
2016-07-03  9:59   ` Jonathan Cameron
2016-07-03 10:02     ` Jonathan Cameron
2016-06-30  1:48 ` [PATCH 06/10 v4] iio: pressure: bmp280: split off an I2C Kconfig entry Linus Walleij
2016-07-03 10:06   ` Jonathan Cameron
2016-07-03 10:07     ` Jonathan Cameron
2016-06-30  1:48 ` [PATCH 07/10 v4] iio: pressure: bmp280: add SPI interface driver Linus Walleij
2016-07-03 10:12   ` Jonathan Cameron
2016-06-30  1:48 ` Linus Walleij [this message]
2016-07-03 10:11   ` [PATCH 08/10 v4] iio: pressure: bmp280: add support for BMP085 EOC interrupt Jonathan Cameron
2016-07-03 10:35     ` Jonathan Cameron
2016-06-30  1:48 ` [PATCH 09/10 v4] iio: pressure: bmp280: add power management Linus Walleij
2016-07-03 10:21   ` Jonathan Cameron
2016-06-30  1:48 ` [PATCH 10/10 v4] iio: pressure: bmp280: read calibration data once Linus Walleij
2016-07-03 10:23   ` Jonathan Cameron
2016-07-05 13:37     ` Linus Walleij

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1467251334-30594-9-git-send-email-linus.walleij@linaro.org \
    --to=linus.walleij@linaro.org \
    --cc=akinobu.mita@gmail.com \
    --cc=christoph.mair@gmail.com \
    --cc=eric.andersson@unixphere.com \
    --cc=hns@goldelico.com \
    --cc=jic23@kernel.org \
    --cc=knaack.h@gmx.de \
    --cc=linux-iio@vger.kernel.org \
    --cc=marek@goldelico.com \
    --cc=mranostay@gmail.com \
    --cc=neilb@suse.de \
    --cc=pmeerw@pmeerw.net \
    --cc=vlad.dogaru@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.