All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] Improve the BMP280 driver v4
@ 2016-06-30  1:48 Linus Walleij
       [not found] ` <1467251334-30594-1-git-send-email-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
                   ` (9 more replies)
  0 siblings, 10 replies; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij

This version should finally deal with all complaints from
build robots and the last round of review comments.

Since reading calibration once seems to be most controversial
I moved it to the end of the series, so it can be applied up
to that point.

The first patch with the DT bindings can also be dropped if
the old one is already applied, just minor things anyway.

Linus Walleij (10):
  iio: pressure: bmp280: augment DT bindings
  iio: pressure: bmp280: support device tree initialization
  iio: pressure: bmp280: add reset GPIO line handling
  iio: pressure: bmp280: support supply regulators
  iio: pressure: bmp280: split driver in logical parts
  iio: pressure: bmp280: split off an I2C Kconfig entry
  iio: pressure: bmp280: add SPI interface driver
  iio: pressure: bmp280: add support for BMP085 EOC interrupt
  iio: pressure: bmp280: add power management
  iio: pressure: bmp280: read calibration data once

 .../devicetree/bindings/iio/pressure/bmp085.txt    |  15 +-
 drivers/iio/pressure/Kconfig                       |  28 +-
 drivers/iio/pressure/Makefile                      |   3 +
 drivers/iio/pressure/{bmp280.c => bmp280-core.c}   | 567 ++++++++++-----------
 drivers/iio/pressure/bmp280-i2c.c                  |  91 ++++
 drivers/iio/pressure/bmp280-regmap.c               |  84 +++
 drivers/iio/pressure/bmp280-spi.c                  | 125 +++++
 drivers/iio/pressure/bmp280.h                      | 112 ++++
 8 files changed, 730 insertions(+), 295 deletions(-)
 rename drivers/iio/pressure/{bmp280.c => bmp280-core.c} (73%)
 create mode 100644 drivers/iio/pressure/bmp280-i2c.c
 create mode 100644 drivers/iio/pressure/bmp280-regmap.c
 create mode 100644 drivers/iio/pressure/bmp280-spi.c
 create mode 100644 drivers/iio/pressure/bmp280.h

-- 
2.4.11


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/10 v4] iio: pressure: bmp280: augment DT bindings
  2016-06-30  1:48 [PATCH 00/10] Improve the BMP280 driver v4 Linus Walleij
@ 2016-06-30  1:48     ` Linus Walleij
  2016-06-30  1:48 ` [PATCH 02/10 v4] iio: pressure: bmp280: support device tree initialization Linus Walleij
                       ` (8 subsequent siblings)
  9 siblings, 0 replies; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio-u79uwXL29TY76Z2rM5mHXA, Akinobu Mita,
	H. Nikolaus Schaller, Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij,
	devicetree-u79uwXL29TY76Z2rM5mHXA

This adds standard device tree bindings for a reset GPIO line, and
the VDDD and VDDA power regulators.

Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
ChangeLog v3->v4:
- Just resending. If the old patch (in the tree) is good enough, just
  drop this.
ChangeLog v2->v3:
- None, just resending in case Jonathan prefers this binding doc
ChangeLog v1->v2:
- Order compatible string on single lines
- Add "bosch,bme280" for the new sensor from Matt
---
 Documentation/devicetree/bindings/iio/pressure/bmp085.txt | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iio/pressure/bmp085.txt b/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
index d7a6deb6b21e..c7198a03c906 100644
--- a/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
+++ b/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
@@ -1,7 +1,11 @@
-BMP085/BMP18x digital pressure sensors
+BMP085/BMP18x/BMP28x digital pressure sensors
 
 Required properties:
-- compatible: bosch,bmp085
+- compatible: must be one of:
+  "bosch,bmp085"
+  "bosch,bmp180"
+  "bosch,bmp280"
+  "bosch,bme280"
 
 Optional properties:
 - chip-id: configurable chip id for non-default chip revisions
@@ -10,6 +14,10 @@ Optional properties:
   value range is 0-3 with rising sensitivity.
 - interrupt-parent: should be the phandle for the interrupt controller
 - interrupts: interrupt mapping for IRQ
+- reset-gpios: a GPIO line handling reset of the sensor: as the line is
+  active low, it should be marked GPIO_ACTIVE_LOW (see gpio/gpio.txt)
+- vddd-supply: digital voltage regulator (see regulator/regulator.txt)
+- vdda-supply: analog voltage regulator (see regulator/regulator.txt)
 
 Example:
 
@@ -21,4 +29,7 @@ pressure@77 {
 	default-oversampling = <2>;
 	interrupt-parent = <&gpio0>;
 	interrupts = <25 IRQ_TYPE_EDGE_RISING>;
+	reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+	vddd-supply = <&foo>;
+	vdda-supply = <&bar>;
 };
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 01/10 v4] iio: pressure: bmp280: augment DT bindings
@ 2016-06-30  1:48     ` Linus Walleij
  0 siblings, 0 replies; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij, devicetree

This adds standard device tree bindings for a reset GPIO line, and
the VDDD and VDDA power regulators.

Cc: devicetree@vger.kernel.org
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v3->v4:
- Just resending. If the old patch (in the tree) is good enough, just
  drop this.
ChangeLog v2->v3:
- None, just resending in case Jonathan prefers this binding doc
ChangeLog v1->v2:
- Order compatible string on single lines
- Add "bosch,bme280" for the new sensor from Matt
---
 Documentation/devicetree/bindings/iio/pressure/bmp085.txt | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iio/pressure/bmp085.txt b/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
index d7a6deb6b21e..c7198a03c906 100644
--- a/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
+++ b/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
@@ -1,7 +1,11 @@
-BMP085/BMP18x digital pressure sensors
+BMP085/BMP18x/BMP28x digital pressure sensors
 
 Required properties:
-- compatible: bosch,bmp085
+- compatible: must be one of:
+  "bosch,bmp085"
+  "bosch,bmp180"
+  "bosch,bmp280"
+  "bosch,bme280"
 
 Optional properties:
 - chip-id: configurable chip id for non-default chip revisions
@@ -10,6 +14,10 @@ Optional properties:
   value range is 0-3 with rising sensitivity.
 - interrupt-parent: should be the phandle for the interrupt controller
 - interrupts: interrupt mapping for IRQ
+- reset-gpios: a GPIO line handling reset of the sensor: as the line is
+  active low, it should be marked GPIO_ACTIVE_LOW (see gpio/gpio.txt)
+- vddd-supply: digital voltage regulator (see regulator/regulator.txt)
+- vdda-supply: analog voltage regulator (see regulator/regulator.txt)
 
 Example:
 
@@ -21,4 +29,7 @@ pressure@77 {
 	default-oversampling = <2>;
 	interrupt-parent = <&gpio0>;
 	interrupts = <25 IRQ_TYPE_EDGE_RISING>;
+	reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+	vddd-supply = <&foo>;
+	vdda-supply = <&bar>;
 };
-- 
2.4.11


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 02/10 v4] iio: pressure: bmp280: support device tree initialization
  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 ` 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
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij

This adds device tree support to the BMP085, BMP180 and BMP280
pressure sensors. Tested on the Qualcomm APQ8060 Dragonboard:

iio:device1$ cat in_temp_input
26700
iio:device1$ cat in_pressure_input
99.185000000

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v3->v4:
- No real changes.
ChangeLog v2->v3:
- Terminate OF ID table properly with an { }
ChangeLog v1->v2:
- Fix some BMP085 misspelled as BMP058 errors.
- Add the new BME280 sensor as well
---
 drivers/iio/pressure/bmp280.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
index 1876b50cc84a..fa76f5851245 100644
--- a/drivers/iio/pressure/bmp280.c
+++ b/drivers/iio/pressure/bmp280.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/acpi.h>
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/delay.h>
 #include <linux/iio/iio.h>
@@ -1094,6 +1095,19 @@ static const struct acpi_device_id bmp280_acpi_match[] = {
 };
 MODULE_DEVICE_TABLE(acpi, bmp280_acpi_match);
 
+#ifdef CONFIG_OF
+static const struct of_device_id bmp280_of_match[] = {
+	{ .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID },
+	{ .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID },
+	{ .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID },
+	{ .compatible = "bosch,bmp085", .data = (void *)BMP180_CHIP_ID },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, bmp280_of_match);
+#else
+#define bmp280_of_match NULL
+#endif
+
 static const struct i2c_device_id bmp280_id[] = {
 	{"bmp280", BMP280_CHIP_ID },
 	{"bmp180", BMP180_CHIP_ID },
@@ -1107,6 +1121,7 @@ static struct i2c_driver bmp280_driver = {
 	.driver = {
 		.name	= "bmp280",
 		.acpi_match_table = ACPI_PTR(bmp280_acpi_match),
+		.of_match_table = of_match_ptr(bmp280_of_match),
 	},
 	.probe		= bmp280_probe,
 	.id_table	= bmp280_id,
-- 
2.4.11


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 03/10 v4] iio: pressure: bmp280: add reset GPIO line handling
  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 02/10 v4] iio: pressure: bmp280: support device tree initialization Linus Walleij
@ 2016-06-30  1:48 ` 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
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij

On the APQ8060 Dragonboard the reset line to the BMP085 pressure
sensor is not deasserted on boot, so the driver needs to handle
this. For a simple GPIO line supplied as a descriptor (from a board
file, device tree or ACPI) this does the trick.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v3->v4:
- Fix BMP058->BMP085 in commit message
ChangeLog v2->v3:
- None, just rebasing/resending
---
 drivers/iio/pressure/bmp280.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
index fa76f5851245..1618968f8889 100644
--- a/drivers/iio/pressure/bmp280.c
+++ b/drivers/iio/pressure/bmp280.c
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/gpio/consumer.h>
 
 /* BMP280 specific registers */
 #define BMP280_REG_HUMIDITY_LSB		0xFE
@@ -1024,6 +1025,7 @@ static int bmp280_probe(struct i2c_client *client,
 	struct iio_dev *indio_dev;
 	struct bmp280_data *data;
 	unsigned int chip_id;
+	struct gpio_desc *gpiod;
 
 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 	if (!indio_dev)
@@ -1063,6 +1065,14 @@ static int bmp280_probe(struct i2c_client *client,
 		return -EINVAL;
 	}
 
+	/* Bring chip out of reset if there is an assigned GPIO line */
+	gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+	/* Deassert the signal */
+	if (!IS_ERR(gpiod)) {
+		dev_info(&client->dev, "release reset\n");
+		gpiod_set_value(gpiod, 0);
+	}
+
 	data->regmap = devm_regmap_init_i2c(client,
 					data->chip_info->regmap_config);
 	if (IS_ERR(data->regmap)) {
-- 
2.4.11


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 04/10 v4] iio: pressure: bmp280: support supply regulators
  2016-06-30  1:48 [PATCH 00/10] Improve the BMP280 driver v4 Linus Walleij
                   ` (2 preceding siblings ...)
  2016-06-30  1:48 ` [PATCH 03/10 v4] iio: pressure: bmp280: add reset GPIO line handling Linus Walleij
@ 2016-06-30  1:48 ` Linus Walleij
  2016-06-30 19:30   ` Jonathan Cameron
  2016-06-30  1:48 ` [PATCH 05/10 v4] iio: pressure: bmp280: split driver in logical parts Linus Walleij
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij, Mark Brown

The BMP085/BMP180/BMP280 is supplied with two power sources:
VDDA (analog power) and VDDD (digital power). As these may come
from regulators (as on the APQ8060 Dragonboard) we need the driver
to attempt to fetch and enable these regulators.

We FAIL if we cannot: boards should either define:
- Proper regulators if present
- Define fixed regulators if power is hardwired to the component
- Rely on dummy regulators (will be present on all DT systems and
  any boardfile system that calls regulator_has_full_constraints().

Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v3->v4:
- Fix missing "regulator" string in enablement message.
- Fix BMP058->BMP085 in commit message
ChangeLog v2->v3:
- Encode a start-up time for each sensor type (from the datasheets)
  this is necessary when coldstarting the sensor with a regulator
  to be sure it is on before we try to use it.
- Introduce a try/catch-style set of goto clauses in the probe
  function to make sure the regulators are properly disabled.
ChangeLog v1->v2:
- Make the regulators non-optional: an optional supply is one you
  can choose not to supply ELECTRICALLY as in an internal charge
  pump taking its place or so.
- Bail out if not present and add some notices to the commit that
  boards need to think about their regulator usage.
- Make sure we disable the regulators, and introduce a .remove()
  call to do that if/when the module is removed.
---
 drivers/iio/pressure/bmp280.c | 64 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 60 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
index 1618968f8889..5245bc598187 100644
--- a/drivers/iio/pressure/bmp280.c
+++ b/drivers/iio/pressure/bmp280.c
@@ -24,6 +24,7 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
 
 /* BMP280 specific registers */
 #define BMP280_REG_HUMIDITY_LSB		0xFE
@@ -124,6 +125,9 @@ struct bmp280_data {
 	struct mutex lock;
 	struct regmap *regmap;
 	const struct bmp280_chip_info *chip_info;
+	struct regulator *vddd;
+	struct regulator *vdda;
+	unsigned int start_up_time; /* in milliseconds */
 
 	/* log of base 2 of oversampling rate */
 	u8 oversampling_press;
@@ -1047,12 +1051,14 @@ static int bmp280_probe(struct i2c_client *client,
 		data->chip_info = &bmp180_chip_info;
 		data->oversampling_press = ilog2(8);
 		data->oversampling_temp = ilog2(1);
+		data->start_up_time = 10;
 		break;
 	case BMP280_CHIP_ID:
 		indio_dev->num_channels = 2;
 		data->chip_info = &bmp280_chip_info;
 		data->oversampling_press = ilog2(16);
 		data->oversampling_temp = ilog2(2);
+		data->start_up_time = 2;
 		break;
 	case BME280_CHIP_ID:
 		indio_dev->num_channels = 3;
@@ -1060,11 +1066,37 @@ static int bmp280_probe(struct i2c_client *client,
 		data->oversampling_press = ilog2(16);
 		data->oversampling_humid = ilog2(16);
 		data->oversampling_temp = ilog2(2);
+		data->start_up_time = 2;
 		break;
 	default:
 		return -EINVAL;
 	}
 
+	/* Bring up regulators */
+	data->vddd = devm_regulator_get(&client->dev, "vddd");
+	if (IS_ERR(data->vddd)) {
+		dev_err(&client->dev, "failed to get VDDD regulator\n");
+		return PTR_ERR(data->vddd);
+	}
+	ret = regulator_enable(data->vddd);
+	if (ret) {
+		dev_err(&client->dev, "failed to enable VDDD regulator\n");
+		return ret;
+	}
+	data->vdda = devm_regulator_get(&client->dev, "vdda");
+	if (IS_ERR(data->vdda)) {
+		dev_err(&client->dev, "failed to get VDDA regulator\n");
+		ret = PTR_ERR(data->vddd);
+		goto out_disable_vddd;
+	}
+	ret = regulator_enable(data->vdda);
+	if (ret) {
+		dev_err(&client->dev, "failed to enable VDDA regulator\n");
+		goto out_disable_vddd;
+	}
+	/* Wait to make sure we started up properly */
+	mdelay(data->start_up_time);
+
 	/* Bring chip out of reset if there is an assigned GPIO line */
 	gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
 	/* Deassert the signal */
@@ -1077,7 +1109,8 @@ static int bmp280_probe(struct i2c_client *client,
 					data->chip_info->regmap_config);
 	if (IS_ERR(data->regmap)) {
 		dev_err(&client->dev, "failed to allocate register map\n");
-		return PTR_ERR(data->regmap);
+		ret = PTR_ERR(data->regmap);
+		goto out_disable_vdda;
 	}
 
 	ret = regmap_read(data->regmap, BMP280_REG_ID, &chip_id);
@@ -1086,14 +1119,36 @@ static int bmp280_probe(struct i2c_client *client,
 	if (chip_id != id->driver_data) {
 		dev_err(&client->dev, "bad chip id.  expected %x got %x\n",
 			BMP280_CHIP_ID, chip_id);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out_disable_vdda;
 	}
 
 	ret = data->chip_info->chip_config(data);
 	if (ret < 0)
-		return ret;
+		goto out_disable_vdda;
+
+	i2c_set_clientdata(client, data);
 
-	return devm_iio_device_register(&client->dev, indio_dev);
+	ret = devm_iio_device_register(&client->dev, indio_dev);
+	if (ret)
+		goto out_disable_vdda;
+
+	return 0;
+
+out_disable_vdda:
+	regulator_disable(data->vdda);
+out_disable_vddd:
+	regulator_disable(data->vddd);
+	return ret;
+}
+
+static int bmp280_remove(struct i2c_client *client)
+{
+	struct bmp280_data *data = i2c_get_clientdata(client);
+
+	regulator_disable(data->vdda);
+	regulator_disable(data->vddd);
+	return 0;
 }
 
 static const struct acpi_device_id bmp280_acpi_match[] = {
@@ -1134,6 +1189,7 @@ static struct i2c_driver bmp280_driver = {
 		.of_match_table = of_match_ptr(bmp280_of_match),
 	},
 	.probe		= bmp280_probe,
+	.remove		= bmp280_remove,
 	.id_table	= bmp280_id,
 };
 module_i2c_driver(bmp280_driver);
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 05/10 v4] iio: pressure: bmp280: split driver in logical parts
  2016-06-30  1:48 [PATCH 00/10] Improve the BMP280 driver v4 Linus Walleij
                   ` (3 preceding siblings ...)
  2016-06-30  1:48 ` [PATCH 04/10 v4] iio: pressure: bmp280: support supply regulators Linus Walleij
@ 2016-06-30  1:48 ` Linus Walleij
  2016-07-03  9:59   ` Jonathan Cameron
  2016-06-30  1:48 ` [PATCH 06/10 v4] iio: pressure: bmp280: split off an I2C Kconfig entry Linus Walleij
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij

This splits the BMP280 driver in three logical parts: the core driver
bmp280-core that only operated on a struct device * and a struct regmap *,
the regmap driver bmp280-regmap that can be shared between I2C and other
transports and the I2C module driver bmp280-i2c.

Cleverly bake all functionality into a single object bmp280.o so that
we still get the same module binary built for the device in the end,
without any fuzz exporting symbols to the left and right.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v3->v4:
- Preserve the MODULE_* macros in the bmp280-core.c file so as to
  avoid "module license 'unspecified' taints kernel" messages from
  the core module
- Rebase on other changes
ChangeLog v2->v3:
- Rebasing, hopefully remember to use -M when formatting patches
ChangeLog v1->v2:
- Rebased on top of Matt Ranostays BME280 with humidity sensor support
- Rebased on top of other changes to e.g. regulator handling
---
 drivers/iio/pressure/Makefile                    |   1 +
 drivers/iio/pressure/{bmp280.c => bmp280-core.c} | 309 +++--------------------
 drivers/iio/pressure/bmp280-i2c.c                |  89 +++++++
 drivers/iio/pressure/bmp280-regmap.c             |  81 ++++++
 drivers/iio/pressure/bmp280.h                    | 108 ++++++++
 5 files changed, 319 insertions(+), 269 deletions(-)
 rename drivers/iio/pressure/{bmp280.c => bmp280-core.c} (73%)
 create mode 100644 drivers/iio/pressure/bmp280-i2c.c
 create mode 100644 drivers/iio/pressure/bmp280-regmap.c
 create mode 100644 drivers/iio/pressure/bmp280.h

diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index 17d6e7afa1ff..2d98a7ff77a8 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -4,6 +4,7 @@
 
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_BMP280) += bmp280.o
+bmp280-objs := bmp280-core.o bmp280-regmap.o bmp280-i2c.o
 obj-$(CONFIG_HID_SENSOR_PRESS)   += hid-sensor-press.o
 obj-$(CONFIG_HP03) += hp03.o
 obj-$(CONFIG_MPL115) += mpl115.o
diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280-core.c
similarity index 73%
rename from drivers/iio/pressure/bmp280.c
rename to drivers/iio/pressure/bmp280-core.c
index 5245bc598187..af981b14b954 100644
--- a/drivers/iio/pressure/bmp280.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -15,10 +15,7 @@
 
 #define pr_fmt(fmt) "bmp280: " fmt
 
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/acpi.h>
-#include <linux/of.h>
+#include <linux/device.h>
 #include <linux/regmap.h>
 #include <linux/delay.h>
 #include <linux/iio/iio.h>
@@ -26,102 +23,10 @@
 #include <linux/gpio/consumer.h>
 #include <linux/regulator/consumer.h>
 
-/* BMP280 specific registers */
-#define BMP280_REG_HUMIDITY_LSB		0xFE
-#define BMP280_REG_HUMIDITY_MSB		0xFD
-#define BMP280_REG_TEMP_XLSB		0xFC
-#define BMP280_REG_TEMP_LSB		0xFB
-#define BMP280_REG_TEMP_MSB		0xFA
-#define BMP280_REG_PRESS_XLSB		0xF9
-#define BMP280_REG_PRESS_LSB		0xF8
-#define BMP280_REG_PRESS_MSB		0xF7
-
-#define BMP280_REG_CONFIG		0xF5
-#define BMP280_REG_CTRL_MEAS		0xF4
-#define BMP280_REG_STATUS		0xF3
-#define BMP280_REG_CTRL_HUMIDITY	0xF2
-
-/* Due to non linear mapping, and data sizes we can't do a bulk read */
-#define BMP280_REG_COMP_H1		0xA1
-#define BMP280_REG_COMP_H2		0xE1
-#define BMP280_REG_COMP_H3		0xE3
-#define BMP280_REG_COMP_H4		0xE4
-#define BMP280_REG_COMP_H5		0xE5
-#define BMP280_REG_COMP_H6		0xE7
-
-#define BMP280_REG_COMP_TEMP_START	0x88
-#define BMP280_COMP_TEMP_REG_COUNT	6
-
-#define BMP280_REG_COMP_PRESS_START	0x8E
-#define BMP280_COMP_PRESS_REG_COUNT	18
-
-#define BMP280_FILTER_MASK		(BIT(4) | BIT(3) | BIT(2))
-#define BMP280_FILTER_OFF		0
-#define BMP280_FILTER_2X		BIT(2)
-#define BMP280_FILTER_4X		BIT(3)
-#define BMP280_FILTER_8X		(BIT(3) | BIT(2))
-#define BMP280_FILTER_16X		BIT(4)
-
-#define BMP280_OSRS_HUMIDITY_MASK	(BIT(2) | BIT(1) | BIT(0))
-#define BMP280_OSRS_HUMIDITIY_X(osrs_h)	((osrs_h) << 0)
-#define BMP280_OSRS_HUMIDITY_SKIP	0
-#define BMP280_OSRS_HUMIDITY_1X		BMP280_OSRS_HUMIDITIY_X(1)
-#define BMP280_OSRS_HUMIDITY_2X		BMP280_OSRS_HUMIDITIY_X(2)
-#define BMP280_OSRS_HUMIDITY_4X		BMP280_OSRS_HUMIDITIY_X(3)
-#define BMP280_OSRS_HUMIDITY_8X		BMP280_OSRS_HUMIDITIY_X(4)
-#define BMP280_OSRS_HUMIDITY_16X	BMP280_OSRS_HUMIDITIY_X(5)
-
-#define BMP280_OSRS_TEMP_MASK		(BIT(7) | BIT(6) | BIT(5))
-#define BMP280_OSRS_TEMP_SKIP		0
-#define BMP280_OSRS_TEMP_X(osrs_t)	((osrs_t) << 5)
-#define BMP280_OSRS_TEMP_1X		BMP280_OSRS_TEMP_X(1)
-#define BMP280_OSRS_TEMP_2X		BMP280_OSRS_TEMP_X(2)
-#define BMP280_OSRS_TEMP_4X		BMP280_OSRS_TEMP_X(3)
-#define BMP280_OSRS_TEMP_8X		BMP280_OSRS_TEMP_X(4)
-#define BMP280_OSRS_TEMP_16X		BMP280_OSRS_TEMP_X(5)
-
-#define BMP280_OSRS_PRESS_MASK		(BIT(4) | BIT(3) | BIT(2))
-#define BMP280_OSRS_PRESS_SKIP		0
-#define BMP280_OSRS_PRESS_X(osrs_p)	((osrs_p) << 2)
-#define BMP280_OSRS_PRESS_1X		BMP280_OSRS_PRESS_X(1)
-#define BMP280_OSRS_PRESS_2X		BMP280_OSRS_PRESS_X(2)
-#define BMP280_OSRS_PRESS_4X		BMP280_OSRS_PRESS_X(3)
-#define BMP280_OSRS_PRESS_8X		BMP280_OSRS_PRESS_X(4)
-#define BMP280_OSRS_PRESS_16X		BMP280_OSRS_PRESS_X(5)
-
-#define BMP280_MODE_MASK		(BIT(1) | BIT(0))
-#define BMP280_MODE_SLEEP		0
-#define BMP280_MODE_FORCED		BIT(0)
-#define BMP280_MODE_NORMAL		(BIT(1) | BIT(0))
-
-/* BMP180 specific registers */
-#define BMP180_REG_OUT_XLSB		0xF8
-#define BMP180_REG_OUT_LSB		0xF7
-#define BMP180_REG_OUT_MSB		0xF6
-
-#define BMP180_REG_CALIB_START		0xAA
-#define BMP180_REG_CALIB_COUNT		22
-
-#define BMP180_MEAS_SCO			BIT(5)
-#define BMP180_MEAS_TEMP		(0x0E | BMP180_MEAS_SCO)
-#define BMP180_MEAS_PRESS_X(oss)	((oss) << 6 | 0x14 | BMP180_MEAS_SCO)
-#define BMP180_MEAS_PRESS_1X		BMP180_MEAS_PRESS_X(0)
-#define BMP180_MEAS_PRESS_2X		BMP180_MEAS_PRESS_X(1)
-#define BMP180_MEAS_PRESS_4X		BMP180_MEAS_PRESS_X(2)
-#define BMP180_MEAS_PRESS_8X		BMP180_MEAS_PRESS_X(3)
-
-/* BMP180 and BMP280 common registers */
-#define BMP280_REG_CTRL_MEAS		0xF4
-#define BMP280_REG_RESET		0xE0
-#define BMP280_REG_ID			0xD0
-
-#define BMP180_CHIP_ID			0x55
-#define BMP280_CHIP_ID			0x58
-#define BME280_CHIP_ID			0x60
-#define BMP280_SOFT_RESET_VAL		0xB6
+#include "bmp280.h"
 
 struct bmp280_data {
-	struct i2c_client *client;
+	struct device *dev;
 	struct mutex lock;
 	struct regmap *regmap;
 	const struct bmp280_chip_info *chip_info;
@@ -142,8 +47,6 @@ struct bmp280_data {
 };
 
 struct bmp280_chip_info {
-	const struct regmap_config *regmap_config;
-
 	const int *oversampling_temp_avail;
 	int num_oversampling_temp_avail;
 
@@ -184,48 +87,6 @@ static const struct iio_chan_spec bmp280_channels[] = {
 	},
 };
 
-static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg)
-{
-	switch (reg) {
-	case BMP280_REG_CONFIG:
-	case BMP280_REG_CTRL_HUMIDITY:
-	case BMP280_REG_CTRL_MEAS:
-	case BMP280_REG_RESET:
-		return true;
-	default:
-		return false;
-	};
-}
-
-static bool bmp280_is_volatile_reg(struct device *dev, unsigned int reg)
-{
-	switch (reg) {
-	case BMP280_REG_HUMIDITY_LSB:
-	case BMP280_REG_HUMIDITY_MSB:
-	case BMP280_REG_TEMP_XLSB:
-	case BMP280_REG_TEMP_LSB:
-	case BMP280_REG_TEMP_MSB:
-	case BMP280_REG_PRESS_XLSB:
-	case BMP280_REG_PRESS_LSB:
-	case BMP280_REG_PRESS_MSB:
-	case BMP280_REG_STATUS:
-		return true;
-	default:
-		return false;
-	}
-}
-
-static const struct regmap_config bmp280_regmap_config = {
-	.reg_bits = 8,
-	.val_bits = 8,
-
-	.max_register = BMP280_REG_HUMIDITY_LSB,
-	.cache_type = REGCACHE_RBTREE,
-
-	.writeable_reg = bmp280_is_writeable_reg,
-	.volatile_reg = bmp280_is_volatile_reg,
-};
-
 /*
  * Returns humidity in percent, resolution is 0.01 percent. Output value of
  * "47445" represents 47445/1024 = 46.333 %RH.
@@ -236,7 +97,7 @@ static const struct regmap_config bmp280_regmap_config = {
 static u32 bmp280_compensate_humidity(struct bmp280_data *data,
 				      s32 adc_humidity)
 {
-	struct device *dev = &data->client->dev;
+	struct device *dev = data->dev;
 	unsigned int H1, H3, tmp;
 	int H2, H4, H5, H6, ret, var;
 
@@ -307,7 +168,7 @@ static s32 bmp280_compensate_temp(struct bmp280_data *data,
 	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START,
 			       buf, BMP280_COMP_TEMP_REG_COUNT);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"failed to read temperature calibration parameters\n");
 		return ret;
 	}
@@ -347,7 +208,7 @@ static u32 bmp280_compensate_press(struct bmp280_data *data,
 	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
 			       buf, BMP280_COMP_PRESS_REG_COUNT);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"failed to read pressure calibration parameters\n");
 		return ret;
 	}
@@ -382,7 +243,7 @@ static int bmp280_read_temp(struct bmp280_data *data,
 	ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB,
 			       (u8 *) &tmp, 3);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "failed to read temperature\n");
+		dev_err(data->dev, "failed to read temperature\n");
 		return ret;
 	}
 
@@ -417,7 +278,7 @@ static int bmp280_read_press(struct bmp280_data *data,
 	ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB,
 			       (u8 *) &tmp, 3);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "failed to read pressure\n");
+		dev_err(data->dev, "failed to read pressure\n");
 		return ret;
 	}
 
@@ -445,7 +306,7 @@ static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
 	ret = regmap_bulk_read(data->regmap, BMP280_REG_HUMIDITY_MSB,
 			       (u8 *) &tmp, 2);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "failed to read humidity\n");
+		dev_err(data->dev, "failed to read humidity\n");
 		return ret;
 	}
 
@@ -663,7 +524,7 @@ static int bmp280_chip_config(struct bmp280_data *data)
 				 BMP280_MODE_MASK,
 				 osrs | BMP280_MODE_NORMAL);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"failed to write ctrl_meas register\n");
 		return ret;
 	}
@@ -672,7 +533,7 @@ static int bmp280_chip_config(struct bmp280_data *data)
 				 BMP280_FILTER_MASK,
 				 BMP280_FILTER_4X);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"failed to write config register\n");
 		return ret;
 	}
@@ -683,8 +544,6 @@ static int bmp280_chip_config(struct bmp280_data *data)
 static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 };
 
 static const struct bmp280_chip_info bmp280_chip_info = {
-	.regmap_config = &bmp280_regmap_config,
-
 	.oversampling_temp_avail = bmp280_oversampling_avail,
 	.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
 
@@ -709,8 +568,6 @@ static int bme280_chip_config(struct bmp280_data *data)
 }
 
 static const struct bmp280_chip_info bme280_chip_info = {
-	.regmap_config = &bmp280_regmap_config,
-
 	.oversampling_temp_avail = bmp280_oversampling_avail,
 	.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
 
@@ -726,42 +583,6 @@ static const struct bmp280_chip_info bme280_chip_info = {
 	.read_humid = bmp280_read_humid,
 };
 
-
-static bool bmp180_is_writeable_reg(struct device *dev, unsigned int reg)
-{
-	switch (reg) {
-	case BMP280_REG_CTRL_MEAS:
-	case BMP280_REG_RESET:
-		return true;
-	default:
-		return false;
-	};
-}
-
-static bool bmp180_is_volatile_reg(struct device *dev, unsigned int reg)
-{
-	switch (reg) {
-	case BMP180_REG_OUT_XLSB:
-	case BMP180_REG_OUT_LSB:
-	case BMP180_REG_OUT_MSB:
-	case BMP280_REG_CTRL_MEAS:
-		return true;
-	default:
-		return false;
-	}
-}
-
-static const struct regmap_config bmp180_regmap_config = {
-	.reg_bits = 8,
-	.val_bits = 8,
-
-	.max_register = BMP180_REG_OUT_XLSB,
-	.cache_type = REGCACHE_RBTREE,
-
-	.writeable_reg = bmp180_is_writeable_reg,
-	.volatile_reg = bmp180_is_volatile_reg,
-};
-
 static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas)
 {
 	int ret;
@@ -877,7 +698,7 @@ static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp)
 
 	ret = bmp180_read_calib(data, &calib);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"failed to read calibration coefficients\n");
 		return ret;
 	}
@@ -947,7 +768,7 @@ static u32 bmp180_compensate_press(struct bmp280_data *data, s32 adc_press)
 
 	ret = bmp180_read_calib(data, &calib);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"failed to read calibration coefficients\n");
 		return ret;
 	}
@@ -1007,8 +828,6 @@ static const int bmp180_oversampling_temp_avail[] = { 1 };
 static const int bmp180_oversampling_press_avail[] = { 1, 2, 4, 8 };
 
 static const struct bmp280_chip_info bmp180_chip_info = {
-	.regmap_config = &bmp180_regmap_config,
-
 	.oversampling_temp_avail = bmp180_oversampling_temp_avail,
 	.num_oversampling_temp_avail =
 		ARRAY_SIZE(bmp180_oversampling_temp_avail),
@@ -1022,8 +841,10 @@ static const struct bmp280_chip_info bmp180_chip_info = {
 	.read_press = bmp180_read_press,
 };
 
-static int bmp280_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+int bmp280_common_probe(struct device *dev,
+			struct regmap *regmap,
+			unsigned int chip,
+			const char *name)
 {
 	int ret;
 	struct iio_dev *indio_dev;
@@ -1031,21 +852,21 @@ static int bmp280_probe(struct i2c_client *client,
 	unsigned int chip_id;
 	struct gpio_desc *gpiod;
 
-	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
 	if (!indio_dev)
 		return -ENOMEM;
 
 	data = iio_priv(indio_dev);
 	mutex_init(&data->lock);
-	data->client = client;
+	data->dev = dev;
 
-	indio_dev->dev.parent = &client->dev;
-	indio_dev->name = id->name;
+	indio_dev->dev.parent = dev;
+	indio_dev->name = name;
 	indio_dev->channels = bmp280_channels;
 	indio_dev->info = &bmp280_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	switch (id->driver_data) {
+	switch (chip) {
 	case BMP180_CHIP_ID:
 		indio_dev->num_channels = 2;
 		data->chip_info = &bmp180_chip_info;
@@ -1073,52 +894,45 @@ static int bmp280_probe(struct i2c_client *client,
 	}
 
 	/* Bring up regulators */
-	data->vddd = devm_regulator_get(&client->dev, "vddd");
+	data->vddd = devm_regulator_get(dev, "vddd");
 	if (IS_ERR(data->vddd)) {
-		dev_err(&client->dev, "failed to get VDDD regulator\n");
+		dev_err(dev, "failed to get VDDD regulator\n");
 		return PTR_ERR(data->vddd);
 	}
 	ret = regulator_enable(data->vddd);
 	if (ret) {
-		dev_err(&client->dev, "failed to enable VDDD regulator\n");
+		dev_err(dev, "failed to enable VDDD regulator\n");
 		return ret;
 	}
-	data->vdda = devm_regulator_get(&client->dev, "vdda");
+	data->vdda = devm_regulator_get(dev, "vdda");
 	if (IS_ERR(data->vdda)) {
-		dev_err(&client->dev, "failed to get VDDA regulator\n");
+		dev_err(dev, "failed to get VDDA regulator\n");
 		ret = PTR_ERR(data->vddd);
 		goto out_disable_vddd;
 	}
 	ret = regulator_enable(data->vdda);
 	if (ret) {
-		dev_err(&client->dev, "failed to enable VDDA regulator\n");
+		dev_err(dev, "failed to enable VDDA regulator\n");
 		goto out_disable_vddd;
 	}
 	/* Wait to make sure we started up properly */
 	mdelay(data->start_up_time);
 
 	/* Bring chip out of reset if there is an assigned GPIO line */
-	gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+	gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
 	/* Deassert the signal */
 	if (!IS_ERR(gpiod)) {
-		dev_info(&client->dev, "release reset\n");
+		dev_info(dev, "release reset\n");
 		gpiod_set_value(gpiod, 0);
 	}
 
-	data->regmap = devm_regmap_init_i2c(client,
-					data->chip_info->regmap_config);
-	if (IS_ERR(data->regmap)) {
-		dev_err(&client->dev, "failed to allocate register map\n");
-		ret = PTR_ERR(data->regmap);
-		goto out_disable_vdda;
-	}
-
-	ret = regmap_read(data->regmap, BMP280_REG_ID, &chip_id);
+	data->regmap = regmap;
+	ret = regmap_read(regmap, BMP280_REG_ID, &chip_id);
 	if (ret < 0)
-		return ret;
-	if (chip_id != id->driver_data) {
-		dev_err(&client->dev, "bad chip id.  expected %x got %x\n",
-			BMP280_CHIP_ID, chip_id);
+		goto out_disable_vdda;
+	if (chip_id != chip) {
+		dev_err(dev, "bad chip id: expected %x got %x\n",
+			chip, chip_id);
 		ret = -EINVAL;
 		goto out_disable_vdda;
 	}
@@ -1127,9 +941,9 @@ static int bmp280_probe(struct i2c_client *client,
 	if (ret < 0)
 		goto out_disable_vdda;
 
-	i2c_set_clientdata(client, data);
+	dev_set_drvdata(dev, data);
 
-	ret = devm_iio_device_register(&client->dev, indio_dev);
+	ret = devm_iio_device_register(dev, indio_dev);
 	if (ret)
 		goto out_disable_vdda;
 
@@ -1142,58 +956,15 @@ out_disable_vddd:
 	return ret;
 }
 
-static int bmp280_remove(struct i2c_client *client)
+int bmp280_common_remove(struct device *dev)
 {
-	struct bmp280_data *data = i2c_get_clientdata(client);
+	struct bmp280_data *data = dev_get_drvdata(dev);
 
 	regulator_disable(data->vdda);
 	regulator_disable(data->vddd);
 	return 0;
 }
 
-static const struct acpi_device_id bmp280_acpi_match[] = {
-	{"BMP0280", BMP280_CHIP_ID },
-	{"BMP0180", BMP180_CHIP_ID },
-	{"BMP0085", BMP180_CHIP_ID },
-	{"BME0280", BME280_CHIP_ID },
-	{ },
-};
-MODULE_DEVICE_TABLE(acpi, bmp280_acpi_match);
-
-#ifdef CONFIG_OF
-static const struct of_device_id bmp280_of_match[] = {
-	{ .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID },
-	{ .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID },
-	{ .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID },
-	{ .compatible = "bosch,bmp085", .data = (void *)BMP180_CHIP_ID },
-	{ },
-};
-MODULE_DEVICE_TABLE(of, bmp280_of_match);
-#else
-#define bmp280_of_match NULL
-#endif
-
-static const struct i2c_device_id bmp280_id[] = {
-	{"bmp280", BMP280_CHIP_ID },
-	{"bmp180", BMP180_CHIP_ID },
-	{"bmp085", BMP180_CHIP_ID },
-	{"bme280", BME280_CHIP_ID },
-	{ },
-};
-MODULE_DEVICE_TABLE(i2c, bmp280_id);
-
-static struct i2c_driver bmp280_driver = {
-	.driver = {
-		.name	= "bmp280",
-		.acpi_match_table = ACPI_PTR(bmp280_acpi_match),
-		.of_match_table = of_match_ptr(bmp280_of_match),
-	},
-	.probe		= bmp280_probe,
-	.remove		= bmp280_remove,
-	.id_table	= bmp280_id,
-};
-module_i2c_driver(bmp280_driver);
-
 MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
 MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c
new file mode 100644
index 000000000000..7c70ee172bba
--- /dev/null
+++ b/drivers/iio/pressure/bmp280-i2c.c
@@ -0,0 +1,89 @@
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/acpi.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+#include "bmp280.h"
+
+static int bmp280_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	struct regmap *regmap;
+	const struct regmap_config *regmap_config;
+
+	switch (id->driver_data) {
+	case BMP180_CHIP_ID:
+		regmap_config = &bmp180_regmap_config;
+		break;
+	case BMP280_CHIP_ID:
+	case BME280_CHIP_ID:
+		regmap_config = &bmp280_regmap_config;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap = devm_regmap_init_i2c(client, regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(&client->dev, "failed to allocate register map\n");
+		return PTR_ERR(regmap);
+	}
+
+	return bmp280_common_probe(&client->dev,
+				   regmap,
+				   id->driver_data,
+				   id->name);
+}
+
+static int bmp280_i2c_remove(struct i2c_client *client)
+{
+	return bmp280_common_remove(&client->dev);
+}
+
+static const struct acpi_device_id bmp280_acpi_i2c_match[] = {
+	{"BMP0280", BMP280_CHIP_ID },
+	{"BMP0180", BMP180_CHIP_ID },
+	{"BMP0085", BMP180_CHIP_ID },
+	{"BME0280", BME280_CHIP_ID },
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, bmp280_acpi_i2c_match);
+
+#ifdef CONFIG_OF
+static const struct of_device_id bmp280_of_i2c_match[] = {
+	{ .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID },
+	{ .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID },
+	{ .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID },
+	{ .compatible = "bosch,bmp085", .data = (void *)BMP180_CHIP_ID },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, bmp280_of_i2c_match);
+#else
+#define bmp280_of_i2c_match NULL
+#endif
+
+static const struct i2c_device_id bmp280_i2c_id[] = {
+	{"bmp280", BMP280_CHIP_ID },
+	{"bmp180", BMP180_CHIP_ID },
+	{"bmp085", BMP180_CHIP_ID },
+	{"bme280", BME280_CHIP_ID },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, bmp280_i2c_id);
+
+static struct i2c_driver bmp280_i2c_driver = {
+	.driver = {
+		.name	= "bmp280",
+		.acpi_match_table = ACPI_PTR(bmp280_acpi_i2c_match),
+		.of_match_table = of_match_ptr(bmp280_of_i2c_match),
+	},
+	.probe		= bmp280_i2c_probe,
+	.remove		= bmp280_i2c_remove,
+	.id_table	= bmp280_i2c_id,
+};
+module_i2c_driver(bmp280_i2c_driver);
+
+MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
+MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/pressure/bmp280-regmap.c b/drivers/iio/pressure/bmp280-regmap.c
new file mode 100644
index 000000000000..3341189d0975
--- /dev/null
+++ b/drivers/iio/pressure/bmp280-regmap.c
@@ -0,0 +1,81 @@
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+#include "bmp280.h"
+
+static bool bmp180_is_writeable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case BMP280_REG_CTRL_MEAS:
+	case BMP280_REG_RESET:
+		return true;
+	default:
+		return false;
+	};
+}
+
+static bool bmp180_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case BMP180_REG_OUT_XLSB:
+	case BMP180_REG_OUT_LSB:
+	case BMP180_REG_OUT_MSB:
+	case BMP280_REG_CTRL_MEAS:
+		return true;
+	default:
+		return false;
+	}
+}
+
+const struct regmap_config bmp180_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = BMP180_REG_OUT_XLSB,
+	.cache_type = REGCACHE_RBTREE,
+
+	.writeable_reg = bmp180_is_writeable_reg,
+	.volatile_reg = bmp180_is_volatile_reg,
+};
+
+static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case BMP280_REG_CONFIG:
+	case BMP280_REG_CTRL_HUMIDITY:
+	case BMP280_REG_CTRL_MEAS:
+	case BMP280_REG_RESET:
+		return true;
+	default:
+		return false;
+	};
+}
+
+static bool bmp280_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case BMP280_REG_HUMIDITY_LSB:
+	case BMP280_REG_HUMIDITY_MSB:
+	case BMP280_REG_TEMP_XLSB:
+	case BMP280_REG_TEMP_LSB:
+	case BMP280_REG_TEMP_MSB:
+	case BMP280_REG_PRESS_XLSB:
+	case BMP280_REG_PRESS_LSB:
+	case BMP280_REG_PRESS_MSB:
+	case BMP280_REG_STATUS:
+		return true;
+	default:
+		return false;
+	}
+}
+
+const struct regmap_config bmp280_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = BMP280_REG_HUMIDITY_LSB,
+	.cache_type = REGCACHE_RBTREE,
+
+	.writeable_reg = bmp280_is_writeable_reg,
+	.volatile_reg = bmp280_is_volatile_reg,
+};
diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
new file mode 100644
index 000000000000..b9fc28ce9428
--- /dev/null
+++ b/drivers/iio/pressure/bmp280.h
@@ -0,0 +1,108 @@
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+/* BMP280 specific registers */
+#define BMP280_REG_HUMIDITY_LSB		0xFE
+#define BMP280_REG_HUMIDITY_MSB		0xFD
+#define BMP280_REG_TEMP_XLSB		0xFC
+#define BMP280_REG_TEMP_LSB		0xFB
+#define BMP280_REG_TEMP_MSB		0xFA
+#define BMP280_REG_PRESS_XLSB		0xF9
+#define BMP280_REG_PRESS_LSB		0xF8
+#define BMP280_REG_PRESS_MSB		0xF7
+
+#define BMP280_REG_CONFIG		0xF5
+#define BMP280_REG_CTRL_MEAS		0xF4
+#define BMP280_REG_STATUS		0xF3
+#define BMP280_REG_CTRL_HUMIDITY	0xF2
+
+/* Due to non linear mapping, and data sizes we can't do a bulk read */
+#define BMP280_REG_COMP_H1		0xA1
+#define BMP280_REG_COMP_H2		0xE1
+#define BMP280_REG_COMP_H3		0xE3
+#define BMP280_REG_COMP_H4		0xE4
+#define BMP280_REG_COMP_H5		0xE5
+#define BMP280_REG_COMP_H6		0xE7
+
+#define BMP280_REG_COMP_TEMP_START	0x88
+#define BMP280_COMP_TEMP_REG_COUNT	6
+
+#define BMP280_REG_COMP_PRESS_START	0x8E
+#define BMP280_COMP_PRESS_REG_COUNT	18
+
+#define BMP280_FILTER_MASK		(BIT(4) | BIT(3) | BIT(2))
+#define BMP280_FILTER_OFF		0
+#define BMP280_FILTER_2X		BIT(2)
+#define BMP280_FILTER_4X		BIT(3)
+#define BMP280_FILTER_8X		(BIT(3) | BIT(2))
+#define BMP280_FILTER_16X		BIT(4)
+
+#define BMP280_OSRS_HUMIDITY_MASK	(BIT(2) | BIT(1) | BIT(0))
+#define BMP280_OSRS_HUMIDITIY_X(osrs_h)	((osrs_h) << 0)
+#define BMP280_OSRS_HUMIDITY_SKIP	0
+#define BMP280_OSRS_HUMIDITY_1X		BMP280_OSRS_HUMIDITIY_X(1)
+#define BMP280_OSRS_HUMIDITY_2X		BMP280_OSRS_HUMIDITIY_X(2)
+#define BMP280_OSRS_HUMIDITY_4X		BMP280_OSRS_HUMIDITIY_X(3)
+#define BMP280_OSRS_HUMIDITY_8X		BMP280_OSRS_HUMIDITIY_X(4)
+#define BMP280_OSRS_HUMIDITY_16X	BMP280_OSRS_HUMIDITIY_X(5)
+
+#define BMP280_OSRS_TEMP_MASK		(BIT(7) | BIT(6) | BIT(5))
+#define BMP280_OSRS_TEMP_SKIP		0
+#define BMP280_OSRS_TEMP_X(osrs_t)	((osrs_t) << 5)
+#define BMP280_OSRS_TEMP_1X		BMP280_OSRS_TEMP_X(1)
+#define BMP280_OSRS_TEMP_2X		BMP280_OSRS_TEMP_X(2)
+#define BMP280_OSRS_TEMP_4X		BMP280_OSRS_TEMP_X(3)
+#define BMP280_OSRS_TEMP_8X		BMP280_OSRS_TEMP_X(4)
+#define BMP280_OSRS_TEMP_16X		BMP280_OSRS_TEMP_X(5)
+
+#define BMP280_OSRS_PRESS_MASK		(BIT(4) | BIT(3) | BIT(2))
+#define BMP280_OSRS_PRESS_SKIP		0
+#define BMP280_OSRS_PRESS_X(osrs_p)	((osrs_p) << 2)
+#define BMP280_OSRS_PRESS_1X		BMP280_OSRS_PRESS_X(1)
+#define BMP280_OSRS_PRESS_2X		BMP280_OSRS_PRESS_X(2)
+#define BMP280_OSRS_PRESS_4X		BMP280_OSRS_PRESS_X(3)
+#define BMP280_OSRS_PRESS_8X		BMP280_OSRS_PRESS_X(4)
+#define BMP280_OSRS_PRESS_16X		BMP280_OSRS_PRESS_X(5)
+
+#define BMP280_MODE_MASK		(BIT(1) | BIT(0))
+#define BMP280_MODE_SLEEP		0
+#define BMP280_MODE_FORCED		BIT(0)
+#define BMP280_MODE_NORMAL		(BIT(1) | BIT(0))
+
+/* BMP180 specific registers */
+#define BMP180_REG_OUT_XLSB		0xF8
+#define BMP180_REG_OUT_LSB		0xF7
+#define BMP180_REG_OUT_MSB		0xF6
+
+#define BMP180_REG_CALIB_START		0xAA
+#define BMP180_REG_CALIB_COUNT		22
+
+#define BMP180_MEAS_SCO			BIT(5)
+#define BMP180_MEAS_TEMP		(0x0E | BMP180_MEAS_SCO)
+#define BMP180_MEAS_PRESS_X(oss)	((oss) << 6 | 0x14 | BMP180_MEAS_SCO)
+#define BMP180_MEAS_PRESS_1X		BMP180_MEAS_PRESS_X(0)
+#define BMP180_MEAS_PRESS_2X		BMP180_MEAS_PRESS_X(1)
+#define BMP180_MEAS_PRESS_4X		BMP180_MEAS_PRESS_X(2)
+#define BMP180_MEAS_PRESS_8X		BMP180_MEAS_PRESS_X(3)
+
+/* BMP180 and BMP280 common registers */
+#define BMP280_REG_CTRL_MEAS		0xF4
+#define BMP280_REG_RESET		0xE0
+#define BMP280_REG_ID			0xD0
+
+#define BMP180_CHIP_ID			0x55
+#define BMP280_CHIP_ID			0x58
+#define BME280_CHIP_ID			0x60
+#define BMP280_SOFT_RESET_VAL		0xB6
+
+/* Regmap configurations */
+extern const struct regmap_config bmp180_regmap_config;
+extern const struct regmap_config bmp280_regmap_config;
+
+/* Probe called from different transports */
+int bmp280_common_probe(struct device *dev,
+			struct regmap *regmap,
+			unsigned int chip,
+			const char *name);
+int bmp280_common_remove(struct device *dev);
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 06/10 v4] iio: pressure: bmp280: split off an I2C Kconfig entry
  2016-06-30  1:48 [PATCH 00/10] Improve the BMP280 driver v4 Linus Walleij
                   ` (4 preceding siblings ...)
  2016-06-30  1:48 ` [PATCH 05/10 v4] iio: pressure: bmp280: split driver in logical parts Linus Walleij
@ 2016-06-30  1:48 ` Linus Walleij
  2016-07-03 10:06   ` Jonathan Cameron
  2016-06-30  1:48 ` [PATCH 07/10 v4] iio: pressure: bmp280: add SPI interface driver Linus Walleij
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij

This creates a separate BMP280_I2C Kconfig entry that gets selected
by BMP280 for I2C transport. As we currently only support I2C
transport there is not much practical change other than getting
a separate object file (or module) for the I2C driver part. The
old Kconfig symbol BMP280 will still select the stuff we need so
that oldconfig and old defconfigs works fine.

Tested-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v3->v4:
- Rebase, no other changes.
ChangeLog v2->v3:
- Fix up Kconfig to put the dependencies to not use the old driver
  directly under the main driver instead of under the I2C part
- Export the common probe, remove and regmap symbols as the I2C driver part
  becomes its own module and need to find those symbols from the
  other parts.
ChangeLog v1->v2:
- None
---
 drivers/iio/pressure/Kconfig         | 17 ++++++++++++-----
 drivers/iio/pressure/Makefile        |  3 ++-
 drivers/iio/pressure/bmp280-core.c   |  3 +++
 drivers/iio/pressure/bmp280-regmap.c |  3 +++
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index 9125a9382b3e..851c4f5aec41 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -6,17 +6,24 @@
 menu "Pressure sensors"
 
 config BMP280
-	tristate "Bosch Sensortec BMP180 and BMP280 pressure sensor driver"
+	tristate "Bosch Sensortec BMP180/BMP280 pressure sensor I2C driver"
 	depends on I2C
 	depends on !(BMP085_I2C=y || BMP085_I2C=m)
-	select REGMAP_I2C
+	select REGMAP
+	select BMP280_I2C if (I2C)
 	help
 	  Say yes here to build support for Bosch Sensortec BMP180 and BMP280
 	  pressure and temperature sensors. Also supports the BE280 with
-	  an additional humidty sensor channel.
+	  an additional humidity sensor channel.
 
-	  To compile this driver as a module, choose M here: the module
-	  will be called bmp280.
+	  To compile this driver as a module, choose M here: the modules
+	  will be called bmp280-i2c and bmp280.
+
+config BMP280_I2C
+	tristate
+	depends on BMP280
+	depends on I2C
+	select REGMAP_I2C
 
 config HID_SENSOR_PRESS
 	depends on HID_SENSOR_HUB
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index 2d98a7ff77a8..736f4305fe46 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -4,7 +4,8 @@
 
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_BMP280) += bmp280.o
-bmp280-objs := bmp280-core.o bmp280-regmap.o bmp280-i2c.o
+bmp280-objs := bmp280-core.o bmp280-regmap.o
+obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o
 obj-$(CONFIG_HID_SENSOR_PRESS)   += hid-sensor-press.o
 obj-$(CONFIG_HP03) += hp03.o
 obj-$(CONFIG_MPL115) += mpl115.o
diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index af981b14b954..e11635d7139e 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -16,6 +16,7 @@
 #define pr_fmt(fmt) "bmp280: " fmt
 
 #include <linux/device.h>
+#include <linux/module.h>
 #include <linux/regmap.h>
 #include <linux/delay.h>
 #include <linux/iio/iio.h>
@@ -955,6 +956,7 @@ out_disable_vddd:
 	regulator_disable(data->vddd);
 	return ret;
 }
+EXPORT_SYMBOL(bmp280_common_probe);
 
 int bmp280_common_remove(struct device *dev)
 {
@@ -964,6 +966,7 @@ int bmp280_common_remove(struct device *dev)
 	regulator_disable(data->vddd);
 	return 0;
 }
+EXPORT_SYMBOL(bmp280_common_remove);
 
 MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
 MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor");
diff --git a/drivers/iio/pressure/bmp280-regmap.c b/drivers/iio/pressure/bmp280-regmap.c
index 3341189d0975..6807113ec09f 100644
--- a/drivers/iio/pressure/bmp280-regmap.c
+++ b/drivers/iio/pressure/bmp280-regmap.c
@@ -1,4 +1,5 @@
 #include <linux/device.h>
+#include <linux/module.h>
 #include <linux/regmap.h>
 
 #include "bmp280.h"
@@ -37,6 +38,7 @@ const struct regmap_config bmp180_regmap_config = {
 	.writeable_reg = bmp180_is_writeable_reg,
 	.volatile_reg = bmp180_is_volatile_reg,
 };
+EXPORT_SYMBOL(bmp180_regmap_config);
 
 static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg)
 {
@@ -79,3 +81,4 @@ const struct regmap_config bmp280_regmap_config = {
 	.writeable_reg = bmp280_is_writeable_reg,
 	.volatile_reg = bmp280_is_volatile_reg,
 };
+EXPORT_SYMBOL(bmp280_regmap_config);
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 07/10 v4] iio: pressure: bmp280: add SPI interface driver
  2016-06-30  1:48 [PATCH 00/10] Improve the BMP280 driver v4 Linus Walleij
                   ` (5 preceding siblings ...)
  2016-06-30  1:48 ` [PATCH 06/10 v4] iio: pressure: bmp280: split off an I2C Kconfig entry Linus Walleij
@ 2016-06-30  1:48 ` Linus Walleij
  2016-07-03 10:12   ` Jonathan Cameron
  2016-06-30  1:48 ` [PATCH 08/10 v4] iio: pressure: bmp280: add support for BMP085 EOC interrupt Linus Walleij
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij

This patch mimics the SPI functionality found in the misc driver in
drivers/misc/bh085-spi.c to make it possible to reuse the existing
BMP280/BMP180/BMP085 driver with all clients of the other driver.
The adoption is straight-forward since like the other driver, it is
a simple matter of using regmap.

This driver is also so obviously inspired/copied from the old misc
driver in drivers/misc/bmp085.c that I just took the liberty to
add in the authors of the other drivers + self in the core driver
file.

The MISC driver also supports a variant named "BMP181" so include
that here to be complete in comparison to the old driver.

The bus mapping code for SPI was written by Akinobu Mita.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Tested-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v3->v4:
- Fix some comma
- Fix a string BMP085->BMP280
ChangeLog v2->v3:
- Fix up some Kconfig warning mess by moving the deps of not
  using the old driver up to the main driver part
- Rebase and call the common remove() function.
ChangeLog v1->v2:
- Fix misnamed device table
- Added Akinobu's bus mapping code for SPI
- Add IDs and match strings for the new BME280 sensor too
---
 drivers/iio/pressure/Kconfig       |  15 ++++-
 drivers/iio/pressure/Makefile      |   1 +
 drivers/iio/pressure/bmp280-core.c |   4 ++
 drivers/iio/pressure/bmp280-spi.c  | 123 +++++++++++++++++++++++++++++++++++++
 4 files changed, 140 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iio/pressure/bmp280-spi.c

diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index 851c4f5aec41..aa1303ceb6a4 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -7,17 +7,20 @@ menu "Pressure sensors"
 
 config BMP280
 	tristate "Bosch Sensortec BMP180/BMP280 pressure sensor I2C driver"
-	depends on I2C
+	depends on (I2C || SPI_MASTER)
 	depends on !(BMP085_I2C=y || BMP085_I2C=m)
+	depends on !(BMP085_SPI=y || BMP085_SPI=m)
 	select REGMAP
 	select BMP280_I2C if (I2C)
+	select BMP280_SPI if (SPI_MASTER)
 	help
 	  Say yes here to build support for Bosch Sensortec BMP180 and BMP280
 	  pressure and temperature sensors. Also supports the BE280 with
 	  an additional humidity sensor channel.
 
-	  To compile this driver as a module, choose M here: the modules
-	  will be called bmp280-i2c and bmp280.
+	  To compile this driver as a module, choose M here: the core module
+	  will be called bmp280 and you will also get bmp280-i2c for I2C
+	  and/or bmp280-spi for SPI support.
 
 config BMP280_I2C
 	tristate
@@ -25,6 +28,12 @@ config BMP280_I2C
 	depends on I2C
 	select REGMAP_I2C
 
+config BMP280_SPI
+	tristate
+	depends on BMP280
+	depends on SPI_MASTER
+	select REGMAP
+
 config HID_SENSOR_PRESS
 	depends on HID_SENSOR_HUB
 	select IIO_BUFFER
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index 736f4305fe46..7f395bed5e88 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_BMP280) += bmp280.o
 bmp280-objs := bmp280-core.o bmp280-regmap.o
 obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o
+obj-$(CONFIG_BMP280_SPI) += bmp280-spi.o
 obj-$(CONFIG_HID_SENSOR_PRESS)   += hid-sensor-press.o
 obj-$(CONFIG_HP03) += hp03.o
 obj-$(CONFIG_MPL115) += mpl115.o
diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index e11635d7139e..89ed608035f8 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -1,5 +1,9 @@
 /*
+ * Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com>
+ * Copyright (c) 2012 Bosch Sensortec GmbH
+ * Copyright (c) 2012 Unixphere AB
  * Copyright (c) 2014 Intel Corporation
+ * Copyright (c) 2016 Linus Walleij <linus.walleij@linaro.org>
  *
  * Driver for Bosch Sensortec BMP180 and BMP280 digital pressure sensor.
  *
diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c
new file mode 100644
index 000000000000..216e64b682bf
--- /dev/null
+++ b/drivers/iio/pressure/bmp280-spi.c
@@ -0,0 +1,123 @@
+/*
+ * SPI interface for the BMP280 driver
+ *
+ * Inspired by the older BMP085 driver drivers/misc/bmp085-spi.c
+ */
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/err.h>
+#include <linux/regmap.h>
+
+#include "bmp280.h"
+
+static int bmp280_regmap_spi_write(void *context, const void *data,
+                                   size_t count)
+{
+	struct device *dev = context;
+	struct spi_device *spi = to_spi_device(dev);
+	u8 buf[2];
+
+	memcpy(buf, data, 2);
+	/*
+	 * The SPI register address (= full register address without bit 7) and
+	 * the write command (bit7 = RW = '0')
+	 */
+	buf[0] &= ~0x80;
+
+	return spi_write_then_read(spi, buf, 2, NULL, 0);
+}
+
+static int bmp280_regmap_spi_read(void *context, const void *reg,
+                                  size_t reg_size, void *val, size_t val_size)
+{
+	struct device *dev = context;
+	struct spi_device *spi = to_spi_device(dev);
+
+	return spi_write_then_read(spi, reg, reg_size, val, val_size);
+}
+
+static struct regmap_bus bmp280_regmap_bus = {
+	.write = bmp280_regmap_spi_write,
+	.read = bmp280_regmap_spi_read,
+	.reg_format_endian_default = REGMAP_ENDIAN_BIG,
+	.val_format_endian_default = REGMAP_ENDIAN_BIG,
+};
+
+static int bmp280_spi_probe(struct spi_device *spi)
+{
+	const struct spi_device_id *id = spi_get_device_id(spi);
+	struct regmap *regmap;
+	const struct regmap_config *regmap_config;
+	int ret;
+
+	spi->bits_per_word = 8;
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		dev_err(&spi->dev, "spi_setup failed!\n");
+		return ret;
+	}
+
+	switch (id->driver_data) {
+	case BMP180_CHIP_ID:
+		regmap_config = &bmp180_regmap_config;
+		break;
+	case BMP280_CHIP_ID:
+	case BME280_CHIP_ID:
+		regmap_config = &bmp280_regmap_config;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap = devm_regmap_init(&spi->dev,
+				  &bmp280_regmap_bus,
+				  &spi->dev,
+				  regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(&spi->dev, "failed to allocate register map\n");
+		return PTR_ERR(regmap);
+	}
+
+	return bmp280_common_probe(&spi->dev,
+				   regmap,
+				   id->driver_data,
+				   id->name);
+}
+
+static int bmp280_spi_remove(struct spi_device *spi)
+{
+	return bmp280_common_remove(&spi->dev);
+}
+
+static const struct of_device_id bmp280_of_spi_match[] = {
+	{ .compatible = "bosch,bmp085", },
+	{ .compatible = "bosch,bmp180", },
+	{ .compatible = "bosch,bmp181", },
+	{ .compatible = "bosch,bmp280", },
+	{ .compatible = "bosch,bme280", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, bmp280_of_spi_match);
+
+static const struct spi_device_id bmp280_spi_id[] = {
+	{ "bmp180", BMP180_CHIP_ID },
+	{ "bmp181", BMP180_CHIP_ID },
+	{ "bmp280", BMP280_CHIP_ID },
+	{ "bme280", BME280_CHIP_ID },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, bmp280_spi_id);
+
+static struct spi_driver bmp280_spi_driver = {
+	.driver = {
+		.name = "bmp280",
+		.of_match_table = bmp280_of_spi_match,
+	},
+	.id_table = bmp280_spi_id,
+	.probe = bmp280_spi_probe,
+	.remove = bmp280_spi_remove,
+};
+module_spi_driver(bmp280_spi_driver);
+
+MODULE_DESCRIPTION("BMP280 SPI bus driver");
+MODULE_LICENSE("GPL");
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 08/10 v4] iio: pressure: bmp280: add support for BMP085 EOC interrupt
  2016-06-30  1:48 [PATCH 00/10] Improve the BMP280 driver v4 Linus Walleij
                   ` (6 preceding siblings ...)
  2016-06-30  1:48 ` [PATCH 07/10 v4] iio: pressure: bmp280: add SPI interface driver Linus Walleij
@ 2016-06-30  1:48 ` Linus Walleij
  2016-07-03 10:11   ` Jonathan Cameron
  2016-06-30  1:48 ` [PATCH 09/10 v4] iio: pressure: bmp280: add power management Linus Walleij
  2016-06-30  1:48 ` [PATCH 10/10 v4] iio: pressure: bmp280: read calibration data once Linus Walleij
  9 siblings, 1 reply; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij

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

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 09/10 v4] iio: pressure: bmp280: add power management
  2016-06-30  1:48 [PATCH 00/10] Improve the BMP280 driver v4 Linus Walleij
                   ` (7 preceding siblings ...)
  2016-06-30  1:48 ` [PATCH 08/10 v4] iio: pressure: bmp280: add support for BMP085 EOC interrupt Linus Walleij
@ 2016-06-30  1:48 ` 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
  9 siblings, 1 reply; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij, Ulf Hansson

The PM280 has an internal standby-mode, but to really save power
we should shut the sensor down and disconnect the power. With
the proper .pm hooks we can enable both runtime and system power
management of the sensor. We use the *force callbacks from the
system PM hooks. When the sensor comes back we always reconfigure
it to make sure it is ready to roll as expected.

Cc: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v3->v4:
- Simplified return statments in runtime suspend/resume hooks.
- Move before calibration optimization patch so the controversial
  stuff is at the end of the series.
- Rebased, edit "runtime PM ops" to "PM ops"
ChangeLog v0->v3:
- New patch on top of the reworked patches: we can add runtime PM,
  so we should.
---
 drivers/iio/pressure/bmp280-core.c | 58 ++++++++++++++++++++++++++++++++++++++
 drivers/iio/pressure/bmp280-i2c.c  |  1 +
 drivers/iio/pressure/bmp280-spi.c  |  1 +
 drivers/iio/pressure/bmp280.h      |  3 ++
 4 files changed, 63 insertions(+)

diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index b2858fbc1049..e8f534240f2d 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -30,6 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h> /* For irq_get_irq_data() */
 #include <linux/completion.h>
+#include <linux/pm_runtime.h>
 
 #include "bmp280.h"
 
@@ -336,6 +337,7 @@ static int bmp280_read_raw(struct iio_dev *indio_dev,
 	int ret;
 	struct bmp280_data *data = iio_priv(indio_dev);
 
+	pm_runtime_get_sync(data->dev);
 	mutex_lock(&data->lock);
 
 	switch (mask) {
@@ -380,6 +382,8 @@ static int bmp280_read_raw(struct iio_dev *indio_dev,
 	}
 
 	mutex_unlock(&data->lock);
+	pm_runtime_mark_last_busy(data->dev);
+	pm_runtime_put_autosuspend(data->dev);
 
 	return ret;
 }
@@ -444,6 +448,7 @@ static int bmp280_write_raw(struct iio_dev *indio_dev,
 
 	switch (mask) {
 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		pm_runtime_get_sync(data->dev);
 		mutex_lock(&data->lock);
 		switch (chan->type) {
 		case IIO_HUMIDITYRELATIVE:
@@ -460,6 +465,8 @@ static int bmp280_write_raw(struct iio_dev *indio_dev,
 			break;
 		}
 		mutex_unlock(&data->lock);
+		pm_runtime_mark_last_busy(data->dev);
+		pm_runtime_put_autosuspend(data->dev);
 		break;
 	default:
 		return -EINVAL;
@@ -1026,6 +1033,18 @@ int bmp280_common_probe(struct device *dev,
 		dev_err(dev, "unable to register IIO device\n");
 		goto out_disable_vdda;
 	}
+
+	/* Enable runtime PM */
+	pm_runtime_get_noresume(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	/*
+	 * Set autosuspend to two orders of magnitude larger than the
+	 * start-up time.
+	 */
+	pm_runtime_set_autosuspend_delay(dev, data->start_up_time *100);
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_put(dev);
 	return 0;
 
 out_disable_vdda:
@@ -1040,12 +1059,51 @@ int bmp280_common_remove(struct device *dev)
 {
 	struct bmp280_data *data = dev_get_drvdata(dev);
 
+	pm_runtime_get_sync(data->dev);
+	pm_runtime_put_noidle(data->dev);
+	pm_runtime_disable(data->dev);
 	regulator_disable(data->vdda);
 	regulator_disable(data->vddd);
 	return 0;
 }
 EXPORT_SYMBOL(bmp280_common_remove);
 
+#ifdef CONFIG_PM
+static int bmp280_runtime_suspend(struct device *dev)
+{
+	struct bmp280_data *data = dev_get_drvdata(dev);
+	int ret;
+
+	ret = regulator_disable(data->vdda);
+	if (ret)
+		return ret;
+	return regulator_disable(data->vddd);
+}
+
+static int bmp280_runtime_resume(struct device *dev)
+{
+	struct bmp280_data *data = dev_get_drvdata(dev);
+	int ret;
+
+	ret = regulator_enable(data->vddd);
+	if (ret)
+		return ret;
+	ret = regulator_enable(data->vdda);
+	if (ret)
+		return ret;
+	msleep(data->start_up_time);
+	return data->chip_info->chip_config(data);
+}
+#endif /* CONFIG_PM */
+
+const struct dev_pm_ops bmp280_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+	SET_RUNTIME_PM_OPS(bmp280_runtime_suspend,
+			   bmp280_runtime_resume, NULL)
+};
+EXPORT_SYMBOL(bmp280_dev_pm_ops);
+
 MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
 MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c
index 8cf8a900bdaa..03742b15b72a 100644
--- a/drivers/iio/pressure/bmp280-i2c.c
+++ b/drivers/iio/pressure/bmp280-i2c.c
@@ -78,6 +78,7 @@ static struct i2c_driver bmp280_i2c_driver = {
 		.name	= "bmp280",
 		.acpi_match_table = ACPI_PTR(bmp280_acpi_i2c_match),
 		.of_match_table = of_match_ptr(bmp280_of_i2c_match),
+		.pm = &bmp280_dev_pm_ops,
 	},
 	.probe		= bmp280_i2c_probe,
 	.remove		= bmp280_i2c_remove,
diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c
index cd365ba74b68..17bc95586f9e 100644
--- a/drivers/iio/pressure/bmp280-spi.c
+++ b/drivers/iio/pressure/bmp280-spi.c
@@ -113,6 +113,7 @@ static struct spi_driver bmp280_spi_driver = {
 	.driver = {
 		.name = "bmp280",
 		.of_match_table = bmp280_of_spi_match,
+		.pm = &bmp280_dev_pm_ops,
 	},
 	.id_table = bmp280_spi_id,
 	.probe = bmp280_spi_probe,
diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
index 573334b8e93b..2c770e13be0e 100644
--- a/drivers/iio/pressure/bmp280.h
+++ b/drivers/iio/pressure/bmp280.h
@@ -107,3 +107,6 @@ int bmp280_common_probe(struct device *dev,
 			const char *name,
 			int irq);
 int bmp280_common_remove(struct device *dev);
+
+/* PM ops */
+extern const struct dev_pm_ops bmp280_dev_pm_ops;
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 10/10 v4] iio: pressure: bmp280: read calibration data once
  2016-06-30  1:48 [PATCH 00/10] Improve the BMP280 driver v4 Linus Walleij
                   ` (8 preceding siblings ...)
  2016-06-30  1:48 ` [PATCH 09/10 v4] iio: pressure: bmp280: add power management Linus Walleij
@ 2016-06-30  1:48 ` Linus Walleij
  2016-07-03 10:23   ` Jonathan Cameron
  9 siblings, 1 reply; 28+ messages in thread
From: Linus Walleij @ 2016-06-30  1:48 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij

The calibration data is described as coming from an E2PROM and that
means it does not change. Just read it once at probe time and store
it in the device state container. Also toss the calibration data
into the entropy pool since it is device unique.

Reviewed-by: Vlad Dogaru <vlad.dogaru@intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v3->v4:
- Fix bmp058/bmp085 typo
- Move patch last so the controversial stuff is at the end of the series
ChangeLog v2->v3:
- Rebase on other changes
- Drop unrelated whitespace fix
ChangeLog v1->v2:
- Remove unused dangling "ret" variable.
---
 drivers/iio/pressure/bmp280-core.c | 94 +++++++++++++++++++-------------------
 1 file changed, 48 insertions(+), 46 deletions(-)

diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index e8f534240f2d..eef4ef0097ce 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -31,9 +31,30 @@
 #include <linux/irq.h> /* For irq_get_irq_data() */
 #include <linux/completion.h>
 #include <linux/pm_runtime.h>
+#include <linux/random.h>
 
 #include "bmp280.h"
 
+/*
+ * These enums are used for indexing into the array of calibration
+ * coefficients for BMP180.
+ */
+enum { AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD };
+
+struct bmp180_calib {
+	s16 AC1;
+	s16 AC2;
+	s16 AC3;
+	u16 AC4;
+	u16 AC5;
+	u16 AC6;
+	s16 B1;
+	s16 B2;
+	s16 MB;
+	s16 MC;
+	s16 MD;
+};
+
 struct bmp280_data {
 	struct device *dev;
 	struct mutex lock;
@@ -41,6 +62,7 @@ struct bmp280_data {
 	struct completion done;
 	bool use_eoc;
 	const struct bmp280_chip_info *chip_info;
+	struct bmp180_calib calib;
 	struct regulator *vddd;
 	struct regulator *vdda;
 	unsigned int start_up_time; /* in milliseconds */
@@ -663,26 +685,6 @@ static int bmp180_read_adc_temp(struct bmp280_data *data, int *val)
 	return 0;
 }
 
-/*
- * These enums are used for indexing into the array of calibration
- * coefficients for BMP180.
- */
-enum { AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD };
-
-struct bmp180_calib {
-	s16 AC1;
-	s16 AC2;
-	s16 AC3;
-	u16 AC4;
-	u16 AC5;
-	u16 AC6;
-	s16 B1;
-	s16 B2;
-	s16 MB;
-	s16 MC;
-	s16 MD;
-};
-
 static int bmp180_read_calib(struct bmp280_data *data,
 			     struct bmp180_calib *calib)
 {
@@ -702,6 +704,9 @@ static int bmp180_read_calib(struct bmp280_data *data,
 			return -EIO;
 	}
 
+	/* Toss the calibration data into the entropy pool */
+	add_device_randomness(buf, sizeof(buf));
+
 	calib->AC1 = be16_to_cpu(buf[AC1]);
 	calib->AC2 = be16_to_cpu(buf[AC2]);
 	calib->AC3 = be16_to_cpu(buf[AC3]);
@@ -725,19 +730,11 @@ static int bmp180_read_calib(struct bmp280_data *data,
  */
 static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp)
 {
-	int ret;
 	s32 x1, x2;
-	struct bmp180_calib calib;
+	struct bmp180_calib *calib = &data->calib;
 
-	ret = bmp180_read_calib(data, &calib);
-	if (ret < 0) {
-		dev_err(data->dev,
-			"failed to read calibration coefficients\n");
-		return ret;
-	}
-
-	x1 = ((adc_temp - calib.AC6) * calib.AC5) >> 15;
-	x2 = (calib.MC << 11) / (x1 + calib.MD);
+	x1 = ((adc_temp - calib->AC6) * calib->AC5) >> 15;
+	x2 = (calib->MC << 11) / (x1 + calib->MD);
 	data->t_fine = x1 + x2;
 
 	return (data->t_fine + 8) >> 4;
@@ -792,29 +789,21 @@ static int bmp180_read_adc_press(struct bmp280_data *data, int *val)
  */
 static u32 bmp180_compensate_press(struct bmp280_data *data, s32 adc_press)
 {
-	int ret;
 	s32 x1, x2, x3, p;
 	s32 b3, b6;
 	u32 b4, b7;
 	s32 oss = data->oversampling_press;
-	struct bmp180_calib calib;
-
-	ret = bmp180_read_calib(data, &calib);
-	if (ret < 0) {
-		dev_err(data->dev,
-			"failed to read calibration coefficients\n");
-		return ret;
-	}
+	struct bmp180_calib *calib = &data->calib;
 
 	b6 = data->t_fine - 4000;
-	x1 = (calib.B2 * (b6 * b6 >> 12)) >> 11;
-	x2 = calib.AC2 * b6 >> 11;
+	x1 = (calib->B2 * (b6 * b6 >> 12)) >> 11;
+	x2 = calib->AC2 * b6 >> 11;
 	x3 = x1 + x2;
-	b3 = ((((s32)calib.AC1 * 4 + x3) << oss) + 2) / 4;
-	x1 = calib.AC3 * b6 >> 13;
-	x2 = (calib.B1 * ((b6 * b6) >> 12)) >> 16;
+	b3 = ((((s32)calib->AC1 * 4 + x3) << oss) + 2) / 4;
+	x1 = calib->AC3 * b6 >> 13;
+	x2 = (calib->B1 * ((b6 * b6) >> 12)) >> 16;
 	x3 = (x1 + x2 + 2) >> 2;
-	b4 = calib.AC4 * (u32)(x3 + 32768) >> 15;
+	b4 = calib->AC4 * (u32)(x3 + 32768) >> 15;
 	b7 = ((u32)adc_press - b3) * (50000 >> oss);
 	if (b7 < 0x80000000)
 		p = (b7 * 2) / b4;
@@ -1018,6 +1007,19 @@ int bmp280_common_probe(struct device *dev,
 	dev_set_drvdata(dev, data);
 
 	/*
+	 * The BMP085 and BMP180 has calibration in an E2PROM, read it out
+	 * at probe time. It will not change.
+	 */
+	if (chip_id  == BMP180_CHIP_ID) {
+		ret = bmp180_read_calib(data, &data->calib);
+		if (ret < 0) {
+			dev_err(data->dev,
+				"failed to read calibration coefficients\n");
+			goto out_disable_vdda;
+		}
+	}
+
+	/*
 	 * 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.
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 01/10 v4] iio: pressure: bmp280: augment DT bindings
  2016-06-30  1:48     ` Linus Walleij
@ 2016-06-30 19:23         ` Jonathan Cameron
  -1 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2016-06-30 19:23 UTC (permalink / raw)
  To: Linus Walleij, linux-iio-u79uwXL29TY76Z2rM5mHXA, Akinobu Mita,
	H. Nikolaus Schaller, Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, devicetree-u79uwXL29TY76Z2rM5mHXA

On 30/06/16 02:48, Linus Walleij wrote:
> This adds standard device tree bindings for a reset GPIO line, and
> the VDDD and VDDA power regulators.
> 
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Applied to the togreg branch of iio.git - initially pushed out as
testing.

Thanks,

Jonathan
> ---
> ChangeLog v3->v4:
> - Just resending. If the old patch (in the tree) is good enough, just
>   drop this.
> ChangeLog v2->v3:
> - None, just resending in case Jonathan prefers this binding doc
> ChangeLog v1->v2:
> - Order compatible string on single lines
> - Add "bosch,bme280" for the new sensor from Matt
> ---
>  Documentation/devicetree/bindings/iio/pressure/bmp085.txt | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/iio/pressure/bmp085.txt b/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
> index d7a6deb6b21e..c7198a03c906 100644
> --- a/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
> +++ b/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
> @@ -1,7 +1,11 @@
> -BMP085/BMP18x digital pressure sensors
> +BMP085/BMP18x/BMP28x digital pressure sensors
>  
>  Required properties:
> -- compatible: bosch,bmp085
> +- compatible: must be one of:
> +  "bosch,bmp085"
> +  "bosch,bmp180"
> +  "bosch,bmp280"
> +  "bosch,bme280"
>  
>  Optional properties:
>  - chip-id: configurable chip id for non-default chip revisions
> @@ -10,6 +14,10 @@ Optional properties:
>    value range is 0-3 with rising sensitivity.
>  - interrupt-parent: should be the phandle for the interrupt controller
>  - interrupts: interrupt mapping for IRQ
> +- reset-gpios: a GPIO line handling reset of the sensor: as the line is
> +  active low, it should be marked GPIO_ACTIVE_LOW (see gpio/gpio.txt)
> +- vddd-supply: digital voltage regulator (see regulator/regulator.txt)
> +- vdda-supply: analog voltage regulator (see regulator/regulator.txt)
>  
>  Example:
>  
> @@ -21,4 +29,7 @@ pressure@77 {
>  	default-oversampling = <2>;
>  	interrupt-parent = <&gpio0>;
>  	interrupts = <25 IRQ_TYPE_EDGE_RISING>;
> +	reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
> +	vddd-supply = <&foo>;
> +	vdda-supply = <&bar>;
>  };
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 01/10 v4] iio: pressure: bmp280: augment DT bindings
@ 2016-06-30 19:23         ` Jonathan Cameron
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2016-06-30 19:23 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, devicetree

On 30/06/16 02:48, Linus Walleij wrote:
> This adds standard device tree bindings for a reset GPIO line, and
> the VDDD and VDDA power regulators.
> 
> Cc: devicetree@vger.kernel.org
> Acked-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Applied to the togreg branch of iio.git - initially pushed out as
testing.

Thanks,

Jonathan
> ---
> ChangeLog v3->v4:
> - Just resending. If the old patch (in the tree) is good enough, just
>   drop this.
> ChangeLog v2->v3:
> - None, just resending in case Jonathan prefers this binding doc
> ChangeLog v1->v2:
> - Order compatible string on single lines
> - Add "bosch,bme280" for the new sensor from Matt
> ---
>  Documentation/devicetree/bindings/iio/pressure/bmp085.txt | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/iio/pressure/bmp085.txt b/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
> index d7a6deb6b21e..c7198a03c906 100644
> --- a/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
> +++ b/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
> @@ -1,7 +1,11 @@
> -BMP085/BMP18x digital pressure sensors
> +BMP085/BMP18x/BMP28x digital pressure sensors
>  
>  Required properties:
> -- compatible: bosch,bmp085
> +- compatible: must be one of:
> +  "bosch,bmp085"
> +  "bosch,bmp180"
> +  "bosch,bmp280"
> +  "bosch,bme280"
>  
>  Optional properties:
>  - chip-id: configurable chip id for non-default chip revisions
> @@ -10,6 +14,10 @@ Optional properties:
>    value range is 0-3 with rising sensitivity.
>  - interrupt-parent: should be the phandle for the interrupt controller
>  - interrupts: interrupt mapping for IRQ
> +- reset-gpios: a GPIO line handling reset of the sensor: as the line is
> +  active low, it should be marked GPIO_ACTIVE_LOW (see gpio/gpio.txt)
> +- vddd-supply: digital voltage regulator (see regulator/regulator.txt)
> +- vdda-supply: analog voltage regulator (see regulator/regulator.txt)
>  
>  Example:
>  
> @@ -21,4 +29,7 @@ pressure@77 {
>  	default-oversampling = <2>;
>  	interrupt-parent = <&gpio0>;
>  	interrupts = <25 IRQ_TYPE_EDGE_RISING>;
> +	reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
> +	vddd-supply = <&foo>;
> +	vdda-supply = <&bar>;
>  };
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 02/10 v4] iio: pressure: bmp280: support device tree initialization
  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
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2016-06-30 19:24 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 30/06/16 02:48, Linus Walleij wrote:
> This adds device tree support to the BMP085, BMP180 and BMP280
> pressure sensors. Tested on the Qualcomm APQ8060 Dragonboard:
> 
> iio:device1$ cat in_temp_input
> 26700
> iio:device1$ cat in_pressure_input
> 99.185000000
> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Applied.
> ---
> ChangeLog v3->v4:
> - No real changes.
> ChangeLog v2->v3:
> - Terminate OF ID table properly with an { }
> ChangeLog v1->v2:
> - Fix some BMP085 misspelled as BMP058 errors.
> - Add the new BME280 sensor as well
> ---
>  drivers/iio/pressure/bmp280.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
> index 1876b50cc84a..fa76f5851245 100644
> --- a/drivers/iio/pressure/bmp280.c
> +++ b/drivers/iio/pressure/bmp280.c
> @@ -18,6 +18,7 @@
>  #include <linux/module.h>
>  #include <linux/i2c.h>
>  #include <linux/acpi.h>
> +#include <linux/of.h>
>  #include <linux/regmap.h>
>  #include <linux/delay.h>
>  #include <linux/iio/iio.h>
> @@ -1094,6 +1095,19 @@ static const struct acpi_device_id bmp280_acpi_match[] = {
>  };
>  MODULE_DEVICE_TABLE(acpi, bmp280_acpi_match);
>  
> +#ifdef CONFIG_OF
> +static const struct of_device_id bmp280_of_match[] = {
> +	{ .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID },
> +	{ .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID },
> +	{ .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID },
> +	{ .compatible = "bosch,bmp085", .data = (void *)BMP180_CHIP_ID },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, bmp280_of_match);
> +#else
> +#define bmp280_of_match NULL
> +#endif
> +
>  static const struct i2c_device_id bmp280_id[] = {
>  	{"bmp280", BMP280_CHIP_ID },
>  	{"bmp180", BMP180_CHIP_ID },
> @@ -1107,6 +1121,7 @@ static struct i2c_driver bmp280_driver = {
>  	.driver = {
>  		.name	= "bmp280",
>  		.acpi_match_table = ACPI_PTR(bmp280_acpi_match),
> +		.of_match_table = of_match_ptr(bmp280_of_match),
>  	},
>  	.probe		= bmp280_probe,
>  	.id_table	= bmp280_id,
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 03/10 v4] iio: pressure: bmp280: add reset GPIO line handling
  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
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2016-06-30 19:25 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 30/06/16 02:48, Linus Walleij wrote:
> On the APQ8060 Dragonboard the reset line to the BMP085 pressure
> sensor is not deasserted on boot, so the driver needs to handle
> this. For a simple GPIO line supplied as a descriptor (from a board
> file, device tree or ACPI) this does the trick.
> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Applied.
> ---
> ChangeLog v3->v4:
> - Fix BMP058->BMP085 in commit message
> ChangeLog v2->v3:
> - None, just rebasing/resending
> ---
>  drivers/iio/pressure/bmp280.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
> index fa76f5851245..1618968f8889 100644
> --- a/drivers/iio/pressure/bmp280.c
> +++ b/drivers/iio/pressure/bmp280.c
> @@ -23,6 +23,7 @@
>  #include <linux/delay.h>
>  #include <linux/iio/iio.h>
>  #include <linux/iio/sysfs.h>
> +#include <linux/gpio/consumer.h>
>  
>  /* BMP280 specific registers */
>  #define BMP280_REG_HUMIDITY_LSB		0xFE
> @@ -1024,6 +1025,7 @@ static int bmp280_probe(struct i2c_client *client,
>  	struct iio_dev *indio_dev;
>  	struct bmp280_data *data;
>  	unsigned int chip_id;
> +	struct gpio_desc *gpiod;
>  
>  	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
>  	if (!indio_dev)
> @@ -1063,6 +1065,14 @@ static int bmp280_probe(struct i2c_client *client,
>  		return -EINVAL;
>  	}
>  
> +	/* Bring chip out of reset if there is an assigned GPIO line */
> +	gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
> +	/* Deassert the signal */
> +	if (!IS_ERR(gpiod)) {
> +		dev_info(&client->dev, "release reset\n");
> +		gpiod_set_value(gpiod, 0);
> +	}
> +
>  	data->regmap = devm_regmap_init_i2c(client,
>  					data->chip_info->regmap_config);
>  	if (IS_ERR(data->regmap)) {
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 04/10 v4] iio: pressure: bmp280: support supply regulators
  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
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2016-06-30 19:30 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Mark Brown

On 30/06/16 02:48, Linus Walleij wrote:
> The BMP085/BMP180/BMP280 is supplied with two power sources:
> VDDA (analog power) and VDDD (digital power). As these may come
> from regulators (as on the APQ8060 Dragonboard) we need the driver
> to attempt to fetch and enable these regulators.
> 
> We FAIL if we cannot: boards should either define:
> - Proper regulators if present
> - Define fixed regulators if power is hardwired to the component
> - Rely on dummy regulators (will be present on all DT systems and
>   any boardfile system that calls regulator_has_full_constraints().
> 
> Cc: Mark Brown <broonie@kernel.org>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Goes to show how well I read this earlier. Coincidentally it
doesn't apply cleanly due to a fix that's made it into the togreg
branch via a fast forward merge.

This one introduces a race, by potentially turning off the
regulators before we have removed the various interfaces that
allow for reading from the iio device.

You need to change the devm_iio_device_register into the non
devm version and unwind it in the remove function.

Jonathan
> ---
> ChangeLog v3->v4:
> - Fix missing "regulator" string in enablement message.
> - Fix BMP058->BMP085 in commit message
> ChangeLog v2->v3:
> - Encode a start-up time for each sensor type (from the datasheets)
>   this is necessary when coldstarting the sensor with a regulator
>   to be sure it is on before we try to use it.
> - Introduce a try/catch-style set of goto clauses in the probe
>   function to make sure the regulators are properly disabled.
> ChangeLog v1->v2:
> - Make the regulators non-optional: an optional supply is one you
>   can choose not to supply ELECTRICALLY as in an internal charge
>   pump taking its place or so.
> - Bail out if not present and add some notices to the commit that
>   boards need to think about their regulator usage.
> - Make sure we disable the regulators, and introduce a .remove()
>   call to do that if/when the module is removed.
> ---
>  drivers/iio/pressure/bmp280.c | 64 ++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 60 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
> index 1618968f8889..5245bc598187 100644
> --- a/drivers/iio/pressure/bmp280.c
> +++ b/drivers/iio/pressure/bmp280.c
> @@ -24,6 +24,7 @@
>  #include <linux/iio/iio.h>
>  #include <linux/iio/sysfs.h>
>  #include <linux/gpio/consumer.h>
> +#include <linux/regulator/consumer.h>
>  
>  /* BMP280 specific registers */
>  #define BMP280_REG_HUMIDITY_LSB		0xFE
> @@ -124,6 +125,9 @@ struct bmp280_data {
>  	struct mutex lock;
>  	struct regmap *regmap;
>  	const struct bmp280_chip_info *chip_info;
> +	struct regulator *vddd;
> +	struct regulator *vdda;
> +	unsigned int start_up_time; /* in milliseconds */
>  
>  	/* log of base 2 of oversampling rate */
>  	u8 oversampling_press;
> @@ -1047,12 +1051,14 @@ static int bmp280_probe(struct i2c_client *client,
>  		data->chip_info = &bmp180_chip_info;
>  		data->oversampling_press = ilog2(8);
>  		data->oversampling_temp = ilog2(1);
> +		data->start_up_time = 10;
>  		break;
>  	case BMP280_CHIP_ID:
>  		indio_dev->num_channels = 2;
>  		data->chip_info = &bmp280_chip_info;
>  		data->oversampling_press = ilog2(16);
>  		data->oversampling_temp = ilog2(2);
> +		data->start_up_time = 2;
>  		break;
>  	case BME280_CHIP_ID:
>  		indio_dev->num_channels = 3;
> @@ -1060,11 +1066,37 @@ static int bmp280_probe(struct i2c_client *client,
>  		data->oversampling_press = ilog2(16);
>  		data->oversampling_humid = ilog2(16);
>  		data->oversampling_temp = ilog2(2);
> +		data->start_up_time = 2;
>  		break;
>  	default:
>  		return -EINVAL;
>  	}
>  
> +	/* Bring up regulators */
> +	data->vddd = devm_regulator_get(&client->dev, "vddd");
> +	if (IS_ERR(data->vddd)) {
> +		dev_err(&client->dev, "failed to get VDDD regulator\n");
> +		return PTR_ERR(data->vddd);
> +	}
> +	ret = regulator_enable(data->vddd);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to enable VDDD regulator\n");
> +		return ret;
> +	}
> +	data->vdda = devm_regulator_get(&client->dev, "vdda");
> +	if (IS_ERR(data->vdda)) {
> +		dev_err(&client->dev, "failed to get VDDA regulator\n");
> +		ret = PTR_ERR(data->vddd);
> +		goto out_disable_vddd;
> +	}
> +	ret = regulator_enable(data->vdda);
> +	if (ret) {
> +		dev_err(&client->dev, "failed to enable VDDA regulator\n");
> +		goto out_disable_vddd;
> +	}
> +	/* Wait to make sure we started up properly */
> +	mdelay(data->start_up_time);
> +
>  	/* Bring chip out of reset if there is an assigned GPIO line */
>  	gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
>  	/* Deassert the signal */
> @@ -1077,7 +1109,8 @@ static int bmp280_probe(struct i2c_client *client,
>  					data->chip_info->regmap_config);
>  	if (IS_ERR(data->regmap)) {
>  		dev_err(&client->dev, "failed to allocate register map\n");
> -		return PTR_ERR(data->regmap);
> +		ret = PTR_ERR(data->regmap);
> +		goto out_disable_vdda;
>  	}
>  
>  	ret = regmap_read(data->regmap, BMP280_REG_ID, &chip_id);
> @@ -1086,14 +1119,36 @@ static int bmp280_probe(struct i2c_client *client,
>  	if (chip_id != id->driver_data) {
>  		dev_err(&client->dev, "bad chip id.  expected %x got %x\n",
>  			BMP280_CHIP_ID, chip_id);
> -		return -EINVAL;
> +		ret = -EINVAL;
> +		goto out_disable_vdda;
>  	}
>  
>  	ret = data->chip_info->chip_config(data);
>  	if (ret < 0)
> -		return ret;
> +		goto out_disable_vdda;
> +
> +	i2c_set_clientdata(client, data);
>  
> -	return devm_iio_device_register(&client->dev, indio_dev);
> +	ret = devm_iio_device_register(&client->dev, indio_dev);
> +	if (ret)
> +		goto out_disable_vdda;
> +
> +	return 0;
> +
> +out_disable_vdda:
> +	regulator_disable(data->vdda);
> +out_disable_vddd:
> +	regulator_disable(data->vddd);
> +	return ret;
> +}
> +
> +static int bmp280_remove(struct i2c_client *client)
> +{
> +	struct bmp280_data *data = i2c_get_clientdata(client);
> +
> +	regulator_disable(data->vdda);
> +	regulator_disable(data->vddd);
Race condition as the userspace and in kernel interfaces to
use the device haven't been removed, but we've turned off the
lights...
> +	return 0;
>  }
>  
>  static const struct acpi_device_id bmp280_acpi_match[] = {
> @@ -1134,6 +1189,7 @@ static struct i2c_driver bmp280_driver = {
>  		.of_match_table = of_match_ptr(bmp280_of_match),
>  	},
>  	.probe		= bmp280_probe,
> +	.remove		= bmp280_remove,
>  	.id_table	= bmp280_id,
>  };
>  module_i2c_driver(bmp280_driver);
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 04/10 v4] iio: pressure: bmp280: support supply regulators
  2016-06-30 19:30   ` Jonathan Cameron
@ 2016-07-03  9:54     ` Jonathan Cameron
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2016-07-03  9:54 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Mark Brown

On 30/06/16 20:30, Jonathan Cameron wrote:
> On 30/06/16 02:48, Linus Walleij wrote:
>> The BMP085/BMP180/BMP280 is supplied with two power sources:
>> VDDA (analog power) and VDDD (digital power). As these may come
>> from regulators (as on the APQ8060 Dragonboard) we need the driver
>> to attempt to fetch and enable these regulators.
>>
>> We FAIL if we cannot: boards should either define:
>> - Proper regulators if present
>> - Define fixed regulators if power is hardwired to the component
>> - Rely on dummy regulators (will be present on all DT systems and
>>   any boardfile system that calls regulator_has_full_constraints().
>>
>> Cc: Mark Brown <broonie@kernel.org>
>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> Goes to show how well I read this earlier. Coincidentally it
> doesn't apply cleanly due to a fix that's made it into the togreg
> branch via a fast forward merge.
> 
> This one introduces a race, by potentially turning off the
> regulators before we have removed the various interfaces that
> allow for reading from the iio device.
> 
> You need to change the devm_iio_device_register into the non
> devm version and unwind it in the remove function.
I'm in an odd mood this morning so will fix this up (mostly to try
and avoid having to see a v5 ;)

Jonathan

Applied this one with the changes mentioned below.  Please check the
result as I may well have messed it up.

The next patch is going to be 'fun'. 


> 
> Jonathan
>> ---
>> ChangeLog v3->v4:
>> - Fix missing "regulator" string in enablement message.
>> - Fix BMP058->BMP085 in commit message
>> ChangeLog v2->v3:
>> - Encode a start-up time for each sensor type (from the datasheets)
>>   this is necessary when coldstarting the sensor with a regulator
>>   to be sure it is on before we try to use it.
>> - Introduce a try/catch-style set of goto clauses in the probe
>>   function to make sure the regulators are properly disabled.
>> ChangeLog v1->v2:
>> - Make the regulators non-optional: an optional supply is one you
>>   can choose not to supply ELECTRICALLY as in an internal charge
>>   pump taking its place or so.
>> - Bail out if not present and add some notices to the commit that
>>   boards need to think about their regulator usage.
>> - Make sure we disable the regulators, and introduce a .remove()
>>   call to do that if/when the module is removed.
>> ---
>>  drivers/iio/pressure/bmp280.c | 64 ++++++++++++++++++++++++++++++++++++++++---
>>  1 file changed, 60 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
>> index 1618968f8889..5245bc598187 100644
>> --- a/drivers/iio/pressure/bmp280.c
>> +++ b/drivers/iio/pressure/bmp280.c
>> @@ -24,6 +24,7 @@
>>  #include <linux/iio/iio.h>
>>  #include <linux/iio/sysfs.h>
>>  #include <linux/gpio/consumer.h>
>> +#include <linux/regulator/consumer.h>
>>  
>>  /* BMP280 specific registers */
>>  #define BMP280_REG_HUMIDITY_LSB		0xFE
>> @@ -124,6 +125,9 @@ struct bmp280_data {
>>  	struct mutex lock;
>>  	struct regmap *regmap;
>>  	const struct bmp280_chip_info *chip_info;
>> +	struct regulator *vddd;
>> +	struct regulator *vdda;
>> +	unsigned int start_up_time; /* in milliseconds */
>>  
>>  	/* log of base 2 of oversampling rate */
>>  	u8 oversampling_press;
>> @@ -1047,12 +1051,14 @@ static int bmp280_probe(struct i2c_client *client,
>>  		data->chip_info = &bmp180_chip_info;
>>  		data->oversampling_press = ilog2(8);
>>  		data->oversampling_temp = ilog2(1);
>> +		data->start_up_time = 10;
>>  		break;
>>  	case BMP280_CHIP_ID:
>>  		indio_dev->num_channels = 2;
>>  		data->chip_info = &bmp280_chip_info;
>>  		data->oversampling_press = ilog2(16);
>>  		data->oversampling_temp = ilog2(2);
>> +		data->start_up_time = 2;
>>  		break;
>>  	case BME280_CHIP_ID:
>>  		indio_dev->num_channels = 3;
>> @@ -1060,11 +1066,37 @@ static int bmp280_probe(struct i2c_client *client,
>>  		data->oversampling_press = ilog2(16);
>>  		data->oversampling_humid = ilog2(16);
>>  		data->oversampling_temp = ilog2(2);
>> +		data->start_up_time = 2;
>>  		break;
>>  	default:
>>  		return -EINVAL;
>>  	}
>>  
>> +	/* Bring up regulators */
>> +	data->vddd = devm_regulator_get(&client->dev, "vddd");
>> +	if (IS_ERR(data->vddd)) {
>> +		dev_err(&client->dev, "failed to get VDDD regulator\n");
>> +		return PTR_ERR(data->vddd);
>> +	}
>> +	ret = regulator_enable(data->vddd);
>> +	if (ret) {
>> +		dev_err(&client->dev, "failed to enable VDDD regulator\n");
>> +		return ret;
>> +	}
>> +	data->vdda = devm_regulator_get(&client->dev, "vdda");
>> +	if (IS_ERR(data->vdda)) {
>> +		dev_err(&client->dev, "failed to get VDDA regulator\n");
>> +		ret = PTR_ERR(data->vddd);
>> +		goto out_disable_vddd;
>> +	}
>> +	ret = regulator_enable(data->vdda);
>> +	if (ret) {
>> +		dev_err(&client->dev, "failed to enable VDDA regulator\n");
>> +		goto out_disable_vddd;
>> +	}
>> +	/* Wait to make sure we started up properly */
>> +	mdelay(data->start_up_time);
>> +
>>  	/* Bring chip out of reset if there is an assigned GPIO line */
>>  	gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
>>  	/* Deassert the signal */
>> @@ -1077,7 +1109,8 @@ static int bmp280_probe(struct i2c_client *client,
>>  					data->chip_info->regmap_config);
>>  	if (IS_ERR(data->regmap)) {
>>  		dev_err(&client->dev, "failed to allocate register map\n");
>> -		return PTR_ERR(data->regmap);
>> +		ret = PTR_ERR(data->regmap);
>> +		goto out_disable_vdda;
>>  	}
>>  
>>  	ret = regmap_read(data->regmap, BMP280_REG_ID, &chip_id);
>> @@ -1086,14 +1119,36 @@ static int bmp280_probe(struct i2c_client *client,
>>  	if (chip_id != id->driver_data) {
>>  		dev_err(&client->dev, "bad chip id.  expected %x got %x\n",
>>  			BMP280_CHIP_ID, chip_id);
>> -		return -EINVAL;
>> +		ret = -EINVAL;
>> +		goto out_disable_vdda;
>>  	}
>>  
>>  	ret = data->chip_info->chip_config(data);
>>  	if (ret < 0)
>> -		return ret;
>> +		goto out_disable_vdda;
>> +
>> +	i2c_set_clientdata(client, data);
>>  
>> -	return devm_iio_device_register(&client->dev, indio_dev);
>> +	ret = devm_iio_device_register(&client->dev, indio_dev);
>> +	if (ret)
>> +		goto out_disable_vdda;
>> +
>> +	return 0;
>> +
>> +out_disable_vdda:
>> +	regulator_disable(data->vdda);
>> +out_disable_vddd:
>> +	regulator_disable(data->vddd);
>> +	return ret;
>> +}
>> +
>> +static int bmp280_remove(struct i2c_client *client)
>> +{
>> +	struct bmp280_data *data = i2c_get_clientdata(client);
>> +
>> +	regulator_disable(data->vdda);
>> +	regulator_disable(data->vddd);
> Race condition as the userspace and in kernel interfaces to
> use the device haven't been removed, but we've turned off the
> lights...
>> +	return 0;
>>  }
>>  
>>  static const struct acpi_device_id bmp280_acpi_match[] = {
>> @@ -1134,6 +1189,7 @@ static struct i2c_driver bmp280_driver = {
>>  		.of_match_table = of_match_ptr(bmp280_of_match),
>>  	},
>>  	.probe		= bmp280_probe,
>> +	.remove		= bmp280_remove,
>>  	.id_table	= bmp280_id,
>>  };
>>  module_i2c_driver(bmp280_driver);
>>
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 05/10 v4] iio: pressure: bmp280: split driver in logical parts
  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
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2016-07-03  9:59 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 30/06/16 02:48, Linus Walleij wrote:
> This splits the BMP280 driver in three logical parts: the core driver
> bmp280-core that only operated on a struct device * and a struct regmap *,
> the regmap driver bmp280-regmap that can be shared between I2C and other
> transports and the I2C module driver bmp280-i2c.
> 
> Cleverly bake all functionality into a single object bmp280.o so that
> we still get the same module binary built for the device in the end,
> without any fuzz exporting symbols to the left and right.
> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Linus,

I suspect you didn't actually build this.  The MODULE* macros aren't
defined without module.h.  I've added it as part of updating this for
the devm change on the previous patch.

Anyhow, applied with relevant fuzz fun from previous patch to the
togreg branch of iio.git - initially pushed out as testing for the
autobuilders to play with it.

Thanks,

Jonathan

> ---
> ChangeLog v3->v4:
> - Preserve the MODULE_* macros in the bmp280-core.c file so as to
>   avoid "module license 'unspecified' taints kernel" messages from
>   the core module
> - Rebase on other changes
> ChangeLog v2->v3:
> - Rebasing, hopefully remember to use -M when formatting patches
> ChangeLog v1->v2:
> - Rebased on top of Matt Ranostays BME280 with humidity sensor support
> - Rebased on top of other changes to e.g. regulator handling
> ---
>  drivers/iio/pressure/Makefile                    |   1 +
>  drivers/iio/pressure/{bmp280.c => bmp280-core.c} | 309 +++--------------------
>  drivers/iio/pressure/bmp280-i2c.c                |  89 +++++++
>  drivers/iio/pressure/bmp280-regmap.c             |  81 ++++++
>  drivers/iio/pressure/bmp280.h                    | 108 ++++++++
>  5 files changed, 319 insertions(+), 269 deletions(-)
>  rename drivers/iio/pressure/{bmp280.c => bmp280-core.c} (73%)
>  create mode 100644 drivers/iio/pressure/bmp280-i2c.c
>  create mode 100644 drivers/iio/pressure/bmp280-regmap.c
>  create mode 100644 drivers/iio/pressure/bmp280.h
> 
> diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
> index 17d6e7afa1ff..2d98a7ff77a8 100644
> --- a/drivers/iio/pressure/Makefile
> +++ b/drivers/iio/pressure/Makefile
> @@ -4,6 +4,7 @@
>  
>  # When adding new entries keep the list in alphabetical order
>  obj-$(CONFIG_BMP280) += bmp280.o
> +bmp280-objs := bmp280-core.o bmp280-regmap.o bmp280-i2c.o
>  obj-$(CONFIG_HID_SENSOR_PRESS)   += hid-sensor-press.o
>  obj-$(CONFIG_HP03) += hp03.o
>  obj-$(CONFIG_MPL115) += mpl115.o
> diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280-core.c
> similarity index 73%
> rename from drivers/iio/pressure/bmp280.c
> rename to drivers/iio/pressure/bmp280-core.c
> index 5245bc598187..af981b14b954 100644
> --- a/drivers/iio/pressure/bmp280.c
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -15,10 +15,7 @@
>  
>  #define pr_fmt(fmt) "bmp280: " fmt
>  
> -#include <linux/module.h>
> -#include <linux/i2c.h>
> -#include <linux/acpi.h>
> -#include <linux/of.h>
> +#include <linux/device.h>
>  #include <linux/regmap.h>
>  #include <linux/delay.h>
>  #include <linux/iio/iio.h>
> @@ -26,102 +23,10 @@
>  #include <linux/gpio/consumer.h>
>  #include <linux/regulator/consumer.h>
>  
> -/* BMP280 specific registers */
> -#define BMP280_REG_HUMIDITY_LSB		0xFE
> -#define BMP280_REG_HUMIDITY_MSB		0xFD
> -#define BMP280_REG_TEMP_XLSB		0xFC
> -#define BMP280_REG_TEMP_LSB		0xFB
> -#define BMP280_REG_TEMP_MSB		0xFA
> -#define BMP280_REG_PRESS_XLSB		0xF9
> -#define BMP280_REG_PRESS_LSB		0xF8
> -#define BMP280_REG_PRESS_MSB		0xF7
> -
> -#define BMP280_REG_CONFIG		0xF5
> -#define BMP280_REG_CTRL_MEAS		0xF4
> -#define BMP280_REG_STATUS		0xF3
> -#define BMP280_REG_CTRL_HUMIDITY	0xF2
> -
> -/* Due to non linear mapping, and data sizes we can't do a bulk read */
> -#define BMP280_REG_COMP_H1		0xA1
> -#define BMP280_REG_COMP_H2		0xE1
> -#define BMP280_REG_COMP_H3		0xE3
> -#define BMP280_REG_COMP_H4		0xE4
> -#define BMP280_REG_COMP_H5		0xE5
> -#define BMP280_REG_COMP_H6		0xE7
> -
> -#define BMP280_REG_COMP_TEMP_START	0x88
> -#define BMP280_COMP_TEMP_REG_COUNT	6
> -
> -#define BMP280_REG_COMP_PRESS_START	0x8E
> -#define BMP280_COMP_PRESS_REG_COUNT	18
> -
> -#define BMP280_FILTER_MASK		(BIT(4) | BIT(3) | BIT(2))
> -#define BMP280_FILTER_OFF		0
> -#define BMP280_FILTER_2X		BIT(2)
> -#define BMP280_FILTER_4X		BIT(3)
> -#define BMP280_FILTER_8X		(BIT(3) | BIT(2))
> -#define BMP280_FILTER_16X		BIT(4)
> -
> -#define BMP280_OSRS_HUMIDITY_MASK	(BIT(2) | BIT(1) | BIT(0))
> -#define BMP280_OSRS_HUMIDITIY_X(osrs_h)	((osrs_h) << 0)
> -#define BMP280_OSRS_HUMIDITY_SKIP	0
> -#define BMP280_OSRS_HUMIDITY_1X		BMP280_OSRS_HUMIDITIY_X(1)
> -#define BMP280_OSRS_HUMIDITY_2X		BMP280_OSRS_HUMIDITIY_X(2)
> -#define BMP280_OSRS_HUMIDITY_4X		BMP280_OSRS_HUMIDITIY_X(3)
> -#define BMP280_OSRS_HUMIDITY_8X		BMP280_OSRS_HUMIDITIY_X(4)
> -#define BMP280_OSRS_HUMIDITY_16X	BMP280_OSRS_HUMIDITIY_X(5)
> -
> -#define BMP280_OSRS_TEMP_MASK		(BIT(7) | BIT(6) | BIT(5))
> -#define BMP280_OSRS_TEMP_SKIP		0
> -#define BMP280_OSRS_TEMP_X(osrs_t)	((osrs_t) << 5)
> -#define BMP280_OSRS_TEMP_1X		BMP280_OSRS_TEMP_X(1)
> -#define BMP280_OSRS_TEMP_2X		BMP280_OSRS_TEMP_X(2)
> -#define BMP280_OSRS_TEMP_4X		BMP280_OSRS_TEMP_X(3)
> -#define BMP280_OSRS_TEMP_8X		BMP280_OSRS_TEMP_X(4)
> -#define BMP280_OSRS_TEMP_16X		BMP280_OSRS_TEMP_X(5)
> -
> -#define BMP280_OSRS_PRESS_MASK		(BIT(4) | BIT(3) | BIT(2))
> -#define BMP280_OSRS_PRESS_SKIP		0
> -#define BMP280_OSRS_PRESS_X(osrs_p)	((osrs_p) << 2)
> -#define BMP280_OSRS_PRESS_1X		BMP280_OSRS_PRESS_X(1)
> -#define BMP280_OSRS_PRESS_2X		BMP280_OSRS_PRESS_X(2)
> -#define BMP280_OSRS_PRESS_4X		BMP280_OSRS_PRESS_X(3)
> -#define BMP280_OSRS_PRESS_8X		BMP280_OSRS_PRESS_X(4)
> -#define BMP280_OSRS_PRESS_16X		BMP280_OSRS_PRESS_X(5)
> -
> -#define BMP280_MODE_MASK		(BIT(1) | BIT(0))
> -#define BMP280_MODE_SLEEP		0
> -#define BMP280_MODE_FORCED		BIT(0)
> -#define BMP280_MODE_NORMAL		(BIT(1) | BIT(0))
> -
> -/* BMP180 specific registers */
> -#define BMP180_REG_OUT_XLSB		0xF8
> -#define BMP180_REG_OUT_LSB		0xF7
> -#define BMP180_REG_OUT_MSB		0xF6
> -
> -#define BMP180_REG_CALIB_START		0xAA
> -#define BMP180_REG_CALIB_COUNT		22
> -
> -#define BMP180_MEAS_SCO			BIT(5)
> -#define BMP180_MEAS_TEMP		(0x0E | BMP180_MEAS_SCO)
> -#define BMP180_MEAS_PRESS_X(oss)	((oss) << 6 | 0x14 | BMP180_MEAS_SCO)
> -#define BMP180_MEAS_PRESS_1X		BMP180_MEAS_PRESS_X(0)
> -#define BMP180_MEAS_PRESS_2X		BMP180_MEAS_PRESS_X(1)
> -#define BMP180_MEAS_PRESS_4X		BMP180_MEAS_PRESS_X(2)
> -#define BMP180_MEAS_PRESS_8X		BMP180_MEAS_PRESS_X(3)
> -
> -/* BMP180 and BMP280 common registers */
> -#define BMP280_REG_CTRL_MEAS		0xF4
> -#define BMP280_REG_RESET		0xE0
> -#define BMP280_REG_ID			0xD0
> -
> -#define BMP180_CHIP_ID			0x55
> -#define BMP280_CHIP_ID			0x58
> -#define BME280_CHIP_ID			0x60
> -#define BMP280_SOFT_RESET_VAL		0xB6
> +#include "bmp280.h"
>  
>  struct bmp280_data {
> -	struct i2c_client *client;
> +	struct device *dev;
>  	struct mutex lock;
>  	struct regmap *regmap;
>  	const struct bmp280_chip_info *chip_info;
> @@ -142,8 +47,6 @@ struct bmp280_data {
>  };
>  
>  struct bmp280_chip_info {
> -	const struct regmap_config *regmap_config;
> -
>  	const int *oversampling_temp_avail;
>  	int num_oversampling_temp_avail;
>  
> @@ -184,48 +87,6 @@ static const struct iio_chan_spec bmp280_channels[] = {
>  	},
>  };
>  
> -static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg)
> -{
> -	switch (reg) {
> -	case BMP280_REG_CONFIG:
> -	case BMP280_REG_CTRL_HUMIDITY:
> -	case BMP280_REG_CTRL_MEAS:
> -	case BMP280_REG_RESET:
> -		return true;
> -	default:
> -		return false;
> -	};
> -}
> -
> -static bool bmp280_is_volatile_reg(struct device *dev, unsigned int reg)
> -{
> -	switch (reg) {
> -	case BMP280_REG_HUMIDITY_LSB:
> -	case BMP280_REG_HUMIDITY_MSB:
> -	case BMP280_REG_TEMP_XLSB:
> -	case BMP280_REG_TEMP_LSB:
> -	case BMP280_REG_TEMP_MSB:
> -	case BMP280_REG_PRESS_XLSB:
> -	case BMP280_REG_PRESS_LSB:
> -	case BMP280_REG_PRESS_MSB:
> -	case BMP280_REG_STATUS:
> -		return true;
> -	default:
> -		return false;
> -	}
> -}
> -
> -static const struct regmap_config bmp280_regmap_config = {
> -	.reg_bits = 8,
> -	.val_bits = 8,
> -
> -	.max_register = BMP280_REG_HUMIDITY_LSB,
> -	.cache_type = REGCACHE_RBTREE,
> -
> -	.writeable_reg = bmp280_is_writeable_reg,
> -	.volatile_reg = bmp280_is_volatile_reg,
> -};
> -
>  /*
>   * Returns humidity in percent, resolution is 0.01 percent. Output value of
>   * "47445" represents 47445/1024 = 46.333 %RH.
> @@ -236,7 +97,7 @@ static const struct regmap_config bmp280_regmap_config = {
>  static u32 bmp280_compensate_humidity(struct bmp280_data *data,
>  				      s32 adc_humidity)
>  {
> -	struct device *dev = &data->client->dev;
> +	struct device *dev = data->dev;
>  	unsigned int H1, H3, tmp;
>  	int H2, H4, H5, H6, ret, var;
>  
> @@ -307,7 +168,7 @@ static s32 bmp280_compensate_temp(struct bmp280_data *data,
>  	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START,
>  			       buf, BMP280_COMP_TEMP_REG_COUNT);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"failed to read temperature calibration parameters\n");
>  		return ret;
>  	}
> @@ -347,7 +208,7 @@ static u32 bmp280_compensate_press(struct bmp280_data *data,
>  	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
>  			       buf, BMP280_COMP_PRESS_REG_COUNT);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"failed to read pressure calibration parameters\n");
>  		return ret;
>  	}
> @@ -382,7 +243,7 @@ static int bmp280_read_temp(struct bmp280_data *data,
>  	ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB,
>  			       (u8 *) &tmp, 3);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "failed to read temperature\n");
> +		dev_err(data->dev, "failed to read temperature\n");
>  		return ret;
>  	}
>  
> @@ -417,7 +278,7 @@ static int bmp280_read_press(struct bmp280_data *data,
>  	ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB,
>  			       (u8 *) &tmp, 3);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "failed to read pressure\n");
> +		dev_err(data->dev, "failed to read pressure\n");
>  		return ret;
>  	}
>  
> @@ -445,7 +306,7 @@ static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
>  	ret = regmap_bulk_read(data->regmap, BMP280_REG_HUMIDITY_MSB,
>  			       (u8 *) &tmp, 2);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "failed to read humidity\n");
> +		dev_err(data->dev, "failed to read humidity\n");
>  		return ret;
>  	}
>  
> @@ -663,7 +524,7 @@ static int bmp280_chip_config(struct bmp280_data *data)
>  				 BMP280_MODE_MASK,
>  				 osrs | BMP280_MODE_NORMAL);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"failed to write ctrl_meas register\n");
>  		return ret;
>  	}
> @@ -672,7 +533,7 @@ static int bmp280_chip_config(struct bmp280_data *data)
>  				 BMP280_FILTER_MASK,
>  				 BMP280_FILTER_4X);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"failed to write config register\n");
>  		return ret;
>  	}
> @@ -683,8 +544,6 @@ static int bmp280_chip_config(struct bmp280_data *data)
>  static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 };
>  
>  static const struct bmp280_chip_info bmp280_chip_info = {
> -	.regmap_config = &bmp280_regmap_config,
> -
>  	.oversampling_temp_avail = bmp280_oversampling_avail,
>  	.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
>  
> @@ -709,8 +568,6 @@ static int bme280_chip_config(struct bmp280_data *data)
>  }
>  
>  static const struct bmp280_chip_info bme280_chip_info = {
> -	.regmap_config = &bmp280_regmap_config,
> -
>  	.oversampling_temp_avail = bmp280_oversampling_avail,
>  	.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
>  
> @@ -726,42 +583,6 @@ static const struct bmp280_chip_info bme280_chip_info = {
>  	.read_humid = bmp280_read_humid,
>  };
>  
> -
> -static bool bmp180_is_writeable_reg(struct device *dev, unsigned int reg)
> -{
> -	switch (reg) {
> -	case BMP280_REG_CTRL_MEAS:
> -	case BMP280_REG_RESET:
> -		return true;
> -	default:
> -		return false;
> -	};
> -}
> -
> -static bool bmp180_is_volatile_reg(struct device *dev, unsigned int reg)
> -{
> -	switch (reg) {
> -	case BMP180_REG_OUT_XLSB:
> -	case BMP180_REG_OUT_LSB:
> -	case BMP180_REG_OUT_MSB:
> -	case BMP280_REG_CTRL_MEAS:
> -		return true;
> -	default:
> -		return false;
> -	}
> -}
> -
> -static const struct regmap_config bmp180_regmap_config = {
> -	.reg_bits = 8,
> -	.val_bits = 8,
> -
> -	.max_register = BMP180_REG_OUT_XLSB,
> -	.cache_type = REGCACHE_RBTREE,
> -
> -	.writeable_reg = bmp180_is_writeable_reg,
> -	.volatile_reg = bmp180_is_volatile_reg,
> -};
> -
>  static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas)
>  {
>  	int ret;
> @@ -877,7 +698,7 @@ static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp)
>  
>  	ret = bmp180_read_calib(data, &calib);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"failed to read calibration coefficients\n");
>  		return ret;
>  	}
> @@ -947,7 +768,7 @@ static u32 bmp180_compensate_press(struct bmp280_data *data, s32 adc_press)
>  
>  	ret = bmp180_read_calib(data, &calib);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"failed to read calibration coefficients\n");
>  		return ret;
>  	}
> @@ -1007,8 +828,6 @@ static const int bmp180_oversampling_temp_avail[] = { 1 };
>  static const int bmp180_oversampling_press_avail[] = { 1, 2, 4, 8 };
>  
>  static const struct bmp280_chip_info bmp180_chip_info = {
> -	.regmap_config = &bmp180_regmap_config,
> -
>  	.oversampling_temp_avail = bmp180_oversampling_temp_avail,
>  	.num_oversampling_temp_avail =
>  		ARRAY_SIZE(bmp180_oversampling_temp_avail),
> @@ -1022,8 +841,10 @@ static const struct bmp280_chip_info bmp180_chip_info = {
>  	.read_press = bmp180_read_press,
>  };
>  
> -static int bmp280_probe(struct i2c_client *client,
> -			const struct i2c_device_id *id)
> +int bmp280_common_probe(struct device *dev,
> +			struct regmap *regmap,
> +			unsigned int chip,
> +			const char *name)
>  {
>  	int ret;
>  	struct iio_dev *indio_dev;
> @@ -1031,21 +852,21 @@ static int bmp280_probe(struct i2c_client *client,
>  	unsigned int chip_id;
>  	struct gpio_desc *gpiod;
>  
> -	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> +	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
>  	if (!indio_dev)
>  		return -ENOMEM;
>  
>  	data = iio_priv(indio_dev);
>  	mutex_init(&data->lock);
> -	data->client = client;
> +	data->dev = dev;
>  
> -	indio_dev->dev.parent = &client->dev;
> -	indio_dev->name = id->name;
> +	indio_dev->dev.parent = dev;
> +	indio_dev->name = name;
>  	indio_dev->channels = bmp280_channels;
>  	indio_dev->info = &bmp280_info;
>  	indio_dev->modes = INDIO_DIRECT_MODE;
>  
> -	switch (id->driver_data) {
> +	switch (chip) {
>  	case BMP180_CHIP_ID:
>  		indio_dev->num_channels = 2;
>  		data->chip_info = &bmp180_chip_info;
> @@ -1073,52 +894,45 @@ static int bmp280_probe(struct i2c_client *client,
>  	}
>  
>  	/* Bring up regulators */
> -	data->vddd = devm_regulator_get(&client->dev, "vddd");
> +	data->vddd = devm_regulator_get(dev, "vddd");
>  	if (IS_ERR(data->vddd)) {
> -		dev_err(&client->dev, "failed to get VDDD regulator\n");
> +		dev_err(dev, "failed to get VDDD regulator\n");
>  		return PTR_ERR(data->vddd);
>  	}
>  	ret = regulator_enable(data->vddd);
>  	if (ret) {
> -		dev_err(&client->dev, "failed to enable VDDD regulator\n");
> +		dev_err(dev, "failed to enable VDDD regulator\n");
>  		return ret;
>  	}
> -	data->vdda = devm_regulator_get(&client->dev, "vdda");
> +	data->vdda = devm_regulator_get(dev, "vdda");
>  	if (IS_ERR(data->vdda)) {
> -		dev_err(&client->dev, "failed to get VDDA regulator\n");
> +		dev_err(dev, "failed to get VDDA regulator\n");
>  		ret = PTR_ERR(data->vddd);
>  		goto out_disable_vddd;
>  	}
>  	ret = regulator_enable(data->vdda);
>  	if (ret) {
> -		dev_err(&client->dev, "failed to enable VDDA regulator\n");
> +		dev_err(dev, "failed to enable VDDA regulator\n");
>  		goto out_disable_vddd;
>  	}
>  	/* Wait to make sure we started up properly */
>  	mdelay(data->start_up_time);
>  
>  	/* Bring chip out of reset if there is an assigned GPIO line */
> -	gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
> +	gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
>  	/* Deassert the signal */
>  	if (!IS_ERR(gpiod)) {
> -		dev_info(&client->dev, "release reset\n");
> +		dev_info(dev, "release reset\n");
>  		gpiod_set_value(gpiod, 0);
>  	}
>  
> -	data->regmap = devm_regmap_init_i2c(client,
> -					data->chip_info->regmap_config);
> -	if (IS_ERR(data->regmap)) {
> -		dev_err(&client->dev, "failed to allocate register map\n");
> -		ret = PTR_ERR(data->regmap);
> -		goto out_disable_vdda;
> -	}
> -
> -	ret = regmap_read(data->regmap, BMP280_REG_ID, &chip_id);
> +	data->regmap = regmap;
> +	ret = regmap_read(regmap, BMP280_REG_ID, &chip_id);
>  	if (ret < 0)
> -		return ret;
> -	if (chip_id != id->driver_data) {
> -		dev_err(&client->dev, "bad chip id.  expected %x got %x\n",
> -			BMP280_CHIP_ID, chip_id);
> +		goto out_disable_vdda;
> +	if (chip_id != chip) {
> +		dev_err(dev, "bad chip id: expected %x got %x\n",
> +			chip, chip_id);
>  		ret = -EINVAL;
>  		goto out_disable_vdda;
>  	}
> @@ -1127,9 +941,9 @@ static int bmp280_probe(struct i2c_client *client,
>  	if (ret < 0)
>  		goto out_disable_vdda;
>  
> -	i2c_set_clientdata(client, data);
> +	dev_set_drvdata(dev, data);
>  
> -	ret = devm_iio_device_register(&client->dev, indio_dev);
> +	ret = devm_iio_device_register(dev, indio_dev);
>  	if (ret)
>  		goto out_disable_vdda;
>  
> @@ -1142,58 +956,15 @@ out_disable_vddd:
>  	return ret;
>  }
>  
> -static int bmp280_remove(struct i2c_client *client)
> +int bmp280_common_remove(struct device *dev)
>  {
> -	struct bmp280_data *data = i2c_get_clientdata(client);
> +	struct bmp280_data *data = dev_get_drvdata(dev);
>  
>  	regulator_disable(data->vdda);
>  	regulator_disable(data->vddd);
>  	return 0;
>  }
>  
> -static const struct acpi_device_id bmp280_acpi_match[] = {
> -	{"BMP0280", BMP280_CHIP_ID },
> -	{"BMP0180", BMP180_CHIP_ID },
> -	{"BMP0085", BMP180_CHIP_ID },
> -	{"BME0280", BME280_CHIP_ID },
> -	{ },
> -};
> -MODULE_DEVICE_TABLE(acpi, bmp280_acpi_match);
> -
> -#ifdef CONFIG_OF
> -static const struct of_device_id bmp280_of_match[] = {
> -	{ .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID },
> -	{ .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID },
> -	{ .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID },
> -	{ .compatible = "bosch,bmp085", .data = (void *)BMP180_CHIP_ID },
> -	{ },
> -};
> -MODULE_DEVICE_TABLE(of, bmp280_of_match);
> -#else
> -#define bmp280_of_match NULL
> -#endif
> -
> -static const struct i2c_device_id bmp280_id[] = {
> -	{"bmp280", BMP280_CHIP_ID },
> -	{"bmp180", BMP180_CHIP_ID },
> -	{"bmp085", BMP180_CHIP_ID },
> -	{"bme280", BME280_CHIP_ID },
> -	{ },
> -};
> -MODULE_DEVICE_TABLE(i2c, bmp280_id);
> -
> -static struct i2c_driver bmp280_driver = {
> -	.driver = {
> -		.name	= "bmp280",
> -		.acpi_match_table = ACPI_PTR(bmp280_acpi_match),
> -		.of_match_table = of_match_ptr(bmp280_of_match),
> -	},
> -	.probe		= bmp280_probe,
> -	.remove		= bmp280_remove,
> -	.id_table	= bmp280_id,
> -};
> -module_i2c_driver(bmp280_driver);
> -
>  MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
>  MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor");
>  MODULE_LICENSE("GPL v2");
> diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c
> new file mode 100644
> index 000000000000..7c70ee172bba
> --- /dev/null
> +++ b/drivers/iio/pressure/bmp280-i2c.c
> @@ -0,0 +1,89 @@
> +#include <linux/module.h>
> +#include <linux/i2c.h>
> +#include <linux/acpi.h>
> +#include <linux/of.h>
> +#include <linux/regmap.h>
> +
> +#include "bmp280.h"
> +
> +static int bmp280_i2c_probe(struct i2c_client *client,
> +			    const struct i2c_device_id *id)
> +{
> +	struct regmap *regmap;
> +	const struct regmap_config *regmap_config;
> +
> +	switch (id->driver_data) {
> +	case BMP180_CHIP_ID:
> +		regmap_config = &bmp180_regmap_config;
> +		break;
> +	case BMP280_CHIP_ID:
> +	case BME280_CHIP_ID:
> +		regmap_config = &bmp280_regmap_config;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	regmap = devm_regmap_init_i2c(client, regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&client->dev, "failed to allocate register map\n");
> +		return PTR_ERR(regmap);
> +	}
> +
> +	return bmp280_common_probe(&client->dev,
> +				   regmap,
> +				   id->driver_data,
> +				   id->name);
> +}
> +
> +static int bmp280_i2c_remove(struct i2c_client *client)
> +{
> +	return bmp280_common_remove(&client->dev);
> +}
> +
> +static const struct acpi_device_id bmp280_acpi_i2c_match[] = {
> +	{"BMP0280", BMP280_CHIP_ID },
> +	{"BMP0180", BMP180_CHIP_ID },
> +	{"BMP0085", BMP180_CHIP_ID },
> +	{"BME0280", BME280_CHIP_ID },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(acpi, bmp280_acpi_i2c_match);
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id bmp280_of_i2c_match[] = {
> +	{ .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID },
> +	{ .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID },
> +	{ .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID },
> +	{ .compatible = "bosch,bmp085", .data = (void *)BMP180_CHIP_ID },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, bmp280_of_i2c_match);
> +#else
> +#define bmp280_of_i2c_match NULL
> +#endif
> +
> +static const struct i2c_device_id bmp280_i2c_id[] = {
> +	{"bmp280", BMP280_CHIP_ID },
> +	{"bmp180", BMP180_CHIP_ID },
> +	{"bmp085", BMP180_CHIP_ID },
> +	{"bme280", BME280_CHIP_ID },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(i2c, bmp280_i2c_id);
> +
> +static struct i2c_driver bmp280_i2c_driver = {
> +	.driver = {
> +		.name	= "bmp280",
> +		.acpi_match_table = ACPI_PTR(bmp280_acpi_i2c_match),
> +		.of_match_table = of_match_ptr(bmp280_of_i2c_match),
> +	},
> +	.probe		= bmp280_i2c_probe,
> +	.remove		= bmp280_i2c_remove,
> +	.id_table	= bmp280_i2c_id,
> +};
> +module_i2c_driver(bmp280_i2c_driver);
> +
> +MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
> +MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/iio/pressure/bmp280-regmap.c b/drivers/iio/pressure/bmp280-regmap.c
> new file mode 100644
> index 000000000000..3341189d0975
> --- /dev/null
> +++ b/drivers/iio/pressure/bmp280-regmap.c
> @@ -0,0 +1,81 @@
> +#include <linux/device.h>
> +#include <linux/regmap.h>
> +
> +#include "bmp280.h"
> +
> +static bool bmp180_is_writeable_reg(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case BMP280_REG_CTRL_MEAS:
> +	case BMP280_REG_RESET:
> +		return true;
> +	default:
> +		return false;
> +	};
> +}
> +
> +static bool bmp180_is_volatile_reg(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case BMP180_REG_OUT_XLSB:
> +	case BMP180_REG_OUT_LSB:
> +	case BMP180_REG_OUT_MSB:
> +	case BMP280_REG_CTRL_MEAS:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +const struct regmap_config bmp180_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +
> +	.max_register = BMP180_REG_OUT_XLSB,
> +	.cache_type = REGCACHE_RBTREE,
> +
> +	.writeable_reg = bmp180_is_writeable_reg,
> +	.volatile_reg = bmp180_is_volatile_reg,
> +};
> +
> +static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case BMP280_REG_CONFIG:
> +	case BMP280_REG_CTRL_HUMIDITY:
> +	case BMP280_REG_CTRL_MEAS:
> +	case BMP280_REG_RESET:
> +		return true;
> +	default:
> +		return false;
> +	};
> +}
> +
> +static bool bmp280_is_volatile_reg(struct device *dev, unsigned int reg)
> +{
> +	switch (reg) {
> +	case BMP280_REG_HUMIDITY_LSB:
> +	case BMP280_REG_HUMIDITY_MSB:
> +	case BMP280_REG_TEMP_XLSB:
> +	case BMP280_REG_TEMP_LSB:
> +	case BMP280_REG_TEMP_MSB:
> +	case BMP280_REG_PRESS_XLSB:
> +	case BMP280_REG_PRESS_LSB:
> +	case BMP280_REG_PRESS_MSB:
> +	case BMP280_REG_STATUS:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +const struct regmap_config bmp280_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +
> +	.max_register = BMP280_REG_HUMIDITY_LSB,
> +	.cache_type = REGCACHE_RBTREE,
> +
> +	.writeable_reg = bmp280_is_writeable_reg,
> +	.volatile_reg = bmp280_is_volatile_reg,
> +};
> diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
> new file mode 100644
> index 000000000000..b9fc28ce9428
> --- /dev/null
> +++ b/drivers/iio/pressure/bmp280.h
> @@ -0,0 +1,108 @@
> +#include <linux/bitops.h>
> +#include <linux/device.h>
> +#include <linux/regmap.h>
> +
> +/* BMP280 specific registers */
> +#define BMP280_REG_HUMIDITY_LSB		0xFE
> +#define BMP280_REG_HUMIDITY_MSB		0xFD
> +#define BMP280_REG_TEMP_XLSB		0xFC
> +#define BMP280_REG_TEMP_LSB		0xFB
> +#define BMP280_REG_TEMP_MSB		0xFA
> +#define BMP280_REG_PRESS_XLSB		0xF9
> +#define BMP280_REG_PRESS_LSB		0xF8
> +#define BMP280_REG_PRESS_MSB		0xF7
> +
> +#define BMP280_REG_CONFIG		0xF5
> +#define BMP280_REG_CTRL_MEAS		0xF4
> +#define BMP280_REG_STATUS		0xF3
> +#define BMP280_REG_CTRL_HUMIDITY	0xF2
> +
> +/* Due to non linear mapping, and data sizes we can't do a bulk read */
> +#define BMP280_REG_COMP_H1		0xA1
> +#define BMP280_REG_COMP_H2		0xE1
> +#define BMP280_REG_COMP_H3		0xE3
> +#define BMP280_REG_COMP_H4		0xE4
> +#define BMP280_REG_COMP_H5		0xE5
> +#define BMP280_REG_COMP_H6		0xE7
> +
> +#define BMP280_REG_COMP_TEMP_START	0x88
> +#define BMP280_COMP_TEMP_REG_COUNT	6
> +
> +#define BMP280_REG_COMP_PRESS_START	0x8E
> +#define BMP280_COMP_PRESS_REG_COUNT	18
> +
> +#define BMP280_FILTER_MASK		(BIT(4) | BIT(3) | BIT(2))
> +#define BMP280_FILTER_OFF		0
> +#define BMP280_FILTER_2X		BIT(2)
> +#define BMP280_FILTER_4X		BIT(3)
> +#define BMP280_FILTER_8X		(BIT(3) | BIT(2))
> +#define BMP280_FILTER_16X		BIT(4)
> +
> +#define BMP280_OSRS_HUMIDITY_MASK	(BIT(2) | BIT(1) | BIT(0))
> +#define BMP280_OSRS_HUMIDITIY_X(osrs_h)	((osrs_h) << 0)
> +#define BMP280_OSRS_HUMIDITY_SKIP	0
> +#define BMP280_OSRS_HUMIDITY_1X		BMP280_OSRS_HUMIDITIY_X(1)
> +#define BMP280_OSRS_HUMIDITY_2X		BMP280_OSRS_HUMIDITIY_X(2)
> +#define BMP280_OSRS_HUMIDITY_4X		BMP280_OSRS_HUMIDITIY_X(3)
> +#define BMP280_OSRS_HUMIDITY_8X		BMP280_OSRS_HUMIDITIY_X(4)
> +#define BMP280_OSRS_HUMIDITY_16X	BMP280_OSRS_HUMIDITIY_X(5)
> +
> +#define BMP280_OSRS_TEMP_MASK		(BIT(7) | BIT(6) | BIT(5))
> +#define BMP280_OSRS_TEMP_SKIP		0
> +#define BMP280_OSRS_TEMP_X(osrs_t)	((osrs_t) << 5)
> +#define BMP280_OSRS_TEMP_1X		BMP280_OSRS_TEMP_X(1)
> +#define BMP280_OSRS_TEMP_2X		BMP280_OSRS_TEMP_X(2)
> +#define BMP280_OSRS_TEMP_4X		BMP280_OSRS_TEMP_X(3)
> +#define BMP280_OSRS_TEMP_8X		BMP280_OSRS_TEMP_X(4)
> +#define BMP280_OSRS_TEMP_16X		BMP280_OSRS_TEMP_X(5)
> +
> +#define BMP280_OSRS_PRESS_MASK		(BIT(4) | BIT(3) | BIT(2))
> +#define BMP280_OSRS_PRESS_SKIP		0
> +#define BMP280_OSRS_PRESS_X(osrs_p)	((osrs_p) << 2)
> +#define BMP280_OSRS_PRESS_1X		BMP280_OSRS_PRESS_X(1)
> +#define BMP280_OSRS_PRESS_2X		BMP280_OSRS_PRESS_X(2)
> +#define BMP280_OSRS_PRESS_4X		BMP280_OSRS_PRESS_X(3)
> +#define BMP280_OSRS_PRESS_8X		BMP280_OSRS_PRESS_X(4)
> +#define BMP280_OSRS_PRESS_16X		BMP280_OSRS_PRESS_X(5)
> +
> +#define BMP280_MODE_MASK		(BIT(1) | BIT(0))
> +#define BMP280_MODE_SLEEP		0
> +#define BMP280_MODE_FORCED		BIT(0)
> +#define BMP280_MODE_NORMAL		(BIT(1) | BIT(0))
> +
> +/* BMP180 specific registers */
> +#define BMP180_REG_OUT_XLSB		0xF8
> +#define BMP180_REG_OUT_LSB		0xF7
> +#define BMP180_REG_OUT_MSB		0xF6
> +
> +#define BMP180_REG_CALIB_START		0xAA
> +#define BMP180_REG_CALIB_COUNT		22
> +
> +#define BMP180_MEAS_SCO			BIT(5)
> +#define BMP180_MEAS_TEMP		(0x0E | BMP180_MEAS_SCO)
> +#define BMP180_MEAS_PRESS_X(oss)	((oss) << 6 | 0x14 | BMP180_MEAS_SCO)
> +#define BMP180_MEAS_PRESS_1X		BMP180_MEAS_PRESS_X(0)
> +#define BMP180_MEAS_PRESS_2X		BMP180_MEAS_PRESS_X(1)
> +#define BMP180_MEAS_PRESS_4X		BMP180_MEAS_PRESS_X(2)
> +#define BMP180_MEAS_PRESS_8X		BMP180_MEAS_PRESS_X(3)
> +
> +/* BMP180 and BMP280 common registers */
> +#define BMP280_REG_CTRL_MEAS		0xF4
> +#define BMP280_REG_RESET		0xE0
> +#define BMP280_REG_ID			0xD0
> +
> +#define BMP180_CHIP_ID			0x55
> +#define BMP280_CHIP_ID			0x58
> +#define BME280_CHIP_ID			0x60
> +#define BMP280_SOFT_RESET_VAL		0xB6
> +
> +/* Regmap configurations */
> +extern const struct regmap_config bmp180_regmap_config;
> +extern const struct regmap_config bmp280_regmap_config;
> +
> +/* Probe called from different transports */
> +int bmp280_common_probe(struct device *dev,
> +			struct regmap *regmap,
> +			unsigned int chip,
> +			const char *name);
> +int bmp280_common_remove(struct device *dev);
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 05/10 v4] iio: pressure: bmp280: split driver in logical parts
  2016-07-03  9:59   ` Jonathan Cameron
@ 2016-07-03 10:02     ` Jonathan Cameron
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2016-07-03 10:02 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 03/07/16 10:59, Jonathan Cameron wrote:
> On 30/06/16 02:48, Linus Walleij wrote:
>> This splits the BMP280 driver in three logical parts: the core driver
>> bmp280-core that only operated on a struct device * and a struct regmap *,
>> the regmap driver bmp280-regmap that can be shared between I2C and other
>> transports and the I2C module driver bmp280-i2c.
>>
>> Cleverly bake all functionality into a single object bmp280.o so that
>> we still get the same module binary built for the device in the end,
>> without any fuzz exporting symbols to the left and right.
>>
>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> Linus,
> 
> I suspect you didn't actually build this.  The MODULE* macros aren't
> defined without module.h.  I've added it as part of updating this for
> the devm change on the previous patch.
Ah, I see what happened - this should have been in the next patch
(where module.h) is.  I'll move the MODULE_AUTHOR etc lines across
with that.

Jonathan
> 
> Anyhow, applied with relevant fuzz fun from previous patch to the
> togreg branch of iio.git - initially pushed out as testing for the
> autobuilders to play with it.
> 
> Thanks,
> 
> Jonathan
> 
>> ---
>> ChangeLog v3->v4:
>> - Preserve the MODULE_* macros in the bmp280-core.c file so as to
>>   avoid "module license 'unspecified' taints kernel" messages from
>>   the core module
>> - Rebase on other changes
>> ChangeLog v2->v3:
>> - Rebasing, hopefully remember to use -M when formatting patches
>> ChangeLog v1->v2:
>> - Rebased on top of Matt Ranostays BME280 with humidity sensor support
>> - Rebased on top of other changes to e.g. regulator handling
>> ---
>>  drivers/iio/pressure/Makefile                    |   1 +
>>  drivers/iio/pressure/{bmp280.c => bmp280-core.c} | 309 +++--------------------
>>  drivers/iio/pressure/bmp280-i2c.c                |  89 +++++++
>>  drivers/iio/pressure/bmp280-regmap.c             |  81 ++++++
>>  drivers/iio/pressure/bmp280.h                    | 108 ++++++++
>>  5 files changed, 319 insertions(+), 269 deletions(-)
>>  rename drivers/iio/pressure/{bmp280.c => bmp280-core.c} (73%)
>>  create mode 100644 drivers/iio/pressure/bmp280-i2c.c
>>  create mode 100644 drivers/iio/pressure/bmp280-regmap.c
>>  create mode 100644 drivers/iio/pressure/bmp280.h
>>
>> diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
>> index 17d6e7afa1ff..2d98a7ff77a8 100644
>> --- a/drivers/iio/pressure/Makefile
>> +++ b/drivers/iio/pressure/Makefile
>> @@ -4,6 +4,7 @@
>>  
>>  # When adding new entries keep the list in alphabetical order
>>  obj-$(CONFIG_BMP280) += bmp280.o
>> +bmp280-objs := bmp280-core.o bmp280-regmap.o bmp280-i2c.o
>>  obj-$(CONFIG_HID_SENSOR_PRESS)   += hid-sensor-press.o
>>  obj-$(CONFIG_HP03) += hp03.o
>>  obj-$(CONFIG_MPL115) += mpl115.o
>> diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280-core.c
>> similarity index 73%
>> rename from drivers/iio/pressure/bmp280.c
>> rename to drivers/iio/pressure/bmp280-core.c
>> index 5245bc598187..af981b14b954 100644
>> --- a/drivers/iio/pressure/bmp280.c
>> +++ b/drivers/iio/pressure/bmp280-core.c
>> @@ -15,10 +15,7 @@
>>  
>>  #define pr_fmt(fmt) "bmp280: " fmt
>>  
>> -#include <linux/module.h>
>> -#include <linux/i2c.h>
>> -#include <linux/acpi.h>
>> -#include <linux/of.h>
>> +#include <linux/device.h>
>>  #include <linux/regmap.h>
>>  #include <linux/delay.h>
>>  #include <linux/iio/iio.h>
>> @@ -26,102 +23,10 @@
>>  #include <linux/gpio/consumer.h>
>>  #include <linux/regulator/consumer.h>
>>  
>> -/* BMP280 specific registers */
>> -#define BMP280_REG_HUMIDITY_LSB		0xFE
>> -#define BMP280_REG_HUMIDITY_MSB		0xFD
>> -#define BMP280_REG_TEMP_XLSB		0xFC
>> -#define BMP280_REG_TEMP_LSB		0xFB
>> -#define BMP280_REG_TEMP_MSB		0xFA
>> -#define BMP280_REG_PRESS_XLSB		0xF9
>> -#define BMP280_REG_PRESS_LSB		0xF8
>> -#define BMP280_REG_PRESS_MSB		0xF7
>> -
>> -#define BMP280_REG_CONFIG		0xF5
>> -#define BMP280_REG_CTRL_MEAS		0xF4
>> -#define BMP280_REG_STATUS		0xF3
>> -#define BMP280_REG_CTRL_HUMIDITY	0xF2
>> -
>> -/* Due to non linear mapping, and data sizes we can't do a bulk read */
>> -#define BMP280_REG_COMP_H1		0xA1
>> -#define BMP280_REG_COMP_H2		0xE1
>> -#define BMP280_REG_COMP_H3		0xE3
>> -#define BMP280_REG_COMP_H4		0xE4
>> -#define BMP280_REG_COMP_H5		0xE5
>> -#define BMP280_REG_COMP_H6		0xE7
>> -
>> -#define BMP280_REG_COMP_TEMP_START	0x88
>> -#define BMP280_COMP_TEMP_REG_COUNT	6
>> -
>> -#define BMP280_REG_COMP_PRESS_START	0x8E
>> -#define BMP280_COMP_PRESS_REG_COUNT	18
>> -
>> -#define BMP280_FILTER_MASK		(BIT(4) | BIT(3) | BIT(2))
>> -#define BMP280_FILTER_OFF		0
>> -#define BMP280_FILTER_2X		BIT(2)
>> -#define BMP280_FILTER_4X		BIT(3)
>> -#define BMP280_FILTER_8X		(BIT(3) | BIT(2))
>> -#define BMP280_FILTER_16X		BIT(4)
>> -
>> -#define BMP280_OSRS_HUMIDITY_MASK	(BIT(2) | BIT(1) | BIT(0))
>> -#define BMP280_OSRS_HUMIDITIY_X(osrs_h)	((osrs_h) << 0)
>> -#define BMP280_OSRS_HUMIDITY_SKIP	0
>> -#define BMP280_OSRS_HUMIDITY_1X		BMP280_OSRS_HUMIDITIY_X(1)
>> -#define BMP280_OSRS_HUMIDITY_2X		BMP280_OSRS_HUMIDITIY_X(2)
>> -#define BMP280_OSRS_HUMIDITY_4X		BMP280_OSRS_HUMIDITIY_X(3)
>> -#define BMP280_OSRS_HUMIDITY_8X		BMP280_OSRS_HUMIDITIY_X(4)
>> -#define BMP280_OSRS_HUMIDITY_16X	BMP280_OSRS_HUMIDITIY_X(5)
>> -
>> -#define BMP280_OSRS_TEMP_MASK		(BIT(7) | BIT(6) | BIT(5))
>> -#define BMP280_OSRS_TEMP_SKIP		0
>> -#define BMP280_OSRS_TEMP_X(osrs_t)	((osrs_t) << 5)
>> -#define BMP280_OSRS_TEMP_1X		BMP280_OSRS_TEMP_X(1)
>> -#define BMP280_OSRS_TEMP_2X		BMP280_OSRS_TEMP_X(2)
>> -#define BMP280_OSRS_TEMP_4X		BMP280_OSRS_TEMP_X(3)
>> -#define BMP280_OSRS_TEMP_8X		BMP280_OSRS_TEMP_X(4)
>> -#define BMP280_OSRS_TEMP_16X		BMP280_OSRS_TEMP_X(5)
>> -
>> -#define BMP280_OSRS_PRESS_MASK		(BIT(4) | BIT(3) | BIT(2))
>> -#define BMP280_OSRS_PRESS_SKIP		0
>> -#define BMP280_OSRS_PRESS_X(osrs_p)	((osrs_p) << 2)
>> -#define BMP280_OSRS_PRESS_1X		BMP280_OSRS_PRESS_X(1)
>> -#define BMP280_OSRS_PRESS_2X		BMP280_OSRS_PRESS_X(2)
>> -#define BMP280_OSRS_PRESS_4X		BMP280_OSRS_PRESS_X(3)
>> -#define BMP280_OSRS_PRESS_8X		BMP280_OSRS_PRESS_X(4)
>> -#define BMP280_OSRS_PRESS_16X		BMP280_OSRS_PRESS_X(5)
>> -
>> -#define BMP280_MODE_MASK		(BIT(1) | BIT(0))
>> -#define BMP280_MODE_SLEEP		0
>> -#define BMP280_MODE_FORCED		BIT(0)
>> -#define BMP280_MODE_NORMAL		(BIT(1) | BIT(0))
>> -
>> -/* BMP180 specific registers */
>> -#define BMP180_REG_OUT_XLSB		0xF8
>> -#define BMP180_REG_OUT_LSB		0xF7
>> -#define BMP180_REG_OUT_MSB		0xF6
>> -
>> -#define BMP180_REG_CALIB_START		0xAA
>> -#define BMP180_REG_CALIB_COUNT		22
>> -
>> -#define BMP180_MEAS_SCO			BIT(5)
>> -#define BMP180_MEAS_TEMP		(0x0E | BMP180_MEAS_SCO)
>> -#define BMP180_MEAS_PRESS_X(oss)	((oss) << 6 | 0x14 | BMP180_MEAS_SCO)
>> -#define BMP180_MEAS_PRESS_1X		BMP180_MEAS_PRESS_X(0)
>> -#define BMP180_MEAS_PRESS_2X		BMP180_MEAS_PRESS_X(1)
>> -#define BMP180_MEAS_PRESS_4X		BMP180_MEAS_PRESS_X(2)
>> -#define BMP180_MEAS_PRESS_8X		BMP180_MEAS_PRESS_X(3)
>> -
>> -/* BMP180 and BMP280 common registers */
>> -#define BMP280_REG_CTRL_MEAS		0xF4
>> -#define BMP280_REG_RESET		0xE0
>> -#define BMP280_REG_ID			0xD0
>> -
>> -#define BMP180_CHIP_ID			0x55
>> -#define BMP280_CHIP_ID			0x58
>> -#define BME280_CHIP_ID			0x60
>> -#define BMP280_SOFT_RESET_VAL		0xB6
>> +#include "bmp280.h"
>>  
>>  struct bmp280_data {
>> -	struct i2c_client *client;
>> +	struct device *dev;
>>  	struct mutex lock;
>>  	struct regmap *regmap;
>>  	const struct bmp280_chip_info *chip_info;
>> @@ -142,8 +47,6 @@ struct bmp280_data {
>>  };
>>  
>>  struct bmp280_chip_info {
>> -	const struct regmap_config *regmap_config;
>> -
>>  	const int *oversampling_temp_avail;
>>  	int num_oversampling_temp_avail;
>>  
>> @@ -184,48 +87,6 @@ static const struct iio_chan_spec bmp280_channels[] = {
>>  	},
>>  };
>>  
>> -static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg)
>> -{
>> -	switch (reg) {
>> -	case BMP280_REG_CONFIG:
>> -	case BMP280_REG_CTRL_HUMIDITY:
>> -	case BMP280_REG_CTRL_MEAS:
>> -	case BMP280_REG_RESET:
>> -		return true;
>> -	default:
>> -		return false;
>> -	};
>> -}
>> -
>> -static bool bmp280_is_volatile_reg(struct device *dev, unsigned int reg)
>> -{
>> -	switch (reg) {
>> -	case BMP280_REG_HUMIDITY_LSB:
>> -	case BMP280_REG_HUMIDITY_MSB:
>> -	case BMP280_REG_TEMP_XLSB:
>> -	case BMP280_REG_TEMP_LSB:
>> -	case BMP280_REG_TEMP_MSB:
>> -	case BMP280_REG_PRESS_XLSB:
>> -	case BMP280_REG_PRESS_LSB:
>> -	case BMP280_REG_PRESS_MSB:
>> -	case BMP280_REG_STATUS:
>> -		return true;
>> -	default:
>> -		return false;
>> -	}
>> -}
>> -
>> -static const struct regmap_config bmp280_regmap_config = {
>> -	.reg_bits = 8,
>> -	.val_bits = 8,
>> -
>> -	.max_register = BMP280_REG_HUMIDITY_LSB,
>> -	.cache_type = REGCACHE_RBTREE,
>> -
>> -	.writeable_reg = bmp280_is_writeable_reg,
>> -	.volatile_reg = bmp280_is_volatile_reg,
>> -};
>> -
>>  /*
>>   * Returns humidity in percent, resolution is 0.01 percent. Output value of
>>   * "47445" represents 47445/1024 = 46.333 %RH.
>> @@ -236,7 +97,7 @@ static const struct regmap_config bmp280_regmap_config = {
>>  static u32 bmp280_compensate_humidity(struct bmp280_data *data,
>>  				      s32 adc_humidity)
>>  {
>> -	struct device *dev = &data->client->dev;
>> +	struct device *dev = data->dev;
>>  	unsigned int H1, H3, tmp;
>>  	int H2, H4, H5, H6, ret, var;
>>  
>> @@ -307,7 +168,7 @@ static s32 bmp280_compensate_temp(struct bmp280_data *data,
>>  	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START,
>>  			       buf, BMP280_COMP_TEMP_REG_COUNT);
>>  	if (ret < 0) {
>> -		dev_err(&data->client->dev,
>> +		dev_err(data->dev,
>>  			"failed to read temperature calibration parameters\n");
>>  		return ret;
>>  	}
>> @@ -347,7 +208,7 @@ static u32 bmp280_compensate_press(struct bmp280_data *data,
>>  	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
>>  			       buf, BMP280_COMP_PRESS_REG_COUNT);
>>  	if (ret < 0) {
>> -		dev_err(&data->client->dev,
>> +		dev_err(data->dev,
>>  			"failed to read pressure calibration parameters\n");
>>  		return ret;
>>  	}
>> @@ -382,7 +243,7 @@ static int bmp280_read_temp(struct bmp280_data *data,
>>  	ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB,
>>  			       (u8 *) &tmp, 3);
>>  	if (ret < 0) {
>> -		dev_err(&data->client->dev, "failed to read temperature\n");
>> +		dev_err(data->dev, "failed to read temperature\n");
>>  		return ret;
>>  	}
>>  
>> @@ -417,7 +278,7 @@ static int bmp280_read_press(struct bmp280_data *data,
>>  	ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB,
>>  			       (u8 *) &tmp, 3);
>>  	if (ret < 0) {
>> -		dev_err(&data->client->dev, "failed to read pressure\n");
>> +		dev_err(data->dev, "failed to read pressure\n");
>>  		return ret;
>>  	}
>>  
>> @@ -445,7 +306,7 @@ static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
>>  	ret = regmap_bulk_read(data->regmap, BMP280_REG_HUMIDITY_MSB,
>>  			       (u8 *) &tmp, 2);
>>  	if (ret < 0) {
>> -		dev_err(&data->client->dev, "failed to read humidity\n");
>> +		dev_err(data->dev, "failed to read humidity\n");
>>  		return ret;
>>  	}
>>  
>> @@ -663,7 +524,7 @@ static int bmp280_chip_config(struct bmp280_data *data)
>>  				 BMP280_MODE_MASK,
>>  				 osrs | BMP280_MODE_NORMAL);
>>  	if (ret < 0) {
>> -		dev_err(&data->client->dev,
>> +		dev_err(data->dev,
>>  			"failed to write ctrl_meas register\n");
>>  		return ret;
>>  	}
>> @@ -672,7 +533,7 @@ static int bmp280_chip_config(struct bmp280_data *data)
>>  				 BMP280_FILTER_MASK,
>>  				 BMP280_FILTER_4X);
>>  	if (ret < 0) {
>> -		dev_err(&data->client->dev,
>> +		dev_err(data->dev,
>>  			"failed to write config register\n");
>>  		return ret;
>>  	}
>> @@ -683,8 +544,6 @@ static int bmp280_chip_config(struct bmp280_data *data)
>>  static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 };
>>  
>>  static const struct bmp280_chip_info bmp280_chip_info = {
>> -	.regmap_config = &bmp280_regmap_config,
>> -
>>  	.oversampling_temp_avail = bmp280_oversampling_avail,
>>  	.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
>>  
>> @@ -709,8 +568,6 @@ static int bme280_chip_config(struct bmp280_data *data)
>>  }
>>  
>>  static const struct bmp280_chip_info bme280_chip_info = {
>> -	.regmap_config = &bmp280_regmap_config,
>> -
>>  	.oversampling_temp_avail = bmp280_oversampling_avail,
>>  	.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
>>  
>> @@ -726,42 +583,6 @@ static const struct bmp280_chip_info bme280_chip_info = {
>>  	.read_humid = bmp280_read_humid,
>>  };
>>  
>> -
>> -static bool bmp180_is_writeable_reg(struct device *dev, unsigned int reg)
>> -{
>> -	switch (reg) {
>> -	case BMP280_REG_CTRL_MEAS:
>> -	case BMP280_REG_RESET:
>> -		return true;
>> -	default:
>> -		return false;
>> -	};
>> -}
>> -
>> -static bool bmp180_is_volatile_reg(struct device *dev, unsigned int reg)
>> -{
>> -	switch (reg) {
>> -	case BMP180_REG_OUT_XLSB:
>> -	case BMP180_REG_OUT_LSB:
>> -	case BMP180_REG_OUT_MSB:
>> -	case BMP280_REG_CTRL_MEAS:
>> -		return true;
>> -	default:
>> -		return false;
>> -	}
>> -}
>> -
>> -static const struct regmap_config bmp180_regmap_config = {
>> -	.reg_bits = 8,
>> -	.val_bits = 8,
>> -
>> -	.max_register = BMP180_REG_OUT_XLSB,
>> -	.cache_type = REGCACHE_RBTREE,
>> -
>> -	.writeable_reg = bmp180_is_writeable_reg,
>> -	.volatile_reg = bmp180_is_volatile_reg,
>> -};
>> -
>>  static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas)
>>  {
>>  	int ret;
>> @@ -877,7 +698,7 @@ static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp)
>>  
>>  	ret = bmp180_read_calib(data, &calib);
>>  	if (ret < 0) {
>> -		dev_err(&data->client->dev,
>> +		dev_err(data->dev,
>>  			"failed to read calibration coefficients\n");
>>  		return ret;
>>  	}
>> @@ -947,7 +768,7 @@ static u32 bmp180_compensate_press(struct bmp280_data *data, s32 adc_press)
>>  
>>  	ret = bmp180_read_calib(data, &calib);
>>  	if (ret < 0) {
>> -		dev_err(&data->client->dev,
>> +		dev_err(data->dev,
>>  			"failed to read calibration coefficients\n");
>>  		return ret;
>>  	}
>> @@ -1007,8 +828,6 @@ static const int bmp180_oversampling_temp_avail[] = { 1 };
>>  static const int bmp180_oversampling_press_avail[] = { 1, 2, 4, 8 };
>>  
>>  static const struct bmp280_chip_info bmp180_chip_info = {
>> -	.regmap_config = &bmp180_regmap_config,
>> -
>>  	.oversampling_temp_avail = bmp180_oversampling_temp_avail,
>>  	.num_oversampling_temp_avail =
>>  		ARRAY_SIZE(bmp180_oversampling_temp_avail),
>> @@ -1022,8 +841,10 @@ static const struct bmp280_chip_info bmp180_chip_info = {
>>  	.read_press = bmp180_read_press,
>>  };
>>  
>> -static int bmp280_probe(struct i2c_client *client,
>> -			const struct i2c_device_id *id)
>> +int bmp280_common_probe(struct device *dev,
>> +			struct regmap *regmap,
>> +			unsigned int chip,
>> +			const char *name)
>>  {
>>  	int ret;
>>  	struct iio_dev *indio_dev;
>> @@ -1031,21 +852,21 @@ static int bmp280_probe(struct i2c_client *client,
>>  	unsigned int chip_id;
>>  	struct gpio_desc *gpiod;
>>  
>> -	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
>> +	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
>>  	if (!indio_dev)
>>  		return -ENOMEM;
>>  
>>  	data = iio_priv(indio_dev);
>>  	mutex_init(&data->lock);
>> -	data->client = client;
>> +	data->dev = dev;
>>  
>> -	indio_dev->dev.parent = &client->dev;
>> -	indio_dev->name = id->name;
>> +	indio_dev->dev.parent = dev;
>> +	indio_dev->name = name;
>>  	indio_dev->channels = bmp280_channels;
>>  	indio_dev->info = &bmp280_info;
>>  	indio_dev->modes = INDIO_DIRECT_MODE;
>>  
>> -	switch (id->driver_data) {
>> +	switch (chip) {
>>  	case BMP180_CHIP_ID:
>>  		indio_dev->num_channels = 2;
>>  		data->chip_info = &bmp180_chip_info;
>> @@ -1073,52 +894,45 @@ static int bmp280_probe(struct i2c_client *client,
>>  	}
>>  
>>  	/* Bring up regulators */
>> -	data->vddd = devm_regulator_get(&client->dev, "vddd");
>> +	data->vddd = devm_regulator_get(dev, "vddd");
>>  	if (IS_ERR(data->vddd)) {
>> -		dev_err(&client->dev, "failed to get VDDD regulator\n");
>> +		dev_err(dev, "failed to get VDDD regulator\n");
>>  		return PTR_ERR(data->vddd);
>>  	}
>>  	ret = regulator_enable(data->vddd);
>>  	if (ret) {
>> -		dev_err(&client->dev, "failed to enable VDDD regulator\n");
>> +		dev_err(dev, "failed to enable VDDD regulator\n");
>>  		return ret;
>>  	}
>> -	data->vdda = devm_regulator_get(&client->dev, "vdda");
>> +	data->vdda = devm_regulator_get(dev, "vdda");
>>  	if (IS_ERR(data->vdda)) {
>> -		dev_err(&client->dev, "failed to get VDDA regulator\n");
>> +		dev_err(dev, "failed to get VDDA regulator\n");
>>  		ret = PTR_ERR(data->vddd);
>>  		goto out_disable_vddd;
>>  	}
>>  	ret = regulator_enable(data->vdda);
>>  	if (ret) {
>> -		dev_err(&client->dev, "failed to enable VDDA regulator\n");
>> +		dev_err(dev, "failed to enable VDDA regulator\n");
>>  		goto out_disable_vddd;
>>  	}
>>  	/* Wait to make sure we started up properly */
>>  	mdelay(data->start_up_time);
>>  
>>  	/* Bring chip out of reset if there is an assigned GPIO line */
>> -	gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
>> +	gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
>>  	/* Deassert the signal */
>>  	if (!IS_ERR(gpiod)) {
>> -		dev_info(&client->dev, "release reset\n");
>> +		dev_info(dev, "release reset\n");
>>  		gpiod_set_value(gpiod, 0);
>>  	}
>>  
>> -	data->regmap = devm_regmap_init_i2c(client,
>> -					data->chip_info->regmap_config);
>> -	if (IS_ERR(data->regmap)) {
>> -		dev_err(&client->dev, "failed to allocate register map\n");
>> -		ret = PTR_ERR(data->regmap);
>> -		goto out_disable_vdda;
>> -	}
>> -
>> -	ret = regmap_read(data->regmap, BMP280_REG_ID, &chip_id);
>> +	data->regmap = regmap;
>> +	ret = regmap_read(regmap, BMP280_REG_ID, &chip_id);
>>  	if (ret < 0)
>> -		return ret;
>> -	if (chip_id != id->driver_data) {
>> -		dev_err(&client->dev, "bad chip id.  expected %x got %x\n",
>> -			BMP280_CHIP_ID, chip_id);
>> +		goto out_disable_vdda;
>> +	if (chip_id != chip) {
>> +		dev_err(dev, "bad chip id: expected %x got %x\n",
>> +			chip, chip_id);
>>  		ret = -EINVAL;
>>  		goto out_disable_vdda;
>>  	}
>> @@ -1127,9 +941,9 @@ static int bmp280_probe(struct i2c_client *client,
>>  	if (ret < 0)
>>  		goto out_disable_vdda;
>>  
>> -	i2c_set_clientdata(client, data);
>> +	dev_set_drvdata(dev, data);
>>  
>> -	ret = devm_iio_device_register(&client->dev, indio_dev);
>> +	ret = devm_iio_device_register(dev, indio_dev);
>>  	if (ret)
>>  		goto out_disable_vdda;
>>  
>> @@ -1142,58 +956,15 @@ out_disable_vddd:
>>  	return ret;
>>  }
>>  
>> -static int bmp280_remove(struct i2c_client *client)
>> +int bmp280_common_remove(struct device *dev)
>>  {
>> -	struct bmp280_data *data = i2c_get_clientdata(client);
>> +	struct bmp280_data *data = dev_get_drvdata(dev);
>>  
>>  	regulator_disable(data->vdda);
>>  	regulator_disable(data->vddd);
>>  	return 0;
>>  }
>>  
>> -static const struct acpi_device_id bmp280_acpi_match[] = {
>> -	{"BMP0280", BMP280_CHIP_ID },
>> -	{"BMP0180", BMP180_CHIP_ID },
>> -	{"BMP0085", BMP180_CHIP_ID },
>> -	{"BME0280", BME280_CHIP_ID },
>> -	{ },
>> -};
>> -MODULE_DEVICE_TABLE(acpi, bmp280_acpi_match);
>> -
>> -#ifdef CONFIG_OF
>> -static const struct of_device_id bmp280_of_match[] = {
>> -	{ .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID },
>> -	{ .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID },
>> -	{ .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID },
>> -	{ .compatible = "bosch,bmp085", .data = (void *)BMP180_CHIP_ID },
>> -	{ },
>> -};
>> -MODULE_DEVICE_TABLE(of, bmp280_of_match);
>> -#else
>> -#define bmp280_of_match NULL
>> -#endif
>> -
>> -static const struct i2c_device_id bmp280_id[] = {
>> -	{"bmp280", BMP280_CHIP_ID },
>> -	{"bmp180", BMP180_CHIP_ID },
>> -	{"bmp085", BMP180_CHIP_ID },
>> -	{"bme280", BME280_CHIP_ID },
>> -	{ },
>> -};
>> -MODULE_DEVICE_TABLE(i2c, bmp280_id);
>> -
>> -static struct i2c_driver bmp280_driver = {
>> -	.driver = {
>> -		.name	= "bmp280",
>> -		.acpi_match_table = ACPI_PTR(bmp280_acpi_match),
>> -		.of_match_table = of_match_ptr(bmp280_of_match),
>> -	},
>> -	.probe		= bmp280_probe,
>> -	.remove		= bmp280_remove,
>> -	.id_table	= bmp280_id,
>> -};
>> -module_i2c_driver(bmp280_driver);
>> -
>>  MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
>>  MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor");
>>  MODULE_LICENSE("GPL v2");
>> diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c
>> new file mode 100644
>> index 000000000000..7c70ee172bba
>> --- /dev/null
>> +++ b/drivers/iio/pressure/bmp280-i2c.c
>> @@ -0,0 +1,89 @@
>> +#include <linux/module.h>
>> +#include <linux/i2c.h>
>> +#include <linux/acpi.h>
>> +#include <linux/of.h>
>> +#include <linux/regmap.h>
>> +
>> +#include "bmp280.h"
>> +
>> +static int bmp280_i2c_probe(struct i2c_client *client,
>> +			    const struct i2c_device_id *id)
>> +{
>> +	struct regmap *regmap;
>> +	const struct regmap_config *regmap_config;
>> +
>> +	switch (id->driver_data) {
>> +	case BMP180_CHIP_ID:
>> +		regmap_config = &bmp180_regmap_config;
>> +		break;
>> +	case BMP280_CHIP_ID:
>> +	case BME280_CHIP_ID:
>> +		regmap_config = &bmp280_regmap_config;
>> +		break;
>> +	default:
>> +		return -EINVAL;
>> +	}
>> +
>> +	regmap = devm_regmap_init_i2c(client, regmap_config);
>> +	if (IS_ERR(regmap)) {
>> +		dev_err(&client->dev, "failed to allocate register map\n");
>> +		return PTR_ERR(regmap);
>> +	}
>> +
>> +	return bmp280_common_probe(&client->dev,
>> +				   regmap,
>> +				   id->driver_data,
>> +				   id->name);
>> +}
>> +
>> +static int bmp280_i2c_remove(struct i2c_client *client)
>> +{
>> +	return bmp280_common_remove(&client->dev);
>> +}
>> +
>> +static const struct acpi_device_id bmp280_acpi_i2c_match[] = {
>> +	{"BMP0280", BMP280_CHIP_ID },
>> +	{"BMP0180", BMP180_CHIP_ID },
>> +	{"BMP0085", BMP180_CHIP_ID },
>> +	{"BME0280", BME280_CHIP_ID },
>> +	{ },
>> +};
>> +MODULE_DEVICE_TABLE(acpi, bmp280_acpi_i2c_match);
>> +
>> +#ifdef CONFIG_OF
>> +static const struct of_device_id bmp280_of_i2c_match[] = {
>> +	{ .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID },
>> +	{ .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID },
>> +	{ .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID },
>> +	{ .compatible = "bosch,bmp085", .data = (void *)BMP180_CHIP_ID },
>> +	{ },
>> +};
>> +MODULE_DEVICE_TABLE(of, bmp280_of_i2c_match);
>> +#else
>> +#define bmp280_of_i2c_match NULL
>> +#endif
>> +
>> +static const struct i2c_device_id bmp280_i2c_id[] = {
>> +	{"bmp280", BMP280_CHIP_ID },
>> +	{"bmp180", BMP180_CHIP_ID },
>> +	{"bmp085", BMP180_CHIP_ID },
>> +	{"bme280", BME280_CHIP_ID },
>> +	{ },
>> +};
>> +MODULE_DEVICE_TABLE(i2c, bmp280_i2c_id);
>> +
>> +static struct i2c_driver bmp280_i2c_driver = {
>> +	.driver = {
>> +		.name	= "bmp280",
>> +		.acpi_match_table = ACPI_PTR(bmp280_acpi_i2c_match),
>> +		.of_match_table = of_match_ptr(bmp280_of_i2c_match),
>> +	},
>> +	.probe		= bmp280_i2c_probe,
>> +	.remove		= bmp280_i2c_remove,
>> +	.id_table	= bmp280_i2c_id,
>> +};
>> +module_i2c_driver(bmp280_i2c_driver);
>> +
>> +MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
>> +MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor");
>> +MODULE_LICENSE("GPL v2");
>> diff --git a/drivers/iio/pressure/bmp280-regmap.c b/drivers/iio/pressure/bmp280-regmap.c
>> new file mode 100644
>> index 000000000000..3341189d0975
>> --- /dev/null
>> +++ b/drivers/iio/pressure/bmp280-regmap.c
>> @@ -0,0 +1,81 @@
>> +#include <linux/device.h>
>> +#include <linux/regmap.h>
>> +
>> +#include "bmp280.h"
>> +
>> +static bool bmp180_is_writeable_reg(struct device *dev, unsigned int reg)
>> +{
>> +	switch (reg) {
>> +	case BMP280_REG_CTRL_MEAS:
>> +	case BMP280_REG_RESET:
>> +		return true;
>> +	default:
>> +		return false;
>> +	};
>> +}
>> +
>> +static bool bmp180_is_volatile_reg(struct device *dev, unsigned int reg)
>> +{
>> +	switch (reg) {
>> +	case BMP180_REG_OUT_XLSB:
>> +	case BMP180_REG_OUT_LSB:
>> +	case BMP180_REG_OUT_MSB:
>> +	case BMP280_REG_CTRL_MEAS:
>> +		return true;
>> +	default:
>> +		return false;
>> +	}
>> +}
>> +
>> +const struct regmap_config bmp180_regmap_config = {
>> +	.reg_bits = 8,
>> +	.val_bits = 8,
>> +
>> +	.max_register = BMP180_REG_OUT_XLSB,
>> +	.cache_type = REGCACHE_RBTREE,
>> +
>> +	.writeable_reg = bmp180_is_writeable_reg,
>> +	.volatile_reg = bmp180_is_volatile_reg,
>> +};
>> +
>> +static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg)
>> +{
>> +	switch (reg) {
>> +	case BMP280_REG_CONFIG:
>> +	case BMP280_REG_CTRL_HUMIDITY:
>> +	case BMP280_REG_CTRL_MEAS:
>> +	case BMP280_REG_RESET:
>> +		return true;
>> +	default:
>> +		return false;
>> +	};
>> +}
>> +
>> +static bool bmp280_is_volatile_reg(struct device *dev, unsigned int reg)
>> +{
>> +	switch (reg) {
>> +	case BMP280_REG_HUMIDITY_LSB:
>> +	case BMP280_REG_HUMIDITY_MSB:
>> +	case BMP280_REG_TEMP_XLSB:
>> +	case BMP280_REG_TEMP_LSB:
>> +	case BMP280_REG_TEMP_MSB:
>> +	case BMP280_REG_PRESS_XLSB:
>> +	case BMP280_REG_PRESS_LSB:
>> +	case BMP280_REG_PRESS_MSB:
>> +	case BMP280_REG_STATUS:
>> +		return true;
>> +	default:
>> +		return false;
>> +	}
>> +}
>> +
>> +const struct regmap_config bmp280_regmap_config = {
>> +	.reg_bits = 8,
>> +	.val_bits = 8,
>> +
>> +	.max_register = BMP280_REG_HUMIDITY_LSB,
>> +	.cache_type = REGCACHE_RBTREE,
>> +
>> +	.writeable_reg = bmp280_is_writeable_reg,
>> +	.volatile_reg = bmp280_is_volatile_reg,
>> +};
>> diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
>> new file mode 100644
>> index 000000000000..b9fc28ce9428
>> --- /dev/null
>> +++ b/drivers/iio/pressure/bmp280.h
>> @@ -0,0 +1,108 @@
>> +#include <linux/bitops.h>
>> +#include <linux/device.h>
>> +#include <linux/regmap.h>
>> +
>> +/* BMP280 specific registers */
>> +#define BMP280_REG_HUMIDITY_LSB		0xFE
>> +#define BMP280_REG_HUMIDITY_MSB		0xFD
>> +#define BMP280_REG_TEMP_XLSB		0xFC
>> +#define BMP280_REG_TEMP_LSB		0xFB
>> +#define BMP280_REG_TEMP_MSB		0xFA
>> +#define BMP280_REG_PRESS_XLSB		0xF9
>> +#define BMP280_REG_PRESS_LSB		0xF8
>> +#define BMP280_REG_PRESS_MSB		0xF7
>> +
>> +#define BMP280_REG_CONFIG		0xF5
>> +#define BMP280_REG_CTRL_MEAS		0xF4
>> +#define BMP280_REG_STATUS		0xF3
>> +#define BMP280_REG_CTRL_HUMIDITY	0xF2
>> +
>> +/* Due to non linear mapping, and data sizes we can't do a bulk read */
>> +#define BMP280_REG_COMP_H1		0xA1
>> +#define BMP280_REG_COMP_H2		0xE1
>> +#define BMP280_REG_COMP_H3		0xE3
>> +#define BMP280_REG_COMP_H4		0xE4
>> +#define BMP280_REG_COMP_H5		0xE5
>> +#define BMP280_REG_COMP_H6		0xE7
>> +
>> +#define BMP280_REG_COMP_TEMP_START	0x88
>> +#define BMP280_COMP_TEMP_REG_COUNT	6
>> +
>> +#define BMP280_REG_COMP_PRESS_START	0x8E
>> +#define BMP280_COMP_PRESS_REG_COUNT	18
>> +
>> +#define BMP280_FILTER_MASK		(BIT(4) | BIT(3) | BIT(2))
>> +#define BMP280_FILTER_OFF		0
>> +#define BMP280_FILTER_2X		BIT(2)
>> +#define BMP280_FILTER_4X		BIT(3)
>> +#define BMP280_FILTER_8X		(BIT(3) | BIT(2))
>> +#define BMP280_FILTER_16X		BIT(4)
>> +
>> +#define BMP280_OSRS_HUMIDITY_MASK	(BIT(2) | BIT(1) | BIT(0))
>> +#define BMP280_OSRS_HUMIDITIY_X(osrs_h)	((osrs_h) << 0)
>> +#define BMP280_OSRS_HUMIDITY_SKIP	0
>> +#define BMP280_OSRS_HUMIDITY_1X		BMP280_OSRS_HUMIDITIY_X(1)
>> +#define BMP280_OSRS_HUMIDITY_2X		BMP280_OSRS_HUMIDITIY_X(2)
>> +#define BMP280_OSRS_HUMIDITY_4X		BMP280_OSRS_HUMIDITIY_X(3)
>> +#define BMP280_OSRS_HUMIDITY_8X		BMP280_OSRS_HUMIDITIY_X(4)
>> +#define BMP280_OSRS_HUMIDITY_16X	BMP280_OSRS_HUMIDITIY_X(5)
>> +
>> +#define BMP280_OSRS_TEMP_MASK		(BIT(7) | BIT(6) | BIT(5))
>> +#define BMP280_OSRS_TEMP_SKIP		0
>> +#define BMP280_OSRS_TEMP_X(osrs_t)	((osrs_t) << 5)
>> +#define BMP280_OSRS_TEMP_1X		BMP280_OSRS_TEMP_X(1)
>> +#define BMP280_OSRS_TEMP_2X		BMP280_OSRS_TEMP_X(2)
>> +#define BMP280_OSRS_TEMP_4X		BMP280_OSRS_TEMP_X(3)
>> +#define BMP280_OSRS_TEMP_8X		BMP280_OSRS_TEMP_X(4)
>> +#define BMP280_OSRS_TEMP_16X		BMP280_OSRS_TEMP_X(5)
>> +
>> +#define BMP280_OSRS_PRESS_MASK		(BIT(4) | BIT(3) | BIT(2))
>> +#define BMP280_OSRS_PRESS_SKIP		0
>> +#define BMP280_OSRS_PRESS_X(osrs_p)	((osrs_p) << 2)
>> +#define BMP280_OSRS_PRESS_1X		BMP280_OSRS_PRESS_X(1)
>> +#define BMP280_OSRS_PRESS_2X		BMP280_OSRS_PRESS_X(2)
>> +#define BMP280_OSRS_PRESS_4X		BMP280_OSRS_PRESS_X(3)
>> +#define BMP280_OSRS_PRESS_8X		BMP280_OSRS_PRESS_X(4)
>> +#define BMP280_OSRS_PRESS_16X		BMP280_OSRS_PRESS_X(5)
>> +
>> +#define BMP280_MODE_MASK		(BIT(1) | BIT(0))
>> +#define BMP280_MODE_SLEEP		0
>> +#define BMP280_MODE_FORCED		BIT(0)
>> +#define BMP280_MODE_NORMAL		(BIT(1) | BIT(0))
>> +
>> +/* BMP180 specific registers */
>> +#define BMP180_REG_OUT_XLSB		0xF8
>> +#define BMP180_REG_OUT_LSB		0xF7
>> +#define BMP180_REG_OUT_MSB		0xF6
>> +
>> +#define BMP180_REG_CALIB_START		0xAA
>> +#define BMP180_REG_CALIB_COUNT		22
>> +
>> +#define BMP180_MEAS_SCO			BIT(5)
>> +#define BMP180_MEAS_TEMP		(0x0E | BMP180_MEAS_SCO)
>> +#define BMP180_MEAS_PRESS_X(oss)	((oss) << 6 | 0x14 | BMP180_MEAS_SCO)
>> +#define BMP180_MEAS_PRESS_1X		BMP180_MEAS_PRESS_X(0)
>> +#define BMP180_MEAS_PRESS_2X		BMP180_MEAS_PRESS_X(1)
>> +#define BMP180_MEAS_PRESS_4X		BMP180_MEAS_PRESS_X(2)
>> +#define BMP180_MEAS_PRESS_8X		BMP180_MEAS_PRESS_X(3)
>> +
>> +/* BMP180 and BMP280 common registers */
>> +#define BMP280_REG_CTRL_MEAS		0xF4
>> +#define BMP280_REG_RESET		0xE0
>> +#define BMP280_REG_ID			0xD0
>> +
>> +#define BMP180_CHIP_ID			0x55
>> +#define BMP280_CHIP_ID			0x58
>> +#define BME280_CHIP_ID			0x60
>> +#define BMP280_SOFT_RESET_VAL		0xB6
>> +
>> +/* Regmap configurations */
>> +extern const struct regmap_config bmp180_regmap_config;
>> +extern const struct regmap_config bmp280_regmap_config;
>> +
>> +/* Probe called from different transports */
>> +int bmp280_common_probe(struct device *dev,
>> +			struct regmap *regmap,
>> +			unsigned int chip,
>> +			const char *name);
>> +int bmp280_common_remove(struct device *dev);
>>
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 06/10 v4] iio: pressure: bmp280: split off an I2C Kconfig entry
  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
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2016-07-03 10:06 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 30/06/16 02:48, Linus Walleij wrote:
> This creates a separate BMP280_I2C Kconfig entry that gets selected
> by BMP280 for I2C transport. As we currently only support I2C
> transport there is not much practical change other than getting
> a separate object file (or module) for the I2C driver part. The
> old Kconfig symbol BMP280 will still select the stuff we need so
> that oldconfig and old defconfigs works fine.
> 
> Tested-by: Akinobu Mita <akinobu.mita@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Hmm. I'm not 100% sure why this wasn't just merged with the
previous patch which would have made life a lot easier.

There is various spill between them (such as iio_common_probe was
exported in the previous patch and iio_common_remove only in this one).

The odd premature export aside it will now bisect successfully
between the two patches so all is fine (if a touch messier than ideal).

Anyhow, applied in some fashion to the togreg branch of iio.git

Thanks,

Jonathan
> ---
> ChangeLog v3->v4:
> - Rebase, no other changes.
> ChangeLog v2->v3:
> - Fix up Kconfig to put the dependencies to not use the old driver
>   directly under the main driver instead of under the I2C part
> - Export the common probe, remove and regmap symbols as the I2C driver part
>   becomes its own module and need to find those symbols from the
>   other parts.
> ChangeLog v1->v2:
> - None
> ---
>  drivers/iio/pressure/Kconfig         | 17 ++++++++++++-----
>  drivers/iio/pressure/Makefile        |  3 ++-
>  drivers/iio/pressure/bmp280-core.c   |  3 +++
>  drivers/iio/pressure/bmp280-regmap.c |  3 +++
>  4 files changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
> index 9125a9382b3e..851c4f5aec41 100644
> --- a/drivers/iio/pressure/Kconfig
> +++ b/drivers/iio/pressure/Kconfig
> @@ -6,17 +6,24 @@
>  menu "Pressure sensors"
>  
>  config BMP280
> -	tristate "Bosch Sensortec BMP180 and BMP280 pressure sensor driver"
> +	tristate "Bosch Sensortec BMP180/BMP280 pressure sensor I2C driver"
>  	depends on I2C
>  	depends on !(BMP085_I2C=y || BMP085_I2C=m)
> -	select REGMAP_I2C
> +	select REGMAP
> +	select BMP280_I2C if (I2C)
>  	help
>  	  Say yes here to build support for Bosch Sensortec BMP180 and BMP280
>  	  pressure and temperature sensors. Also supports the BE280 with
> -	  an additional humidty sensor channel.
> +	  an additional humidity sensor channel.
>  
> -	  To compile this driver as a module, choose M here: the module
> -	  will be called bmp280.
> +	  To compile this driver as a module, choose M here: the modules
> +	  will be called bmp280-i2c and bmp280.
> +
> +config BMP280_I2C
> +	tristate
> +	depends on BMP280
> +	depends on I2C
> +	select REGMAP_I2C
>  
>  config HID_SENSOR_PRESS
>  	depends on HID_SENSOR_HUB
> diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
> index 2d98a7ff77a8..736f4305fe46 100644
> --- a/drivers/iio/pressure/Makefile
> +++ b/drivers/iio/pressure/Makefile
> @@ -4,7 +4,8 @@
>  
>  # When adding new entries keep the list in alphabetical order
>  obj-$(CONFIG_BMP280) += bmp280.o
> -bmp280-objs := bmp280-core.o bmp280-regmap.o bmp280-i2c.o
> +bmp280-objs := bmp280-core.o bmp280-regmap.o
> +obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o
>  obj-$(CONFIG_HID_SENSOR_PRESS)   += hid-sensor-press.o
>  obj-$(CONFIG_HP03) += hp03.o
>  obj-$(CONFIG_MPL115) += mpl115.o
> diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
> index af981b14b954..e11635d7139e 100644
> --- a/drivers/iio/pressure/bmp280-core.c
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -16,6 +16,7 @@
>  #define pr_fmt(fmt) "bmp280: " fmt
>  
>  #include <linux/device.h>
> +#include <linux/module.h>
>  #include <linux/regmap.h>
>  #include <linux/delay.h>
>  #include <linux/iio/iio.h>
> @@ -955,6 +956,7 @@ out_disable_vddd:
>  	regulator_disable(data->vddd);
>  	return ret;
>  }
> +EXPORT_SYMBOL(bmp280_common_probe);
>  
>  int bmp280_common_remove(struct device *dev)
>  {
> @@ -964,6 +966,7 @@ int bmp280_common_remove(struct device *dev)
>  	regulator_disable(data->vddd);
>  	return 0;
>  }
> +EXPORT_SYMBOL(bmp280_common_remove);
>  
>  MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
>  MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor");
> diff --git a/drivers/iio/pressure/bmp280-regmap.c b/drivers/iio/pressure/bmp280-regmap.c
> index 3341189d0975..6807113ec09f 100644
> --- a/drivers/iio/pressure/bmp280-regmap.c
> +++ b/drivers/iio/pressure/bmp280-regmap.c
> @@ -1,4 +1,5 @@
>  #include <linux/device.h>
> +#include <linux/module.h>
>  #include <linux/regmap.h>
>  
>  #include "bmp280.h"
> @@ -37,6 +38,7 @@ const struct regmap_config bmp180_regmap_config = {
>  	.writeable_reg = bmp180_is_writeable_reg,
>  	.volatile_reg = bmp180_is_volatile_reg,
>  };
> +EXPORT_SYMBOL(bmp180_regmap_config);
>  
>  static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg)
>  {
> @@ -79,3 +81,4 @@ const struct regmap_config bmp280_regmap_config = {
>  	.writeable_reg = bmp280_is_writeable_reg,
>  	.volatile_reg = bmp280_is_volatile_reg,
>  };
> +EXPORT_SYMBOL(bmp280_regmap_config);
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 06/10 v4] iio: pressure: bmp280: split off an I2C Kconfig entry
  2016-07-03 10:06   ` Jonathan Cameron
@ 2016-07-03 10:07     ` Jonathan Cameron
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2016-07-03 10:07 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 03/07/16 11:06, Jonathan Cameron wrote:
> On 30/06/16 02:48, Linus Walleij wrote:
>> This creates a separate BMP280_I2C Kconfig entry that gets selected
>> by BMP280 for I2C transport. As we currently only support I2C
>> transport there is not much practical change other than getting
>> a separate object file (or module) for the I2C driver part. The
>> old Kconfig symbol BMP280 will still select the stuff we need so
>> that oldconfig and old defconfigs works fine.
>>
>> Tested-by: Akinobu Mita <akinobu.mita@gmail.com>
>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> Hmm. I'm not 100% sure why this wasn't just merged with the
> previous patch which would have made life a lot easier.
> 
> There is various spill between them (such as iio_common_probe was
> exported in the previous patch and iio_common_remove only in this one).
Scratch that - it was merely in a block that applied cleanly so I'm
talking rubbish ;)  only the module.h and appropriate macros were
in the wrong patch.

J
> 
> The odd premature export aside it will now bisect successfully
> between the two patches so all is fine (if a touch messier than ideal).
> 
> Anyhow, applied in some fashion to the togreg branch of iio.git
> 
> Thanks,
> 
> Jonathan
>> ---
>> ChangeLog v3->v4:
>> - Rebase, no other changes.
>> ChangeLog v2->v3:
>> - Fix up Kconfig to put the dependencies to not use the old driver
>>   directly under the main driver instead of under the I2C part
>> - Export the common probe, remove and regmap symbols as the I2C driver part
>>   becomes its own module and need to find those symbols from the
>>   other parts.
>> ChangeLog v1->v2:
>> - None
>> ---
>>  drivers/iio/pressure/Kconfig         | 17 ++++++++++++-----
>>  drivers/iio/pressure/Makefile        |  3 ++-
>>  drivers/iio/pressure/bmp280-core.c   |  3 +++
>>  drivers/iio/pressure/bmp280-regmap.c |  3 +++
>>  4 files changed, 20 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
>> index 9125a9382b3e..851c4f5aec41 100644
>> --- a/drivers/iio/pressure/Kconfig
>> +++ b/drivers/iio/pressure/Kconfig
>> @@ -6,17 +6,24 @@
>>  menu "Pressure sensors"
>>  
>>  config BMP280
>> -	tristate "Bosch Sensortec BMP180 and BMP280 pressure sensor driver"
>> +	tristate "Bosch Sensortec BMP180/BMP280 pressure sensor I2C driver"
>>  	depends on I2C
>>  	depends on !(BMP085_I2C=y || BMP085_I2C=m)
>> -	select REGMAP_I2C
>> +	select REGMAP
>> +	select BMP280_I2C if (I2C)
>>  	help
>>  	  Say yes here to build support for Bosch Sensortec BMP180 and BMP280
>>  	  pressure and temperature sensors. Also supports the BE280 with
>> -	  an additional humidty sensor channel.
>> +	  an additional humidity sensor channel.
>>  
>> -	  To compile this driver as a module, choose M here: the module
>> -	  will be called bmp280.
>> +	  To compile this driver as a module, choose M here: the modules
>> +	  will be called bmp280-i2c and bmp280.
>> +
>> +config BMP280_I2C
>> +	tristate
>> +	depends on BMP280
>> +	depends on I2C
>> +	select REGMAP_I2C
>>  
>>  config HID_SENSOR_PRESS
>>  	depends on HID_SENSOR_HUB
>> diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
>> index 2d98a7ff77a8..736f4305fe46 100644
>> --- a/drivers/iio/pressure/Makefile
>> +++ b/drivers/iio/pressure/Makefile
>> @@ -4,7 +4,8 @@
>>  
>>  # When adding new entries keep the list in alphabetical order
>>  obj-$(CONFIG_BMP280) += bmp280.o
>> -bmp280-objs := bmp280-core.o bmp280-regmap.o bmp280-i2c.o
>> +bmp280-objs := bmp280-core.o bmp280-regmap.o
>> +obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o
>>  obj-$(CONFIG_HID_SENSOR_PRESS)   += hid-sensor-press.o
>>  obj-$(CONFIG_HP03) += hp03.o
>>  obj-$(CONFIG_MPL115) += mpl115.o
>> diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
>> index af981b14b954..e11635d7139e 100644
>> --- a/drivers/iio/pressure/bmp280-core.c
>> +++ b/drivers/iio/pressure/bmp280-core.c
>> @@ -16,6 +16,7 @@
>>  #define pr_fmt(fmt) "bmp280: " fmt
>>  
>>  #include <linux/device.h>
>> +#include <linux/module.h>
>>  #include <linux/regmap.h>
>>  #include <linux/delay.h>
>>  #include <linux/iio/iio.h>
>> @@ -955,6 +956,7 @@ out_disable_vddd:
>>  	regulator_disable(data->vddd);
>>  	return ret;
>>  }
>> +EXPORT_SYMBOL(bmp280_common_probe);
>>  
>>  int bmp280_common_remove(struct device *dev)
>>  {
>> @@ -964,6 +966,7 @@ int bmp280_common_remove(struct device *dev)
>>  	regulator_disable(data->vddd);
>>  	return 0;
>>  }
>> +EXPORT_SYMBOL(bmp280_common_remove);
>>  
>>  MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
>>  MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor");
>> diff --git a/drivers/iio/pressure/bmp280-regmap.c b/drivers/iio/pressure/bmp280-regmap.c
>> index 3341189d0975..6807113ec09f 100644
>> --- a/drivers/iio/pressure/bmp280-regmap.c
>> +++ b/drivers/iio/pressure/bmp280-regmap.c
>> @@ -1,4 +1,5 @@
>>  #include <linux/device.h>
>> +#include <linux/module.h>
>>  #include <linux/regmap.h>
>>  
>>  #include "bmp280.h"
>> @@ -37,6 +38,7 @@ const struct regmap_config bmp180_regmap_config = {
>>  	.writeable_reg = bmp180_is_writeable_reg,
>>  	.volatile_reg = bmp180_is_volatile_reg,
>>  };
>> +EXPORT_SYMBOL(bmp180_regmap_config);
>>  
>>  static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg)
>>  {
>> @@ -79,3 +81,4 @@ const struct regmap_config bmp280_regmap_config = {
>>  	.writeable_reg = bmp280_is_writeable_reg,
>>  	.volatile_reg = bmp280_is_volatile_reg,
>>  };
>> +EXPORT_SYMBOL(bmp280_regmap_config);
>>
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/10 v4] iio: pressure: bmp280: add support for BMP085 EOC interrupt
  2016-06-30  1:48 ` [PATCH 08/10 v4] iio: pressure: bmp280: add support for BMP085 EOC interrupt Linus Walleij
@ 2016-07-03 10:11   ` Jonathan Cameron
  2016-07-03 10:35     ` Jonathan Cameron
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2016-07-03 10:11 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 30/06/16 02:48, Linus Walleij wrote:
> 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>
Bit of fuzz on this + one unrelated change that I've simply dropped.
If it matters to you send up a follow up patch.
> ---
> 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");
Nothing whatsoever to do with this patch.
>  		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);
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 07/10 v4] iio: pressure: bmp280: add SPI interface driver
  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
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2016-07-03 10:12 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 30/06/16 02:48, Linus Walleij wrote:
> This patch mimics the SPI functionality found in the misc driver in
> drivers/misc/bh085-spi.c to make it possible to reuse the existing
> BMP280/BMP180/BMP085 driver with all clients of the other driver.
> The adoption is straight-forward since like the other driver, it is
> a simple matter of using regmap.
> 
> This driver is also so obviously inspired/copied from the old misc
> driver in drivers/misc/bmp085.c that I just took the liberty to
> add in the authors of the other drivers + self in the core driver
> file.
> 
> The MISC driver also supports a variant named "BMP181" so include
> that here to be complete in comparison to the old driver.
> 
> The bus mapping code for SPI was written by Akinobu Mita.
> 
> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
> Tested-by: Akinobu Mita <akinobu.mita@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Applied to the togreg branch of iio.git - initially pushed out as
testing for the autobuilders to find out what I messed up merging
it ;)  Actually this one is well separated and applied fine.

Jonathan
> ---
> ChangeLog v3->v4:
> - Fix some comma
> - Fix a string BMP085->BMP280
> ChangeLog v2->v3:
> - Fix up some Kconfig warning mess by moving the deps of not
>   using the old driver up to the main driver part
> - Rebase and call the common remove() function.
> ChangeLog v1->v2:
> - Fix misnamed device table
> - Added Akinobu's bus mapping code for SPI
> - Add IDs and match strings for the new BME280 sensor too
> ---
>  drivers/iio/pressure/Kconfig       |  15 ++++-
>  drivers/iio/pressure/Makefile      |   1 +
>  drivers/iio/pressure/bmp280-core.c |   4 ++
>  drivers/iio/pressure/bmp280-spi.c  | 123 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 140 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/iio/pressure/bmp280-spi.c
> 
> diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
> index 851c4f5aec41..aa1303ceb6a4 100644
> --- a/drivers/iio/pressure/Kconfig
> +++ b/drivers/iio/pressure/Kconfig
> @@ -7,17 +7,20 @@ menu "Pressure sensors"
>  
>  config BMP280
>  	tristate "Bosch Sensortec BMP180/BMP280 pressure sensor I2C driver"
> -	depends on I2C
> +	depends on (I2C || SPI_MASTER)
>  	depends on !(BMP085_I2C=y || BMP085_I2C=m)
> +	depends on !(BMP085_SPI=y || BMP085_SPI=m)
>  	select REGMAP
>  	select BMP280_I2C if (I2C)
> +	select BMP280_SPI if (SPI_MASTER)
>  	help
>  	  Say yes here to build support for Bosch Sensortec BMP180 and BMP280
>  	  pressure and temperature sensors. Also supports the BE280 with
>  	  an additional humidity sensor channel.
>  
> -	  To compile this driver as a module, choose M here: the modules
> -	  will be called bmp280-i2c and bmp280.
> +	  To compile this driver as a module, choose M here: the core module
> +	  will be called bmp280 and you will also get bmp280-i2c for I2C
> +	  and/or bmp280-spi for SPI support.
>  
>  config BMP280_I2C
>  	tristate
> @@ -25,6 +28,12 @@ config BMP280_I2C
>  	depends on I2C
>  	select REGMAP_I2C
>  
> +config BMP280_SPI
> +	tristate
> +	depends on BMP280
> +	depends on SPI_MASTER
> +	select REGMAP
> +
>  config HID_SENSOR_PRESS
>  	depends on HID_SENSOR_HUB
>  	select IIO_BUFFER
> diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
> index 736f4305fe46..7f395bed5e88 100644
> --- a/drivers/iio/pressure/Makefile
> +++ b/drivers/iio/pressure/Makefile
> @@ -6,6 +6,7 @@
>  obj-$(CONFIG_BMP280) += bmp280.o
>  bmp280-objs := bmp280-core.o bmp280-regmap.o
>  obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o
> +obj-$(CONFIG_BMP280_SPI) += bmp280-spi.o
>  obj-$(CONFIG_HID_SENSOR_PRESS)   += hid-sensor-press.o
>  obj-$(CONFIG_HP03) += hp03.o
>  obj-$(CONFIG_MPL115) += mpl115.o
> diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
> index e11635d7139e..89ed608035f8 100644
> --- a/drivers/iio/pressure/bmp280-core.c
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -1,5 +1,9 @@
>  /*
> + * Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com>
> + * Copyright (c) 2012 Bosch Sensortec GmbH
> + * Copyright (c) 2012 Unixphere AB
>   * Copyright (c) 2014 Intel Corporation
> + * Copyright (c) 2016 Linus Walleij <linus.walleij@linaro.org>
>   *
>   * Driver for Bosch Sensortec BMP180 and BMP280 digital pressure sensor.
>   *
> diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c
> new file mode 100644
> index 000000000000..216e64b682bf
> --- /dev/null
> +++ b/drivers/iio/pressure/bmp280-spi.c
> @@ -0,0 +1,123 @@
> +/*
> + * SPI interface for the BMP280 driver
> + *
> + * Inspired by the older BMP085 driver drivers/misc/bmp085-spi.c
> + */
> +#include <linux/module.h>
> +#include <linux/spi/spi.h>
> +#include <linux/err.h>
> +#include <linux/regmap.h>
> +
> +#include "bmp280.h"
> +
> +static int bmp280_regmap_spi_write(void *context, const void *data,
> +                                   size_t count)
> +{
> +	struct device *dev = context;
> +	struct spi_device *spi = to_spi_device(dev);
> +	u8 buf[2];
> +
> +	memcpy(buf, data, 2);
> +	/*
> +	 * The SPI register address (= full register address without bit 7) and
> +	 * the write command (bit7 = RW = '0')
> +	 */
> +	buf[0] &= ~0x80;
> +
> +	return spi_write_then_read(spi, buf, 2, NULL, 0);
> +}
> +
> +static int bmp280_regmap_spi_read(void *context, const void *reg,
> +                                  size_t reg_size, void *val, size_t val_size)
> +{
> +	struct device *dev = context;
> +	struct spi_device *spi = to_spi_device(dev);
> +
> +	return spi_write_then_read(spi, reg, reg_size, val, val_size);
> +}
> +
> +static struct regmap_bus bmp280_regmap_bus = {
> +	.write = bmp280_regmap_spi_write,
> +	.read = bmp280_regmap_spi_read,
> +	.reg_format_endian_default = REGMAP_ENDIAN_BIG,
> +	.val_format_endian_default = REGMAP_ENDIAN_BIG,
> +};
> +
> +static int bmp280_spi_probe(struct spi_device *spi)
> +{
> +	const struct spi_device_id *id = spi_get_device_id(spi);
> +	struct regmap *regmap;
> +	const struct regmap_config *regmap_config;
> +	int ret;
> +
> +	spi->bits_per_word = 8;
> +	ret = spi_setup(spi);
> +	if (ret < 0) {
> +		dev_err(&spi->dev, "spi_setup failed!\n");
> +		return ret;
> +	}
> +
> +	switch (id->driver_data) {
> +	case BMP180_CHIP_ID:
> +		regmap_config = &bmp180_regmap_config;
> +		break;
> +	case BMP280_CHIP_ID:
> +	case BME280_CHIP_ID:
> +		regmap_config = &bmp280_regmap_config;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	regmap = devm_regmap_init(&spi->dev,
> +				  &bmp280_regmap_bus,
> +				  &spi->dev,
> +				  regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&spi->dev, "failed to allocate register map\n");
> +		return PTR_ERR(regmap);
> +	}
> +
> +	return bmp280_common_probe(&spi->dev,
> +				   regmap,
> +				   id->driver_data,
> +				   id->name);
> +}
> +
> +static int bmp280_spi_remove(struct spi_device *spi)
> +{
> +	return bmp280_common_remove(&spi->dev);
> +}
> +
> +static const struct of_device_id bmp280_of_spi_match[] = {
> +	{ .compatible = "bosch,bmp085", },
> +	{ .compatible = "bosch,bmp180", },
> +	{ .compatible = "bosch,bmp181", },
> +	{ .compatible = "bosch,bmp280", },
> +	{ .compatible = "bosch,bme280", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, bmp280_of_spi_match);
> +
> +static const struct spi_device_id bmp280_spi_id[] = {
> +	{ "bmp180", BMP180_CHIP_ID },
> +	{ "bmp181", BMP180_CHIP_ID },
> +	{ "bmp280", BMP280_CHIP_ID },
> +	{ "bme280", BME280_CHIP_ID },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(spi, bmp280_spi_id);
> +
> +static struct spi_driver bmp280_spi_driver = {
> +	.driver = {
> +		.name = "bmp280",
> +		.of_match_table = bmp280_of_spi_match,
> +	},
> +	.id_table = bmp280_spi_id,
> +	.probe = bmp280_spi_probe,
> +	.remove = bmp280_spi_remove,
> +};
> +module_spi_driver(bmp280_spi_driver);
> +
> +MODULE_DESCRIPTION("BMP280 SPI bus driver");
> +MODULE_LICENSE("GPL");
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 09/10 v4] iio: pressure: bmp280: add power management
  2016-06-30  1:48 ` [PATCH 09/10 v4] iio: pressure: bmp280: add power management Linus Walleij
@ 2016-07-03 10:21   ` Jonathan Cameron
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2016-07-03 10:21 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Ulf Hansson

On 30/06/16 02:48, Linus Walleij wrote:
> The PM280 has an internal standby-mode, but to really save power
> we should shut the sensor down and disconnect the power. With
> the proper .pm hooks we can enable both runtime and system power
> management of the sensor. We use the *force callbacks from the
> system PM hooks. When the sensor comes back we always reconfigure
> it to make sure it is ready to roll as expected.
> 
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
I believe this suffers from the same potential races around
iio_device_register and iio_device_unregister in that
it can leave the device power disabled when it is still possible
for readings to come in.

As such I've reorganised the probe and remove order.  Please again
check I haven't caused any issues.

Jonathan
> ---
> ChangeLog v3->v4:
> - Simplified return statments in runtime suspend/resume hooks.
> - Move before calibration optimization patch so the controversial
>   stuff is at the end of the series.
> - Rebased, edit "runtime PM ops" to "PM ops"
> ChangeLog v0->v3:
> - New patch on top of the reworked patches: we can add runtime PM,
>   so we should.
> ---
>  drivers/iio/pressure/bmp280-core.c | 58 ++++++++++++++++++++++++++++++++++++++
>  drivers/iio/pressure/bmp280-i2c.c  |  1 +
>  drivers/iio/pressure/bmp280-spi.c  |  1 +
>  drivers/iio/pressure/bmp280.h      |  3 ++
>  4 files changed, 63 insertions(+)
> 
> diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
> index b2858fbc1049..e8f534240f2d 100644
> --- a/drivers/iio/pressure/bmp280-core.c
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -30,6 +30,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/irq.h> /* For irq_get_irq_data() */
>  #include <linux/completion.h>
> +#include <linux/pm_runtime.h>
>  
>  #include "bmp280.h"
>  
> @@ -336,6 +337,7 @@ static int bmp280_read_raw(struct iio_dev *indio_dev,
>  	int ret;
>  	struct bmp280_data *data = iio_priv(indio_dev);
>  
> +	pm_runtime_get_sync(data->dev);
>  	mutex_lock(&data->lock);
>  
>  	switch (mask) {
> @@ -380,6 +382,8 @@ static int bmp280_read_raw(struct iio_dev *indio_dev,
>  	}
>  
>  	mutex_unlock(&data->lock);
> +	pm_runtime_mark_last_busy(data->dev);
> +	pm_runtime_put_autosuspend(data->dev);
>  
>  	return ret;
>  }
> @@ -444,6 +448,7 @@ static int bmp280_write_raw(struct iio_dev *indio_dev,
>  
>  	switch (mask) {
>  	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +		pm_runtime_get_sync(data->dev);
>  		mutex_lock(&data->lock);
>  		switch (chan->type) {
>  		case IIO_HUMIDITYRELATIVE:
> @@ -460,6 +465,8 @@ static int bmp280_write_raw(struct iio_dev *indio_dev,
>  			break;
>  		}
>  		mutex_unlock(&data->lock);
> +		pm_runtime_mark_last_busy(data->dev);
> +		pm_runtime_put_autosuspend(data->dev);
>  		break;
>  	default:
>  		return -EINVAL;
> @@ -1026,6 +1033,18 @@ int bmp280_common_probe(struct device *dev,
>  		dev_err(dev, "unable to register IIO device\n");
>  		goto out_disable_vdda;
>  	}
> +
> +	/* Enable runtime PM */
> +	pm_runtime_get_noresume(dev);
> +	pm_runtime_set_active(dev);
> +	pm_runtime_enable(dev);
> +	/*
> +	 * Set autosuspend to two orders of magnitude larger than the
> +	 * start-up time.
> +	 */
> +	pm_runtime_set_autosuspend_delay(dev, data->start_up_time *100);
> +	pm_runtime_use_autosuspend(dev);
> +	pm_runtime_put(dev);
>  	return 0;
>  
>  out_disable_vdda:
> @@ -1040,12 +1059,51 @@ int bmp280_common_remove(struct device *dev)
>  {
>  	struct bmp280_data *data = dev_get_drvdata(dev);
>  
> +	pm_runtime_get_sync(data->dev);
> +	pm_runtime_put_noidle(data->dev);
> +	pm_runtime_disable(data->dev);
>  	regulator_disable(data->vdda);
>  	regulator_disable(data->vddd);
>  	return 0;
>  }
>  EXPORT_SYMBOL(bmp280_common_remove);
>  
> +#ifdef CONFIG_PM
> +static int bmp280_runtime_suspend(struct device *dev)
> +{
> +	struct bmp280_data *data = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = regulator_disable(data->vdda);
> +	if (ret)
> +		return ret;
> +	return regulator_disable(data->vddd);
> +}
> +
> +static int bmp280_runtime_resume(struct device *dev)
> +{
> +	struct bmp280_data *data = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = regulator_enable(data->vddd);
> +	if (ret)
> +		return ret;
> +	ret = regulator_enable(data->vdda);
> +	if (ret)
> +		return ret;
> +	msleep(data->start_up_time);
> +	return data->chip_info->chip_config(data);
> +}
> +#endif /* CONFIG_PM */
> +
> +const struct dev_pm_ops bmp280_dev_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> +				pm_runtime_force_resume)
> +	SET_RUNTIME_PM_OPS(bmp280_runtime_suspend,
> +			   bmp280_runtime_resume, NULL)
> +};
> +EXPORT_SYMBOL(bmp280_dev_pm_ops);
> +
>  MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
>  MODULE_DESCRIPTION("Driver for Bosch Sensortec BMP180/BMP280 pressure and temperature sensor");
>  MODULE_LICENSE("GPL v2");
> diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c
> index 8cf8a900bdaa..03742b15b72a 100644
> --- a/drivers/iio/pressure/bmp280-i2c.c
> +++ b/drivers/iio/pressure/bmp280-i2c.c
> @@ -78,6 +78,7 @@ static struct i2c_driver bmp280_i2c_driver = {
>  		.name	= "bmp280",
>  		.acpi_match_table = ACPI_PTR(bmp280_acpi_i2c_match),
>  		.of_match_table = of_match_ptr(bmp280_of_i2c_match),
> +		.pm = &bmp280_dev_pm_ops,
>  	},
>  	.probe		= bmp280_i2c_probe,
>  	.remove		= bmp280_i2c_remove,
> diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c
> index cd365ba74b68..17bc95586f9e 100644
> --- a/drivers/iio/pressure/bmp280-spi.c
> +++ b/drivers/iio/pressure/bmp280-spi.c
> @@ -113,6 +113,7 @@ static struct spi_driver bmp280_spi_driver = {
>  	.driver = {
>  		.name = "bmp280",
>  		.of_match_table = bmp280_of_spi_match,
> +		.pm = &bmp280_dev_pm_ops,
>  	},
>  	.id_table = bmp280_spi_id,
>  	.probe = bmp280_spi_probe,
> diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
> index 573334b8e93b..2c770e13be0e 100644
> --- a/drivers/iio/pressure/bmp280.h
> +++ b/drivers/iio/pressure/bmp280.h
> @@ -107,3 +107,6 @@ int bmp280_common_probe(struct device *dev,
>  			const char *name,
>  			int irq);
>  int bmp280_common_remove(struct device *dev);
> +
> +/* PM ops */
> +extern const struct dev_pm_ops bmp280_dev_pm_ops;
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 10/10 v4] iio: pressure: bmp280: read calibration data once
  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
  0 siblings, 1 reply; 28+ messages in thread
From: Jonathan Cameron @ 2016-07-03 10:23 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 30/06/16 02:48, Linus Walleij wrote:
> The calibration data is described as coming from an E2PROM and that
> means it does not change. Just read it once at probe time and store
> it in the device state container. Also toss the calibration data
> into the entropy pool since it is device unique.
> 
> Reviewed-by: Vlad Dogaru <vlad.dogaru@intel.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Applied with a whole 1 line of fuzz ;)

Jonathan
> ---
> ChangeLog v3->v4:
> - Fix bmp058/bmp085 typo
> - Move patch last so the controversial stuff is at the end of the series
> ChangeLog v2->v3:
> - Rebase on other changes
> - Drop unrelated whitespace fix
> ChangeLog v1->v2:
> - Remove unused dangling "ret" variable.
> ---
>  drivers/iio/pressure/bmp280-core.c | 94 +++++++++++++++++++-------------------
>  1 file changed, 48 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
> index e8f534240f2d..eef4ef0097ce 100644
> --- a/drivers/iio/pressure/bmp280-core.c
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -31,9 +31,30 @@
>  #include <linux/irq.h> /* For irq_get_irq_data() */
>  #include <linux/completion.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/random.h>
>  
>  #include "bmp280.h"
>  
> +/*
> + * These enums are used for indexing into the array of calibration
> + * coefficients for BMP180.
> + */
> +enum { AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD };
> +
> +struct bmp180_calib {
> +	s16 AC1;
> +	s16 AC2;
> +	s16 AC3;
> +	u16 AC4;
> +	u16 AC5;
> +	u16 AC6;
> +	s16 B1;
> +	s16 B2;
> +	s16 MB;
> +	s16 MC;
> +	s16 MD;
> +};
> +
>  struct bmp280_data {
>  	struct device *dev;
>  	struct mutex lock;
> @@ -41,6 +62,7 @@ struct bmp280_data {
>  	struct completion done;
>  	bool use_eoc;
>  	const struct bmp280_chip_info *chip_info;
> +	struct bmp180_calib calib;
>  	struct regulator *vddd;
>  	struct regulator *vdda;
>  	unsigned int start_up_time; /* in milliseconds */
> @@ -663,26 +685,6 @@ static int bmp180_read_adc_temp(struct bmp280_data *data, int *val)
>  	return 0;
>  }
>  
> -/*
> - * These enums are used for indexing into the array of calibration
> - * coefficients for BMP180.
> - */
> -enum { AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD };
> -
> -struct bmp180_calib {
> -	s16 AC1;
> -	s16 AC2;
> -	s16 AC3;
> -	u16 AC4;
> -	u16 AC5;
> -	u16 AC6;
> -	s16 B1;
> -	s16 B2;
> -	s16 MB;
> -	s16 MC;
> -	s16 MD;
> -};
> -
>  static int bmp180_read_calib(struct bmp280_data *data,
>  			     struct bmp180_calib *calib)
>  {
> @@ -702,6 +704,9 @@ static int bmp180_read_calib(struct bmp280_data *data,
>  			return -EIO;
>  	}
>  
> +	/* Toss the calibration data into the entropy pool */
> +	add_device_randomness(buf, sizeof(buf));
> +
>  	calib->AC1 = be16_to_cpu(buf[AC1]);
>  	calib->AC2 = be16_to_cpu(buf[AC2]);
>  	calib->AC3 = be16_to_cpu(buf[AC3]);
> @@ -725,19 +730,11 @@ static int bmp180_read_calib(struct bmp280_data *data,
>   */
>  static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp)
>  {
> -	int ret;
>  	s32 x1, x2;
> -	struct bmp180_calib calib;
> +	struct bmp180_calib *calib = &data->calib;
>  
> -	ret = bmp180_read_calib(data, &calib);
> -	if (ret < 0) {
> -		dev_err(data->dev,
> -			"failed to read calibration coefficients\n");
> -		return ret;
> -	}
> -
> -	x1 = ((adc_temp - calib.AC6) * calib.AC5) >> 15;
> -	x2 = (calib.MC << 11) / (x1 + calib.MD);
> +	x1 = ((adc_temp - calib->AC6) * calib->AC5) >> 15;
> +	x2 = (calib->MC << 11) / (x1 + calib->MD);
>  	data->t_fine = x1 + x2;
>  
>  	return (data->t_fine + 8) >> 4;
> @@ -792,29 +789,21 @@ static int bmp180_read_adc_press(struct bmp280_data *data, int *val)
>   */
>  static u32 bmp180_compensate_press(struct bmp280_data *data, s32 adc_press)
>  {
> -	int ret;
>  	s32 x1, x2, x3, p;
>  	s32 b3, b6;
>  	u32 b4, b7;
>  	s32 oss = data->oversampling_press;
> -	struct bmp180_calib calib;
> -
> -	ret = bmp180_read_calib(data, &calib);
> -	if (ret < 0) {
> -		dev_err(data->dev,
> -			"failed to read calibration coefficients\n");
> -		return ret;
> -	}
> +	struct bmp180_calib *calib = &data->calib;
>  
>  	b6 = data->t_fine - 4000;
> -	x1 = (calib.B2 * (b6 * b6 >> 12)) >> 11;
> -	x2 = calib.AC2 * b6 >> 11;
> +	x1 = (calib->B2 * (b6 * b6 >> 12)) >> 11;
> +	x2 = calib->AC2 * b6 >> 11;
>  	x3 = x1 + x2;
> -	b3 = ((((s32)calib.AC1 * 4 + x3) << oss) + 2) / 4;
> -	x1 = calib.AC3 * b6 >> 13;
> -	x2 = (calib.B1 * ((b6 * b6) >> 12)) >> 16;
> +	b3 = ((((s32)calib->AC1 * 4 + x3) << oss) + 2) / 4;
> +	x1 = calib->AC3 * b6 >> 13;
> +	x2 = (calib->B1 * ((b6 * b6) >> 12)) >> 16;
>  	x3 = (x1 + x2 + 2) >> 2;
> -	b4 = calib.AC4 * (u32)(x3 + 32768) >> 15;
> +	b4 = calib->AC4 * (u32)(x3 + 32768) >> 15;
>  	b7 = ((u32)adc_press - b3) * (50000 >> oss);
>  	if (b7 < 0x80000000)
>  		p = (b7 * 2) / b4;
> @@ -1018,6 +1007,19 @@ int bmp280_common_probe(struct device *dev,
>  	dev_set_drvdata(dev, data);
>  
>  	/*
> +	 * The BMP085 and BMP180 has calibration in an E2PROM, read it out
> +	 * at probe time. It will not change.
> +	 */
> +	if (chip_id  == BMP180_CHIP_ID) {
> +		ret = bmp180_read_calib(data, &data->calib);
> +		if (ret < 0) {
> +			dev_err(data->dev,
> +				"failed to read calibration coefficients\n");
> +			goto out_disable_vdda;
> +		}
> +	}
> +
> +	/*
>  	 * 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.
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/10 v4] iio: pressure: bmp280: add support for BMP085 EOC interrupt
  2016-07-03 10:11   ` Jonathan Cameron
@ 2016-07-03 10:35     ` Jonathan Cameron
  0 siblings, 0 replies; 28+ messages in thread
From: Jonathan Cameron @ 2016-07-03 10:35 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Peter Meerwald-Stadler
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 03/07/16 11:11, Jonathan Cameron wrote:
> On 30/06/16 02:48, Linus Walleij wrote:
>> 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>
> Bit of fuzz on this + one unrelated change that I've simply dropped.
> If it matters to you send up a follow up patch.
Also build tests pointed out a function that should have been declared
static so did a fixup an repushed out with that.

Jonathan
>> ---
>> 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");
> Nothing whatsoever to do with this patch.
>>  		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);
>>
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 10/10 v4] iio: pressure: bmp280: read calibration data once
  2016-07-03 10:23   ` Jonathan Cameron
@ 2016-07-05 13:37     ` Linus Walleij
  0 siblings, 0 replies; 28+ messages in thread
From: Linus Walleij @ 2016-07-05 13:37 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio, Akinobu Mita, H. Nikolaus Schaller, Matt Ranostay,
	Peter Meerwald-Stadler, Christoph Mair, Vlad Dogaru,
	Hartmut Knaack, Marek Belisko, Eric Andersson, Neil Brown

On Sun, Jul 3, 2016 at 12:23 PM, Jonathan Cameron <jic23@kernel.org> wrote:
> On 30/06/16 02:48, Linus Walleij wrote:
>> The calibration data is described as coming from an E2PROM and that
>> means it does not change. Just read it once at probe time and store
>> it in the device state container. Also toss the calibration data
>> into the entropy pool since it is device unique.
>>
>> Reviewed-by: Vlad Dogaru <vlad.dogaru@intel.com>
>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> Applied with a whole 1 line of fuzz ;)

Thanks for applying and fixing my silly mistakes along the road.

Part of the churn comes from massaging review comments into
the patch set, I guess I just need to be more careful to build at
every step along the way when doing that.

But the patch splitting up the driver was driving me nuts with
the constant rebasing and drew a lot of focus, I blame it all on
that one.

Mostly the splitting and adding SPI interface was about obsoleting
the misc driver so it's for a higher cause....

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2016-07-05 13:37 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 08/10 v4] iio: pressure: bmp280: add support for BMP085 EOC interrupt Linus Walleij
2016-07-03 10:11   ` 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

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.