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

This is version two of the previous patchset. Changes:

- Rebased on top of Matt Ranostays BME280 support patch so everything
  applies cleanly on top of Jonathans development branch

- Added Akinobu Mitas special SPI bus handling code snippets

- Made the regulators non-optional: if the chip has supplies, it should
  have regulators for them

- Fixed review comments and build remarks provided by the zeroday
  build robot

Linus Walleij (9):
  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: read calibration data once

 .../devicetree/bindings/iio/pressure/bmp085.txt    |   15 +-
 drivers/iio/pressure/Kconfig                       |   29 +-
 drivers/iio/pressure/Makefile                      |    3 +
 drivers/iio/pressure/bmp280-core.c                 | 1009 ++++++++++++++++++
 drivers/iio/pressure/bmp280-i2c.c                  |   83 ++
 drivers/iio/pressure/bmp280-regmap.c               |   81 ++
 drivers/iio/pressure/bmp280-spi.c                  |  118 +++
 drivers/iio/pressure/bmp280.c                      | 1118 --------------------
 drivers/iio/pressure/bmp280.h                      |  108 ++
 9 files changed, 1437 insertions(+), 1127 deletions(-)
 create mode 100644 drivers/iio/pressure/bmp280-core.c
 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
 delete mode 100644 drivers/iio/pressure/bmp280.c
 create mode 100644 drivers/iio/pressure/bmp280.h

-- 
2.4.11


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

* [PATCH 1/9 v2] iio: pressure: bmp280: augment DT bindings
  2016-06-22 20:53 [PATCH 0/9] Improve BMP280 driver v2 Linus Walleij
@ 2016-06-22 20:53     ` Linus Walleij
  2016-06-22 20:53 ` [PATCH 2/9 v2] iio: pressure: bmp280: support device tree initialization Linus Walleij
                       ` (8 subsequent siblings)
  9 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2016-06-22 20:53 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio-u79uwXL29TY76Z2rM5mHXA, Akinobu Mita,
	H. Nikolaus Schaller, Matt Ranostay
  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 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

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 1/9 v2] iio: pressure: bmp280: augment DT bindings
@ 2016-06-22 20:53     ` Linus Walleij
  0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2016-06-22 20:53 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  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 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] 32+ messages in thread

* [PATCH 2/9 v2] iio: pressure: bmp280: support device tree initialization
  2016-06-22 20:53 [PATCH 0/9] Improve BMP280 driver v2 Linus Walleij
       [not found] ` <1466628819-29784-1-git-send-email-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2016-06-22 20:53 ` Linus Walleij
  2016-06-23  8:18   ` H. Nikolaus Schaller
  2016-06-26  9:52   ` Jonathan Cameron
  2016-06-22 20:53 ` [PATCH 3/9 v2] iio: pressure: bmp280: add reset GPIO line handling Linus Walleij
                   ` (7 subsequent siblings)
  9 siblings, 2 replies; 32+ messages in thread
From: Linus Walleij @ 2016-06-22 20:53 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  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 v1->v2:
- Fix some BMP085 misspelled as BMP058 errors.
- Add the new BME280 sensor as well
---
 drivers/iio/pressure/bmp280.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
index dbbcd6d83e3b..655e888ef8f9 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,18 @@ 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 +1120,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] 32+ messages in thread

* [PATCH 3/9 v2] iio: pressure: bmp280: add reset GPIO line handling
  2016-06-22 20:53 [PATCH 0/9] Improve BMP280 driver v2 Linus Walleij
       [not found] ` <1466628819-29784-1-git-send-email-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  2016-06-22 20:53 ` [PATCH 2/9 v2] iio: pressure: bmp280: support device tree initialization Linus Walleij
@ 2016-06-22 20:53 ` Linus Walleij
  2016-06-22 20:53 ` [PATCH 4/9 v2] iio: pressure: bmp280: support supply regulators Linus Walleij
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2016-06-22 20:53 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij

On the APQ8060 Dragonboard the reset line to the BMP058 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>
---
 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 655e888ef8f9..f7fd98e93850 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] 32+ messages in thread

* [PATCH 4/9 v2] iio: pressure: bmp280: support supply regulators
  2016-06-22 20:53 [PATCH 0/9] Improve BMP280 driver v2 Linus Walleij
                   ` (2 preceding siblings ...)
  2016-06-22 20:53 ` [PATCH 3/9 v2] iio: pressure: bmp280: add reset GPIO line handling Linus Walleij
@ 2016-06-22 20:53 ` Linus Walleij
  2016-06-23 10:02   ` Mark Brown
  2016-06-22 20:53 ` [PATCH 5/9 v2] iio: pressure: bmp280: split driver in logical parts Linus Walleij
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2016-06-22 20:53 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Linus Walleij, Mark Brown

The BMP058/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 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.
---
 drivers/iio/pressure/bmp280.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
index f7fd98e93850..3051e7c444d2 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,8 @@ struct bmp280_data {
 	struct mutex lock;
 	struct regmap *regmap;
 	const struct bmp280_chip_info *chip_info;
+	struct regulator *vddd;
+	struct regulator *vdda;
 
 	/* log of base 2 of oversampling rate */
 	u8 oversampling_press;
@@ -1065,6 +1068,28 @@ static int bmp280_probe(struct i2c_client *client,
 		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");
+		return PTR_ERR(data->vddd);
+	}
+	ret = regulator_enable(data->vdda);
+	if (ret) {
+		dev_err(&client->dev, "failed to enable VDDA\n");
+		return ret;
+	}
+
 	/* 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 */
-- 
2.4.11

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

* [PATCH 5/9 v2] iio: pressure: bmp280: split driver in logical parts
  2016-06-22 20:53 [PATCH 0/9] Improve BMP280 driver v2 Linus Walleij
                   ` (3 preceding siblings ...)
  2016-06-22 20:53 ` [PATCH 4/9 v2] iio: pressure: bmp280: support supply regulators Linus Walleij
@ 2016-06-22 20:53 ` Linus Walleij
  2016-06-23  8:18   ` H. Nikolaus Schaller
  2016-06-26 10:04   ` Jonathan Cameron
  2016-06-22 20:53 ` [PATCH 6/9 v2] iio: pressure: bmp280: split off an I2C Kconfig entry Linus Walleij
                   ` (4 subsequent siblings)
  9 siblings, 2 replies; 32+ messages in thread
From: Linus Walleij @ 2016-06-22 20:53 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  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 v1->v2:
- Rebased on top of Matt Ranostays BME280 with humidity sensor support
---
 drivers/iio/pressure/Makefile        |    1 +
 drivers/iio/pressure/bmp280-core.c   |  937 +++++++++++++++++++++++++++
 drivers/iio/pressure/bmp280-i2c.c    |   82 +++
 drivers/iio/pressure/bmp280-regmap.c |   81 +++
 drivers/iio/pressure/bmp280.c        | 1167 ----------------------------------
 drivers/iio/pressure/bmp280.h        |  107 ++++
 6 files changed, 1208 insertions(+), 1167 deletions(-)
 create mode 100644 drivers/iio/pressure/bmp280-core.c
 create mode 100644 drivers/iio/pressure/bmp280-i2c.c
 create mode 100644 drivers/iio/pressure/bmp280-regmap.c
 delete mode 100644 drivers/iio/pressure/bmp280.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-core.c b/drivers/iio/pressure/bmp280-core.c
new file mode 100644
index 000000000000..77f0fc935c09
--- /dev/null
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -0,0 +1,937 @@
+/*
+ * Copyright (c) 2014 Intel Corporation
+ *
+ * Driver for Bosch Sensortec BMP180 and BMP280 digital pressure sensor.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Datasheet:
+ * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP180-DS000-121.pdf
+ * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP280-DS001-12.pdf
+ * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_DS001-11.pdf
+ */
+
+#define pr_fmt(fmt) "bmp280: " fmt
+
+#include <linux/device.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
+
+#include "bmp280.h"
+
+struct bmp280_data {
+	struct device *dev;
+	struct mutex lock;
+	struct regmap *regmap;
+	const struct bmp280_chip_info *chip_info;
+	struct regulator *vddd;
+	struct regulator *vdda;
+
+	/* log of base 2 of oversampling rate */
+	u8 oversampling_press;
+	u8 oversampling_temp;
+	u8 oversampling_humid;
+
+	/*
+	 * Carryover value from temperature conversion, used in pressure
+	 * calculation.
+	 */
+	s32 t_fine;
+};
+
+struct bmp280_chip_info {
+	const int *oversampling_temp_avail;
+	int num_oversampling_temp_avail;
+
+	const int *oversampling_press_avail;
+	int num_oversampling_press_avail;
+
+	const int *oversampling_humid_avail;
+	int num_oversampling_humid_avail;
+
+	int (*chip_config)(struct bmp280_data *);
+	int (*read_temp)(struct bmp280_data *, int *);
+	int (*read_press)(struct bmp280_data *, int *, int *);
+	int (*read_humid)(struct bmp280_data *, int *, int *);
+};
+
+/*
+ * These enums are used for indexing into the array of compensation
+ * parameters for BMP280.
+ */
+enum { T1, T2, T3 };
+enum { P1, P2, P3, P4, P5, P6, P7, P8, P9 };
+
+static const struct iio_chan_spec bmp280_channels[] = {
+	{
+		.type = IIO_PRESSURE,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
+				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
+	},
+	{
+		.type = IIO_TEMP,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
+				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
+	},
+	{
+		.type = IIO_HUMIDITYRELATIVE,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
+				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
+	},
+};
+
+/*
+ * Returns humidity in percent, resolution is 0.01 percent. Output value of
+ * "47445" represents 47445/1024 = 46.333 %RH.
+ *
+ * Taken from BME280 datasheet, Section 4.2.3, "Compensation formula".
+ */
+
+static u32 bmp280_compensate_humidity(struct bmp280_data *data,
+				      s32 adc_humidity)
+{
+	struct device *dev = data->dev;
+	unsigned int H1, H3, tmp;
+	int H2, H4, H5, H6, ret, var;
+
+	ret = regmap_read(data->regmap, BMP280_REG_COMP_H1, &H1);
+	if (ret < 0) {
+		dev_err(dev, "failed to read H1 comp value\n");
+		return ret;
+	}
+
+	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H2, &tmp, 2);
+	if (ret < 0) {
+		dev_err(dev, "failed to read H2 comp value\n");
+		return ret;
+	}
+	H2 = sign_extend32(le16_to_cpu(tmp), 15);
+
+	ret = regmap_read(data->regmap, BMP280_REG_COMP_H3, &H3);
+	if (ret < 0) {
+		dev_err(dev, "failed to read H3 comp value\n");
+		return ret;
+	}
+
+	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H4, &tmp, 2);
+	if (ret < 0) {
+		dev_err(dev, "failed to read H4 comp value\n");
+		return ret;
+	}
+	H4 = sign_extend32(((be16_to_cpu(tmp) >> 4) & 0xff0) |
+			  (be16_to_cpu(tmp) & 0xf), 11);
+
+	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H5, &tmp, 2);
+	if (ret < 0) {
+		dev_err(dev, "failed to read H5 comp value\n");
+		return ret;
+	}
+	H5 = sign_extend32(((le16_to_cpu(tmp) >> 4) & 0xfff), 11);
+
+	ret = regmap_read(data->regmap, BMP280_REG_COMP_H6, &tmp);
+	if (ret < 0) {
+		dev_err(dev, "failed to read H6 comp value\n");
+		return ret;
+	}
+	H6 = sign_extend32(tmp, 7);
+
+	var = ((s32)data->t_fine) - 76800;
+	var = ((((adc_humidity << 14) - (H4 << 20) - (H5 * var)) + 16384) >> 15)
+		* (((((((var * H6) >> 10) * (((var * H3) >> 11) + 32768)) >> 10)
+		+ 2097152) * H2 + 8192) >> 14);
+	var -= ((((var >> 15) * (var >> 15)) >> 7) * H1) >> 4;
+
+	return var >> 12;
+};
+
+/*
+ * Returns temperature in DegC, resolution is 0.01 DegC.  Output value of
+ * "5123" equals 51.23 DegC.  t_fine carries fine temperature as global
+ * value.
+ *
+ * Taken from datasheet, Section 3.11.3, "Compensation formula".
+ */
+static s32 bmp280_compensate_temp(struct bmp280_data *data,
+				  s32 adc_temp)
+{
+	int ret;
+	s32 var1, var2;
+	__le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2];
+
+	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START,
+			       buf, BMP280_COMP_TEMP_REG_COUNT);
+	if (ret < 0) {
+		dev_err(data->dev,
+			"failed to read temperature calibration parameters\n");
+		return ret;
+	}
+
+	/*
+	 * The double casts are necessary because le16_to_cpu returns an
+	 * unsigned 16-bit value.  Casting that value directly to a
+	 * signed 32-bit will not do proper sign extension.
+	 *
+	 * Conversely, T1 and P1 are unsigned values, so they can be
+	 * cast straight to the larger type.
+	 */
+	var1 = (((adc_temp >> 3) - ((s32)le16_to_cpu(buf[T1]) << 1)) *
+		((s32)(s16)le16_to_cpu(buf[T2]))) >> 11;
+	var2 = (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) *
+		  ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> 12) *
+		((s32)(s16)le16_to_cpu(buf[T3]))) >> 14;
+	data->t_fine = var1 + var2;
+
+	return (data->t_fine * 5 + 128) >> 8;
+}
+
+/*
+ * Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24
+ * integer bits and 8 fractional bits).  Output value of "24674867"
+ * represents 24674867/256 = 96386.2 Pa = 963.862 hPa
+ *
+ * Taken from datasheet, Section 3.11.3, "Compensation formula".
+ */
+static u32 bmp280_compensate_press(struct bmp280_data *data,
+				   s32 adc_press)
+{
+	int ret;
+	s64 var1, var2, p;
+	__le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2];
+
+	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
+			       buf, BMP280_COMP_PRESS_REG_COUNT);
+	if (ret < 0) {
+		dev_err(data->dev,
+			"failed to read pressure calibration parameters\n");
+		return ret;
+	}
+
+	var1 = ((s64)data->t_fine) - 128000;
+	var2 = var1 * var1 * (s64)(s16)le16_to_cpu(buf[P6]);
+	var2 += (var1 * (s64)(s16)le16_to_cpu(buf[P5])) << 17;
+	var2 += ((s64)(s16)le16_to_cpu(buf[P4])) << 35;
+	var1 = ((var1 * var1 * (s64)(s16)le16_to_cpu(buf[P3])) >> 8) +
+		((var1 * (s64)(s16)le16_to_cpu(buf[P2])) << 12);
+	var1 = ((((s64)1) << 47) + var1) * ((s64)le16_to_cpu(buf[P1])) >> 33;
+
+	if (var1 == 0)
+		return 0;
+
+	p = ((((s64)1048576 - adc_press) << 31) - var2) * 3125;
+	p = div64_s64(p, var1);
+	var1 = (((s64)(s16)le16_to_cpu(buf[P9])) * (p >> 13) * (p >> 13)) >> 25;
+	var2 = (((s64)(s16)le16_to_cpu(buf[P8])) * p) >> 19;
+	p = ((p + var1 + var2) >> 8) + (((s64)(s16)le16_to_cpu(buf[P7])) << 4);
+
+	return (u32)p;
+}
+
+static int bmp280_read_temp(struct bmp280_data *data,
+			    int *val)
+{
+	int ret;
+	__be32 tmp = 0;
+	s32 adc_temp, comp_temp;
+
+	ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB,
+			       (u8 *) &tmp, 3);
+	if (ret < 0) {
+		dev_err(data->dev, "failed to read temperature\n");
+		return ret;
+	}
+
+	adc_temp = be32_to_cpu(tmp) >> 12;
+	comp_temp = bmp280_compensate_temp(data, adc_temp);
+
+	/*
+	 * val might be NULL if we're called by the read_press routine,
+	 * who only cares about the carry over t_fine value.
+	 */
+	if (val) {
+		*val = comp_temp * 10;
+		return IIO_VAL_INT;
+	}
+
+	return 0;
+}
+
+static int bmp280_read_press(struct bmp280_data *data,
+			     int *val, int *val2)
+{
+	int ret;
+	__be32 tmp = 0;
+	s32 adc_press;
+	u32 comp_press;
+
+	/* Read and compensate temperature so we get a reading of t_fine. */
+	ret = bmp280_read_temp(data, NULL);
+	if (ret < 0)
+		return ret;
+
+	ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB,
+			       (u8 *) &tmp, 3);
+	if (ret < 0) {
+		dev_err(data->dev, "failed to read pressure\n");
+		return ret;
+	}
+
+	adc_press = be32_to_cpu(tmp) >> 12;
+	comp_press = bmp280_compensate_press(data, adc_press);
+
+	*val = comp_press;
+	*val2 = 256000;
+
+	return IIO_VAL_FRACTIONAL;
+}
+
+static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
+{
+	int ret;
+	__be16 tmp = 0;
+	s32 adc_humidity;
+	u32 comp_humidity;
+
+	/* Read and compensate temperature so we get a reading of t_fine. */
+	ret = bmp280_read_temp(data, NULL);
+	if (ret < 0)
+		return ret;
+
+	ret = regmap_bulk_read(data->regmap, BMP280_REG_HUMIDITY_MSB,
+			       (u8 *) &tmp, 2);
+	if (ret < 0) {
+		dev_err(data->dev, "failed to read humidity\n");
+		return ret;
+	}
+
+	adc_humidity = be16_to_cpu(tmp);
+	comp_humidity = bmp280_compensate_humidity(data, adc_humidity);
+
+	*val = comp_humidity;
+	*val2 = 1024;
+
+	return IIO_VAL_FRACTIONAL;
+}
+
+static int bmp280_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val, int *val2, long mask)
+{
+	int ret;
+	struct bmp280_data *data = iio_priv(indio_dev);
+
+	mutex_lock(&data->lock);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_PROCESSED:
+		switch (chan->type) {
+		case IIO_HUMIDITYRELATIVE:
+			ret = data->chip_info->read_humid(data, val, val2);
+			break;
+		case IIO_PRESSURE:
+			ret = data->chip_info->read_press(data, val, val2);
+			break;
+		case IIO_TEMP:
+			ret = data->chip_info->read_temp(data, val);
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+		break;
+	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		switch (chan->type) {
+		case IIO_HUMIDITYRELATIVE:
+			*val = 1 << data->oversampling_humid;
+			ret = IIO_VAL_INT;
+			break;
+		case IIO_PRESSURE:
+			*val = 1 << data->oversampling_press;
+			ret = IIO_VAL_INT;
+			break;
+		case IIO_TEMP:
+			*val = 1 << data->oversampling_temp;
+			ret = IIO_VAL_INT;
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int bmp280_write_oversampling_ratio_humid(struct bmp280_data *data,
+					       int val)
+{
+	int i;
+	const int *avail = data->chip_info->oversampling_humid_avail;
+	const int n = data->chip_info->num_oversampling_humid_avail;
+
+	for (i = 0; i < n; i++) {
+		if (avail[i] == val) {
+			data->oversampling_humid = ilog2(val);
+
+			return data->chip_info->chip_config(data);
+		}
+	}
+	return -EINVAL;
+}
+
+static int bmp280_write_oversampling_ratio_temp(struct bmp280_data *data,
+					       int val)
+{
+	int i;
+	const int *avail = data->chip_info->oversampling_temp_avail;
+	const int n = data->chip_info->num_oversampling_temp_avail;
+
+	for (i = 0; i < n; i++) {
+		if (avail[i] == val) {
+			data->oversampling_temp = ilog2(val);
+
+			return data->chip_info->chip_config(data);
+		}
+	}
+	return -EINVAL;
+}
+
+static int bmp280_write_oversampling_ratio_press(struct bmp280_data *data,
+					       int val)
+{
+	int i;
+	const int *avail = data->chip_info->oversampling_press_avail;
+	const int n = data->chip_info->num_oversampling_press_avail;
+
+	for (i = 0; i < n; i++) {
+		if (avail[i] == val) {
+			data->oversampling_press = ilog2(val);
+
+			return data->chip_info->chip_config(data);
+		}
+	}
+	return -EINVAL;
+}
+
+static int bmp280_write_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int val, int val2, long mask)
+{
+	int ret = 0;
+	struct bmp280_data *data = iio_priv(indio_dev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
+		mutex_lock(&data->lock);
+		switch (chan->type) {
+		case IIO_HUMIDITYRELATIVE:
+			ret = bmp280_write_oversampling_ratio_humid(data, val);
+			break;
+		case IIO_PRESSURE:
+			ret = bmp280_write_oversampling_ratio_press(data, val);
+			break;
+		case IIO_TEMP:
+			ret = bmp280_write_oversampling_ratio_temp(data, val);
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+		mutex_unlock(&data->lock);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static ssize_t bmp280_show_avail(char *buf, const int *vals, const int n)
+{
+	size_t len = 0;
+	int i;
+
+	for (i = 0; i < n; i++)
+		len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", vals[i]);
+
+	buf[len - 1] = '\n';
+
+	return len;
+}
+
+static ssize_t bmp280_show_temp_oversampling_avail(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct bmp280_data *data = iio_priv(dev_to_iio_dev(dev));
+
+	return bmp280_show_avail(buf, data->chip_info->oversampling_temp_avail,
+				 data->chip_info->num_oversampling_temp_avail);
+}
+
+static ssize_t bmp280_show_press_oversampling_avail(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct bmp280_data *data = iio_priv(dev_to_iio_dev(dev));
+
+	return bmp280_show_avail(buf, data->chip_info->oversampling_press_avail,
+				 data->chip_info->num_oversampling_press_avail);
+}
+
+static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available,
+	S_IRUGO, bmp280_show_temp_oversampling_avail, NULL, 0);
+
+static IIO_DEVICE_ATTR(in_pressure_oversampling_ratio_available,
+	S_IRUGO, bmp280_show_press_oversampling_avail, NULL, 0);
+
+static struct attribute *bmp280_attributes[] = {
+	&iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr,
+	&iio_dev_attr_in_pressure_oversampling_ratio_available.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group bmp280_attrs_group = {
+	.attrs = bmp280_attributes,
+};
+
+static const struct iio_info bmp280_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &bmp280_read_raw,
+	.write_raw = &bmp280_write_raw,
+	.attrs = &bmp280_attrs_group,
+};
+
+static int bmp280_chip_config(struct bmp280_data *data)
+{
+	int ret;
+	u8 osrs = BMP280_OSRS_TEMP_X(data->oversampling_temp + 1) |
+		  BMP280_OSRS_PRESS_X(data->oversampling_press + 1);
+
+	ret = regmap_update_bits(data->regmap, BMP280_REG_CTRL_MEAS,
+				 BMP280_OSRS_TEMP_MASK |
+				 BMP280_OSRS_PRESS_MASK |
+				 BMP280_MODE_MASK,
+				 osrs | BMP280_MODE_NORMAL);
+	if (ret < 0) {
+		dev_err(data->dev,
+			"failed to write ctrl_meas register\n");
+		return ret;
+	}
+
+	ret = regmap_update_bits(data->regmap, BMP280_REG_CONFIG,
+				 BMP280_FILTER_MASK,
+				 BMP280_FILTER_4X);
+	if (ret < 0) {
+		dev_err(data->dev,
+			"failed to write config register\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 };
+
+static const struct bmp280_chip_info bmp280_chip_info = {
+	.oversampling_temp_avail = bmp280_oversampling_avail,
+	.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
+
+	.oversampling_press_avail = bmp280_oversampling_avail,
+	.num_oversampling_press_avail = ARRAY_SIZE(bmp280_oversampling_avail),
+
+	.chip_config = bmp280_chip_config,
+	.read_temp = bmp280_read_temp,
+	.read_press = bmp280_read_press,
+};
+
+static int bme280_chip_config(struct bmp280_data *data)
+{
+	int ret = bmp280_chip_config(data);
+	u8 osrs = BMP280_OSRS_HUMIDITIY_X(data->oversampling_humid + 1);
+
+	if (ret < 0)
+		return ret;
+
+	return regmap_update_bits(data->regmap, BMP280_REG_CTRL_HUMIDITY,
+				  BMP280_OSRS_HUMIDITY_MASK, osrs);
+}
+
+static const struct bmp280_chip_info bme280_chip_info = {
+	.oversampling_temp_avail = bmp280_oversampling_avail,
+	.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
+
+	.oversampling_press_avail = bmp280_oversampling_avail,
+	.num_oversampling_press_avail = ARRAY_SIZE(bmp280_oversampling_avail),
+
+	.oversampling_humid_avail = bmp280_oversampling_avail,
+	.num_oversampling_humid_avail = ARRAY_SIZE(bmp280_oversampling_avail),
+
+	.chip_config = bme280_chip_config,
+	.read_temp = bmp280_read_temp,
+	.read_press = bmp280_read_press,
+	.read_humid = bmp280_read_humid,
+};
+
+static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas)
+{
+	int ret;
+	const int conversion_time_max[] = { 4500, 7500, 13500, 25500 };
+	unsigned int delay_us;
+	unsigned int ctrl;
+
+	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);
+
+	ret = regmap_read(data->regmap, BMP280_REG_CTRL_MEAS, &ctrl);
+	if (ret)
+		return ret;
+
+	/* The value of this bit reset to "0" after conversion is complete */
+	if (ctrl & BMP180_MEAS_SCO)
+		return -EIO;
+
+	return 0;
+}
+
+static int bmp180_read_adc_temp(struct bmp280_data *data, int *val)
+{
+	int ret;
+	__be16 tmp = 0;
+
+	ret = bmp180_measure(data, BMP180_MEAS_TEMP);
+	if (ret)
+		return ret;
+
+	ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 *)&tmp, 2);
+	if (ret)
+		return ret;
+
+	*val = be16_to_cpu(tmp);
+
+	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)
+{
+	int ret;
+	int i;
+	__be16 buf[BMP180_REG_CALIB_COUNT / 2];
+
+	ret = regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, buf,
+			       sizeof(buf));
+
+	if (ret < 0)
+		return ret;
+
+	/* None of the words has the value 0 or 0xFFFF */
+	for (i = 0; i < ARRAY_SIZE(buf); i++) {
+		if (buf[i] == cpu_to_be16(0) || buf[i] == cpu_to_be16(0xffff))
+			return -EIO;
+	}
+
+	calib->AC1 = be16_to_cpu(buf[AC1]);
+	calib->AC2 = be16_to_cpu(buf[AC2]);
+	calib->AC3 = be16_to_cpu(buf[AC3]);
+	calib->AC4 = be16_to_cpu(buf[AC4]);
+	calib->AC5 = be16_to_cpu(buf[AC5]);
+	calib->AC6 = be16_to_cpu(buf[AC6]);
+	calib->B1 = be16_to_cpu(buf[B1]);
+	calib->B2 = be16_to_cpu(buf[B2]);
+	calib->MB = be16_to_cpu(buf[MB]);
+	calib->MC = be16_to_cpu(buf[MC]);
+	calib->MD = be16_to_cpu(buf[MD]);
+
+	return 0;
+}
+
+/*
+ * Returns temperature in DegC, resolution is 0.1 DegC.
+ * t_fine carries fine temperature as global value.
+ *
+ * Taken from datasheet, Section 3.5, "Calculating pressure and temperature".
+ */
+static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp)
+{
+	int ret;
+	s32 x1, x2;
+	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;
+	}
+
+	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;
+}
+
+static int bmp180_read_temp(struct bmp280_data *data, int *val)
+{
+	int ret;
+	s32 adc_temp, comp_temp;
+
+	ret = bmp180_read_adc_temp(data, &adc_temp);
+	if (ret)
+		return ret;
+
+	comp_temp = bmp180_compensate_temp(data, adc_temp);
+
+	/*
+	 * val might be NULL if we're called by the read_press routine,
+	 * who only cares about the carry over t_fine value.
+	 */
+	if (val) {
+		*val = comp_temp * 100;
+		return IIO_VAL_INT;
+	}
+
+	return 0;
+}
+
+static int bmp180_read_adc_press(struct bmp280_data *data, int *val)
+{
+	int ret;
+	__be32 tmp = 0;
+	u8 oss = data->oversampling_press;
+
+	ret = bmp180_measure(data, BMP180_MEAS_PRESS_X(oss));
+	if (ret)
+		return ret;
+
+	ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 *)&tmp, 3);
+	if (ret)
+		return ret;
+
+	*val = (be32_to_cpu(tmp) >> 8) >> (8 - oss);
+
+	return 0;
+}
+
+/*
+ * Returns pressure in Pa, resolution is 1 Pa.
+ *
+ * Taken from datasheet, Section 3.5, "Calculating pressure and temperature".
+ */
+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;
+	}
+
+	b6 = data->t_fine - 4000;
+	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;
+	x3 = (x1 + x2 + 2) >> 2;
+	b4 = calib.AC4 * (u32)(x3 + 32768) >> 15;
+	b7 = ((u32)adc_press - b3) * (50000 >> oss);
+	if (b7 < 0x80000000)
+		p = (b7 * 2) / b4;
+	else
+		p = (b7 / b4) * 2;
+
+	x1 = (p >> 8) * (p >> 8);
+	x1 = (x1 * 3038) >> 16;
+	x2 = (-7357 * p) >> 16;
+
+	return p + ((x1 + x2 + 3791) >> 4);
+}
+
+static int bmp180_read_press(struct bmp280_data *data,
+			     int *val, int *val2)
+{
+	int ret;
+	s32 adc_press;
+	u32 comp_press;
+
+	/* Read and compensate temperature so we get a reading of t_fine. */
+	ret = bmp180_read_temp(data, NULL);
+	if (ret)
+		return ret;
+
+	ret = bmp180_read_adc_press(data, &adc_press);
+	if (ret)
+		return ret;
+
+	comp_press = bmp180_compensate_press(data, adc_press);
+
+	*val = comp_press;
+	*val2 = 1000;
+
+	return IIO_VAL_FRACTIONAL;
+}
+
+static int bmp180_chip_config(struct bmp280_data *data)
+{
+	return 0;
+}
+
+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 = {
+	.oversampling_temp_avail = bmp180_oversampling_temp_avail,
+	.num_oversampling_temp_avail =
+		ARRAY_SIZE(bmp180_oversampling_temp_avail),
+
+	.oversampling_press_avail = bmp180_oversampling_press_avail,
+	.num_oversampling_press_avail =
+		ARRAY_SIZE(bmp180_oversampling_press_avail),
+
+	.chip_config = bmp180_chip_config,
+	.read_temp = bmp180_read_temp,
+	.read_press = bmp180_read_press,
+};
+
+int bmp280_common_probe(struct device *dev,
+			struct regmap *regmap,
+			unsigned int chip,
+			const char *name)
+{
+	int ret;
+	struct iio_dev *indio_dev;
+	struct bmp280_data *data;
+	unsigned int chip_id;
+	struct gpio_desc *gpiod;
+
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	data = iio_priv(indio_dev);
+	mutex_init(&data->lock);
+	data->dev = dev;
+
+	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 (chip) {
+	case BMP180_CHIP_ID:
+		indio_dev->num_channels = 2;
+		data->chip_info = &bmp180_chip_info;
+		data->oversampling_press = ilog2(8);
+		data->oversampling_temp = ilog2(1);
+		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);
+		break;
+	case BME280_CHIP_ID:
+		indio_dev->num_channels = 3;
+		data->chip_info = &bme280_chip_info;
+		data->oversampling_press = ilog2(16);
+		data->oversampling_humid = ilog2(16);
+		data->oversampling_temp = ilog2(2);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Bring up regulators */
+	data->vddd = devm_regulator_get(dev, "vddd");
+	if (IS_ERR(data->vddd)) {
+		dev_err(dev, "failed to get VDDD regulator\n");
+		return PTR_ERR(data->vddd);
+	}
+	ret = regulator_enable(data->vddd);
+	if (ret) {
+		dev_err(dev, "failed to enable VDDD regulator\n");
+		return ret;
+	}
+	data->vdda = devm_regulator_get(dev, "vdda");
+	if (IS_ERR(data->vdda)) {
+		dev_err(dev, "failed to get VDDA regulator\n");
+		return PTR_ERR(data->vddd);
+	}
+	ret = regulator_enable(data->vdda);
+	if (ret) {
+		dev_err(dev, "failed to enable VDDA\n");
+		return ret;
+	}
+
+	/* Bring chip out of reset if there is an assigned GPIO line */
+	gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+	/* Deassert the signal */
+	if (!IS_ERR(gpiod)) {
+		dev_info(dev, "release reset\n");
+		gpiod_set_value(gpiod, 0);
+	}
+
+	data->regmap = regmap;
+	ret = regmap_read(regmap, BMP280_REG_ID, &chip_id);
+	if (ret < 0)
+		return ret;
+	if (chip_id != chip) {
+		dev_err(dev, "bad chip id: expected %x got %x\n",
+			chip, chip_id);
+		return -EINVAL;
+	}
+
+	ret = data->chip_info->chip_config(data);
+	if (ret < 0)
+		return ret;
+
+	return devm_iio_device_register(dev, indio_dev);
+}
diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c
new file mode 100644
index 000000000000..a981670e5dc0
--- /dev/null
+++ b/drivers/iio/pressure/bmp280-i2c.c
@@ -0,0 +1,82 @@
+#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 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,
+	.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.c b/drivers/iio/pressure/bmp280.c
deleted file mode 100644
index 3051e7c444d2..000000000000
--- a/drivers/iio/pressure/bmp280.c
+++ /dev/null
@@ -1,1167 +0,0 @@
-/*
- * Copyright (c) 2014 Intel Corporation
- *
- * Driver for Bosch Sensortec BMP180 and BMP280 digital pressure sensor.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Datasheet:
- * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP180-DS000-121.pdf
- * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP280-DS001-12.pdf
- * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_DS001-11.pdf
- */
-
-#define pr_fmt(fmt) "bmp280: " fmt
-
-#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>
-#include <linux/iio/sysfs.h>
-#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
-
-struct bmp280_data {
-	struct i2c_client *client;
-	struct mutex lock;
-	struct regmap *regmap;
-	const struct bmp280_chip_info *chip_info;
-	struct regulator *vddd;
-	struct regulator *vdda;
-
-	/* log of base 2 of oversampling rate */
-	u8 oversampling_press;
-	u8 oversampling_temp;
-	u8 oversampling_humid;
-
-	/*
-	 * Carryover value from temperature conversion, used in pressure
-	 * calculation.
-	 */
-	s32 t_fine;
-};
-
-struct bmp280_chip_info {
-	const struct regmap_config *regmap_config;
-
-	const int *oversampling_temp_avail;
-	int num_oversampling_temp_avail;
-
-	const int *oversampling_press_avail;
-	int num_oversampling_press_avail;
-
-	const int *oversampling_humid_avail;
-	int num_oversampling_humid_avail;
-
-	int (*chip_config)(struct bmp280_data *);
-	int (*read_temp)(struct bmp280_data *, int *);
-	int (*read_press)(struct bmp280_data *, int *, int *);
-	int (*read_humid)(struct bmp280_data *, int *, int *);
-};
-
-/*
- * These enums are used for indexing into the array of compensation
- * parameters for BMP280.
- */
-enum { T1, T2, T3 };
-enum { P1, P2, P3, P4, P5, P6, P7, P8, P9 };
-
-static const struct iio_chan_spec bmp280_channels[] = {
-	{
-		.type = IIO_PRESSURE,
-		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
-				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
-	},
-	{
-		.type = IIO_TEMP,
-		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
-				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
-	},
-	{
-		.type = IIO_HUMIDITYRELATIVE,
-		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
-				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
-	},
-};
-
-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.
- *
- * Taken from BME280 datasheet, Section 4.2.3, "Compensation formula".
- */
-
-static u32 bmp280_compensate_humidity(struct bmp280_data *data,
-				      s32 adc_humidity)
-{
-	struct device *dev = &data->client->dev;
-	unsigned int H1, H3, tmp;
-	int H2, H4, H5, H6, ret, var;
-
-	ret = regmap_read(data->regmap, BMP280_REG_COMP_H1, &H1);
-	if (ret < 0) {
-		dev_err(dev, "failed to read H1 comp value\n");
-		return ret;
-	}
-
-	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H2, &tmp, 2);
-	if (ret < 0) {
-		dev_err(dev, "failed to read H2 comp value\n");
-		return ret;
-	}
-	H2 = sign_extend32(le16_to_cpu(tmp), 15);
-
-	ret = regmap_read(data->regmap, BMP280_REG_COMP_H3, &H3);
-	if (ret < 0) {
-		dev_err(dev, "failed to read H3 comp value\n");
-		return ret;
-	}
-
-	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H4, &tmp, 2);
-	if (ret < 0) {
-		dev_err(dev, "failed to read H4 comp value\n");
-		return ret;
-	}
-	H4 = sign_extend32(((be16_to_cpu(tmp) >> 4) & 0xff0) |
-			  (be16_to_cpu(tmp) & 0xf), 11);
-
-	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H5, &tmp, 2);
-	if (ret < 0) {
-		dev_err(dev, "failed to read H5 comp value\n");
-		return ret;
-	}
-	H5 = sign_extend32(((le16_to_cpu(tmp) >> 4) & 0xfff), 11);
-
-	ret = regmap_read(data->regmap, BMP280_REG_COMP_H6, &tmp);
-	if (ret < 0) {
-		dev_err(dev, "failed to read H6 comp value\n");
-		return ret;
-	}
-	H6 = sign_extend32(tmp, 7);
-
-	var = ((s32)data->t_fine) - 76800;
-	var = ((((adc_humidity << 14) - (H4 << 20) - (H5 * var)) + 16384) >> 15)
-		* (((((((var * H6) >> 10) * (((var * H3) >> 11) + 32768)) >> 10)
-		+ 2097152) * H2 + 8192) >> 14);
-	var -= ((((var >> 15) * (var >> 15)) >> 7) * H1) >> 4;
-
-	return var >> 12;
-};
-
-/*
- * Returns temperature in DegC, resolution is 0.01 DegC.  Output value of
- * "5123" equals 51.23 DegC.  t_fine carries fine temperature as global
- * value.
- *
- * Taken from datasheet, Section 3.11.3, "Compensation formula".
- */
-static s32 bmp280_compensate_temp(struct bmp280_data *data,
-				  s32 adc_temp)
-{
-	int ret;
-	s32 var1, var2;
-	__le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2];
-
-	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,
-			"failed to read temperature calibration parameters\n");
-		return ret;
-	}
-
-	/*
-	 * The double casts are necessary because le16_to_cpu returns an
-	 * unsigned 16-bit value.  Casting that value directly to a
-	 * signed 32-bit will not do proper sign extension.
-	 *
-	 * Conversely, T1 and P1 are unsigned values, so they can be
-	 * cast straight to the larger type.
-	 */
-	var1 = (((adc_temp >> 3) - ((s32)le16_to_cpu(buf[T1]) << 1)) *
-		((s32)(s16)le16_to_cpu(buf[T2]))) >> 11;
-	var2 = (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) *
-		  ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> 12) *
-		((s32)(s16)le16_to_cpu(buf[T3]))) >> 14;
-	data->t_fine = var1 + var2;
-
-	return (data->t_fine * 5 + 128) >> 8;
-}
-
-/*
- * Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24
- * integer bits and 8 fractional bits).  Output value of "24674867"
- * represents 24674867/256 = 96386.2 Pa = 963.862 hPa
- *
- * Taken from datasheet, Section 3.11.3, "Compensation formula".
- */
-static u32 bmp280_compensate_press(struct bmp280_data *data,
-				   s32 adc_press)
-{
-	int ret;
-	s64 var1, var2, p;
-	__le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2];
-
-	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,
-			"failed to read pressure calibration parameters\n");
-		return ret;
-	}
-
-	var1 = ((s64)data->t_fine) - 128000;
-	var2 = var1 * var1 * (s64)(s16)le16_to_cpu(buf[P6]);
-	var2 += (var1 * (s64)(s16)le16_to_cpu(buf[P5])) << 17;
-	var2 += ((s64)(s16)le16_to_cpu(buf[P4])) << 35;
-	var1 = ((var1 * var1 * (s64)(s16)le16_to_cpu(buf[P3])) >> 8) +
-		((var1 * (s64)(s16)le16_to_cpu(buf[P2])) << 12);
-	var1 = ((((s64)1) << 47) + var1) * ((s64)le16_to_cpu(buf[P1])) >> 33;
-
-	if (var1 == 0)
-		return 0;
-
-	p = ((((s64)1048576 - adc_press) << 31) - var2) * 3125;
-	p = div64_s64(p, var1);
-	var1 = (((s64)(s16)le16_to_cpu(buf[P9])) * (p >> 13) * (p >> 13)) >> 25;
-	var2 = (((s64)(s16)le16_to_cpu(buf[P8])) * p) >> 19;
-	p = ((p + var1 + var2) >> 8) + (((s64)(s16)le16_to_cpu(buf[P7])) << 4);
-
-	return (u32)p;
-}
-
-static int bmp280_read_temp(struct bmp280_data *data,
-			    int *val)
-{
-	int ret;
-	__be32 tmp = 0;
-	s32 adc_temp, comp_temp;
-
-	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");
-		return ret;
-	}
-
-	adc_temp = be32_to_cpu(tmp) >> 12;
-	comp_temp = bmp280_compensate_temp(data, adc_temp);
-
-	/*
-	 * val might be NULL if we're called by the read_press routine,
-	 * who only cares about the carry over t_fine value.
-	 */
-	if (val) {
-		*val = comp_temp * 10;
-		return IIO_VAL_INT;
-	}
-
-	return 0;
-}
-
-static int bmp280_read_press(struct bmp280_data *data,
-			     int *val, int *val2)
-{
-	int ret;
-	__be32 tmp = 0;
-	s32 adc_press;
-	u32 comp_press;
-
-	/* Read and compensate temperature so we get a reading of t_fine. */
-	ret = bmp280_read_temp(data, NULL);
-	if (ret < 0)
-		return ret;
-
-	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");
-		return ret;
-	}
-
-	adc_press = be32_to_cpu(tmp) >> 12;
-	comp_press = bmp280_compensate_press(data, adc_press);
-
-	*val = comp_press;
-	*val2 = 256000;
-
-	return IIO_VAL_FRACTIONAL;
-}
-
-static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
-{
-	int ret;
-	__be16 tmp = 0;
-	s32 adc_humidity;
-	u32 comp_humidity;
-
-	/* Read and compensate temperature so we get a reading of t_fine. */
-	ret = bmp280_read_temp(data, NULL);
-	if (ret < 0)
-		return ret;
-
-	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");
-		return ret;
-	}
-
-	adc_humidity = be16_to_cpu(tmp);
-	comp_humidity = bmp280_compensate_humidity(data, adc_humidity);
-
-	*val = comp_humidity;
-	*val2 = 1024;
-
-	return IIO_VAL_FRACTIONAL;
-}
-
-static int bmp280_read_raw(struct iio_dev *indio_dev,
-			   struct iio_chan_spec const *chan,
-			   int *val, int *val2, long mask)
-{
-	int ret;
-	struct bmp280_data *data = iio_priv(indio_dev);
-
-	mutex_lock(&data->lock);
-
-	switch (mask) {
-	case IIO_CHAN_INFO_PROCESSED:
-		switch (chan->type) {
-		case IIO_HUMIDITYRELATIVE:
-			ret = data->chip_info->read_humid(data, val, val2);
-			break;
-		case IIO_PRESSURE:
-			ret = data->chip_info->read_press(data, val, val2);
-			break;
-		case IIO_TEMP:
-			ret = data->chip_info->read_temp(data, val);
-			break;
-		default:
-			ret = -EINVAL;
-			break;
-		}
-		break;
-	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
-		switch (chan->type) {
-		case IIO_HUMIDITYRELATIVE:
-			*val = 1 << data->oversampling_humid;
-			ret = IIO_VAL_INT;
-			break;
-		case IIO_PRESSURE:
-			*val = 1 << data->oversampling_press;
-			ret = IIO_VAL_INT;
-			break;
-		case IIO_TEMP:
-			*val = 1 << data->oversampling_temp;
-			ret = IIO_VAL_INT;
-			break;
-		default:
-			ret = -EINVAL;
-			break;
-		}
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	mutex_unlock(&data->lock);
-
-	return ret;
-}
-
-static int bmp280_write_oversampling_ratio_humid(struct bmp280_data *data,
-					       int val)
-{
-	int i;
-	const int *avail = data->chip_info->oversampling_humid_avail;
-	const int n = data->chip_info->num_oversampling_humid_avail;
-
-	for (i = 0; i < n; i++) {
-		if (avail[i] == val) {
-			data->oversampling_humid = ilog2(val);
-
-			return data->chip_info->chip_config(data);
-		}
-	}
-	return -EINVAL;
-}
-
-static int bmp280_write_oversampling_ratio_temp(struct bmp280_data *data,
-					       int val)
-{
-	int i;
-	const int *avail = data->chip_info->oversampling_temp_avail;
-	const int n = data->chip_info->num_oversampling_temp_avail;
-
-	for (i = 0; i < n; i++) {
-		if (avail[i] == val) {
-			data->oversampling_temp = ilog2(val);
-
-			return data->chip_info->chip_config(data);
-		}
-	}
-	return -EINVAL;
-}
-
-static int bmp280_write_oversampling_ratio_press(struct bmp280_data *data,
-					       int val)
-{
-	int i;
-	const int *avail = data->chip_info->oversampling_press_avail;
-	const int n = data->chip_info->num_oversampling_press_avail;
-
-	for (i = 0; i < n; i++) {
-		if (avail[i] == val) {
-			data->oversampling_press = ilog2(val);
-
-			return data->chip_info->chip_config(data);
-		}
-	}
-	return -EINVAL;
-}
-
-static int bmp280_write_raw(struct iio_dev *indio_dev,
-			    struct iio_chan_spec const *chan,
-			    int val, int val2, long mask)
-{
-	int ret = 0;
-	struct bmp280_data *data = iio_priv(indio_dev);
-
-	switch (mask) {
-	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
-		mutex_lock(&data->lock);
-		switch (chan->type) {
-		case IIO_HUMIDITYRELATIVE:
-			ret = bmp280_write_oversampling_ratio_humid(data, val);
-			break;
-		case IIO_PRESSURE:
-			ret = bmp280_write_oversampling_ratio_press(data, val);
-			break;
-		case IIO_TEMP:
-			ret = bmp280_write_oversampling_ratio_temp(data, val);
-			break;
-		default:
-			ret = -EINVAL;
-			break;
-		}
-		mutex_unlock(&data->lock);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return ret;
-}
-
-static ssize_t bmp280_show_avail(char *buf, const int *vals, const int n)
-{
-	size_t len = 0;
-	int i;
-
-	for (i = 0; i < n; i++)
-		len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", vals[i]);
-
-	buf[len - 1] = '\n';
-
-	return len;
-}
-
-static ssize_t bmp280_show_temp_oversampling_avail(struct device *dev,
-				struct device_attribute *attr, char *buf)
-{
-	struct bmp280_data *data = iio_priv(dev_to_iio_dev(dev));
-
-	return bmp280_show_avail(buf, data->chip_info->oversampling_temp_avail,
-				 data->chip_info->num_oversampling_temp_avail);
-}
-
-static ssize_t bmp280_show_press_oversampling_avail(struct device *dev,
-				struct device_attribute *attr, char *buf)
-{
-	struct bmp280_data *data = iio_priv(dev_to_iio_dev(dev));
-
-	return bmp280_show_avail(buf, data->chip_info->oversampling_press_avail,
-				 data->chip_info->num_oversampling_press_avail);
-}
-
-static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available,
-	S_IRUGO, bmp280_show_temp_oversampling_avail, NULL, 0);
-
-static IIO_DEVICE_ATTR(in_pressure_oversampling_ratio_available,
-	S_IRUGO, bmp280_show_press_oversampling_avail, NULL, 0);
-
-static struct attribute *bmp280_attributes[] = {
-	&iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr,
-	&iio_dev_attr_in_pressure_oversampling_ratio_available.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group bmp280_attrs_group = {
-	.attrs = bmp280_attributes,
-};
-
-static const struct iio_info bmp280_info = {
-	.driver_module = THIS_MODULE,
-	.read_raw = &bmp280_read_raw,
-	.write_raw = &bmp280_write_raw,
-	.attrs = &bmp280_attrs_group,
-};
-
-static int bmp280_chip_config(struct bmp280_data *data)
-{
-	int ret;
-	u8 osrs = BMP280_OSRS_TEMP_X(data->oversampling_temp + 1) |
-		  BMP280_OSRS_PRESS_X(data->oversampling_press + 1);
-
-	ret = regmap_update_bits(data->regmap, BMP280_REG_CTRL_MEAS,
-				 BMP280_OSRS_TEMP_MASK |
-				 BMP280_OSRS_PRESS_MASK |
-				 BMP280_MODE_MASK,
-				 osrs | BMP280_MODE_NORMAL);
-	if (ret < 0) {
-		dev_err(&data->client->dev,
-			"failed to write ctrl_meas register\n");
-		return ret;
-	}
-
-	ret = regmap_update_bits(data->regmap, BMP280_REG_CONFIG,
-				 BMP280_FILTER_MASK,
-				 BMP280_FILTER_4X);
-	if (ret < 0) {
-		dev_err(&data->client->dev,
-			"failed to write config register\n");
-		return ret;
-	}
-
-	return ret;
-}
-
-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),
-
-	.oversampling_press_avail = bmp280_oversampling_avail,
-	.num_oversampling_press_avail = ARRAY_SIZE(bmp280_oversampling_avail),
-
-	.chip_config = bmp280_chip_config,
-	.read_temp = bmp280_read_temp,
-	.read_press = bmp280_read_press,
-};
-
-static int bme280_chip_config(struct bmp280_data *data)
-{
-	int ret = bmp280_chip_config(data);
-	u8 osrs = BMP280_OSRS_HUMIDITIY_X(data->oversampling_humid + 1);
-
-	if (ret < 0)
-		return ret;
-
-	return regmap_update_bits(data->regmap, BMP280_REG_CTRL_HUMIDITY,
-				  BMP280_OSRS_HUMIDITY_MASK, osrs);
-}
-
-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),
-
-	.oversampling_press_avail = bmp280_oversampling_avail,
-	.num_oversampling_press_avail = ARRAY_SIZE(bmp280_oversampling_avail),
-
-	.oversampling_humid_avail = bmp280_oversampling_avail,
-	.num_oversampling_humid_avail = ARRAY_SIZE(bmp280_oversampling_avail),
-
-	.chip_config = bme280_chip_config,
-	.read_temp = bmp280_read_temp,
-	.read_press = bmp280_read_press,
-	.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;
-	const int conversion_time_max[] = { 4500, 7500, 13500, 25500 };
-	unsigned int delay_us;
-	unsigned int ctrl;
-
-	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);
-
-	ret = regmap_read(data->regmap, BMP280_REG_CTRL_MEAS, &ctrl);
-	if (ret)
-		return ret;
-
-	/* The value of this bit reset to "0" after conversion is complete */
-	if (ctrl & BMP180_MEAS_SCO)
-		return -EIO;
-
-	return 0;
-}
-
-static int bmp180_read_adc_temp(struct bmp280_data *data, int *val)
-{
-	int ret;
-	__be16 tmp = 0;
-
-	ret = bmp180_measure(data, BMP180_MEAS_TEMP);
-	if (ret)
-		return ret;
-
-	ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 *)&tmp, 2);
-	if (ret)
-		return ret;
-
-	*val = be16_to_cpu(tmp);
-
-	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)
-{
-	int ret;
-	int i;
-	__be16 buf[BMP180_REG_CALIB_COUNT / 2];
-
-	ret = regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, buf,
-			       sizeof(buf));
-
-	if (ret < 0)
-		return ret;
-
-	/* None of the words has the value 0 or 0xFFFF */
-	for (i = 0; i < ARRAY_SIZE(buf); i++) {
-		if (buf[i] == cpu_to_be16(0) || buf[i] == cpu_to_be16(0xffff))
-			return -EIO;
-	}
-
-	calib->AC1 = be16_to_cpu(buf[AC1]);
-	calib->AC2 = be16_to_cpu(buf[AC2]);
-	calib->AC3 = be16_to_cpu(buf[AC3]);
-	calib->AC4 = be16_to_cpu(buf[AC4]);
-	calib->AC5 = be16_to_cpu(buf[AC5]);
-	calib->AC6 = be16_to_cpu(buf[AC6]);
-	calib->B1 = be16_to_cpu(buf[B1]);
-	calib->B2 = be16_to_cpu(buf[B2]);
-	calib->MB = be16_to_cpu(buf[MB]);
-	calib->MC = be16_to_cpu(buf[MC]);
-	calib->MD = be16_to_cpu(buf[MD]);
-
-	return 0;
-}
-
-/*
- * Returns temperature in DegC, resolution is 0.1 DegC.
- * t_fine carries fine temperature as global value.
- *
- * Taken from datasheet, Section 3.5, "Calculating pressure and temperature".
- */
-static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp)
-{
-	int ret;
-	s32 x1, x2;
-	struct bmp180_calib calib;
-
-	ret = bmp180_read_calib(data, &calib);
-	if (ret < 0) {
-		dev_err(&data->client->dev,
-			"failed to read calibration coefficients\n");
-		return ret;
-	}
-
-	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;
-}
-
-static int bmp180_read_temp(struct bmp280_data *data, int *val)
-{
-	int ret;
-	s32 adc_temp, comp_temp;
-
-	ret = bmp180_read_adc_temp(data, &adc_temp);
-	if (ret)
-		return ret;
-
-	comp_temp = bmp180_compensate_temp(data, adc_temp);
-
-	/*
-	 * val might be NULL if we're called by the read_press routine,
-	 * who only cares about the carry over t_fine value.
-	 */
-	if (val) {
-		*val = comp_temp * 100;
-		return IIO_VAL_INT;
-	}
-
-	return 0;
-}
-
-static int bmp180_read_adc_press(struct bmp280_data *data, int *val)
-{
-	int ret;
-	__be32 tmp = 0;
-	u8 oss = data->oversampling_press;
-
-	ret = bmp180_measure(data, BMP180_MEAS_PRESS_X(oss));
-	if (ret)
-		return ret;
-
-	ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 *)&tmp, 3);
-	if (ret)
-		return ret;
-
-	*val = (be32_to_cpu(tmp) >> 8) >> (8 - oss);
-
-	return 0;
-}
-
-/*
- * Returns pressure in Pa, resolution is 1 Pa.
- *
- * Taken from datasheet, Section 3.5, "Calculating pressure and temperature".
- */
-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->client->dev,
-			"failed to read calibration coefficients\n");
-		return ret;
-	}
-
-	b6 = data->t_fine - 4000;
-	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;
-	x3 = (x1 + x2 + 2) >> 2;
-	b4 = calib.AC4 * (u32)(x3 + 32768) >> 15;
-	b7 = ((u32)adc_press - b3) * (50000 >> oss);
-	if (b7 < 0x80000000)
-		p = (b7 * 2) / b4;
-	else
-		p = (b7 / b4) * 2;
-
-	x1 = (p >> 8) * (p >> 8);
-	x1 = (x1 * 3038) >> 16;
-	x2 = (-7357 * p) >> 16;
-
-	return p + ((x1 + x2 + 3791) >> 4);
-}
-
-static int bmp180_read_press(struct bmp280_data *data,
-			     int *val, int *val2)
-{
-	int ret;
-	s32 adc_press;
-	u32 comp_press;
-
-	/* Read and compensate temperature so we get a reading of t_fine. */
-	ret = bmp180_read_temp(data, NULL);
-	if (ret)
-		return ret;
-
-	ret = bmp180_read_adc_press(data, &adc_press);
-	if (ret)
-		return ret;
-
-	comp_press = bmp180_compensate_press(data, adc_press);
-
-	*val = comp_press;
-	*val2 = 1000;
-
-	return IIO_VAL_FRACTIONAL;
-}
-
-static int bmp180_chip_config(struct bmp280_data *data)
-{
-	return 0;
-}
-
-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),
-
-	.oversampling_press_avail = bmp180_oversampling_press_avail,
-	.num_oversampling_press_avail =
-		ARRAY_SIZE(bmp180_oversampling_press_avail),
-
-	.chip_config = bmp180_chip_config,
-	.read_temp = bmp180_read_temp,
-	.read_press = bmp180_read_press,
-};
-
-static int bmp280_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
-{
-	int ret;
-	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)
-		return -ENOMEM;
-
-	data = iio_priv(indio_dev);
-	mutex_init(&data->lock);
-	data->client = client;
-
-	indio_dev->dev.parent = &client->dev;
-	indio_dev->name = id->name;
-	indio_dev->channels = bmp280_channels;
-	indio_dev->info = &bmp280_info;
-	indio_dev->modes = INDIO_DIRECT_MODE;
-
-	switch (id->driver_data) {
-	case BMP180_CHIP_ID:
-		indio_dev->num_channels = 2;
-		data->chip_info = &bmp180_chip_info;
-		data->oversampling_press = ilog2(8);
-		data->oversampling_temp = ilog2(1);
-		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);
-		break;
-	case BME280_CHIP_ID:
-		indio_dev->num_channels = 3;
-		data->chip_info = &bme280_chip_info;
-		data->oversampling_press = ilog2(16);
-		data->oversampling_humid = ilog2(16);
-		data->oversampling_temp = ilog2(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");
-		return PTR_ERR(data->vddd);
-	}
-	ret = regulator_enable(data->vdda);
-	if (ret) {
-		dev_err(&client->dev, "failed to enable VDDA\n");
-		return ret;
-	}
-
-	/* 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)) {
-		dev_err(&client->dev, "failed to allocate register map\n");
-		return PTR_ERR(data->regmap);
-	}
-
-	ret = regmap_read(data->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 %lx got %x\n",
-			id->driver_data, chip_id);
-		return -EINVAL;
-	}
-
-	ret = data->chip_info->chip_config(data);
-	if (ret < 0)
-		return ret;
-
-	return devm_iio_device_register(&client->dev, indio_dev);
-}
-
-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,
-	.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.h b/drivers/iio/pressure/bmp280.h
new file mode 100644
index 000000000000..acb40de2f581
--- /dev/null
+++ b/drivers/iio/pressure/bmp280.h
@@ -0,0 +1,107 @@
+#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);
-- 
2.4.11

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

* [PATCH 6/9 v2] iio: pressure: bmp280: split off an I2C Kconfig entry
  2016-06-22 20:53 [PATCH 0/9] Improve BMP280 driver v2 Linus Walleij
                   ` (4 preceding siblings ...)
  2016-06-22 20:53 ` [PATCH 5/9 v2] iio: pressure: bmp280: split driver in logical parts Linus Walleij
@ 2016-06-22 20:53 ` Linus Walleij
  2016-06-22 20:53 ` [PATCH 7/9 v2] iio: pressure: bmp280: add SPI interface driver Linus Walleij
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2016-06-22 20:53 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  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.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/iio/pressure/Kconfig  | 18 ++++++++++++------
 drivers/iio/pressure/Makefile |  3 ++-
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index 9125a9382b3e..94ad8e7ad0ec 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -6,17 +6,23 @@
 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 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
+	depends on !(BMP085_I2C=y || BMP085_I2C=m)
+	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
-- 
2.4.11


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

* [PATCH 7/9 v2] iio: pressure: bmp280: add SPI interface driver
  2016-06-22 20:53 [PATCH 0/9] Improve BMP280 driver v2 Linus Walleij
                   ` (5 preceding siblings ...)
  2016-06-22 20:53 ` [PATCH 6/9 v2] iio: pressure: bmp280: split off an I2C Kconfig entry Linus Walleij
@ 2016-06-22 20:53 ` Linus Walleij
  2016-06-26 10:15   ` Jonathan Cameron
  2016-06-22 20:53 ` [PATCH 8/9 v2] iio: pressure: bmp280: add support for BMP085 EOC interrupt Linus Walleij
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2016-06-22 20:53 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  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 bus mapping code for SPI was written by Akinobu Mita.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
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  | 117 +++++++++++++++++++++++++++++++++++++
 4 files changed, 134 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 94ad8e7ad0ec..8b209d14bac9 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -7,15 +7,17 @@ menu "Pressure sensors"
 
 config BMP280
 	tristate "Bosch Sensortec BMP180/BMP280 pressure sensor I2C driver"
-	depends on I2C
+	depends on (I2C || SPI_MASTER)
 	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
@@ -24,6 +26,13 @@ config BMP280_I2C
 	depends on !(BMP085_I2C=y || BMP085_I2C=m)
 	select REGMAP_I2C
 
+config BMP280_SPI
+	tristate
+	depends on BMP280
+	depends on SPI_MASTER
+	depends on !(BMP085_SPI=y || BMP085_SPI=m)
+	select REGMAP_SPI
+
 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 77f0fc935c09..733ef3c08102 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..2b9955f48d58
--- /dev/null
+++ b/drivers/iio/pressure/bmp280-spi.c
@@ -0,0 +1,117 @@
+/*
+ * 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 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,
+};
+module_spi_driver(bmp280_spi_driver);
+
+MODULE_DESCRIPTION("BMP085 SPI bus driver");
+MODULE_LICENSE("GPL");
-- 
2.4.11


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

* [PATCH 8/9 v2] iio: pressure: bmp280: add support for BMP085 EOC interrupt
  2016-06-22 20:53 [PATCH 0/9] Improve BMP280 driver v2 Linus Walleij
                   ` (6 preceding siblings ...)
  2016-06-22 20:53 ` [PATCH 7/9 v2] iio: pressure: bmp280: add SPI interface driver Linus Walleij
@ 2016-06-22 20:53 ` Linus Walleij
  2016-06-26 10:18   ` Jonathan Cameron
  2016-06-22 20:53 ` [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once Linus Walleij
  2016-06-23  8:17 ` [PATCH 0/9] Improve BMP280 driver v2 H. Nikolaus Schaller
  9 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2016-06-22 20:53 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  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 v1->v2:
- Fix spelling mistakes
---
 drivers/iio/pressure/bmp280-core.c | 83 ++++++++++++++++++++++++++++++++++----
 drivers/iio/pressure/bmp280-i2c.c  |  3 +-
 drivers/iio/pressure/bmp280-spi.c  |  3 +-
 drivers/iio/pressure/bmp280.h      |  3 +-
 4 files changed, 81 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index 733ef3c08102..7b2a03d6fd1d 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -26,6 +26,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"
 
@@ -33,6 +36,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;
@@ -593,16 +598,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)
@@ -844,16 +865,28 @@ static const struct bmp280_chip_info bmp180_chip_info = {
 	.read_press = bmp180_read_press,
 };
 
+static irqreturn_t bmp058_eoc_irq(int irq, void *d)
+{
+	struct bmp280_data *data = d;
+
+	complete(&data->done);
+
+	return IRQ_HANDLED;
+}
+
+
 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;
 	struct bmp280_data *data;
 	unsigned int chip_id;
 	struct gpio_desc *gpiod;
+	unsigned long irq_trig;
 
 	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
 	if (!indio_dev)
@@ -937,5 +970,39 @@ int bmp280_common_probe(struct device *dev,
 	if (ret < 0)
 		return ret;
 
-	return devm_iio_device_register(dev, indio_dev);
+	ret = devm_iio_device_register(dev, indio_dev);
+	if (ret) {
+		dev_err(dev, "unable to register IIO device\n");
+		return ret;
+	}
+
+	/*
+	 * Attempt to grab an optional EOC IRQ - only the BMP058 has this
+	 * however as it happens, the BMP058 shares the chip ID of BMP180
+	 * so we look for an IRQ if we have that.
+	 */
+	if (irq <= 0 || (chip_id  != BMP180_CHIP_ID))
+		return 0;
+
+	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,
+			bmp058_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;
 }
diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c
index a981670e5dc0..b9a2562e8a7e 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 const struct acpi_device_id bmp280_acpi_i2c_match[] = {
diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c
index 2b9955f48d58..05ddf2ee7519 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 const struct of_device_id bmp280_of_spi_match[] = {
diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
index acb40de2f581..9dee048b5a74 100644
--- a/drivers/iio/pressure/bmp280.h
+++ b/drivers/iio/pressure/bmp280.h
@@ -104,4 +104,5 @@ 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);
-- 
2.4.11


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

* [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once
  2016-06-22 20:53 [PATCH 0/9] Improve BMP280 driver v2 Linus Walleij
                   ` (7 preceding siblings ...)
  2016-06-22 20:53 ` [PATCH 8/9 v2] iio: pressure: bmp280: add support for BMP085 EOC interrupt Linus Walleij
@ 2016-06-22 20:53 ` Linus Walleij
  2016-06-26 10:21   ` Jonathan Cameron
  2016-06-27  7:42   ` Vlad Dogaru
  2016-06-23  8:17 ` [PATCH 0/9] Improve BMP280 driver v2 H. Nikolaus Schaller
  9 siblings, 2 replies; 32+ messages in thread
From: Linus Walleij @ 2016-06-22 20:53 UTC (permalink / raw)
  To: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  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.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Remove unused dangling "ret" variable.
---
 drivers/iio/pressure/bmp280-core.c | 95 +++++++++++++++++++-------------------
 1 file changed, 48 insertions(+), 47 deletions(-)

diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index 7b2a03d6fd1d..6559455f0335 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -29,9 +29,30 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h> /* For irq_get_irq_data() */
 #include <linux/completion.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;
@@ -39,6 +60,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;
 
@@ -654,26 +676,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)
 {
@@ -683,7 +685,6 @@ static int bmp180_read_calib(struct bmp280_data *data,
 
 	ret = regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, buf,
 			       sizeof(buf));
-
 	if (ret < 0)
 		return ret;
 
@@ -693,6 +694,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]);
@@ -716,19 +720,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;
@@ -783,29 +779,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;
@@ -970,6 +958,19 @@ int bmp280_common_probe(struct device *dev,
 	if (ret < 0)
 		return ret;
 
+	/*
+	 * The BMP058 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");
+			return ret;
+		}
+	}
+
 	ret = devm_iio_device_register(dev, indio_dev);
 	if (ret) {
 		dev_err(dev, "unable to register IIO device\n");
-- 
2.4.11


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

* Re: [PATCH 0/9] Improve BMP280 driver v2
  2016-06-22 20:53 [PATCH 0/9] Improve BMP280 driver v2 Linus Walleij
                   ` (8 preceding siblings ...)
  2016-06-22 20:53 ` [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once Linus Walleij
@ 2016-06-23  8:17 ` H. Nikolaus Schaller
  9 siblings, 0 replies; 32+ messages in thread
From: H. Nikolaus Schaller @ 2016-06-23  8:17 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jonathan Cameron, linux-iio, Akinobu Mita, Matt Ranostay,
	Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, letux-kernel-bounces, kernel


> Am 22.06.2016 um 22:53 schrieb Linus Walleij <linus.walleij@linaro.org>:
> 
> This is version two of the previous patchset. Changes:
> 
> - Rebased on top of Matt Ranostays BME280 support patch so everything
>  applies cleanly on top of Jonathans development branch
> 
> - Added Akinobu Mitas special SPI bus handling code snippets
> 
> - Made the regulators non-optional: if the chip has supplies, it should
>  have regulators for them
> 
> - Fixed review comments and build remarks provided by the zeroday
>  build robot
> 
> Linus Walleij (9):
>  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: read calibration data once
> 
> .../devicetree/bindings/iio/pressure/bmp085.txt    |   15 +-
> drivers/iio/pressure/Kconfig                       |   29 +-
> drivers/iio/pressure/Makefile                      |    3 +
> drivers/iio/pressure/bmp280-core.c                 | 1009 ++++++++++++++++++
> drivers/iio/pressure/bmp280-i2c.c                  |   83 ++
> drivers/iio/pressure/bmp280-regmap.c               |   81 ++
> drivers/iio/pressure/bmp280-spi.c                  |  118 +++
> drivers/iio/pressure/bmp280.c                      | 1118 --------------------
> drivers/iio/pressure/bmp280.h                      |  108 ++
> 9 files changed, 1437 insertions(+), 1127 deletions(-)
> create mode 100644 drivers/iio/pressure/bmp280-core.c
> 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
> delete mode 100644 drivers/iio/pressure/bmp280.c
> create mode 100644 drivers/iio/pressure/bmp280.h

Tests on GTA04 (BMP085 with EOC) by reading /sys/bus/iio /.../in_*_input
- temperature value in m°C is perfect and
  typical value: 34300 (for 34.3°C)
- pressure seems to be reasonable (if multiplied by 10 to give mBar)
  typical value: 95.108000000 (would it be better to report µBar as integer?)

Tests on Pyra-Handheld (BME280 w/o EOC)
- temp and pressure seem to agree with GTA04
- humitidy reports RH = 71.854492187 % which might be correct or not (can't check)

Detailed suggestions follow for individual patches.

Thanks,
Nikolaus


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

* Re: [PATCH 2/9 v2] iio: pressure: bmp280: support device tree initialization
  2016-06-22 20:53 ` [PATCH 2/9 v2] iio: pressure: bmp280: support device tree initialization Linus Walleij
@ 2016-06-23  8:18   ` H. Nikolaus Schaller
  2016-06-24 10:26     ` Linus Walleij
  2016-06-26  9:52   ` Jonathan Cameron
  1 sibling, 1 reply; 32+ messages in thread
From: H. Nikolaus Schaller @ 2016-06-23  8:18 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jonathan Cameron, linux-iio, Akinobu Mita, Matt Ranostay,
	Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Discussions about the Letux Kernel,
	kernel


> Am 22.06.2016 um 22:53 schrieb Linus Walleij <linus.walleij@linaro.org>:
> 
> 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 v1->v2:
> - Fix some BMP085 misspelled as BMP058 errors.
> - Add the new BME280 sensor as well
> ---
> drivers/iio/pressure/bmp280.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
> index dbbcd6d83e3b..655e888ef8f9 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,18 @@ 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 },

Here I get:

FATAL: drivers/iio/pressure/bmp280-i2c: struct of_device_id is not terminated with a NULL entry!

> +};
> +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 +1120,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	[flat|nested] 32+ messages in thread

* Re: [PATCH 5/9 v2] iio: pressure: bmp280: split driver in logical parts
  2016-06-22 20:53 ` [PATCH 5/9 v2] iio: pressure: bmp280: split driver in logical parts Linus Walleij
@ 2016-06-23  8:18   ` H. Nikolaus Schaller
  2016-06-24 10:28     ` Linus Walleij
  2016-06-26 10:04   ` Jonathan Cameron
  1 sibling, 1 reply; 32+ messages in thread
From: H. Nikolaus Schaller @ 2016-06-23  8:18 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jonathan Cameron, linux-iio, Akinobu Mita, Matt Ranostay,
	Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Discussions about the Letux Kernel,
	kernel


> Am 22.06.2016 um 22:53 schrieb Linus Walleij =
<linus.walleij@linaro.org>:
>=20
> 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.
>=20
> 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.
>=20
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v1->v2:
> - Rebased on top of Matt Ranostays BME280 with humidity sensor support
> ---
> drivers/iio/pressure/Makefile        |    1 +
> drivers/iio/pressure/bmp280-core.c   |  937 =
+++++++++++++++++++++++++++
> drivers/iio/pressure/bmp280-i2c.c    |   82 +++
> drivers/iio/pressure/bmp280-regmap.c |   81 +++
> drivers/iio/pressure/bmp280.c        | 1167 =
----------------------------------
> drivers/iio/pressure/bmp280.h        |  107 ++++
> 6 files changed, 1208 insertions(+), 1167 deletions(-)
> create mode 100644 drivers/iio/pressure/bmp280-core.c
> create mode 100644 drivers/iio/pressure/bmp280-i2c.c
> create mode 100644 drivers/iio/pressure/bmp280-regmap.c
> delete mode 100644 drivers/iio/pressure/bmp280.c
> create mode 100644 drivers/iio/pressure/bmp280.h
>=20
> 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 @@
>=20
> # When adding new entries keep the list in alphabetical order
> obj-$(CONFIG_BMP280) +=3D bmp280.o
> +bmp280-objs :=3D bmp280-core.o bmp280-regmap.o bmp280-i2c.o

With menuconfig setting to 'M'

CONFIG_BMP280=3Dm
CONFIG_BMP280_I2C=3Dm
CONFIG_BMP280_SPI=3Dm

I get

ERROR: "bmp280_regmap_config" [drivers/iio/pressure/bmp280-spi.ko] =
undefined!
ERROR: "bmp180_regmap_config" [drivers/iio/pressure/bmp280-spi.ko] =
undefined!
ERROR: "bmp280_common_probe" [drivers/iio/pressure/bmp280-spi.ko] =
undefined!
ERROR: "bmp280_regmap_config" [drivers/iio/pressure/bmp280-i2c.ko] =
undefined!
ERROR: "bmp180_regmap_config" [drivers/iio/pressure/bmp280-i2c.ko] =
undefined!
ERROR: "bmp280_common_probe" [drivers/iio/pressure/bmp280-i2c.ko] =
undefined!

CONFIG_BMP280*=3Dy compiles.

> obj-$(CONFIG_HID_SENSOR_PRESS)   +=3D hid-sensor-press.o
> obj-$(CONFIG_HP03) +=3D hp03.o
> obj-$(CONFIG_MPL115) +=3D mpl115.o
> diff --git a/drivers/iio/pressure/bmp280-core.c =
b/drivers/iio/pressure/bmp280-core.c
> new file mode 100644
> index 000000000000..77f0fc935c09
> --- /dev/null
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -0,0 +1,937 @@
> +/*
> + * Copyright (c) 2014 Intel Corporation
> + *
> + * Driver for Bosch Sensortec BMP180 and BMP280 digital pressure =
sensor.
> + *
> + * This program is free software; you can redistribute it and/or =
modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Datasheet:
> + * =
https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP180-=
DS000-121.pdf
> + * =
https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP280-=
DS001-12.pdf
> + * =
https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_=
DS001-11.pdf
> + */
> +
> +#define pr_fmt(fmt) "bmp280: " fmt
> +
> +#include <linux/device.h>
> +#include <linux/regmap.h>
> +#include <linux/delay.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/regulator/consumer.h>
> +
> +#include "bmp280.h"
> +
> +struct bmp280_data {
> +	struct device *dev;
> +	struct mutex lock;
> +	struct regmap *regmap;
> +	const struct bmp280_chip_info *chip_info;
> +	struct regulator *vddd;
> +	struct regulator *vdda;
> +
> +	/* log of base 2 of oversampling rate */
> +	u8 oversampling_press;
> +	u8 oversampling_temp;
> +	u8 oversampling_humid;
> +
> +	/*
> +	 * Carryover value from temperature conversion, used in pressure
> +	 * calculation.
> +	 */
> +	s32 t_fine;
> +};
> +
> +struct bmp280_chip_info {
> +	const int *oversampling_temp_avail;
> +	int num_oversampling_temp_avail;
> +
> +	const int *oversampling_press_avail;
> +	int num_oversampling_press_avail;
> +
> +	const int *oversampling_humid_avail;
> +	int num_oversampling_humid_avail;
> +
> +	int (*chip_config)(struct bmp280_data *);
> +	int (*read_temp)(struct bmp280_data *, int *);
> +	int (*read_press)(struct bmp280_data *, int *, int *);
> +	int (*read_humid)(struct bmp280_data *, int *, int *);
> +};
> +
> +/*
> + * These enums are used for indexing into the array of compensation
> + * parameters for BMP280.
> + */
> +enum { T1, T2, T3 };
> +enum { P1, P2, P3, P4, P5, P6, P7, P8, P9 };
> +
> +static const struct iio_chan_spec bmp280_channels[] =3D {
> +	{
> +		.type =3D IIO_PRESSURE,
> +		.info_mask_separate =3D BIT(IIO_CHAN_INFO_PROCESSED) |
> +				      =
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> +	},
> +	{
> +		.type =3D IIO_TEMP,
> +		.info_mask_separate =3D BIT(IIO_CHAN_INFO_PROCESSED) |
> +				      =
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> +	},
> +	{
> +		.type =3D IIO_HUMIDITYRELATIVE,
> +		.info_mask_separate =3D BIT(IIO_CHAN_INFO_PROCESSED) |
> +				      =
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> +	},
> +};
> +
> +/*
> + * Returns humidity in percent, resolution is 0.01 percent. Output =
value of
> + * "47445" represents 47445/1024 =3D 46.333 %RH.
> + *
> + * Taken from BME280 datasheet, Section 4.2.3, "Compensation =
formula".
> + */
> +
> +static u32 bmp280_compensate_humidity(struct bmp280_data *data,
> +				      s32 adc_humidity)
> +{
> +	struct device *dev =3D data->dev;
> +	unsigned int H1, H3, tmp;
> +	int H2, H4, H5, H6, ret, var;
> +
> +	ret =3D regmap_read(data->regmap, BMP280_REG_COMP_H1, &H1);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H1 comp value\n");
> +		return ret;
> +	}
> +
> +	ret =3D regmap_bulk_read(data->regmap, BMP280_REG_COMP_H2, &tmp, =
2);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H2 comp value\n");
> +		return ret;
> +	}
> +	H2 =3D sign_extend32(le16_to_cpu(tmp), 15);
> +
> +	ret =3D regmap_read(data->regmap, BMP280_REG_COMP_H3, &H3);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H3 comp value\n");
> +		return ret;
> +	}
> +
> +	ret =3D regmap_bulk_read(data->regmap, BMP280_REG_COMP_H4, &tmp, =
2);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H4 comp value\n");
> +		return ret;
> +	}
> +	H4 =3D sign_extend32(((be16_to_cpu(tmp) >> 4) & 0xff0) |
> +			  (be16_to_cpu(tmp) & 0xf), 11);
> +
> +	ret =3D regmap_bulk_read(data->regmap, BMP280_REG_COMP_H5, &tmp, =
2);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H5 comp value\n");
> +		return ret;
> +	}
> +	H5 =3D sign_extend32(((le16_to_cpu(tmp) >> 4) & 0xfff), 11);
> +
> +	ret =3D regmap_read(data->regmap, BMP280_REG_COMP_H6, &tmp);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H6 comp value\n");
> +		return ret;
> +	}
> +	H6 =3D sign_extend32(tmp, 7);
> +
> +	var =3D ((s32)data->t_fine) - 76800;
> +	var =3D ((((adc_humidity << 14) - (H4 << 20) - (H5 * var)) + =
16384) >> 15)
> +		* (((((((var * H6) >> 10) * (((var * H3) >> 11) + =
32768)) >> 10)
> +		+ 2097152) * H2 + 8192) >> 14);
> +	var -=3D ((((var >> 15) * (var >> 15)) >> 7) * H1) >> 4;
> +
> +	return var >> 12;
> +};
> +
> +/*
> + * Returns temperature in DegC, resolution is 0.01 DegC.  Output =
value of
> + * "5123" equals 51.23 DegC.  t_fine carries fine temperature as =
global
> + * value.
> + *
> + * Taken from datasheet, Section 3.11.3, "Compensation formula".
> + */
> +static s32 bmp280_compensate_temp(struct bmp280_data *data,
> +				  s32 adc_temp)
> +{
> +	int ret;
> +	s32 var1, var2;
> +	__le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2];
> +
> +	ret =3D regmap_bulk_read(data->regmap, =
BMP280_REG_COMP_TEMP_START,
> +			       buf, BMP280_COMP_TEMP_REG_COUNT);
> +	if (ret < 0) {
> +		dev_err(data->dev,
> +			"failed to read temperature calibration =
parameters\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * The double casts are necessary because le16_to_cpu returns an
> +	 * unsigned 16-bit value.  Casting that value directly to a
> +	 * signed 32-bit will not do proper sign extension.
> +	 *
> +	 * Conversely, T1 and P1 are unsigned values, so they can be
> +	 * cast straight to the larger type.
> +	 */
> +	var1 =3D (((adc_temp >> 3) - ((s32)le16_to_cpu(buf[T1]) << 1)) *
> +		((s32)(s16)le16_to_cpu(buf[T2]))) >> 11;
> +	var2 =3D (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) *
> +		  ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> =
12) *
> +		((s32)(s16)le16_to_cpu(buf[T3]))) >> 14;
> +	data->t_fine =3D var1 + var2;
> +
> +	return (data->t_fine * 5 + 128) >> 8;
> +}
> +
> +/*
> + * Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format =
(24
> + * integer bits and 8 fractional bits).  Output value of "24674867"
> + * represents 24674867/256 =3D 96386.2 Pa =3D 963.862 hPa
> + *
> + * Taken from datasheet, Section 3.11.3, "Compensation formula".
> + */
> +static u32 bmp280_compensate_press(struct bmp280_data *data,
> +				   s32 adc_press)
> +{
> +	int ret;
> +	s64 var1, var2, p;
> +	__le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2];
> +
> +	ret =3D regmap_bulk_read(data->regmap, =
BMP280_REG_COMP_PRESS_START,
> +			       buf, BMP280_COMP_PRESS_REG_COUNT);
> +	if (ret < 0) {
> +		dev_err(data->dev,
> +			"failed to read pressure calibration =
parameters\n");
> +		return ret;
> +	}
> +
> +	var1 =3D ((s64)data->t_fine) - 128000;
> +	var2 =3D var1 * var1 * (s64)(s16)le16_to_cpu(buf[P6]);
> +	var2 +=3D (var1 * (s64)(s16)le16_to_cpu(buf[P5])) << 17;
> +	var2 +=3D ((s64)(s16)le16_to_cpu(buf[P4])) << 35;
> +	var1 =3D ((var1 * var1 * (s64)(s16)le16_to_cpu(buf[P3])) >> 8) +
> +		((var1 * (s64)(s16)le16_to_cpu(buf[P2])) << 12);
> +	var1 =3D ((((s64)1) << 47) + var1) * ((s64)le16_to_cpu(buf[P1])) =
>> 33;
> +
> +	if (var1 =3D=3D 0)
> +		return 0;
> +
> +	p =3D ((((s64)1048576 - adc_press) << 31) - var2) * 3125;
> +	p =3D div64_s64(p, var1);
> +	var1 =3D (((s64)(s16)le16_to_cpu(buf[P9])) * (p >> 13) * (p >> =
13)) >> 25;
> +	var2 =3D (((s64)(s16)le16_to_cpu(buf[P8])) * p) >> 19;
> +	p =3D ((p + var1 + var2) >> 8) + =
(((s64)(s16)le16_to_cpu(buf[P7])) << 4);
> +
> +	return (u32)p;
> +}
> +
> +static int bmp280_read_temp(struct bmp280_data *data,
> +			    int *val)
> +{
> +	int ret;
> +	__be32 tmp =3D 0;
> +	s32 adc_temp, comp_temp;
> +
> +	ret =3D regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB,
> +			       (u8 *) &tmp, 3);
> +	if (ret < 0) {
> +		dev_err(data->dev, "failed to read temperature\n");
> +		return ret;
> +	}
> +
> +	adc_temp =3D be32_to_cpu(tmp) >> 12;
> +	comp_temp =3D bmp280_compensate_temp(data, adc_temp);
> +
> +	/*
> +	 * val might be NULL if we're called by the read_press routine,
> +	 * who only cares about the carry over t_fine value.
> +	 */
> +	if (val) {
> +		*val =3D comp_temp * 10;
> +		return IIO_VAL_INT;
> +	}
> +
> +	return 0;
> +}
> +
> +static int bmp280_read_press(struct bmp280_data *data,
> +			     int *val, int *val2)
> +{
> +	int ret;
> +	__be32 tmp =3D 0;
> +	s32 adc_press;
> +	u32 comp_press;
> +
> +	/* Read and compensate temperature so we get a reading of =
t_fine. */
> +	ret =3D bmp280_read_temp(data, NULL);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret =3D regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB,
> +			       (u8 *) &tmp, 3);
> +	if (ret < 0) {
> +		dev_err(data->dev, "failed to read pressure\n");
> +		return ret;
> +	}
> +
> +	adc_press =3D be32_to_cpu(tmp) >> 12;
> +	comp_press =3D bmp280_compensate_press(data, adc_press);
> +
> +	*val =3D comp_press;
> +	*val2 =3D 256000;
> +
> +	return IIO_VAL_FRACTIONAL;
> +}
> +
> +static int bmp280_read_humid(struct bmp280_data *data, int *val, int =
*val2)
> +{
> +	int ret;
> +	__be16 tmp =3D 0;
> +	s32 adc_humidity;
> +	u32 comp_humidity;
> +
> +	/* Read and compensate temperature so we get a reading of =
t_fine. */
> +	ret =3D bmp280_read_temp(data, NULL);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret =3D regmap_bulk_read(data->regmap, BMP280_REG_HUMIDITY_MSB,
> +			       (u8 *) &tmp, 2);
> +	if (ret < 0) {
> +		dev_err(data->dev, "failed to read humidity\n");
> +		return ret;
> +	}
> +
> +	adc_humidity =3D be16_to_cpu(tmp);
> +	comp_humidity =3D bmp280_compensate_humidity(data, =
adc_humidity);
> +
> +	*val =3D comp_humidity;
> +	*val2 =3D 1024;
> +
> +	return IIO_VAL_FRACTIONAL;
> +}
> +
> +static int bmp280_read_raw(struct iio_dev *indio_dev,
> +			   struct iio_chan_spec const *chan,
> +			   int *val, int *val2, long mask)
> +{
> +	int ret;
> +	struct bmp280_data *data =3D iio_priv(indio_dev);
> +
> +	mutex_lock(&data->lock);
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_PROCESSED:
> +		switch (chan->type) {
> +		case IIO_HUMIDITYRELATIVE:
> +			ret =3D data->chip_info->read_humid(data, val, =
val2);
> +			break;
> +		case IIO_PRESSURE:
> +			ret =3D data->chip_info->read_press(data, val, =
val2);
> +			break;
> +		case IIO_TEMP:
> +			ret =3D data->chip_info->read_temp(data, val);
> +			break;
> +		default:
> +			ret =3D -EINVAL;
> +			break;
> +		}
> +		break;
> +	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +		switch (chan->type) {
> +		case IIO_HUMIDITYRELATIVE:
> +			*val =3D 1 << data->oversampling_humid;
> +			ret =3D IIO_VAL_INT;
> +			break;
> +		case IIO_PRESSURE:
> +			*val =3D 1 << data->oversampling_press;
> +			ret =3D IIO_VAL_INT;
> +			break;
> +		case IIO_TEMP:
> +			*val =3D 1 << data->oversampling_temp;
> +			ret =3D IIO_VAL_INT;
> +			break;
> +		default:
> +			ret =3D -EINVAL;
> +			break;
> +		}
> +		break;
> +	default:
> +		ret =3D -EINVAL;
> +		break;
> +	}
> +
> +	mutex_unlock(&data->lock);
> +
> +	return ret;
> +}
> +
> +static int bmp280_write_oversampling_ratio_humid(struct bmp280_data =
*data,
> +					       int val)
> +{
> +	int i;
> +	const int *avail =3D data->chip_info->oversampling_humid_avail;
> +	const int n =3D data->chip_info->num_oversampling_humid_avail;
> +
> +	for (i =3D 0; i < n; i++) {
> +		if (avail[i] =3D=3D val) {
> +			data->oversampling_humid =3D ilog2(val);
> +
> +			return data->chip_info->chip_config(data);
> +		}
> +	}
> +	return -EINVAL;
> +}
> +
> +static int bmp280_write_oversampling_ratio_temp(struct bmp280_data =
*data,
> +					       int val)
> +{
> +	int i;
> +	const int *avail =3D data->chip_info->oversampling_temp_avail;
> +	const int n =3D data->chip_info->num_oversampling_temp_avail;
> +
> +	for (i =3D 0; i < n; i++) {
> +		if (avail[i] =3D=3D val) {
> +			data->oversampling_temp =3D ilog2(val);
> +
> +			return data->chip_info->chip_config(data);
> +		}
> +	}
> +	return -EINVAL;
> +}
> +
> +static int bmp280_write_oversampling_ratio_press(struct bmp280_data =
*data,
> +					       int val)
> +{
> +	int i;
> +	const int *avail =3D data->chip_info->oversampling_press_avail;
> +	const int n =3D data->chip_info->num_oversampling_press_avail;
> +
> +	for (i =3D 0; i < n; i++) {
> +		if (avail[i] =3D=3D val) {
> +			data->oversampling_press =3D ilog2(val);
> +
> +			return data->chip_info->chip_config(data);
> +		}
> +	}
> +	return -EINVAL;
> +}
> +
> +static int bmp280_write_raw(struct iio_dev *indio_dev,
> +			    struct iio_chan_spec const *chan,
> +			    int val, int val2, long mask)
> +{
> +	int ret =3D 0;
> +	struct bmp280_data *data =3D iio_priv(indio_dev);
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +		mutex_lock(&data->lock);
> +		switch (chan->type) {
> +		case IIO_HUMIDITYRELATIVE:
> +			ret =3D =
bmp280_write_oversampling_ratio_humid(data, val);
> +			break;
> +		case IIO_PRESSURE:
> +			ret =3D =
bmp280_write_oversampling_ratio_press(data, val);
> +			break;
> +		case IIO_TEMP:
> +			ret =3D =
bmp280_write_oversampling_ratio_temp(data, val);
> +			break;
> +		default:
> +			ret =3D -EINVAL;
> +			break;
> +		}
> +		mutex_unlock(&data->lock);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static ssize_t bmp280_show_avail(char *buf, const int *vals, const =
int n)
> +{
> +	size_t len =3D 0;
> +	int i;
> +
> +	for (i =3D 0; i < n; i++)
> +		len +=3D scnprintf(buf + len, PAGE_SIZE - len, "%d ", =
vals[i]);
> +
> +	buf[len - 1] =3D '\n';
> +
> +	return len;
> +}
> +
> +static ssize_t bmp280_show_temp_oversampling_avail(struct device =
*dev,
> +				struct device_attribute *attr, char =
*buf)
> +{
> +	struct bmp280_data *data =3D iio_priv(dev_to_iio_dev(dev));
> +
> +	return bmp280_show_avail(buf, =
data->chip_info->oversampling_temp_avail,
> +				 =
data->chip_info->num_oversampling_temp_avail);
> +}
> +
> +static ssize_t bmp280_show_press_oversampling_avail(struct device =
*dev,
> +				struct device_attribute *attr, char =
*buf)
> +{
> +	struct bmp280_data *data =3D iio_priv(dev_to_iio_dev(dev));
> +
> +	return bmp280_show_avail(buf, =
data->chip_info->oversampling_press_avail,
> +				 =
data->chip_info->num_oversampling_press_avail);
> +}
> +
> +static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available,
> +	S_IRUGO, bmp280_show_temp_oversampling_avail, NULL, 0);
> +
> +static IIO_DEVICE_ATTR(in_pressure_oversampling_ratio_available,
> +	S_IRUGO, bmp280_show_press_oversampling_avail, NULL, 0);
> +
> +static struct attribute *bmp280_attributes[] =3D {
> +	=
&iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr,
> +	=
&iio_dev_attr_in_pressure_oversampling_ratio_available.dev_attr.attr,
> +	NULL,
> +};
> +
> +static const struct attribute_group bmp280_attrs_group =3D {
> +	.attrs =3D bmp280_attributes,
> +};
> +
> +static const struct iio_info bmp280_info =3D {
> +	.driver_module =3D THIS_MODULE,
> +	.read_raw =3D &bmp280_read_raw,
> +	.write_raw =3D &bmp280_write_raw,
> +	.attrs =3D &bmp280_attrs_group,
> +};
> +
> +static int bmp280_chip_config(struct bmp280_data *data)
> +{
> +	int ret;
> +	u8 osrs =3D BMP280_OSRS_TEMP_X(data->oversampling_temp + 1) |
> +		  BMP280_OSRS_PRESS_X(data->oversampling_press + 1);
> +
> +	ret =3D regmap_update_bits(data->regmap, BMP280_REG_CTRL_MEAS,
> +				 BMP280_OSRS_TEMP_MASK |
> +				 BMP280_OSRS_PRESS_MASK |
> +				 BMP280_MODE_MASK,
> +				 osrs | BMP280_MODE_NORMAL);
> +	if (ret < 0) {
> +		dev_err(data->dev,
> +			"failed to write ctrl_meas register\n");
> +		return ret;
> +	}
> +
> +	ret =3D regmap_update_bits(data->regmap, BMP280_REG_CONFIG,
> +				 BMP280_FILTER_MASK,
> +				 BMP280_FILTER_4X);
> +	if (ret < 0) {
> +		dev_err(data->dev,
> +			"failed to write config register\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +static const int bmp280_oversampling_avail[] =3D { 1, 2, 4, 8, 16 };
> +
> +static const struct bmp280_chip_info bmp280_chip_info =3D {
> +	.oversampling_temp_avail =3D bmp280_oversampling_avail,
> +	.num_oversampling_temp_avail =3D =
ARRAY_SIZE(bmp280_oversampling_avail),
> +
> +	.oversampling_press_avail =3D bmp280_oversampling_avail,
> +	.num_oversampling_press_avail =3D =
ARRAY_SIZE(bmp280_oversampling_avail),
> +
> +	.chip_config =3D bmp280_chip_config,
> +	.read_temp =3D bmp280_read_temp,
> +	.read_press =3D bmp280_read_press,
> +};
> +
> +static int bme280_chip_config(struct bmp280_data *data)
> +{
> +	int ret =3D bmp280_chip_config(data);
> +	u8 osrs =3D BMP280_OSRS_HUMIDITIY_X(data->oversampling_humid + =
1);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	return regmap_update_bits(data->regmap, =
BMP280_REG_CTRL_HUMIDITY,
> +				  BMP280_OSRS_HUMIDITY_MASK, osrs);
> +}
> +
> +static const struct bmp280_chip_info bme280_chip_info =3D {
> +	.oversampling_temp_avail =3D bmp280_oversampling_avail,
> +	.num_oversampling_temp_avail =3D =
ARRAY_SIZE(bmp280_oversampling_avail),
> +
> +	.oversampling_press_avail =3D bmp280_oversampling_avail,
> +	.num_oversampling_press_avail =3D =
ARRAY_SIZE(bmp280_oversampling_avail),
> +
> +	.oversampling_humid_avail =3D bmp280_oversampling_avail,
> +	.num_oversampling_humid_avail =3D =
ARRAY_SIZE(bmp280_oversampling_avail),
> +
> +	.chip_config =3D bme280_chip_config,
> +	.read_temp =3D bmp280_read_temp,
> +	.read_press =3D bmp280_read_press,
> +	.read_humid =3D bmp280_read_humid,
> +};
> +
> +static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas)
> +{
> +	int ret;
> +	const int conversion_time_max[] =3D { 4500, 7500, 13500, 25500 =
};
> +	unsigned int delay_us;
> +	unsigned int ctrl;
> +
> +	ret =3D regmap_write(data->regmap, BMP280_REG_CTRL_MEAS, =
ctrl_meas);
> +	if (ret)
> +		return ret;
> +
> +	if (ctrl_meas =3D=3D BMP180_MEAS_TEMP)
> +		delay_us =3D 4500;
> +	else
> +		delay_us =3D =
conversion_time_max[data->oversampling_press];
> +
> +	usleep_range(delay_us, delay_us + 1000);
> +
> +	ret =3D regmap_read(data->regmap, BMP280_REG_CTRL_MEAS, &ctrl);
> +	if (ret)
> +		return ret;
> +
> +	/* The value of this bit reset to "0" after conversion is =
complete */
> +	if (ctrl & BMP180_MEAS_SCO)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int bmp180_read_adc_temp(struct bmp280_data *data, int *val)
> +{
> +	int ret;
> +	__be16 tmp =3D 0;
> +
> +	ret =3D bmp180_measure(data, BMP180_MEAS_TEMP);
> +	if (ret)
> +		return ret;
> +
> +	ret =3D regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 =
*)&tmp, 2);
> +	if (ret)
> +		return ret;
> +
> +	*val =3D be16_to_cpu(tmp);
> +
> +	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)
> +{
> +	int ret;
> +	int i;
> +	__be16 buf[BMP180_REG_CALIB_COUNT / 2];
> +
> +	ret =3D regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, =
buf,
> +			       sizeof(buf));
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	/* None of the words has the value 0 or 0xFFFF */
> +	for (i =3D 0; i < ARRAY_SIZE(buf); i++) {
> +		if (buf[i] =3D=3D cpu_to_be16(0) || buf[i] =3D=3D =
cpu_to_be16(0xffff))
> +			return -EIO;
> +	}
> +
> +	calib->AC1 =3D be16_to_cpu(buf[AC1]);
> +	calib->AC2 =3D be16_to_cpu(buf[AC2]);
> +	calib->AC3 =3D be16_to_cpu(buf[AC3]);
> +	calib->AC4 =3D be16_to_cpu(buf[AC4]);
> +	calib->AC5 =3D be16_to_cpu(buf[AC5]);
> +	calib->AC6 =3D be16_to_cpu(buf[AC6]);
> +	calib->B1 =3D be16_to_cpu(buf[B1]);
> +	calib->B2 =3D be16_to_cpu(buf[B2]);
> +	calib->MB =3D be16_to_cpu(buf[MB]);
> +	calib->MC =3D be16_to_cpu(buf[MC]);
> +	calib->MD =3D be16_to_cpu(buf[MD]);
> +
> +	return 0;
> +}
> +
> +/*
> + * Returns temperature in DegC, resolution is 0.1 DegC.
> + * t_fine carries fine temperature as global value.
> + *
> + * Taken from datasheet, Section 3.5, "Calculating pressure and =
temperature".
> + */
> +static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 =
adc_temp)
> +{
> +	int ret;
> +	s32 x1, x2;
> +	struct bmp180_calib calib;
> +
> +	ret =3D bmp180_read_calib(data, &calib);
> +	if (ret < 0) {
> +		dev_err(data->dev,
> +			"failed to read calibration coefficients\n");
> +		return ret;
> +	}
> +
> +	x1 =3D ((adc_temp - calib.AC6) * calib.AC5) >> 15;
> +	x2 =3D (calib.MC << 11) / (x1 + calib.MD);
> +	data->t_fine =3D x1 + x2;
> +
> +	return (data->t_fine + 8) >> 4;
> +}
> +
> +static int bmp180_read_temp(struct bmp280_data *data, int *val)
> +{
> +	int ret;
> +	s32 adc_temp, comp_temp;
> +
> +	ret =3D bmp180_read_adc_temp(data, &adc_temp);
> +	if (ret)
> +		return ret;
> +
> +	comp_temp =3D bmp180_compensate_temp(data, adc_temp);
> +
> +	/*
> +	 * val might be NULL if we're called by the read_press routine,
> +	 * who only cares about the carry over t_fine value.
> +	 */
> +	if (val) {
> +		*val =3D comp_temp * 100;
> +		return IIO_VAL_INT;
> +	}
> +
> +	return 0;
> +}
> +
> +static int bmp180_read_adc_press(struct bmp280_data *data, int *val)
> +{
> +	int ret;
> +	__be32 tmp =3D 0;
> +	u8 oss =3D data->oversampling_press;
> +
> +	ret =3D bmp180_measure(data, BMP180_MEAS_PRESS_X(oss));
> +	if (ret)
> +		return ret;
> +
> +	ret =3D regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 =
*)&tmp, 3);
> +	if (ret)
> +		return ret;
> +
> +	*val =3D (be32_to_cpu(tmp) >> 8) >> (8 - oss);
> +
> +	return 0;
> +}
> +
> +/*
> + * Returns pressure in Pa, resolution is 1 Pa.
> + *
> + * Taken from datasheet, Section 3.5, "Calculating pressure and =
temperature".
> + */
> +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 =3D data->oversampling_press;
> +	struct bmp180_calib calib;
> +
> +	ret =3D bmp180_read_calib(data, &calib);
> +	if (ret < 0) {
> +		dev_err(data->dev,
> +			"failed to read calibration coefficients\n");
> +		return ret;
> +	}
> +
> +	b6 =3D data->t_fine - 4000;
> +	x1 =3D (calib.B2 * (b6 * b6 >> 12)) >> 11;
> +	x2 =3D calib.AC2 * b6 >> 11;
> +	x3 =3D x1 + x2;
> +	b3 =3D ((((s32)calib.AC1 * 4 + x3) << oss) + 2) / 4;
> +	x1 =3D calib.AC3 * b6 >> 13;
> +	x2 =3D (calib.B1 * ((b6 * b6) >> 12)) >> 16;
> +	x3 =3D (x1 + x2 + 2) >> 2;
> +	b4 =3D calib.AC4 * (u32)(x3 + 32768) >> 15;
> +	b7 =3D ((u32)adc_press - b3) * (50000 >> oss);
> +	if (b7 < 0x80000000)
> +		p =3D (b7 * 2) / b4;
> +	else
> +		p =3D (b7 / b4) * 2;
> +
> +	x1 =3D (p >> 8) * (p >> 8);
> +	x1 =3D (x1 * 3038) >> 16;
> +	x2 =3D (-7357 * p) >> 16;
> +
> +	return p + ((x1 + x2 + 3791) >> 4);
> +}
> +
> +static int bmp180_read_press(struct bmp280_data *data,
> +			     int *val, int *val2)
> +{
> +	int ret;
> +	s32 adc_press;
> +	u32 comp_press;
> +
> +	/* Read and compensate temperature so we get a reading of =
t_fine. */
> +	ret =3D bmp180_read_temp(data, NULL);
> +	if (ret)
> +		return ret;
> +
> +	ret =3D bmp180_read_adc_press(data, &adc_press);
> +	if (ret)
> +		return ret;
> +
> +	comp_press =3D bmp180_compensate_press(data, adc_press);
> +
> +	*val =3D comp_press;
> +	*val2 =3D 1000;
> +
> +	return IIO_VAL_FRACTIONAL;
> +}
> +
> +static int bmp180_chip_config(struct bmp280_data *data)
> +{
> +	return 0;
> +}
> +
> +static const int bmp180_oversampling_temp_avail[] =3D { 1 };
> +static const int bmp180_oversampling_press_avail[] =3D { 1, 2, 4, 8 =
};
> +
> +static const struct bmp280_chip_info bmp180_chip_info =3D {
> +	.oversampling_temp_avail =3D bmp180_oversampling_temp_avail,
> +	.num_oversampling_temp_avail =3D
> +		ARRAY_SIZE(bmp180_oversampling_temp_avail),
> +
> +	.oversampling_press_avail =3D bmp180_oversampling_press_avail,
> +	.num_oversampling_press_avail =3D
> +		ARRAY_SIZE(bmp180_oversampling_press_avail),
> +
> +	.chip_config =3D bmp180_chip_config,
> +	.read_temp =3D bmp180_read_temp,
> +	.read_press =3D bmp180_read_press,
> +};
> +
> +int bmp280_common_probe(struct device *dev,
> +			struct regmap *regmap,
> +			unsigned int chip,
> +			const char *name)
> +{
> +	int ret;
> +	struct iio_dev *indio_dev;
> +	struct bmp280_data *data;
> +	unsigned int chip_id;
> +	struct gpio_desc *gpiod;
> +
> +	indio_dev =3D devm_iio_device_alloc(dev, sizeof(*data));
> +	if (!indio_dev)
> +		return -ENOMEM;
> +
> +	data =3D iio_priv(indio_dev);
> +	mutex_init(&data->lock);
> +	data->dev =3D dev;
> +
> +	indio_dev->dev.parent =3D dev;
> +	indio_dev->name =3D name;
> +	indio_dev->channels =3D bmp280_channels;
> +	indio_dev->info =3D &bmp280_info;
> +	indio_dev->modes =3D INDIO_DIRECT_MODE;
> +
> +	switch (chip) {
> +	case BMP180_CHIP_ID:
> +		indio_dev->num_channels =3D 2;
> +		data->chip_info =3D &bmp180_chip_info;
> +		data->oversampling_press =3D ilog2(8);
> +		data->oversampling_temp =3D ilog2(1);
> +		break;
> +	case BMP280_CHIP_ID:
> +		indio_dev->num_channels =3D 2;
> +		data->chip_info =3D &bmp280_chip_info;
> +		data->oversampling_press =3D ilog2(16);
> +		data->oversampling_temp =3D ilog2(2);
> +		break;
> +	case BME280_CHIP_ID:
> +		indio_dev->num_channels =3D 3;
> +		data->chip_info =3D &bme280_chip_info;
> +		data->oversampling_press =3D ilog2(16);
> +		data->oversampling_humid =3D ilog2(16);
> +		data->oversampling_temp =3D ilog2(2);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	/* Bring up regulators */
> +	data->vddd =3D devm_regulator_get(dev, "vddd");
> +	if (IS_ERR(data->vddd)) {
> +		dev_err(dev, "failed to get VDDD regulator\n");
> +		return PTR_ERR(data->vddd);
> +	}
> +	ret =3D regulator_enable(data->vddd);
> +	if (ret) {
> +		dev_err(dev, "failed to enable VDDD regulator\n");
> +		return ret;
> +	}
> +	data->vdda =3D devm_regulator_get(dev, "vdda");
> +	if (IS_ERR(data->vdda)) {
> +		dev_err(dev, "failed to get VDDA regulator\n");
> +		return PTR_ERR(data->vddd);
> +	}
> +	ret =3D regulator_enable(data->vdda);
> +	if (ret) {
> +		dev_err(dev, "failed to enable VDDA\n");
> +		return ret;
> +	}
> +
> +	/* Bring chip out of reset if there is an assigned GPIO line */
> +	gpiod =3D devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
> +	/* Deassert the signal */
> +	if (!IS_ERR(gpiod)) {
> +		dev_info(dev, "release reset\n");
> +		gpiod_set_value(gpiod, 0);
> +	}
> +
> +	data->regmap =3D regmap;
> +	ret =3D regmap_read(regmap, BMP280_REG_ID, &chip_id);
> +	if (ret < 0)
> +		return ret;
> +	if (chip_id !=3D chip) {
> +		dev_err(dev, "bad chip id: expected %x got %x\n",
> +			chip, chip_id);
> +		return -EINVAL;
> +	}
> +
> +	ret =3D data->chip_info->chip_config(data);
> +	if (ret < 0)
> +		return ret;
> +
> +	return devm_iio_device_register(dev, indio_dev);
> +}
> diff --git a/drivers/iio/pressure/bmp280-i2c.c =
b/drivers/iio/pressure/bmp280-i2c.c
> new file mode 100644
> index 000000000000..a981670e5dc0
> --- /dev/null
> +++ b/drivers/iio/pressure/bmp280-i2c.c
> @@ -0,0 +1,82 @@
> +#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 =3D &bmp180_regmap_config;
> +		break;
> +	case BMP280_CHIP_ID:
> +	case BME280_CHIP_ID:
> +		regmap_config =3D &bmp280_regmap_config;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	regmap =3D 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 const struct acpi_device_id bmp280_acpi_i2c_match[] =3D {
> +	{"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[] =3D {
> +	{ .compatible =3D "bosch,bme280", .data =3D (void =
*)BME280_CHIP_ID },
> +	{ .compatible =3D "bosch,bmp280", .data =3D (void =
*)BMP280_CHIP_ID },
> +	{ .compatible =3D "bosch,bmp180", .data =3D (void =
*)BMP180_CHIP_ID },
> +	{ .compatible =3D "bosch,bmp085", .data =3D (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[] =3D {
> +	{"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 =3D {
> +	.driver =3D {
> +		.name	=3D "bmp280",
> +		.acpi_match_table =3D ACPI_PTR(bmp280_acpi_i2c_match),
> +		.of_match_table =3D of_match_ptr(bmp280_of_i2c_match),
> +	},
> +	.probe		=3D bmp280_i2c_probe,
> +	.id_table	=3D 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 =3D {
> +	.reg_bits =3D 8,
> +	.val_bits =3D 8,
> +
> +	.max_register =3D BMP180_REG_OUT_XLSB,
> +	.cache_type =3D REGCACHE_RBTREE,
> +
> +	.writeable_reg =3D bmp180_is_writeable_reg,
> +	.volatile_reg =3D 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 =3D {
> +	.reg_bits =3D 8,
> +	.val_bits =3D 8,
> +
> +	.max_register =3D BMP280_REG_HUMIDITY_LSB,
> +	.cache_type =3D REGCACHE_RBTREE,
> +
> +	.writeable_reg =3D bmp280_is_writeable_reg,
> +	.volatile_reg =3D bmp280_is_volatile_reg,
> +};
> diff --git a/drivers/iio/pressure/bmp280.c =
b/drivers/iio/pressure/bmp280.c
> deleted file mode 100644
> index 3051e7c444d2..000000000000
> --- a/drivers/iio/pressure/bmp280.c
> +++ /dev/null
> @@ -1,1167 +0,0 @@
> -/*
> - * Copyright (c) 2014 Intel Corporation
> - *
> - * Driver for Bosch Sensortec BMP180 and BMP280 digital pressure =
sensor.
> - *
> - * This program is free software; you can redistribute it and/or =
modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - *
> - * Datasheet:
> - * =
https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP180-=
DS000-121.pdf
> - * =
https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP280-=
DS001-12.pdf
> - * =
https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_=
DS001-11.pdf
> - */
> -
> -#define pr_fmt(fmt) "bmp280: " fmt
> -
> -#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>
> -#include <linux/iio/sysfs.h>
> -#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
> -
> -struct bmp280_data {
> -	struct i2c_client *client;
> -	struct mutex lock;
> -	struct regmap *regmap;
> -	const struct bmp280_chip_info *chip_info;
> -	struct regulator *vddd;
> -	struct regulator *vdda;
> -
> -	/* log of base 2 of oversampling rate */
> -	u8 oversampling_press;
> -	u8 oversampling_temp;
> -	u8 oversampling_humid;
> -
> -	/*
> -	 * Carryover value from temperature conversion, used in pressure
> -	 * calculation.
> -	 */
> -	s32 t_fine;
> -};
> -
> -struct bmp280_chip_info {
> -	const struct regmap_config *regmap_config;
> -
> -	const int *oversampling_temp_avail;
> -	int num_oversampling_temp_avail;
> -
> -	const int *oversampling_press_avail;
> -	int num_oversampling_press_avail;
> -
> -	const int *oversampling_humid_avail;
> -	int num_oversampling_humid_avail;
> -
> -	int (*chip_config)(struct bmp280_data *);
> -	int (*read_temp)(struct bmp280_data *, int *);
> -	int (*read_press)(struct bmp280_data *, int *, int *);
> -	int (*read_humid)(struct bmp280_data *, int *, int *);
> -};
> -
> -/*
> - * These enums are used for indexing into the array of compensation
> - * parameters for BMP280.
> - */
> -enum { T1, T2, T3 };
> -enum { P1, P2, P3, P4, P5, P6, P7, P8, P9 };
> -
> -static const struct iio_chan_spec bmp280_channels[] =3D {
> -	{
> -		.type =3D IIO_PRESSURE,
> -		.info_mask_separate =3D BIT(IIO_CHAN_INFO_PROCESSED) |
> -				      =
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> -	},
> -	{
> -		.type =3D IIO_TEMP,
> -		.info_mask_separate =3D BIT(IIO_CHAN_INFO_PROCESSED) |
> -				      =
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> -	},
> -	{
> -		.type =3D IIO_HUMIDITYRELATIVE,
> -		.info_mask_separate =3D BIT(IIO_CHAN_INFO_PROCESSED) |
> -				      =
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> -	},
> -};
> -
> -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 =3D {
> -	.reg_bits =3D 8,
> -	.val_bits =3D 8,
> -
> -	.max_register =3D BMP280_REG_HUMIDITY_LSB,
> -	.cache_type =3D REGCACHE_RBTREE,
> -
> -	.writeable_reg =3D bmp280_is_writeable_reg,
> -	.volatile_reg =3D bmp280_is_volatile_reg,
> -};
> -
> -/*
> - * Returns humidity in percent, resolution is 0.01 percent. Output =
value of
> - * "47445" represents 47445/1024 =3D 46.333 %RH.
> - *
> - * Taken from BME280 datasheet, Section 4.2.3, "Compensation =
formula".
> - */
> -
> -static u32 bmp280_compensate_humidity(struct bmp280_data *data,
> -				      s32 adc_humidity)
> -{
> -	struct device *dev =3D &data->client->dev;
> -	unsigned int H1, H3, tmp;
> -	int H2, H4, H5, H6, ret, var;
> -
> -	ret =3D regmap_read(data->regmap, BMP280_REG_COMP_H1, &H1);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H1 comp value\n");
> -		return ret;
> -	}
> -
> -	ret =3D regmap_bulk_read(data->regmap, BMP280_REG_COMP_H2, &tmp, =
2);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H2 comp value\n");
> -		return ret;
> -	}
> -	H2 =3D sign_extend32(le16_to_cpu(tmp), 15);
> -
> -	ret =3D regmap_read(data->regmap, BMP280_REG_COMP_H3, &H3);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H3 comp value\n");
> -		return ret;
> -	}
> -
> -	ret =3D regmap_bulk_read(data->regmap, BMP280_REG_COMP_H4, &tmp, =
2);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H4 comp value\n");
> -		return ret;
> -	}
> -	H4 =3D sign_extend32(((be16_to_cpu(tmp) >> 4) & 0xff0) |
> -			  (be16_to_cpu(tmp) & 0xf), 11);
> -
> -	ret =3D regmap_bulk_read(data->regmap, BMP280_REG_COMP_H5, &tmp, =
2);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H5 comp value\n");
> -		return ret;
> -	}
> -	H5 =3D sign_extend32(((le16_to_cpu(tmp) >> 4) & 0xfff), 11);
> -
> -	ret =3D regmap_read(data->regmap, BMP280_REG_COMP_H6, &tmp);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H6 comp value\n");
> -		return ret;
> -	}
> -	H6 =3D sign_extend32(tmp, 7);
> -
> -	var =3D ((s32)data->t_fine) - 76800;
> -	var =3D ((((adc_humidity << 14) - (H4 << 20) - (H5 * var)) + =
16384) >> 15)
> -		* (((((((var * H6) >> 10) * (((var * H3) >> 11) + =
32768)) >> 10)
> -		+ 2097152) * H2 + 8192) >> 14);
> -	var -=3D ((((var >> 15) * (var >> 15)) >> 7) * H1) >> 4;
> -
> -	return var >> 12;
> -};
> -
> -/*
> - * Returns temperature in DegC, resolution is 0.01 DegC.  Output =
value of
> - * "5123" equals 51.23 DegC.  t_fine carries fine temperature as =
global
> - * value.
> - *
> - * Taken from datasheet, Section 3.11.3, "Compensation formula".
> - */
> -static s32 bmp280_compensate_temp(struct bmp280_data *data,
> -				  s32 adc_temp)
> -{
> -	int ret;
> -	s32 var1, var2;
> -	__le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2];
> -
> -	ret =3D regmap_bulk_read(data->regmap, =
BMP280_REG_COMP_TEMP_START,
> -			       buf, BMP280_COMP_TEMP_REG_COUNT);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev,
> -			"failed to read temperature calibration =
parameters\n");
> -		return ret;
> -	}
> -
> -	/*
> -	 * The double casts are necessary because le16_to_cpu returns an
> -	 * unsigned 16-bit value.  Casting that value directly to a
> -	 * signed 32-bit will not do proper sign extension.
> -	 *
> -	 * Conversely, T1 and P1 are unsigned values, so they can be
> -	 * cast straight to the larger type.
> -	 */
> -	var1 =3D (((adc_temp >> 3) - ((s32)le16_to_cpu(buf[T1]) << 1)) *
> -		((s32)(s16)le16_to_cpu(buf[T2]))) >> 11;
> -	var2 =3D (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) *
> -		  ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> =
12) *
> -		((s32)(s16)le16_to_cpu(buf[T3]))) >> 14;
> -	data->t_fine =3D var1 + var2;
> -
> -	return (data->t_fine * 5 + 128) >> 8;
> -}
> -
> -/*
> - * Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format =
(24
> - * integer bits and 8 fractional bits).  Output value of "24674867"
> - * represents 24674867/256 =3D 96386.2 Pa =3D 963.862 hPa
> - *
> - * Taken from datasheet, Section 3.11.3, "Compensation formula".
> - */
> -static u32 bmp280_compensate_press(struct bmp280_data *data,
> -				   s32 adc_press)
> -{
> -	int ret;
> -	s64 var1, var2, p;
> -	__le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2];
> -
> -	ret =3D regmap_bulk_read(data->regmap, =
BMP280_REG_COMP_PRESS_START,
> -			       buf, BMP280_COMP_PRESS_REG_COUNT);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev,
> -			"failed to read pressure calibration =
parameters\n");
> -		return ret;
> -	}
> -
> -	var1 =3D ((s64)data->t_fine) - 128000;
> -	var2 =3D var1 * var1 * (s64)(s16)le16_to_cpu(buf[P6]);
> -	var2 +=3D (var1 * (s64)(s16)le16_to_cpu(buf[P5])) << 17;
> -	var2 +=3D ((s64)(s16)le16_to_cpu(buf[P4])) << 35;
> -	var1 =3D ((var1 * var1 * (s64)(s16)le16_to_cpu(buf[P3])) >> 8) +
> -		((var1 * (s64)(s16)le16_to_cpu(buf[P2])) << 12);
> -	var1 =3D ((((s64)1) << 47) + var1) * ((s64)le16_to_cpu(buf[P1])) =
>> 33;
> -
> -	if (var1 =3D=3D 0)
> -		return 0;
> -
> -	p =3D ((((s64)1048576 - adc_press) << 31) - var2) * 3125;
> -	p =3D div64_s64(p, var1);
> -	var1 =3D (((s64)(s16)le16_to_cpu(buf[P9])) * (p >> 13) * (p >> =
13)) >> 25;
> -	var2 =3D (((s64)(s16)le16_to_cpu(buf[P8])) * p) >> 19;
> -	p =3D ((p + var1 + var2) >> 8) + =
(((s64)(s16)le16_to_cpu(buf[P7])) << 4);
> -
> -	return (u32)p;
> -}
> -
> -static int bmp280_read_temp(struct bmp280_data *data,
> -			    int *val)
> -{
> -	int ret;
> -	__be32 tmp =3D 0;
> -	s32 adc_temp, comp_temp;
> -
> -	ret =3D 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");
> -		return ret;
> -	}
> -
> -	adc_temp =3D be32_to_cpu(tmp) >> 12;
> -	comp_temp =3D bmp280_compensate_temp(data, adc_temp);
> -
> -	/*
> -	 * val might be NULL if we're called by the read_press routine,
> -	 * who only cares about the carry over t_fine value.
> -	 */
> -	if (val) {
> -		*val =3D comp_temp * 10;
> -		return IIO_VAL_INT;
> -	}
> -
> -	return 0;
> -}
> -
> -static int bmp280_read_press(struct bmp280_data *data,
> -			     int *val, int *val2)
> -{
> -	int ret;
> -	__be32 tmp =3D 0;
> -	s32 adc_press;
> -	u32 comp_press;
> -
> -	/* Read and compensate temperature so we get a reading of =
t_fine. */
> -	ret =3D bmp280_read_temp(data, NULL);
> -	if (ret < 0)
> -		return ret;
> -
> -	ret =3D 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");
> -		return ret;
> -	}
> -
> -	adc_press =3D be32_to_cpu(tmp) >> 12;
> -	comp_press =3D bmp280_compensate_press(data, adc_press);
> -
> -	*val =3D comp_press;
> -	*val2 =3D 256000;
> -
> -	return IIO_VAL_FRACTIONAL;
> -}
> -
> -static int bmp280_read_humid(struct bmp280_data *data, int *val, int =
*val2)
> -{
> -	int ret;
> -	__be16 tmp =3D 0;
> -	s32 adc_humidity;
> -	u32 comp_humidity;
> -
> -	/* Read and compensate temperature so we get a reading of =
t_fine. */
> -	ret =3D bmp280_read_temp(data, NULL);
> -	if (ret < 0)
> -		return ret;
> -
> -	ret =3D 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");
> -		return ret;
> -	}
> -
> -	adc_humidity =3D be16_to_cpu(tmp);
> -	comp_humidity =3D bmp280_compensate_humidity(data, =
adc_humidity);
> -
> -	*val =3D comp_humidity;
> -	*val2 =3D 1024;
> -
> -	return IIO_VAL_FRACTIONAL;
> -}
> -
> -static int bmp280_read_raw(struct iio_dev *indio_dev,
> -			   struct iio_chan_spec const *chan,
> -			   int *val, int *val2, long mask)
> -{
> -	int ret;
> -	struct bmp280_data *data =3D iio_priv(indio_dev);
> -
> -	mutex_lock(&data->lock);
> -
> -	switch (mask) {
> -	case IIO_CHAN_INFO_PROCESSED:
> -		switch (chan->type) {
> -		case IIO_HUMIDITYRELATIVE:
> -			ret =3D data->chip_info->read_humid(data, val, =
val2);
> -			break;
> -		case IIO_PRESSURE:
> -			ret =3D data->chip_info->read_press(data, val, =
val2);
> -			break;
> -		case IIO_TEMP:
> -			ret =3D data->chip_info->read_temp(data, val);
> -			break;
> -		default:
> -			ret =3D -EINVAL;
> -			break;
> -		}
> -		break;
> -	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> -		switch (chan->type) {
> -		case IIO_HUMIDITYRELATIVE:
> -			*val =3D 1 << data->oversampling_humid;
> -			ret =3D IIO_VAL_INT;
> -			break;
> -		case IIO_PRESSURE:
> -			*val =3D 1 << data->oversampling_press;
> -			ret =3D IIO_VAL_INT;
> -			break;
> -		case IIO_TEMP:
> -			*val =3D 1 << data->oversampling_temp;
> -			ret =3D IIO_VAL_INT;
> -			break;
> -		default:
> -			ret =3D -EINVAL;
> -			break;
> -		}
> -		break;
> -	default:
> -		ret =3D -EINVAL;
> -		break;
> -	}
> -
> -	mutex_unlock(&data->lock);
> -
> -	return ret;
> -}
> -
> -static int bmp280_write_oversampling_ratio_humid(struct bmp280_data =
*data,
> -					       int val)
> -{
> -	int i;
> -	const int *avail =3D data->chip_info->oversampling_humid_avail;
> -	const int n =3D data->chip_info->num_oversampling_humid_avail;
> -
> -	for (i =3D 0; i < n; i++) {
> -		if (avail[i] =3D=3D val) {
> -			data->oversampling_humid =3D ilog2(val);
> -
> -			return data->chip_info->chip_config(data);
> -		}
> -	}
> -	return -EINVAL;
> -}
> -
> -static int bmp280_write_oversampling_ratio_temp(struct bmp280_data =
*data,
> -					       int val)
> -{
> -	int i;
> -	const int *avail =3D data->chip_info->oversampling_temp_avail;
> -	const int n =3D data->chip_info->num_oversampling_temp_avail;
> -
> -	for (i =3D 0; i < n; i++) {
> -		if (avail[i] =3D=3D val) {
> -			data->oversampling_temp =3D ilog2(val);
> -
> -			return data->chip_info->chip_config(data);
> -		}
> -	}
> -	return -EINVAL;
> -}
> -
> -static int bmp280_write_oversampling_ratio_press(struct bmp280_data =
*data,
> -					       int val)
> -{
> -	int i;
> -	const int *avail =3D data->chip_info->oversampling_press_avail;
> -	const int n =3D data->chip_info->num_oversampling_press_avail;
> -
> -	for (i =3D 0; i < n; i++) {
> -		if (avail[i] =3D=3D val) {
> -			data->oversampling_press =3D ilog2(val);
> -
> -			return data->chip_info->chip_config(data);
> -		}
> -	}
> -	return -EINVAL;
> -}
> -
> -static int bmp280_write_raw(struct iio_dev *indio_dev,
> -			    struct iio_chan_spec const *chan,
> -			    int val, int val2, long mask)
> -{
> -	int ret =3D 0;
> -	struct bmp280_data *data =3D iio_priv(indio_dev);
> -
> -	switch (mask) {
> -	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> -		mutex_lock(&data->lock);
> -		switch (chan->type) {
> -		case IIO_HUMIDITYRELATIVE:
> -			ret =3D =
bmp280_write_oversampling_ratio_humid(data, val);
> -			break;
> -		case IIO_PRESSURE:
> -			ret =3D =
bmp280_write_oversampling_ratio_press(data, val);
> -			break;
> -		case IIO_TEMP:
> -			ret =3D =
bmp280_write_oversampling_ratio_temp(data, val);
> -			break;
> -		default:
> -			ret =3D -EINVAL;
> -			break;
> -		}
> -		mutex_unlock(&data->lock);
> -		break;
> -	default:
> -		return -EINVAL;
> -	}
> -
> -	return ret;
> -}
> -
> -static ssize_t bmp280_show_avail(char *buf, const int *vals, const =
int n)
> -{
> -	size_t len =3D 0;
> -	int i;
> -
> -	for (i =3D 0; i < n; i++)
> -		len +=3D scnprintf(buf + len, PAGE_SIZE - len, "%d ", =
vals[i]);
> -
> -	buf[len - 1] =3D '\n';
> -
> -	return len;
> -}
> -
> -static ssize_t bmp280_show_temp_oversampling_avail(struct device =
*dev,
> -				struct device_attribute *attr, char =
*buf)
> -{
> -	struct bmp280_data *data =3D iio_priv(dev_to_iio_dev(dev));
> -
> -	return bmp280_show_avail(buf, =
data->chip_info->oversampling_temp_avail,
> -				 =
data->chip_info->num_oversampling_temp_avail);
> -}
> -
> -static ssize_t bmp280_show_press_oversampling_avail(struct device =
*dev,
> -				struct device_attribute *attr, char =
*buf)
> -{
> -	struct bmp280_data *data =3D iio_priv(dev_to_iio_dev(dev));
> -
> -	return bmp280_show_avail(buf, =
data->chip_info->oversampling_press_avail,
> -				 =
data->chip_info->num_oversampling_press_avail);
> -}
> -
> -static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available,
> -	S_IRUGO, bmp280_show_temp_oversampling_avail, NULL, 0);
> -
> -static IIO_DEVICE_ATTR(in_pressure_oversampling_ratio_available,
> -	S_IRUGO, bmp280_show_press_oversampling_avail, NULL, 0);
> -
> -static struct attribute *bmp280_attributes[] =3D {
> -	=
&iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr,
> -	=
&iio_dev_attr_in_pressure_oversampling_ratio_available.dev_attr.attr,
> -	NULL,
> -};
> -
> -static const struct attribute_group bmp280_attrs_group =3D {
> -	.attrs =3D bmp280_attributes,
> -};
> -
> -static const struct iio_info bmp280_info =3D {
> -	.driver_module =3D THIS_MODULE,
> -	.read_raw =3D &bmp280_read_raw,
> -	.write_raw =3D &bmp280_write_raw,
> -	.attrs =3D &bmp280_attrs_group,
> -};
> -
> -static int bmp280_chip_config(struct bmp280_data *data)
> -{
> -	int ret;
> -	u8 osrs =3D BMP280_OSRS_TEMP_X(data->oversampling_temp + 1) |
> -		  BMP280_OSRS_PRESS_X(data->oversampling_press + 1);
> -
> -	ret =3D regmap_update_bits(data->regmap, BMP280_REG_CTRL_MEAS,
> -				 BMP280_OSRS_TEMP_MASK |
> -				 BMP280_OSRS_PRESS_MASK |
> -				 BMP280_MODE_MASK,
> -				 osrs | BMP280_MODE_NORMAL);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev,
> -			"failed to write ctrl_meas register\n");
> -		return ret;
> -	}
> -
> -	ret =3D regmap_update_bits(data->regmap, BMP280_REG_CONFIG,
> -				 BMP280_FILTER_MASK,
> -				 BMP280_FILTER_4X);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev,
> -			"failed to write config register\n");
> -		return ret;
> -	}
> -
> -	return ret;
> -}
> -
> -static const int bmp280_oversampling_avail[] =3D { 1, 2, 4, 8, 16 };
> -
> -static const struct bmp280_chip_info bmp280_chip_info =3D {
> -	.regmap_config =3D &bmp280_regmap_config,
> -
> -	.oversampling_temp_avail =3D bmp280_oversampling_avail,
> -	.num_oversampling_temp_avail =3D =
ARRAY_SIZE(bmp280_oversampling_avail),
> -
> -	.oversampling_press_avail =3D bmp280_oversampling_avail,
> -	.num_oversampling_press_avail =3D =
ARRAY_SIZE(bmp280_oversampling_avail),
> -
> -	.chip_config =3D bmp280_chip_config,
> -	.read_temp =3D bmp280_read_temp,
> -	.read_press =3D bmp280_read_press,
> -};
> -
> -static int bme280_chip_config(struct bmp280_data *data)
> -{
> -	int ret =3D bmp280_chip_config(data);
> -	u8 osrs =3D BMP280_OSRS_HUMIDITIY_X(data->oversampling_humid + =
1);
> -
> -	if (ret < 0)
> -		return ret;
> -
> -	return regmap_update_bits(data->regmap, =
BMP280_REG_CTRL_HUMIDITY,
> -				  BMP280_OSRS_HUMIDITY_MASK, osrs);
> -}
> -
> -static const struct bmp280_chip_info bme280_chip_info =3D {
> -	.regmap_config =3D &bmp280_regmap_config,
> -
> -	.oversampling_temp_avail =3D bmp280_oversampling_avail,
> -	.num_oversampling_temp_avail =3D =
ARRAY_SIZE(bmp280_oversampling_avail),
> -
> -	.oversampling_press_avail =3D bmp280_oversampling_avail,
> -	.num_oversampling_press_avail =3D =
ARRAY_SIZE(bmp280_oversampling_avail),
> -
> -	.oversampling_humid_avail =3D bmp280_oversampling_avail,
> -	.num_oversampling_humid_avail =3D =
ARRAY_SIZE(bmp280_oversampling_avail),
> -
> -	.chip_config =3D bme280_chip_config,
> -	.read_temp =3D bmp280_read_temp,
> -	.read_press =3D bmp280_read_press,
> -	.read_humid =3D 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 =3D {
> -	.reg_bits =3D 8,
> -	.val_bits =3D 8,
> -
> -	.max_register =3D BMP180_REG_OUT_XLSB,
> -	.cache_type =3D REGCACHE_RBTREE,
> -
> -	.writeable_reg =3D bmp180_is_writeable_reg,
> -	.volatile_reg =3D bmp180_is_volatile_reg,
> -};
> -
> -static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas)
> -{
> -	int ret;
> -	const int conversion_time_max[] =3D { 4500, 7500, 13500, 25500 =
};
> -	unsigned int delay_us;
> -	unsigned int ctrl;
> -
> -	ret =3D regmap_write(data->regmap, BMP280_REG_CTRL_MEAS, =
ctrl_meas);
> -	if (ret)
> -		return ret;
> -
> -	if (ctrl_meas =3D=3D BMP180_MEAS_TEMP)
> -		delay_us =3D 4500;
> -	else
> -		delay_us =3D =
conversion_time_max[data->oversampling_press];
> -
> -	usleep_range(delay_us, delay_us + 1000);
> -
> -	ret =3D regmap_read(data->regmap, BMP280_REG_CTRL_MEAS, &ctrl);
> -	if (ret)
> -		return ret;
> -
> -	/* The value of this bit reset to "0" after conversion is =
complete */
> -	if (ctrl & BMP180_MEAS_SCO)
> -		return -EIO;
> -
> -	return 0;
> -}
> -
> -static int bmp180_read_adc_temp(struct bmp280_data *data, int *val)
> -{
> -	int ret;
> -	__be16 tmp =3D 0;
> -
> -	ret =3D bmp180_measure(data, BMP180_MEAS_TEMP);
> -	if (ret)
> -		return ret;
> -
> -	ret =3D regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 =
*)&tmp, 2);
> -	if (ret)
> -		return ret;
> -
> -	*val =3D be16_to_cpu(tmp);
> -
> -	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)
> -{
> -	int ret;
> -	int i;
> -	__be16 buf[BMP180_REG_CALIB_COUNT / 2];
> -
> -	ret =3D regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, =
buf,
> -			       sizeof(buf));
> -
> -	if (ret < 0)
> -		return ret;
> -
> -	/* None of the words has the value 0 or 0xFFFF */
> -	for (i =3D 0; i < ARRAY_SIZE(buf); i++) {
> -		if (buf[i] =3D=3D cpu_to_be16(0) || buf[i] =3D=3D =
cpu_to_be16(0xffff))
> -			return -EIO;
> -	}
> -
> -	calib->AC1 =3D be16_to_cpu(buf[AC1]);
> -	calib->AC2 =3D be16_to_cpu(buf[AC2]);
> -	calib->AC3 =3D be16_to_cpu(buf[AC3]);
> -	calib->AC4 =3D be16_to_cpu(buf[AC4]);
> -	calib->AC5 =3D be16_to_cpu(buf[AC5]);
> -	calib->AC6 =3D be16_to_cpu(buf[AC6]);
> -	calib->B1 =3D be16_to_cpu(buf[B1]);
> -	calib->B2 =3D be16_to_cpu(buf[B2]);
> -	calib->MB =3D be16_to_cpu(buf[MB]);
> -	calib->MC =3D be16_to_cpu(buf[MC]);
> -	calib->MD =3D be16_to_cpu(buf[MD]);
> -
> -	return 0;
> -}
> -
> -/*
> - * Returns temperature in DegC, resolution is 0.1 DegC.
> - * t_fine carries fine temperature as global value.
> - *
> - * Taken from datasheet, Section 3.5, "Calculating pressure and =
temperature".
> - */
> -static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 =
adc_temp)
> -{
> -	int ret;
> -	s32 x1, x2;
> -	struct bmp180_calib calib;
> -
> -	ret =3D bmp180_read_calib(data, &calib);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev,
> -			"failed to read calibration coefficients\n");
> -		return ret;
> -	}
> -
> -	x1 =3D ((adc_temp - calib.AC6) * calib.AC5) >> 15;
> -	x2 =3D (calib.MC << 11) / (x1 + calib.MD);
> -	data->t_fine =3D x1 + x2;
> -
> -	return (data->t_fine + 8) >> 4;
> -}
> -
> -static int bmp180_read_temp(struct bmp280_data *data, int *val)
> -{
> -	int ret;
> -	s32 adc_temp, comp_temp;
> -
> -	ret =3D bmp180_read_adc_temp(data, &adc_temp);
> -	if (ret)
> -		return ret;
> -
> -	comp_temp =3D bmp180_compensate_temp(data, adc_temp);
> -
> -	/*
> -	 * val might be NULL if we're called by the read_press routine,
> -	 * who only cares about the carry over t_fine value.
> -	 */
> -	if (val) {
> -		*val =3D comp_temp * 100;
> -		return IIO_VAL_INT;
> -	}
> -
> -	return 0;
> -}
> -
> -static int bmp180_read_adc_press(struct bmp280_data *data, int *val)
> -{
> -	int ret;
> -	__be32 tmp =3D 0;
> -	u8 oss =3D data->oversampling_press;
> -
> -	ret =3D bmp180_measure(data, BMP180_MEAS_PRESS_X(oss));
> -	if (ret)
> -		return ret;
> -
> -	ret =3D regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 =
*)&tmp, 3);
> -	if (ret)
> -		return ret;
> -
> -	*val =3D (be32_to_cpu(tmp) >> 8) >> (8 - oss);
> -
> -	return 0;
> -}
> -
> -/*
> - * Returns pressure in Pa, resolution is 1 Pa.
> - *
> - * Taken from datasheet, Section 3.5, "Calculating pressure and =
temperature".
> - */
> -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 =3D data->oversampling_press;
> -	struct bmp180_calib calib;
> -
> -	ret =3D bmp180_read_calib(data, &calib);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev,
> -			"failed to read calibration coefficients\n");
> -		return ret;
> -	}
> -
> -	b6 =3D data->t_fine - 4000;
> -	x1 =3D (calib.B2 * (b6 * b6 >> 12)) >> 11;
> -	x2 =3D calib.AC2 * b6 >> 11;
> -	x3 =3D x1 + x2;
> -	b3 =3D ((((s32)calib.AC1 * 4 + x3) << oss) + 2) / 4;
> -	x1 =3D calib.AC3 * b6 >> 13;
> -	x2 =3D (calib.B1 * ((b6 * b6) >> 12)) >> 16;
> -	x3 =3D (x1 + x2 + 2) >> 2;
> -	b4 =3D calib.AC4 * (u32)(x3 + 32768) >> 15;
> -	b7 =3D ((u32)adc_press - b3) * (50000 >> oss);
> -	if (b7 < 0x80000000)
> -		p =3D (b7 * 2) / b4;
> -	else
> -		p =3D (b7 / b4) * 2;
> -
> -	x1 =3D (p >> 8) * (p >> 8);
> -	x1 =3D (x1 * 3038) >> 16;
> -	x2 =3D (-7357 * p) >> 16;
> -
> -	return p + ((x1 + x2 + 3791) >> 4);
> -}
> -
> -static int bmp180_read_press(struct bmp280_data *data,
> -			     int *val, int *val2)
> -{
> -	int ret;
> -	s32 adc_press;
> -	u32 comp_press;
> -
> -	/* Read and compensate temperature so we get a reading of =
t_fine. */
> -	ret =3D bmp180_read_temp(data, NULL);
> -	if (ret)
> -		return ret;
> -
> -	ret =3D bmp180_read_adc_press(data, &adc_press);
> -	if (ret)
> -		return ret;
> -
> -	comp_press =3D bmp180_compensate_press(data, adc_press);
> -
> -	*val =3D comp_press;
> -	*val2 =3D 1000;
> -
> -	return IIO_VAL_FRACTIONAL;
> -}
> -
> -static int bmp180_chip_config(struct bmp280_data *data)
> -{
> -	return 0;
> -}
> -
> -static const int bmp180_oversampling_temp_avail[] =3D { 1 };
> -static const int bmp180_oversampling_press_avail[] =3D { 1, 2, 4, 8 =
};
> -
> -static const struct bmp280_chip_info bmp180_chip_info =3D {
> -	.regmap_config =3D &bmp180_regmap_config,
> -
> -	.oversampling_temp_avail =3D bmp180_oversampling_temp_avail,
> -	.num_oversampling_temp_avail =3D
> -		ARRAY_SIZE(bmp180_oversampling_temp_avail),
> -
> -	.oversampling_press_avail =3D bmp180_oversampling_press_avail,
> -	.num_oversampling_press_avail =3D
> -		ARRAY_SIZE(bmp180_oversampling_press_avail),
> -
> -	.chip_config =3D bmp180_chip_config,
> -	.read_temp =3D bmp180_read_temp,
> -	.read_press =3D bmp180_read_press,
> -};
> -
> -static int bmp280_probe(struct i2c_client *client,
> -			const struct i2c_device_id *id)
> -{
> -	int ret;
> -	struct iio_dev *indio_dev;
> -	struct bmp280_data *data;
> -	unsigned int chip_id;
> -	struct gpio_desc *gpiod;
> -
> -	indio_dev =3D devm_iio_device_alloc(&client->dev, =
sizeof(*data));
> -	if (!indio_dev)
> -		return -ENOMEM;
> -
> -	data =3D iio_priv(indio_dev);
> -	mutex_init(&data->lock);
> -	data->client =3D client;
> -
> -	indio_dev->dev.parent =3D &client->dev;
> -	indio_dev->name =3D id->name;
> -	indio_dev->channels =3D bmp280_channels;
> -	indio_dev->info =3D &bmp280_info;
> -	indio_dev->modes =3D INDIO_DIRECT_MODE;
> -
> -	switch (id->driver_data) {
> -	case BMP180_CHIP_ID:
> -		indio_dev->num_channels =3D 2;
> -		data->chip_info =3D &bmp180_chip_info;
> -		data->oversampling_press =3D ilog2(8);
> -		data->oversampling_temp =3D ilog2(1);
> -		break;
> -	case BMP280_CHIP_ID:
> -		indio_dev->num_channels =3D 2;
> -		data->chip_info =3D &bmp280_chip_info;
> -		data->oversampling_press =3D ilog2(16);
> -		data->oversampling_temp =3D ilog2(2);
> -		break;
> -	case BME280_CHIP_ID:
> -		indio_dev->num_channels =3D 3;
> -		data->chip_info =3D &bme280_chip_info;
> -		data->oversampling_press =3D ilog2(16);
> -		data->oversampling_humid =3D ilog2(16);
> -		data->oversampling_temp =3D ilog2(2);
> -		break;
> -	default:
> -		return -EINVAL;
> -	}
> -
> -	/* Bring up regulators */
> -	data->vddd =3D 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 =3D regulator_enable(data->vddd);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to enable VDDD =
regulator\n");
> -		return ret;
> -	}
> -	data->vdda =3D devm_regulator_get(&client->dev, "vdda");
> -	if (IS_ERR(data->vdda)) {
> -		dev_err(&client->dev, "failed to get VDDA regulator\n");
> -		return PTR_ERR(data->vddd);
> -	}
> -	ret =3D regulator_enable(data->vdda);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to enable VDDA\n");
> -		return ret;
> -	}
> -
> -	/* Bring chip out of reset if there is an assigned GPIO line */
> -	gpiod =3D 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 =3D 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");
> -		return PTR_ERR(data->regmap);
> -	}
> -
> -	ret =3D regmap_read(data->regmap, BMP280_REG_ID, &chip_id);
> -	if (ret < 0)
> -		return ret;
> -	if (chip_id !=3D id->driver_data) {
> -		dev_err(&client->dev, "bad chip id.  expected %lx got =
%x\n",
> -			id->driver_data, chip_id);
> -		return -EINVAL;
> -	}
> -
> -	ret =3D data->chip_info->chip_config(data);
> -	if (ret < 0)
> -		return ret;
> -
> -	return devm_iio_device_register(&client->dev, indio_dev);
> -}
> -
> -static const struct acpi_device_id bmp280_acpi_match[] =3D {
> -	{"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[] =3D {
> -	{ .compatible =3D "bosch,bme280", .data =3D (void =
*)BME280_CHIP_ID },
> -	{ .compatible =3D "bosch,bmp280", .data =3D (void =
*)BMP280_CHIP_ID },
> -	{ .compatible =3D "bosch,bmp180", .data =3D (void =
*)BMP180_CHIP_ID },
> -	{ .compatible =3D "bosch,bmp085", .data =3D (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[] =3D {
> -	{"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 =3D {
> -	.driver =3D {
> -		.name	=3D "bmp280",
> -		.acpi_match_table =3D ACPI_PTR(bmp280_acpi_match),
> -		.of_match_table =3D of_match_ptr(bmp280_of_match),
> -	},
> -	.probe		=3D bmp280_probe,
> -	.id_table	=3D 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.h =
b/drivers/iio/pressure/bmp280.h
> new file mode 100644
> index 000000000000..acb40de2f581
> --- /dev/null
> +++ b/drivers/iio/pressure/bmp280.h
> @@ -0,0 +1,107 @@
> +#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);
> --=20
> 2.4.11
>=20

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

* Re: [PATCH 4/9 v2] iio: pressure: bmp280: support supply regulators
  2016-06-22 20:53 ` [PATCH 4/9 v2] iio: pressure: bmp280: support supply regulators Linus Walleij
@ 2016-06-23 10:02   ` Mark Brown
  0 siblings, 0 replies; 32+ messages in thread
From: Mark Brown @ 2016-06-23 10:02 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Christoph Mair, Vlad Dogaru, Hartmut Knaack,
	Marek Belisko, Eric Andersson, Neil Brown

[-- Attachment #1: Type: text/plain, Size: 464 bytes --]

On Wed, Jun 22, 2016 at 10:53:34PM +0200, Linus Walleij wrote:

> +	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;
> +	}

I'm not seeing any matching regulator_disable() calls anywhere...

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* Re: [PATCH 2/9 v2] iio: pressure: bmp280: support device tree initialization
  2016-06-23  8:18   ` H. Nikolaus Schaller
@ 2016-06-24 10:26     ` Linus Walleij
  0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2016-06-24 10:26 UTC (permalink / raw)
  To: H. Nikolaus Schaller
  Cc: Jonathan Cameron, linux-iio, Akinobu Mita, Matt Ranostay,
	Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Discussions about the Letux Kernel,
	kernel

On Thu, Jun 23, 2016 at 10:18 AM, H. Nikolaus Schaller
<hns@goldelico.com> wrote:
>> Am 22.06.2016 um 22:53 schrieb Linus Walleij <linus.walleij@linaro.org>:

>> +#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 },
>
> Here I get:
>
> FATAL: drivers/iio/pressure/bmp280-i2c: struct of_device_id is not terminated with a NULL entry!

I got this from the build robot too, fixed locally and resending in v3.
Thanks!

Yours,
Linus Walleij

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

* Re: [PATCH 5/9 v2] iio: pressure: bmp280: split driver in logical parts
  2016-06-23  8:18   ` H. Nikolaus Schaller
@ 2016-06-24 10:28     ` Linus Walleij
  0 siblings, 0 replies; 32+ messages in thread
From: Linus Walleij @ 2016-06-24 10:28 UTC (permalink / raw)
  To: H. Nikolaus Schaller
  Cc: Jonathan Cameron, linux-iio, Akinobu Mita, Matt Ranostay,
	Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Discussions about the Letux Kernel,
	kernel

On Thu, Jun 23, 2016 at 10:18 AM, H. Nikolaus Schaller
<hns@goldelico.com> wrote:
>> Am 22.06.2016 um 22:53 schrieb Linus Walleij <linus.walleij@linaro.org>:

>> # 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
>
> With menuconfig setting to 'M'
>
> CONFIG_BMP280=m
> CONFIG_BMP280_I2C=m
> CONFIG_BMP280_SPI=m
>
> I get
>
> ERROR: "bmp280_regmap_config" [drivers/iio/pressure/bmp280-spi.ko] undefined!
> ERROR: "bmp180_regmap_config" [drivers/iio/pressure/bmp280-spi.ko] undefined!
> ERROR: "bmp280_common_probe" [drivers/iio/pressure/bmp280-spi.ko] undefined!
> ERROR: "bmp280_regmap_config" [drivers/iio/pressure/bmp280-i2c.ko] undefined!
> ERROR: "bmp180_regmap_config" [drivers/iio/pressure/bmp280-i2c.ko] undefined!
> ERROR: "bmp280_common_probe" [drivers/iio/pressure/bmp280-i2c.ko] undefined!

Yeah module deps is one of my weak spots :(
The build robot found it too.

Fixing in v3. Thanks!

Yours,
Linus Walleij

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

* Re: [PATCH 2/9 v2] iio: pressure: bmp280: support device tree initialization
  2016-06-22 20:53 ` [PATCH 2/9 v2] iio: pressure: bmp280: support device tree initialization Linus Walleij
  2016-06-23  8:18   ` H. Nikolaus Schaller
@ 2016-06-26  9:52   ` Jonathan Cameron
  2016-06-26 10:27     ` H. Nikolaus Schaller
  1 sibling, 1 reply; 32+ messages in thread
From: Jonathan Cameron @ 2016-06-26  9:52 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 22/06/16 21:53, 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
> 
Please also confirm the value of 'name' given the mess we have had
over that recently.


> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v1->v2:
> - Fix some BMP085 misspelled as BMP058 errors.
> - Add the new BME280 sensor as well
> ---
>  drivers/iio/pressure/bmp280.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
> index dbbcd6d83e3b..655e888ef8f9 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,18 @@ 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 +1120,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] 32+ messages in thread

* Re: [PATCH 5/9 v2] iio: pressure: bmp280: split driver in logical parts
  2016-06-22 20:53 ` [PATCH 5/9 v2] iio: pressure: bmp280: split driver in logical parts Linus Walleij
  2016-06-23  8:18   ` H. Nikolaus Schaller
@ 2016-06-26 10:04   ` Jonathan Cameron
  2016-06-27 11:29     ` Linus Walleij
  1 sibling, 1 reply; 32+ messages in thread
From: Jonathan Cameron @ 2016-06-26 10:04 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 22/06/16 21:53, 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>

Few trivial bits inline.

Main thought here is why not roll the regmap bit into the core?  It's hardly
a huge addition and that would allow you to also pull all of the header
register defines etc into there..

Jonathan
> ---
> ChangeLog v1->v2:
> - Rebased on top of Matt Ranostays BME280 with humidity sensor support
> ---
>  drivers/iio/pressure/Makefile        |    1 +
>  drivers/iio/pressure/bmp280-core.c   |  937 +++++++++++++++++++++++++++
>  drivers/iio/pressure/bmp280-i2c.c    |   82 +++
>  drivers/iio/pressure/bmp280-regmap.c |   81 +++
>  drivers/iio/pressure/bmp280.c        | 1167 ----------------------------------
>  drivers/iio/pressure/bmp280.h        |  107 ++++
>  6 files changed, 1208 insertions(+), 1167 deletions(-)
>  create mode 100644 drivers/iio/pressure/bmp280-core.c
>  create mode 100644 drivers/iio/pressure/bmp280-i2c.c
>  create mode 100644 drivers/iio/pressure/bmp280-regmap.c
>  delete mode 100644 drivers/iio/pressure/bmp280.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-core.c b/drivers/iio/pressure/bmp280-core.c
> new file mode 100644
> index 000000000000..77f0fc935c09
> --- /dev/null
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -0,0 +1,937 @@
> +/*
> + * Copyright (c) 2014 Intel Corporation
> + *
> + * Driver for Bosch Sensortec BMP180 and BMP280 digital pressure sensor.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Datasheet:
> + * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP180-DS000-121.pdf
> + * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP280-DS001-12.pdf
> + * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_DS001-11.pdf
> + */
> +
> +#define pr_fmt(fmt) "bmp280: " fmt
> +
> +#include <linux/device.h>
> +#include <linux/regmap.h>
> +#include <linux/delay.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/regulator/consumer.h>
> +
> +#include "bmp280.h"
> +
> +struct bmp280_data {
> +	struct device *dev;
> +	struct mutex lock;
> +	struct regmap *regmap;
> +	const struct bmp280_chip_info *chip_info;
> +	struct regulator *vddd;
> +	struct regulator *vdda;
> +
> +	/* log of base 2 of oversampling rate */
> +	u8 oversampling_press;
> +	u8 oversampling_temp;
> +	u8 oversampling_humid;
> +
> +	/*
> +	 * Carryover value from temperature conversion, used in pressure
> +	 * calculation.
> +	 */
> +	s32 t_fine;
> +};
> +
> +struct bmp280_chip_info {
> +	const int *oversampling_temp_avail;
> +	int num_oversampling_temp_avail;
> +
> +	const int *oversampling_press_avail;
> +	int num_oversampling_press_avail;
> +
> +	const int *oversampling_humid_avail;
> +	int num_oversampling_humid_avail;
> +
> +	int (*chip_config)(struct bmp280_data *);
> +	int (*read_temp)(struct bmp280_data *, int *);
> +	int (*read_press)(struct bmp280_data *, int *, int *);
> +	int (*read_humid)(struct bmp280_data *, int *, int *);
> +};
> +
> +/*
> + * These enums are used for indexing into the array of compensation
> + * parameters for BMP280.
> + */
> +enum { T1, T2, T3 };
> +enum { P1, P2, P3, P4, P5, P6, P7, P8, P9 };
> +
> +static const struct iio_chan_spec bmp280_channels[] = {
> +	{
> +		.type = IIO_PRESSURE,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
> +				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> +	},
> +	{
> +		.type = IIO_TEMP,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
> +				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> +	},
> +	{
> +		.type = IIO_HUMIDITYRELATIVE,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
> +				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> +	},
> +};
> +
> +/*
> + * Returns humidity in percent, resolution is 0.01 percent. Output value of
> + * "47445" represents 47445/1024 = 46.333 %RH.
> + *
> + * Taken from BME280 datasheet, Section 4.2.3, "Compensation formula".
> + */
> +
Guessing this is from the original cut and paste, but it's inconsistent
to have a blank line here!
> +static u32 bmp280_compensate_humidity(struct bmp280_data *data,
> +				      s32 adc_humidity)
> +{
> +	struct device *dev = data->dev;
> +	unsigned int H1, H3, tmp;
> +	int H2, H4, H5, H6, ret, var;
> +
> +	ret = regmap_read(data->regmap, BMP280_REG_COMP_H1, &H1);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H1 comp value\n");
> +		return ret;
> +	}
> +
> +	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H2, &tmp, 2);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H2 comp value\n");
> +		return ret;
> +	}
> +	H2 = sign_extend32(le16_to_cpu(tmp), 15);
> +
> +	ret = regmap_read(data->regmap, BMP280_REG_COMP_H3, &H3);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H3 comp value\n");
> +		return ret;
> +	}
> +
> +	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H4, &tmp, 2);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H4 comp value\n");
> +		return ret;
> +	}
> +	H4 = sign_extend32(((be16_to_cpu(tmp) >> 4) & 0xff0) |
> +			  (be16_to_cpu(tmp) & 0xf), 11);
> +
> +	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H5, &tmp, 2);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H5 comp value\n");
> +		return ret;
> +	}
> +	H5 = sign_extend32(((le16_to_cpu(tmp) >> 4) & 0xfff), 11);
> +
> +	ret = regmap_read(data->regmap, BMP280_REG_COMP_H6, &tmp);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to read H6 comp value\n");
> +		return ret;
> +	}
> +	H6 = sign_extend32(tmp, 7);
> +
> +	var = ((s32)data->t_fine) - 76800;
> +	var = ((((adc_humidity << 14) - (H4 << 20) - (H5 * var)) + 16384) >> 15)
> +		* (((((((var * H6) >> 10) * (((var * H3) >> 11) + 32768)) >> 10)
> +		+ 2097152) * H2 + 8192) >> 14);
> +	var -= ((((var >> 15) * (var >> 15)) >> 7) * H1) >> 4;
> +
> +	return var >> 12;
> +};
> +
> +/*
> + * Returns temperature in DegC, resolution is 0.01 DegC.  Output value of
> + * "5123" equals 51.23 DegC.  t_fine carries fine temperature as global
> + * value.
> + *
> + * Taken from datasheet, Section 3.11.3, "Compensation formula".
> + */
> +static s32 bmp280_compensate_temp(struct bmp280_data *data,
> +				  s32 adc_temp)
> +{
> +	int ret;
> +	s32 var1, var2;
> +	__le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2];
> +
> +	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START,
> +			       buf, BMP280_COMP_TEMP_REG_COUNT);
> +	if (ret < 0) {
> +		dev_err(data->dev,
> +			"failed to read temperature calibration parameters\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * The double casts are necessary because le16_to_cpu returns an
> +	 * unsigned 16-bit value.  Casting that value directly to a
> +	 * signed 32-bit will not do proper sign extension.
> +	 *
> +	 * Conversely, T1 and P1 are unsigned values, so they can be
> +	 * cast straight to the larger type.
> +	 */
> +	var1 = (((adc_temp >> 3) - ((s32)le16_to_cpu(buf[T1]) << 1)) *
> +		((s32)(s16)le16_to_cpu(buf[T2]))) >> 11;
> +	var2 = (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) *
> +		  ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> 12) *
> +		((s32)(s16)le16_to_cpu(buf[T3]))) >> 14;
> +	data->t_fine = var1 + var2;
> +
> +	return (data->t_fine * 5 + 128) >> 8;
> +}
> +
> +/*
> + * Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24
> + * integer bits and 8 fractional bits).  Output value of "24674867"
> + * represents 24674867/256 = 96386.2 Pa = 963.862 hPa
> + *
> + * Taken from datasheet, Section 3.11.3, "Compensation formula".
> + */
> +static u32 bmp280_compensate_press(struct bmp280_data *data,
> +				   s32 adc_press)
> +{
> +	int ret;
> +	s64 var1, var2, p;
> +	__le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2];
> +
> +	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
> +			       buf, BMP280_COMP_PRESS_REG_COUNT);
> +	if (ret < 0) {
> +		dev_err(data->dev,
> +			"failed to read pressure calibration parameters\n");
> +		return ret;
> +	}
> +
> +	var1 = ((s64)data->t_fine) - 128000;
> +	var2 = var1 * var1 * (s64)(s16)le16_to_cpu(buf[P6]);
> +	var2 += (var1 * (s64)(s16)le16_to_cpu(buf[P5])) << 17;
> +	var2 += ((s64)(s16)le16_to_cpu(buf[P4])) << 35;
> +	var1 = ((var1 * var1 * (s64)(s16)le16_to_cpu(buf[P3])) >> 8) +
> +		((var1 * (s64)(s16)le16_to_cpu(buf[P2])) << 12);
> +	var1 = ((((s64)1) << 47) + var1) * ((s64)le16_to_cpu(buf[P1])) >> 33;
> +
> +	if (var1 == 0)
> +		return 0;
> +
> +	p = ((((s64)1048576 - adc_press) << 31) - var2) * 3125;
> +	p = div64_s64(p, var1);
> +	var1 = (((s64)(s16)le16_to_cpu(buf[P9])) * (p >> 13) * (p >> 13)) >> 25;
> +	var2 = (((s64)(s16)le16_to_cpu(buf[P8])) * p) >> 19;
> +	p = ((p + var1 + var2) >> 8) + (((s64)(s16)le16_to_cpu(buf[P7])) << 4);
> +
> +	return (u32)p;
> +}
> +
> +static int bmp280_read_temp(struct bmp280_data *data,
> +			    int *val)
> +{
> +	int ret;
> +	__be32 tmp = 0;
> +	s32 adc_temp, comp_temp;
> +
> +	ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB,
> +			       (u8 *) &tmp, 3);
> +	if (ret < 0) {
> +		dev_err(data->dev, "failed to read temperature\n");
> +		return ret;
> +	}
> +
> +	adc_temp = be32_to_cpu(tmp) >> 12;
> +	comp_temp = bmp280_compensate_temp(data, adc_temp);
> +
> +	/*
> +	 * val might be NULL if we're called by the read_press routine,
> +	 * who only cares about the carry over t_fine value.
> +	 */
> +	if (val) {
> +		*val = comp_temp * 10;
> +		return IIO_VAL_INT;
> +	}
> +
> +	return 0;
> +}
> +
> +static int bmp280_read_press(struct bmp280_data *data,
> +			     int *val, int *val2)
> +{
> +	int ret;
> +	__be32 tmp = 0;
> +	s32 adc_press;
> +	u32 comp_press;
> +
> +	/* Read and compensate temperature so we get a reading of t_fine. */
> +	ret = bmp280_read_temp(data, NULL);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB,
> +			       (u8 *) &tmp, 3);
> +	if (ret < 0) {
> +		dev_err(data->dev, "failed to read pressure\n");
> +		return ret;
> +	}
> +
> +	adc_press = be32_to_cpu(tmp) >> 12;
> +	comp_press = bmp280_compensate_press(data, adc_press);
> +
> +	*val = comp_press;
> +	*val2 = 256000;
> +
> +	return IIO_VAL_FRACTIONAL;
> +}
> +
> +static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
> +{
> +	int ret;
> +	__be16 tmp = 0;
> +	s32 adc_humidity;
> +	u32 comp_humidity;
> +
> +	/* Read and compensate temperature so we get a reading of t_fine. */
> +	ret = bmp280_read_temp(data, NULL);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = regmap_bulk_read(data->regmap, BMP280_REG_HUMIDITY_MSB,
> +			       (u8 *) &tmp, 2);
> +	if (ret < 0) {
> +		dev_err(data->dev, "failed to read humidity\n");
> +		return ret;
> +	}
> +
> +	adc_humidity = be16_to_cpu(tmp);
> +	comp_humidity = bmp280_compensate_humidity(data, adc_humidity);
> +
> +	*val = comp_humidity;
> +	*val2 = 1024;
> +
> +	return IIO_VAL_FRACTIONAL;
> +}
> +
> +static int bmp280_read_raw(struct iio_dev *indio_dev,
> +			   struct iio_chan_spec const *chan,
> +			   int *val, int *val2, long mask)
> +{
> +	int ret;
> +	struct bmp280_data *data = iio_priv(indio_dev);
> +
> +	mutex_lock(&data->lock);
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_PROCESSED:
> +		switch (chan->type) {
> +		case IIO_HUMIDITYRELATIVE:
> +			ret = data->chip_info->read_humid(data, val, val2);
> +			break;
> +		case IIO_PRESSURE:
> +			ret = data->chip_info->read_press(data, val, val2);
> +			break;
> +		case IIO_TEMP:
> +			ret = data->chip_info->read_temp(data, val);
> +			break;
> +		default:
> +			ret = -EINVAL;
> +			break;
> +		}
> +		break;
> +	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +		switch (chan->type) {
> +		case IIO_HUMIDITYRELATIVE:
> +			*val = 1 << data->oversampling_humid;
> +			ret = IIO_VAL_INT;
> +			break;
> +		case IIO_PRESSURE:
> +			*val = 1 << data->oversampling_press;
> +			ret = IIO_VAL_INT;
> +			break;
> +		case IIO_TEMP:
> +			*val = 1 << data->oversampling_temp;
> +			ret = IIO_VAL_INT;
> +			break;
> +		default:
> +			ret = -EINVAL;
> +			break;
> +		}
> +		break;
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +	mutex_unlock(&data->lock);
> +
> +	return ret;
> +}
> +
> +static int bmp280_write_oversampling_ratio_humid(struct bmp280_data *data,
> +					       int val)
> +{
> +	int i;
> +	const int *avail = data->chip_info->oversampling_humid_avail;
> +	const int n = data->chip_info->num_oversampling_humid_avail;
> +
> +	for (i = 0; i < n; i++) {
> +		if (avail[i] == val) {
> +			data->oversampling_humid = ilog2(val);
> +
> +			return data->chip_info->chip_config(data);
> +		}
> +	}
> +	return -EINVAL;
> +}
> +
> +static int bmp280_write_oversampling_ratio_temp(struct bmp280_data *data,
> +					       int val)
> +{
> +	int i;
> +	const int *avail = data->chip_info->oversampling_temp_avail;
> +	const int n = data->chip_info->num_oversampling_temp_avail;
> +
> +	for (i = 0; i < n; i++) {
> +		if (avail[i] == val) {
> +			data->oversampling_temp = ilog2(val);
> +
> +			return data->chip_info->chip_config(data);
> +		}
> +	}
> +	return -EINVAL;
> +}
> +
> +static int bmp280_write_oversampling_ratio_press(struct bmp280_data *data,
> +					       int val)
> +{
> +	int i;
> +	const int *avail = data->chip_info->oversampling_press_avail;
> +	const int n = data->chip_info->num_oversampling_press_avail;
> +
> +	for (i = 0; i < n; i++) {
> +		if (avail[i] == val) {
> +			data->oversampling_press = ilog2(val);
> +
> +			return data->chip_info->chip_config(data);
> +		}
> +	}
> +	return -EINVAL;
> +}
> +
> +static int bmp280_write_raw(struct iio_dev *indio_dev,
> +			    struct iio_chan_spec const *chan,
> +			    int val, int val2, long mask)
> +{
> +	int ret = 0;
> +	struct bmp280_data *data = iio_priv(indio_dev);
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +		mutex_lock(&data->lock);
> +		switch (chan->type) {
> +		case IIO_HUMIDITYRELATIVE:
> +			ret = bmp280_write_oversampling_ratio_humid(data, val);
> +			break;
> +		case IIO_PRESSURE:
> +			ret = bmp280_write_oversampling_ratio_press(data, val);
> +			break;
> +		case IIO_TEMP:
> +			ret = bmp280_write_oversampling_ratio_temp(data, val);
> +			break;
> +		default:
> +			ret = -EINVAL;
> +			break;
> +		}
> +		mutex_unlock(&data->lock);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static ssize_t bmp280_show_avail(char *buf, const int *vals, const int n)
> +{
> +	size_t len = 0;
> +	int i;
> +
> +	for (i = 0; i < n; i++)
> +		len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", vals[i]);
> +
> +	buf[len - 1] = '\n';
> +
> +	return len;
> +}
> +
> +static ssize_t bmp280_show_temp_oversampling_avail(struct device *dev,
> +				struct device_attribute *attr, char *buf)
> +{
> +	struct bmp280_data *data = iio_priv(dev_to_iio_dev(dev));
> +
> +	return bmp280_show_avail(buf, data->chip_info->oversampling_temp_avail,
> +				 data->chip_info->num_oversampling_temp_avail);
> +}
> +
> +static ssize_t bmp280_show_press_oversampling_avail(struct device *dev,
> +				struct device_attribute *attr, char *buf)
> +{
> +	struct bmp280_data *data = iio_priv(dev_to_iio_dev(dev));
> +
> +	return bmp280_show_avail(buf, data->chip_info->oversampling_press_avail,
> +				 data->chip_info->num_oversampling_press_avail);
> +}
> +
> +static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available,
> +	S_IRUGO, bmp280_show_temp_oversampling_avail, NULL, 0);
> +
> +static IIO_DEVICE_ATTR(in_pressure_oversampling_ratio_available,
> +	S_IRUGO, bmp280_show_press_oversampling_avail, NULL, 0);
> +
> +static struct attribute *bmp280_attributes[] = {
> +	&iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr,
> +	&iio_dev_attr_in_pressure_oversampling_ratio_available.dev_attr.attr,
> +	NULL,
> +};
> +
> +static const struct attribute_group bmp280_attrs_group = {
> +	.attrs = bmp280_attributes,
> +};
> +
> +static const struct iio_info bmp280_info = {
> +	.driver_module = THIS_MODULE,
> +	.read_raw = &bmp280_read_raw,
> +	.write_raw = &bmp280_write_raw,
> +	.attrs = &bmp280_attrs_group,
> +};
> +
> +static int bmp280_chip_config(struct bmp280_data *data)
> +{
> +	int ret;
> +	u8 osrs = BMP280_OSRS_TEMP_X(data->oversampling_temp + 1) |
> +		  BMP280_OSRS_PRESS_X(data->oversampling_press + 1);
> +
> +	ret = regmap_update_bits(data->regmap, BMP280_REG_CTRL_MEAS,
> +				 BMP280_OSRS_TEMP_MASK |
> +				 BMP280_OSRS_PRESS_MASK |
> +				 BMP280_MODE_MASK,
> +				 osrs | BMP280_MODE_NORMAL);
> +	if (ret < 0) {
> +		dev_err(data->dev,
> +			"failed to write ctrl_meas register\n");
> +		return ret;
> +	}
> +
> +	ret = regmap_update_bits(data->regmap, BMP280_REG_CONFIG,
> +				 BMP280_FILTER_MASK,
> +				 BMP280_FILTER_4X);
> +	if (ret < 0) {
> +		dev_err(data->dev,
> +			"failed to write config register\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 };
> +
> +static const struct bmp280_chip_info bmp280_chip_info = {
> +	.oversampling_temp_avail = bmp280_oversampling_avail,
> +	.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
> +
> +	.oversampling_press_avail = bmp280_oversampling_avail,
> +	.num_oversampling_press_avail = ARRAY_SIZE(bmp280_oversampling_avail),
> +
> +	.chip_config = bmp280_chip_config,
> +	.read_temp = bmp280_read_temp,
> +	.read_press = bmp280_read_press,
> +};
> +
> +static int bme280_chip_config(struct bmp280_data *data)
> +{
> +	int ret = bmp280_chip_config(data);
> +	u8 osrs = BMP280_OSRS_HUMIDITIY_X(data->oversampling_humid + 1);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	return regmap_update_bits(data->regmap, BMP280_REG_CTRL_HUMIDITY,
> +				  BMP280_OSRS_HUMIDITY_MASK, osrs);
> +}
> +
> +static const struct bmp280_chip_info bme280_chip_info = {
> +	.oversampling_temp_avail = bmp280_oversampling_avail,
> +	.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
> +
> +	.oversampling_press_avail = bmp280_oversampling_avail,
> +	.num_oversampling_press_avail = ARRAY_SIZE(bmp280_oversampling_avail),
> +
> +	.oversampling_humid_avail = bmp280_oversampling_avail,
> +	.num_oversampling_humid_avail = ARRAY_SIZE(bmp280_oversampling_avail),
> +
> +	.chip_config = bme280_chip_config,
> +	.read_temp = bmp280_read_temp,
> +	.read_press = bmp280_read_press,
> +	.read_humid = bmp280_read_humid,
> +};
> +
> +static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas)
> +{
> +	int ret;
> +	const int conversion_time_max[] = { 4500, 7500, 13500, 25500 };
> +	unsigned int delay_us;
> +	unsigned int ctrl;
> +
> +	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);
> +
> +	ret = regmap_read(data->regmap, BMP280_REG_CTRL_MEAS, &ctrl);
> +	if (ret)
> +		return ret;
> +
> +	/* The value of this bit reset to "0" after conversion is complete */
> +	if (ctrl & BMP180_MEAS_SCO)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int bmp180_read_adc_temp(struct bmp280_data *data, int *val)
> +{
> +	int ret;
> +	__be16 tmp = 0;
> +
> +	ret = bmp180_measure(data, BMP180_MEAS_TEMP);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 *)&tmp, 2);
> +	if (ret)
> +		return ret;
> +
> +	*val = be16_to_cpu(tmp);
> +
> +	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)
> +{
> +	int ret;
> +	int i;
> +	__be16 buf[BMP180_REG_CALIB_COUNT / 2];
> +
> +	ret = regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, buf,
> +			       sizeof(buf));
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	/* None of the words has the value 0 or 0xFFFF */
> +	for (i = 0; i < ARRAY_SIZE(buf); i++) {
> +		if (buf[i] == cpu_to_be16(0) || buf[i] == cpu_to_be16(0xffff))
> +			return -EIO;
> +	}
> +
> +	calib->AC1 = be16_to_cpu(buf[AC1]);
> +	calib->AC2 = be16_to_cpu(buf[AC2]);
> +	calib->AC3 = be16_to_cpu(buf[AC3]);
> +	calib->AC4 = be16_to_cpu(buf[AC4]);
> +	calib->AC5 = be16_to_cpu(buf[AC5]);
> +	calib->AC6 = be16_to_cpu(buf[AC6]);
> +	calib->B1 = be16_to_cpu(buf[B1]);
> +	calib->B2 = be16_to_cpu(buf[B2]);
> +	calib->MB = be16_to_cpu(buf[MB]);
> +	calib->MC = be16_to_cpu(buf[MC]);
> +	calib->MD = be16_to_cpu(buf[MD]);
> +
> +	return 0;
> +}
> +
> +/*
> + * Returns temperature in DegC, resolution is 0.1 DegC.
> + * t_fine carries fine temperature as global value.
> + *
> + * Taken from datasheet, Section 3.5, "Calculating pressure and temperature".
> + */
> +static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp)
> +{
> +	int ret;
> +	s32 x1, x2;
> +	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;
> +	}
> +
> +	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;
> +}
> +
> +static int bmp180_read_temp(struct bmp280_data *data, int *val)
> +{
> +	int ret;
> +	s32 adc_temp, comp_temp;
> +
> +	ret = bmp180_read_adc_temp(data, &adc_temp);
> +	if (ret)
> +		return ret;
> +
> +	comp_temp = bmp180_compensate_temp(data, adc_temp);
> +
> +	/*
> +	 * val might be NULL if we're called by the read_press routine,
> +	 * who only cares about the carry over t_fine value.
> +	 */
> +	if (val) {
> +		*val = comp_temp * 100;
> +		return IIO_VAL_INT;
> +	}
> +
> +	return 0;
> +}
> +
> +static int bmp180_read_adc_press(struct bmp280_data *data, int *val)
> +{
> +	int ret;
> +	__be32 tmp = 0;
> +	u8 oss = data->oversampling_press;
> +
> +	ret = bmp180_measure(data, BMP180_MEAS_PRESS_X(oss));
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 *)&tmp, 3);
> +	if (ret)
> +		return ret;
> +
> +	*val = (be32_to_cpu(tmp) >> 8) >> (8 - oss);
> +
> +	return 0;
> +}
> +
> +/*
> + * Returns pressure in Pa, resolution is 1 Pa.
> + *
> + * Taken from datasheet, Section 3.5, "Calculating pressure and temperature".
> + */
> +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;
> +	}
> +
> +	b6 = data->t_fine - 4000;
> +	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;
> +	x3 = (x1 + x2 + 2) >> 2;
> +	b4 = calib.AC4 * (u32)(x3 + 32768) >> 15;
> +	b7 = ((u32)adc_press - b3) * (50000 >> oss);
> +	if (b7 < 0x80000000)
> +		p = (b7 * 2) / b4;
> +	else
> +		p = (b7 / b4) * 2;
> +
> +	x1 = (p >> 8) * (p >> 8);
> +	x1 = (x1 * 3038) >> 16;
> +	x2 = (-7357 * p) >> 16;
> +
> +	return p + ((x1 + x2 + 3791) >> 4);
> +}
> +
> +static int bmp180_read_press(struct bmp280_data *data,
> +			     int *val, int *val2)
> +{
> +	int ret;
> +	s32 adc_press;
> +	u32 comp_press;
> +
> +	/* Read and compensate temperature so we get a reading of t_fine. */
> +	ret = bmp180_read_temp(data, NULL);
> +	if (ret)
> +		return ret;
> +
> +	ret = bmp180_read_adc_press(data, &adc_press);
> +	if (ret)
> +		return ret;
> +
> +	comp_press = bmp180_compensate_press(data, adc_press);
> +
> +	*val = comp_press;
> +	*val2 = 1000;
> +
> +	return IIO_VAL_FRACTIONAL;
> +}
> +
> +static int bmp180_chip_config(struct bmp280_data *data)
> +{
> +	return 0;
> +}
> +
> +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 = {
> +	.oversampling_temp_avail = bmp180_oversampling_temp_avail,
> +	.num_oversampling_temp_avail =
> +		ARRAY_SIZE(bmp180_oversampling_temp_avail),
> +
> +	.oversampling_press_avail = bmp180_oversampling_press_avail,
> +	.num_oversampling_press_avail =
> +		ARRAY_SIZE(bmp180_oversampling_press_avail),
> +
> +	.chip_config = bmp180_chip_config,
> +	.read_temp = bmp180_read_temp,
> +	.read_press = bmp180_read_press,
> +};
> +
> +int bmp280_common_probe(struct device *dev,
> +			struct regmap *regmap,
> +			unsigned int chip,
> +			const char *name)
> +{
> +	int ret;
> +	struct iio_dev *indio_dev;
> +	struct bmp280_data *data;
> +	unsigned int chip_id;
> +	struct gpio_desc *gpiod;
> +
> +	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
> +	if (!indio_dev)
> +		return -ENOMEM;
> +
> +	data = iio_priv(indio_dev);
> +	mutex_init(&data->lock);
> +	data->dev = dev;
> +
> +	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 (chip) {
> +	case BMP180_CHIP_ID:
> +		indio_dev->num_channels = 2;
> +		data->chip_info = &bmp180_chip_info;
> +		data->oversampling_press = ilog2(8);
> +		data->oversampling_temp = ilog2(1);
> +		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);
> +		break;
> +	case BME280_CHIP_ID:
> +		indio_dev->num_channels = 3;
> +		data->chip_info = &bme280_chip_info;
> +		data->oversampling_press = ilog2(16);
> +		data->oversampling_humid = ilog2(16);
> +		data->oversampling_temp = ilog2(2);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	/* Bring up regulators */
> +	data->vddd = devm_regulator_get(dev, "vddd");
> +	if (IS_ERR(data->vddd)) {
> +		dev_err(dev, "failed to get VDDD regulator\n");
> +		return PTR_ERR(data->vddd);
> +	}
> +	ret = regulator_enable(data->vddd);
> +	if (ret) {
> +		dev_err(dev, "failed to enable VDDD regulator\n");
> +		return ret;
> +	}
> +	data->vdda = devm_regulator_get(dev, "vdda");
> +	if (IS_ERR(data->vdda)) {
> +		dev_err(dev, "failed to get VDDA regulator\n");
> +		return PTR_ERR(data->vddd);
> +	}
> +	ret = regulator_enable(data->vdda);
> +	if (ret) {
> +		dev_err(dev, "failed to enable VDDA\n");
> +		return ret;
> +	}
> +
> +	/* Bring chip out of reset if there is an assigned GPIO line */
> +	gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
> +	/* Deassert the signal */
> +	if (!IS_ERR(gpiod)) {
> +		dev_info(dev, "release reset\n");
> +		gpiod_set_value(gpiod, 0);
> +	}
> +
> +	data->regmap = regmap;
> +	ret = regmap_read(regmap, BMP280_REG_ID, &chip_id);
> +	if (ret < 0)
> +		return ret;
> +	if (chip_id != chip) {
> +		dev_err(dev, "bad chip id: expected %x got %x\n",
> +			chip, chip_id);
> +		return -EINVAL;
> +	}
> +
> +	ret = data->chip_info->chip_config(data);
> +	if (ret < 0)
> +		return ret;
> +
> +	return devm_iio_device_register(dev, indio_dev);
> +}
> diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c
> new file mode 100644
> index 000000000000..a981670e5dc0
> --- /dev/null
> +++ b/drivers/iio/pressure/bmp280-i2c.c
> @@ -0,0 +1,82 @@
> +#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 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 },
Fairly obvious, but carry through the empty field from the issue in the
earlier patch...
> +};
> +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,
> +	.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.c b/drivers/iio/pressure/bmp280.c
> deleted file mode 100644
> index 3051e7c444d2..000000000000
> --- a/drivers/iio/pressure/bmp280.c
> +++ /dev/null
> @@ -1,1167 +0,0 @@
> -/*
> - * Copyright (c) 2014 Intel Corporation
> - *
> - * Driver for Bosch Sensortec BMP180 and BMP280 digital pressure sensor.
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 as
> - * published by the Free Software Foundation.
> - *
> - * Datasheet:
> - * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP180-DS000-121.pdf
> - * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP280-DS001-12.pdf
> - * https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_DS001-11.pdf
> - */
> -
> -#define pr_fmt(fmt) "bmp280: " fmt
> -
> -#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>
> -#include <linux/iio/sysfs.h>
> -#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
> -
> -struct bmp280_data {
> -	struct i2c_client *client;
> -	struct mutex lock;
> -	struct regmap *regmap;
> -	const struct bmp280_chip_info *chip_info;
> -	struct regulator *vddd;
> -	struct regulator *vdda;
> -
> -	/* log of base 2 of oversampling rate */
> -	u8 oversampling_press;
> -	u8 oversampling_temp;
> -	u8 oversampling_humid;
> -
> -	/*
> -	 * Carryover value from temperature conversion, used in pressure
> -	 * calculation.
> -	 */
> -	s32 t_fine;
> -};
> -
> -struct bmp280_chip_info {
> -	const struct regmap_config *regmap_config;
> -
> -	const int *oversampling_temp_avail;
> -	int num_oversampling_temp_avail;
> -
> -	const int *oversampling_press_avail;
> -	int num_oversampling_press_avail;
> -
> -	const int *oversampling_humid_avail;
> -	int num_oversampling_humid_avail;
> -
> -	int (*chip_config)(struct bmp280_data *);
> -	int (*read_temp)(struct bmp280_data *, int *);
> -	int (*read_press)(struct bmp280_data *, int *, int *);
> -	int (*read_humid)(struct bmp280_data *, int *, int *);
> -};
> -
> -/*
> - * These enums are used for indexing into the array of compensation
> - * parameters for BMP280.
> - */
> -enum { T1, T2, T3 };
> -enum { P1, P2, P3, P4, P5, P6, P7, P8, P9 };
> -
> -static const struct iio_chan_spec bmp280_channels[] = {
> -	{
> -		.type = IIO_PRESSURE,
> -		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
> -				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> -	},
> -	{
> -		.type = IIO_TEMP,
> -		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
> -				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> -	},
> -	{
> -		.type = IIO_HUMIDITYRELATIVE,
> -		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
> -				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
> -	},
> -};
> -
> -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.
> - *
> - * Taken from BME280 datasheet, Section 4.2.3, "Compensation formula".
> - */
> -
> -static u32 bmp280_compensate_humidity(struct bmp280_data *data,
> -				      s32 adc_humidity)
> -{
> -	struct device *dev = &data->client->dev;
> -	unsigned int H1, H3, tmp;
> -	int H2, H4, H5, H6, ret, var;
> -
> -	ret = regmap_read(data->regmap, BMP280_REG_COMP_H1, &H1);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H1 comp value\n");
> -		return ret;
> -	}
> -
> -	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H2, &tmp, 2);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H2 comp value\n");
> -		return ret;
> -	}
> -	H2 = sign_extend32(le16_to_cpu(tmp), 15);
> -
> -	ret = regmap_read(data->regmap, BMP280_REG_COMP_H3, &H3);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H3 comp value\n");
> -		return ret;
> -	}
> -
> -	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H4, &tmp, 2);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H4 comp value\n");
> -		return ret;
> -	}
> -	H4 = sign_extend32(((be16_to_cpu(tmp) >> 4) & 0xff0) |
> -			  (be16_to_cpu(tmp) & 0xf), 11);
> -
> -	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H5, &tmp, 2);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H5 comp value\n");
> -		return ret;
> -	}
> -	H5 = sign_extend32(((le16_to_cpu(tmp) >> 4) & 0xfff), 11);
> -
> -	ret = regmap_read(data->regmap, BMP280_REG_COMP_H6, &tmp);
> -	if (ret < 0) {
> -		dev_err(dev, "failed to read H6 comp value\n");
> -		return ret;
> -	}
> -	H6 = sign_extend32(tmp, 7);
> -
> -	var = ((s32)data->t_fine) - 76800;
> -	var = ((((adc_humidity << 14) - (H4 << 20) - (H5 * var)) + 16384) >> 15)
> -		* (((((((var * H6) >> 10) * (((var * H3) >> 11) + 32768)) >> 10)
> -		+ 2097152) * H2 + 8192) >> 14);
> -	var -= ((((var >> 15) * (var >> 15)) >> 7) * H1) >> 4;
> -
> -	return var >> 12;
> -};
> -
> -/*
> - * Returns temperature in DegC, resolution is 0.01 DegC.  Output value of
> - * "5123" equals 51.23 DegC.  t_fine carries fine temperature as global
> - * value.
> - *
> - * Taken from datasheet, Section 3.11.3, "Compensation formula".
> - */
> -static s32 bmp280_compensate_temp(struct bmp280_data *data,
> -				  s32 adc_temp)
> -{
> -	int ret;
> -	s32 var1, var2;
> -	__le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2];
> -
> -	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,
> -			"failed to read temperature calibration parameters\n");
> -		return ret;
> -	}
> -
> -	/*
> -	 * The double casts are necessary because le16_to_cpu returns an
> -	 * unsigned 16-bit value.  Casting that value directly to a
> -	 * signed 32-bit will not do proper sign extension.
> -	 *
> -	 * Conversely, T1 and P1 are unsigned values, so they can be
> -	 * cast straight to the larger type.
> -	 */
> -	var1 = (((adc_temp >> 3) - ((s32)le16_to_cpu(buf[T1]) << 1)) *
> -		((s32)(s16)le16_to_cpu(buf[T2]))) >> 11;
> -	var2 = (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) *
> -		  ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> 12) *
> -		((s32)(s16)le16_to_cpu(buf[T3]))) >> 14;
> -	data->t_fine = var1 + var2;
> -
> -	return (data->t_fine * 5 + 128) >> 8;
> -}
> -
> -/*
> - * Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24
> - * integer bits and 8 fractional bits).  Output value of "24674867"
> - * represents 24674867/256 = 96386.2 Pa = 963.862 hPa
> - *
> - * Taken from datasheet, Section 3.11.3, "Compensation formula".
> - */
> -static u32 bmp280_compensate_press(struct bmp280_data *data,
> -				   s32 adc_press)
> -{
> -	int ret;
> -	s64 var1, var2, p;
> -	__le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2];
> -
> -	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,
> -			"failed to read pressure calibration parameters\n");
> -		return ret;
> -	}
> -
> -	var1 = ((s64)data->t_fine) - 128000;
> -	var2 = var1 * var1 * (s64)(s16)le16_to_cpu(buf[P6]);
> -	var2 += (var1 * (s64)(s16)le16_to_cpu(buf[P5])) << 17;
> -	var2 += ((s64)(s16)le16_to_cpu(buf[P4])) << 35;
> -	var1 = ((var1 * var1 * (s64)(s16)le16_to_cpu(buf[P3])) >> 8) +
> -		((var1 * (s64)(s16)le16_to_cpu(buf[P2])) << 12);
> -	var1 = ((((s64)1) << 47) + var1) * ((s64)le16_to_cpu(buf[P1])) >> 33;
> -
> -	if (var1 == 0)
> -		return 0;
> -
> -	p = ((((s64)1048576 - adc_press) << 31) - var2) * 3125;
> -	p = div64_s64(p, var1);
> -	var1 = (((s64)(s16)le16_to_cpu(buf[P9])) * (p >> 13) * (p >> 13)) >> 25;
> -	var2 = (((s64)(s16)le16_to_cpu(buf[P8])) * p) >> 19;
> -	p = ((p + var1 + var2) >> 8) + (((s64)(s16)le16_to_cpu(buf[P7])) << 4);
> -
> -	return (u32)p;
> -}
> -
> -static int bmp280_read_temp(struct bmp280_data *data,
> -			    int *val)
> -{
> -	int ret;
> -	__be32 tmp = 0;
> -	s32 adc_temp, comp_temp;
> -
> -	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");
> -		return ret;
> -	}
> -
> -	adc_temp = be32_to_cpu(tmp) >> 12;
> -	comp_temp = bmp280_compensate_temp(data, adc_temp);
> -
> -	/*
> -	 * val might be NULL if we're called by the read_press routine,
> -	 * who only cares about the carry over t_fine value.
> -	 */
> -	if (val) {
> -		*val = comp_temp * 10;
> -		return IIO_VAL_INT;
> -	}
> -
> -	return 0;
> -}
> -
> -static int bmp280_read_press(struct bmp280_data *data,
> -			     int *val, int *val2)
> -{
> -	int ret;
> -	__be32 tmp = 0;
> -	s32 adc_press;
> -	u32 comp_press;
> -
> -	/* Read and compensate temperature so we get a reading of t_fine. */
> -	ret = bmp280_read_temp(data, NULL);
> -	if (ret < 0)
> -		return ret;
> -
> -	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");
> -		return ret;
> -	}
> -
> -	adc_press = be32_to_cpu(tmp) >> 12;
> -	comp_press = bmp280_compensate_press(data, adc_press);
> -
> -	*val = comp_press;
> -	*val2 = 256000;
> -
> -	return IIO_VAL_FRACTIONAL;
> -}
> -
> -static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
> -{
> -	int ret;
> -	__be16 tmp = 0;
> -	s32 adc_humidity;
> -	u32 comp_humidity;
> -
> -	/* Read and compensate temperature so we get a reading of t_fine. */
> -	ret = bmp280_read_temp(data, NULL);
> -	if (ret < 0)
> -		return ret;
> -
> -	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");
> -		return ret;
> -	}
> -
> -	adc_humidity = be16_to_cpu(tmp);
> -	comp_humidity = bmp280_compensate_humidity(data, adc_humidity);
> -
> -	*val = comp_humidity;
> -	*val2 = 1024;
> -
> -	return IIO_VAL_FRACTIONAL;
> -}
> -
> -static int bmp280_read_raw(struct iio_dev *indio_dev,
> -			   struct iio_chan_spec const *chan,
> -			   int *val, int *val2, long mask)
> -{
> -	int ret;
> -	struct bmp280_data *data = iio_priv(indio_dev);
> -
> -	mutex_lock(&data->lock);
> -
> -	switch (mask) {
> -	case IIO_CHAN_INFO_PROCESSED:
> -		switch (chan->type) {
> -		case IIO_HUMIDITYRELATIVE:
> -			ret = data->chip_info->read_humid(data, val, val2);
> -			break;
> -		case IIO_PRESSURE:
> -			ret = data->chip_info->read_press(data, val, val2);
> -			break;
> -		case IIO_TEMP:
> -			ret = data->chip_info->read_temp(data, val);
> -			break;
> -		default:
> -			ret = -EINVAL;
> -			break;
> -		}
> -		break;
> -	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> -		switch (chan->type) {
> -		case IIO_HUMIDITYRELATIVE:
> -			*val = 1 << data->oversampling_humid;
> -			ret = IIO_VAL_INT;
> -			break;
> -		case IIO_PRESSURE:
> -			*val = 1 << data->oversampling_press;
> -			ret = IIO_VAL_INT;
> -			break;
> -		case IIO_TEMP:
> -			*val = 1 << data->oversampling_temp;
> -			ret = IIO_VAL_INT;
> -			break;
> -		default:
> -			ret = -EINVAL;
> -			break;
> -		}
> -		break;
> -	default:
> -		ret = -EINVAL;
> -		break;
> -	}
> -
> -	mutex_unlock(&data->lock);
> -
> -	return ret;
> -}
> -
> -static int bmp280_write_oversampling_ratio_humid(struct bmp280_data *data,
> -					       int val)
> -{
> -	int i;
> -	const int *avail = data->chip_info->oversampling_humid_avail;
> -	const int n = data->chip_info->num_oversampling_humid_avail;
> -
> -	for (i = 0; i < n; i++) {
> -		if (avail[i] == val) {
> -			data->oversampling_humid = ilog2(val);
> -
> -			return data->chip_info->chip_config(data);
> -		}
> -	}
> -	return -EINVAL;
> -}
> -
> -static int bmp280_write_oversampling_ratio_temp(struct bmp280_data *data,
> -					       int val)
> -{
> -	int i;
> -	const int *avail = data->chip_info->oversampling_temp_avail;
> -	const int n = data->chip_info->num_oversampling_temp_avail;
> -
> -	for (i = 0; i < n; i++) {
> -		if (avail[i] == val) {
> -			data->oversampling_temp = ilog2(val);
> -
> -			return data->chip_info->chip_config(data);
> -		}
> -	}
> -	return -EINVAL;
> -}
> -
> -static int bmp280_write_oversampling_ratio_press(struct bmp280_data *data,
> -					       int val)
> -{
> -	int i;
> -	const int *avail = data->chip_info->oversampling_press_avail;
> -	const int n = data->chip_info->num_oversampling_press_avail;
> -
> -	for (i = 0; i < n; i++) {
> -		if (avail[i] == val) {
> -			data->oversampling_press = ilog2(val);
> -
> -			return data->chip_info->chip_config(data);
> -		}
> -	}
> -	return -EINVAL;
> -}
> -
> -static int bmp280_write_raw(struct iio_dev *indio_dev,
> -			    struct iio_chan_spec const *chan,
> -			    int val, int val2, long mask)
> -{
> -	int ret = 0;
> -	struct bmp280_data *data = iio_priv(indio_dev);
> -
> -	switch (mask) {
> -	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> -		mutex_lock(&data->lock);
> -		switch (chan->type) {
> -		case IIO_HUMIDITYRELATIVE:
> -			ret = bmp280_write_oversampling_ratio_humid(data, val);
> -			break;
> -		case IIO_PRESSURE:
> -			ret = bmp280_write_oversampling_ratio_press(data, val);
> -			break;
> -		case IIO_TEMP:
> -			ret = bmp280_write_oversampling_ratio_temp(data, val);
> -			break;
> -		default:
> -			ret = -EINVAL;
> -			break;
> -		}
> -		mutex_unlock(&data->lock);
> -		break;
> -	default:
> -		return -EINVAL;
> -	}
> -
> -	return ret;
> -}
> -
> -static ssize_t bmp280_show_avail(char *buf, const int *vals, const int n)
> -{
> -	size_t len = 0;
> -	int i;
> -
> -	for (i = 0; i < n; i++)
> -		len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", vals[i]);
> -
> -	buf[len - 1] = '\n';
> -
> -	return len;
> -}
> -
> -static ssize_t bmp280_show_temp_oversampling_avail(struct device *dev,
> -				struct device_attribute *attr, char *buf)
> -{
> -	struct bmp280_data *data = iio_priv(dev_to_iio_dev(dev));
> -
> -	return bmp280_show_avail(buf, data->chip_info->oversampling_temp_avail,
> -				 data->chip_info->num_oversampling_temp_avail);
> -}
> -
> -static ssize_t bmp280_show_press_oversampling_avail(struct device *dev,
> -				struct device_attribute *attr, char *buf)
> -{
> -	struct bmp280_data *data = iio_priv(dev_to_iio_dev(dev));
> -
> -	return bmp280_show_avail(buf, data->chip_info->oversampling_press_avail,
> -				 data->chip_info->num_oversampling_press_avail);
> -}
> -
> -static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available,
> -	S_IRUGO, bmp280_show_temp_oversampling_avail, NULL, 0);
> -
> -static IIO_DEVICE_ATTR(in_pressure_oversampling_ratio_available,
> -	S_IRUGO, bmp280_show_press_oversampling_avail, NULL, 0);
> -
> -static struct attribute *bmp280_attributes[] = {
> -	&iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr,
> -	&iio_dev_attr_in_pressure_oversampling_ratio_available.dev_attr.attr,
> -	NULL,
> -};
> -
> -static const struct attribute_group bmp280_attrs_group = {
> -	.attrs = bmp280_attributes,
> -};
> -
> -static const struct iio_info bmp280_info = {
> -	.driver_module = THIS_MODULE,
> -	.read_raw = &bmp280_read_raw,
> -	.write_raw = &bmp280_write_raw,
> -	.attrs = &bmp280_attrs_group,
> -};
> -
> -static int bmp280_chip_config(struct bmp280_data *data)
> -{
> -	int ret;
> -	u8 osrs = BMP280_OSRS_TEMP_X(data->oversampling_temp + 1) |
> -		  BMP280_OSRS_PRESS_X(data->oversampling_press + 1);
> -
> -	ret = regmap_update_bits(data->regmap, BMP280_REG_CTRL_MEAS,
> -				 BMP280_OSRS_TEMP_MASK |
> -				 BMP280_OSRS_PRESS_MASK |
> -				 BMP280_MODE_MASK,
> -				 osrs | BMP280_MODE_NORMAL);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev,
> -			"failed to write ctrl_meas register\n");
> -		return ret;
> -	}
> -
> -	ret = regmap_update_bits(data->regmap, BMP280_REG_CONFIG,
> -				 BMP280_FILTER_MASK,
> -				 BMP280_FILTER_4X);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev,
> -			"failed to write config register\n");
> -		return ret;
> -	}
> -
> -	return ret;
> -}
> -
> -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),
> -
> -	.oversampling_press_avail = bmp280_oversampling_avail,
> -	.num_oversampling_press_avail = ARRAY_SIZE(bmp280_oversampling_avail),
> -
> -	.chip_config = bmp280_chip_config,
> -	.read_temp = bmp280_read_temp,
> -	.read_press = bmp280_read_press,
> -};
> -
> -static int bme280_chip_config(struct bmp280_data *data)
> -{
> -	int ret = bmp280_chip_config(data);
> -	u8 osrs = BMP280_OSRS_HUMIDITIY_X(data->oversampling_humid + 1);
> -
> -	if (ret < 0)
> -		return ret;
> -
> -	return regmap_update_bits(data->regmap, BMP280_REG_CTRL_HUMIDITY,
> -				  BMP280_OSRS_HUMIDITY_MASK, osrs);
> -}
> -
> -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),
> -
> -	.oversampling_press_avail = bmp280_oversampling_avail,
> -	.num_oversampling_press_avail = ARRAY_SIZE(bmp280_oversampling_avail),
> -
> -	.oversampling_humid_avail = bmp280_oversampling_avail,
> -	.num_oversampling_humid_avail = ARRAY_SIZE(bmp280_oversampling_avail),
> -
> -	.chip_config = bme280_chip_config,
> -	.read_temp = bmp280_read_temp,
> -	.read_press = bmp280_read_press,
> -	.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;
> -	const int conversion_time_max[] = { 4500, 7500, 13500, 25500 };
> -	unsigned int delay_us;
> -	unsigned int ctrl;
> -
> -	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);
> -
> -	ret = regmap_read(data->regmap, BMP280_REG_CTRL_MEAS, &ctrl);
> -	if (ret)
> -		return ret;
> -
> -	/* The value of this bit reset to "0" after conversion is complete */
> -	if (ctrl & BMP180_MEAS_SCO)
> -		return -EIO;
> -
> -	return 0;
> -}
> -
> -static int bmp180_read_adc_temp(struct bmp280_data *data, int *val)
> -{
> -	int ret;
> -	__be16 tmp = 0;
> -
> -	ret = bmp180_measure(data, BMP180_MEAS_TEMP);
> -	if (ret)
> -		return ret;
> -
> -	ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 *)&tmp, 2);
> -	if (ret)
> -		return ret;
> -
> -	*val = be16_to_cpu(tmp);
> -
> -	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)
> -{
> -	int ret;
> -	int i;
> -	__be16 buf[BMP180_REG_CALIB_COUNT / 2];
> -
> -	ret = regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, buf,
> -			       sizeof(buf));
> -
> -	if (ret < 0)
> -		return ret;
> -
> -	/* None of the words has the value 0 or 0xFFFF */
> -	for (i = 0; i < ARRAY_SIZE(buf); i++) {
> -		if (buf[i] == cpu_to_be16(0) || buf[i] == cpu_to_be16(0xffff))
> -			return -EIO;
> -	}
> -
> -	calib->AC1 = be16_to_cpu(buf[AC1]);
> -	calib->AC2 = be16_to_cpu(buf[AC2]);
> -	calib->AC3 = be16_to_cpu(buf[AC3]);
> -	calib->AC4 = be16_to_cpu(buf[AC4]);
> -	calib->AC5 = be16_to_cpu(buf[AC5]);
> -	calib->AC6 = be16_to_cpu(buf[AC6]);
> -	calib->B1 = be16_to_cpu(buf[B1]);
> -	calib->B2 = be16_to_cpu(buf[B2]);
> -	calib->MB = be16_to_cpu(buf[MB]);
> -	calib->MC = be16_to_cpu(buf[MC]);
> -	calib->MD = be16_to_cpu(buf[MD]);
> -
> -	return 0;
> -}
> -
> -/*
> - * Returns temperature in DegC, resolution is 0.1 DegC.
> - * t_fine carries fine temperature as global value.
> - *
> - * Taken from datasheet, Section 3.5, "Calculating pressure and temperature".
> - */
> -static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp)
> -{
> -	int ret;
> -	s32 x1, x2;
> -	struct bmp180_calib calib;
> -
> -	ret = bmp180_read_calib(data, &calib);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev,
> -			"failed to read calibration coefficients\n");
> -		return ret;
> -	}
> -
> -	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;
> -}
> -
> -static int bmp180_read_temp(struct bmp280_data *data, int *val)
> -{
> -	int ret;
> -	s32 adc_temp, comp_temp;
> -
> -	ret = bmp180_read_adc_temp(data, &adc_temp);
> -	if (ret)
> -		return ret;
> -
> -	comp_temp = bmp180_compensate_temp(data, adc_temp);
> -
> -	/*
> -	 * val might be NULL if we're called by the read_press routine,
> -	 * who only cares about the carry over t_fine value.
> -	 */
> -	if (val) {
> -		*val = comp_temp * 100;
> -		return IIO_VAL_INT;
> -	}
> -
> -	return 0;
> -}
> -
> -static int bmp180_read_adc_press(struct bmp280_data *data, int *val)
> -{
> -	int ret;
> -	__be32 tmp = 0;
> -	u8 oss = data->oversampling_press;
> -
> -	ret = bmp180_measure(data, BMP180_MEAS_PRESS_X(oss));
> -	if (ret)
> -		return ret;
> -
> -	ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB, (u8 *)&tmp, 3);
> -	if (ret)
> -		return ret;
> -
> -	*val = (be32_to_cpu(tmp) >> 8) >> (8 - oss);
> -
> -	return 0;
> -}
> -
> -/*
> - * Returns pressure in Pa, resolution is 1 Pa.
> - *
> - * Taken from datasheet, Section 3.5, "Calculating pressure and temperature".
> - */
> -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->client->dev,
> -			"failed to read calibration coefficients\n");
> -		return ret;
> -	}
> -
> -	b6 = data->t_fine - 4000;
> -	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;
> -	x3 = (x1 + x2 + 2) >> 2;
> -	b4 = calib.AC4 * (u32)(x3 + 32768) >> 15;
> -	b7 = ((u32)adc_press - b3) * (50000 >> oss);
> -	if (b7 < 0x80000000)
> -		p = (b7 * 2) / b4;
> -	else
> -		p = (b7 / b4) * 2;
> -
> -	x1 = (p >> 8) * (p >> 8);
> -	x1 = (x1 * 3038) >> 16;
> -	x2 = (-7357 * p) >> 16;
> -
> -	return p + ((x1 + x2 + 3791) >> 4);
> -}
> -
> -static int bmp180_read_press(struct bmp280_data *data,
> -			     int *val, int *val2)
> -{
> -	int ret;
> -	s32 adc_press;
> -	u32 comp_press;
> -
> -	/* Read and compensate temperature so we get a reading of t_fine. */
> -	ret = bmp180_read_temp(data, NULL);
> -	if (ret)
> -		return ret;
> -
> -	ret = bmp180_read_adc_press(data, &adc_press);
> -	if (ret)
> -		return ret;
> -
> -	comp_press = bmp180_compensate_press(data, adc_press);
> -
> -	*val = comp_press;
> -	*val2 = 1000;
> -
> -	return IIO_VAL_FRACTIONAL;
> -}
> -
> -static int bmp180_chip_config(struct bmp280_data *data)
> -{
> -	return 0;
> -}
> -
> -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),
> -
> -	.oversampling_press_avail = bmp180_oversampling_press_avail,
> -	.num_oversampling_press_avail =
> -		ARRAY_SIZE(bmp180_oversampling_press_avail),
> -
> -	.chip_config = bmp180_chip_config,
> -	.read_temp = bmp180_read_temp,
> -	.read_press = bmp180_read_press,
> -};
> -
> -static int bmp280_probe(struct i2c_client *client,
> -			const struct i2c_device_id *id)
> -{
> -	int ret;
> -	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)
> -		return -ENOMEM;
> -
> -	data = iio_priv(indio_dev);
> -	mutex_init(&data->lock);
> -	data->client = client;
> -
> -	indio_dev->dev.parent = &client->dev;
> -	indio_dev->name = id->name;
> -	indio_dev->channels = bmp280_channels;
> -	indio_dev->info = &bmp280_info;
> -	indio_dev->modes = INDIO_DIRECT_MODE;
> -
> -	switch (id->driver_data) {
> -	case BMP180_CHIP_ID:
> -		indio_dev->num_channels = 2;
> -		data->chip_info = &bmp180_chip_info;
> -		data->oversampling_press = ilog2(8);
> -		data->oversampling_temp = ilog2(1);
> -		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);
> -		break;
> -	case BME280_CHIP_ID:
> -		indio_dev->num_channels = 3;
> -		data->chip_info = &bme280_chip_info;
> -		data->oversampling_press = ilog2(16);
> -		data->oversampling_humid = ilog2(16);
> -		data->oversampling_temp = ilog2(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");
> -		return PTR_ERR(data->vddd);
> -	}
> -	ret = regulator_enable(data->vdda);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to enable VDDA\n");
> -		return ret;
> -	}
> -
> -	/* 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)) {
> -		dev_err(&client->dev, "failed to allocate register map\n");
> -		return PTR_ERR(data->regmap);
> -	}
> -
> -	ret = regmap_read(data->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 %lx got %x\n",
> -			id->driver_data, chip_id);
> -		return -EINVAL;
> -	}
> -
> -	ret = data->chip_info->chip_config(data);
> -	if (ret < 0)
> -		return ret;
> -
> -	return devm_iio_device_register(&client->dev, indio_dev);
> -}
> -
> -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,
> -	.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.h b/drivers/iio/pressure/bmp280.h
> new file mode 100644
> index 000000000000..acb40de2f581
> --- /dev/null
> +++ b/drivers/iio/pressure/bmp280.h
> @@ -0,0 +1,107 @@
> +#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);
> 


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

* Re: [PATCH 7/9 v2] iio: pressure: bmp280: add SPI interface driver
  2016-06-22 20:53 ` [PATCH 7/9 v2] iio: pressure: bmp280: add SPI interface driver Linus Walleij
@ 2016-06-26 10:15   ` Jonathan Cameron
  0 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron @ 2016-06-26 10:15 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown, Mark Brown

On 22/06/16 21:53, 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 bus mapping code for SPI was written by Akinobu Mita.
> 
> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

On suggestion inline about whether it makes more sense to make the
regmap-spi version of the read function available, or to maintain
a local copy of the same code here. It's a trivial amount of code
obviously so not a big issue.

Mark, can you take a quick glance at this?

Thanks,

Jonathan
> ---
> 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  | 117 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 134 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 94ad8e7ad0ec..8b209d14bac9 100644
> --- a/drivers/iio/pressure/Kconfig
> +++ b/drivers/iio/pressure/Kconfig
> @@ -7,15 +7,17 @@ menu "Pressure sensors"
>  
>  config BMP280
>  	tristate "Bosch Sensortec BMP180/BMP280 pressure sensor I2C driver"
> -	depends on I2C
> +	depends on (I2C || SPI_MASTER)
>  	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
> @@ -24,6 +26,13 @@ config BMP280_I2C
>  	depends on !(BMP085_I2C=y || BMP085_I2C=m)
>  	select REGMAP_I2C
>  
> +config BMP280_SPI
> +	tristate
> +	depends on BMP280
> +	depends on SPI_MASTER
> +	depends on !(BMP085_SPI=y || BMP085_SPI=m)
> +	select REGMAP_SPI
> +
>  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 77f0fc935c09..733ef3c08102 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..2b9955f48d58
> --- /dev/null
> +++ b/drivers/iio/pressure/bmp280-spi.c
> @@ -0,0 +1,117 @@
> +/*
> + * 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);
> +}
I'd be tempted to export the regmap-spi version of this then use it here..
That would make it immediately clear that the change here is only in the
write function.

Mark, what do you think?

> +
> +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 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,
> +};
> +module_spi_driver(bmp280_spi_driver);
> +
> +MODULE_DESCRIPTION("BMP085 SPI bus driver");
> +MODULE_LICENSE("GPL");
> 


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

* Re: [PATCH 8/9 v2] iio: pressure: bmp280: add support for BMP085 EOC interrupt
  2016-06-22 20:53 ` [PATCH 8/9 v2] iio: pressure: bmp280: add support for BMP085 EOC interrupt Linus Walleij
@ 2016-06-26 10:18   ` Jonathan Cameron
  0 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron @ 2016-06-26 10:18 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 22/06/16 21:53, 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>
Rather obvious race condition in probe..
> ---
> ChangeLog v1->v2:
> - Fix spelling mistakes
> ---
>  drivers/iio/pressure/bmp280-core.c | 83 ++++++++++++++++++++++++++++++++++----
>  drivers/iio/pressure/bmp280-i2c.c  |  3 +-
>  drivers/iio/pressure/bmp280-spi.c  |  3 +-
>  drivers/iio/pressure/bmp280.h      |  3 +-
>  4 files changed, 81 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
> index 733ef3c08102..7b2a03d6fd1d 100644
> --- a/drivers/iio/pressure/bmp280-core.c
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -26,6 +26,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"
>  
> @@ -33,6 +36,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;
> @@ -593,16 +598,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)
> @@ -844,16 +865,28 @@ static const struct bmp280_chip_info bmp180_chip_info = {
>  	.read_press = bmp180_read_press,
>  };
>  
> +static irqreturn_t bmp058_eoc_irq(int irq, void *d)
> +{
> +	struct bmp280_data *data = d;
> +
> +	complete(&data->done);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +
>  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;
>  	struct bmp280_data *data;
>  	unsigned int chip_id;
>  	struct gpio_desc *gpiod;
> +	unsigned long irq_trig;
>  
>  	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
>  	if (!indio_dev)
> @@ -937,5 +970,39 @@ int bmp280_common_probe(struct device *dev,
>  	if (ret < 0)
>  		return ret;
>  
> -	return devm_iio_device_register(dev, indio_dev);
> +	ret = devm_iio_device_register(dev, indio_dev);
You just exposed the userspace interface here.... Yet (see below)
> +	if (ret) {
> +		dev_err(dev, "unable to register IIO device\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * Attempt to grab an optional EOC IRQ - only the BMP058 has this
> +	 * however as it happens, the BMP058 shares the chip ID of BMP180
> +	 * so we look for an IRQ if we have that.
> +	 */
> +	if (irq <= 0 || (chip_id  != BMP180_CHIP_ID))
> +		return 0;
> +
> +	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,
> +			bmp058_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;
> +	}
A necessary interrupt isn't available until here.  Please reorder.
The register call for userspace (and for that matter inkernel users) must
be made only one everything else is ready.

 
> +
> +	data->use_eoc = true;
> +	return 0;
>  }
> diff --git a/drivers/iio/pressure/bmp280-i2c.c b/drivers/iio/pressure/bmp280-i2c.c
> index a981670e5dc0..b9a2562e8a7e 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 const struct acpi_device_id bmp280_acpi_i2c_match[] = {
> diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c
> index 2b9955f48d58..05ddf2ee7519 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 const struct of_device_id bmp280_of_spi_match[] = {
> diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
> index acb40de2f581..9dee048b5a74 100644
> --- a/drivers/iio/pressure/bmp280.h
> +++ b/drivers/iio/pressure/bmp280.h
> @@ -104,4 +104,5 @@ 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);
> 


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

* Re: [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once
  2016-06-22 20:53 ` [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once Linus Walleij
@ 2016-06-26 10:21   ` Jonathan Cameron
  2016-06-27 12:11     ` Linus Walleij
  2016-06-27  7:42   ` Vlad Dogaru
  1 sibling, 1 reply; 32+ messages in thread
From: Jonathan Cameron @ 2016-06-26 10:21 UTC (permalink / raw)
  To: Linus Walleij, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay
  Cc: Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 22/06/16 21:53, 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.
> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
One nitpick inline, but it's minor enough I'm just being grumpy
about it so don't bother fixing it unless you want to.

On the adding entropy bit, any idea who to sanity check that with?
It's not something we've done before, so I just want a bit of
reassurance ideally;)

Jonathan
> ---
> ChangeLog v1->v2:
> - Remove unused dangling "ret" variable.
> ---
>  drivers/iio/pressure/bmp280-core.c | 95 +++++++++++++++++++-------------------
>  1 file changed, 48 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
> index 7b2a03d6fd1d..6559455f0335 100644
> --- a/drivers/iio/pressure/bmp280-core.c
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -29,9 +29,30 @@
>  #include <linux/interrupt.h>
>  #include <linux/irq.h> /* For irq_get_irq_data() */
>  #include <linux/completion.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;
> @@ -39,6 +60,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;
>  
> @@ -654,26 +676,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)
>  {
> @@ -683,7 +685,6 @@ static int bmp180_read_calib(struct bmp280_data *data,
>  
>  	ret = regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, buf,
>  			       sizeof(buf));
> -
Good but unrelated change.  Should have been in a different patch...
>  	if (ret < 0)
>  		return ret;
>  
> @@ -693,6 +694,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]);
> @@ -716,19 +720,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;
> @@ -783,29 +779,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;
> @@ -970,6 +958,19 @@ int bmp280_common_probe(struct device *dev,
>  	if (ret < 0)
>  		return ret;
>  
> +	/*
> +	 * The BMP058 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");
> +			return ret;
> +		}
> +	}
> +
>  	ret = devm_iio_device_register(dev, indio_dev);
>  	if (ret) {
>  		dev_err(dev, "unable to register IIO device\n");
> 


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

* Re: [PATCH 2/9 v2] iio: pressure: bmp280: support device tree initialization
  2016-06-26  9:52   ` Jonathan Cameron
@ 2016-06-26 10:27     ` H. Nikolaus Schaller
  2016-06-26 10:39       ` Jonathan Cameron
  0 siblings, 1 reply; 32+ messages in thread
From: H. Nikolaus Schaller @ 2016-06-26 10:27 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Linus Walleij, linux-iio, Akinobu Mita, Matt Ranostay,
	Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

Hi,

> Am 26.06.2016 um 11:52 schrieb Jonathan Cameron <jic23@kernel.org>:
>=20
> On 22/06/16 21:53, Linus Walleij wrote:
>> This adds device tree support to the BMP085, BMP180 and BMP280
>> pressure sensors. Tested on the Qualcomm APQ8060 Dragonboard:
>>=20
>> iio:device1$ cat in_temp_input
>> 26700
>> iio:device1$ cat in_pressure_input
>> 99.185000000
>>=20
> Please also confirm the value of 'name' given the mess we have had
> over that recently.

Here is what I get on a bmp085 equipped device:

root@letux:/sys/bus/iio/devices/iio:device0# for i in *
> do
> echo $i $(cat $i)
> done
dev 252:0
in_pressure_input 94.778000000
in_pressure_oversampling_ratio 8
in_pressure_oversampling_ratio_available 1 2 4 8
in_temp_input 33200
in_temp_oversampling_ratio 1
in_temp_oversampling_ratio_available 1
name bmp085
of_node
power
subsystem
uevent MAJOR=3D252 MINOR=3D0 DEVNAME=3Diio:device0 DEVTYPE=3Diio_device =
OF_NAME=3Dbmp085 OF_FULLNAME=3D/ocp/i2c@48072000/bmp085@77 =
OF_COMPATIBLE_0=3Dbosch,bmp085 OF_COMPATIBLE_N=3D1
root@letux:/sys/bus/iio/devices/iio:device0#=20

So "name" is the name of the chip variant.

>=20
>=20
>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
>> ---
>> ChangeLog v1->v2:
>> - Fix some BMP085 misspelled as BMP058 errors.
>> - Add the new BME280 sensor as well
>> ---
>> drivers/iio/pressure/bmp280.c | 14 ++++++++++++++
>> 1 file changed, 14 insertions(+)
>>=20
>> diff --git a/drivers/iio/pressure/bmp280.c =
b/drivers/iio/pressure/bmp280.c
>> index dbbcd6d83e3b..655e888ef8f9 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,18 @@ static const struct acpi_device_id =
bmp280_acpi_match[] =3D {
>> };
>> MODULE_DEVICE_TABLE(acpi, bmp280_acpi_match);
>>=20
>> +#ifdef CONFIG_OF
>> +static const struct of_device_id bmp280_of_match[] =3D {
>> +	{ .compatible =3D "bosch,bme280", .data =3D (void =
*)BME280_CHIP_ID },
>> +	{ .compatible =3D "bosch,bmp280", .data =3D (void =
*)BMP280_CHIP_ID },
>> +	{ .compatible =3D "bosch,bmp180", .data =3D (void =
*)BMP180_CHIP_ID },
>> +	{ .compatible =3D "bosch,bmp085", .data =3D (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[] =3D {
>> 	{"bmp280", BMP280_CHIP_ID },
>> 	{"bmp180", BMP180_CHIP_ID },
>> @@ -1107,6 +1120,7 @@ static struct i2c_driver bmp280_driver =3D {
>> 	.driver =3D {
>> 		.name	=3D "bmp280",
>> 		.acpi_match_table =3D ACPI_PTR(bmp280_acpi_match),
>> +		.of_match_table =3D of_match_ptr(bmp280_of_match),
>> 	},
>> 	.probe		=3D bmp280_probe,
>> 	.id_table	=3D bmp280_id,
>>=20
>=20


BR,
Nikolaus=

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

* Re: [PATCH 2/9 v2] iio: pressure: bmp280: support device tree initialization
  2016-06-26 10:27     ` H. Nikolaus Schaller
@ 2016-06-26 10:39       ` Jonathan Cameron
  0 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron @ 2016-06-26 10:39 UTC (permalink / raw)
  To: H. Nikolaus Schaller
  Cc: Linus Walleij, linux-iio, Akinobu Mita, Matt Ranostay,
	Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 26/06/16 11:27, H. Nikolaus Schaller wrote:
> Hi,
> 
>> Am 26.06.2016 um 11:52 schrieb Jonathan Cameron <jic23@kernel.org>:
>>
>> On 22/06/16 21:53, 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
>>>
>> Please also confirm the value of 'name' given the mess we have had
>> over that recently.
> 
> Here is what I get on a bmp085 equipped device:
> 
> root@letux:/sys/bus/iio/devices/iio:device0# for i in *
>> do
>> echo $i $(cat $i)
>> done
> dev 252:0
> in_pressure_input 94.778000000
> in_pressure_oversampling_ratio 8
> in_pressure_oversampling_ratio_available 1 2 4 8
> in_temp_input 33200
> in_temp_oversampling_ratio 1
> in_temp_oversampling_ratio_available 1
> name bmp085
> of_node
> power
> subsystem
> uevent MAJOR=252 MINOR=0 DEVNAME=iio:device0 DEVTYPE=iio_device OF_NAME=bmp085 OF_FULLNAME=/ocp/i2c@48072000/bmp085@77 OF_COMPATIBLE_0=bosch,bmp085 OF_COMPATIBLE_N=1
> root@letux:/sys/bus/iio/devices/iio:device0# 
> 
> So "name" is the name of the chip variant.
Thanks.  That's great then.

Jonathan
> 
>>
>>
>>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
>>> ---
>>> ChangeLog v1->v2:
>>> - Fix some BMP085 misspelled as BMP058 errors.
>>> - Add the new BME280 sensor as well
>>> ---
>>> drivers/iio/pressure/bmp280.c | 14 ++++++++++++++
>>> 1 file changed, 14 insertions(+)
>>>
>>> diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
>>> index dbbcd6d83e3b..655e888ef8f9 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,18 @@ 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 +1120,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,
>>>
>>
> 
> 
> BR,
> Nikolaus
> 


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

* Re: [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once
  2016-06-22 20:53 ` [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once Linus Walleij
  2016-06-26 10:21   ` Jonathan Cameron
@ 2016-06-27  7:42   ` Vlad Dogaru
  2016-06-27 18:57     ` Jonathan Cameron
  1 sibling, 1 reply; 32+ messages in thread
From: Vlad Dogaru @ 2016-06-27  7:42 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Christoph Mair, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On Wed, Jun 22, 2016 at 10:53:39PM +0200, 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.

I think my initial thought when writing this was that regmap will take
care of the caching and not hit the i2c bus each time.  But I don't have
an issue with this change.  Other than that, series looks good to me.

> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Reviewed-by: Vlad Dogaru <vlad.dogaru@intel.com>

> ---
> ChangeLog v1->v2:
> - Remove unused dangling "ret" variable.
> ---
>  drivers/iio/pressure/bmp280-core.c | 95 +++++++++++++++++++-------------------
>  1 file changed, 48 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
> index 7b2a03d6fd1d..6559455f0335 100644
> --- a/drivers/iio/pressure/bmp280-core.c
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -29,9 +29,30 @@
>  #include <linux/interrupt.h>
>  #include <linux/irq.h> /* For irq_get_irq_data() */
>  #include <linux/completion.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;
> @@ -39,6 +60,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;
>  
> @@ -654,26 +676,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)
>  {
> @@ -683,7 +685,6 @@ static int bmp180_read_calib(struct bmp280_data *data,
>  
>  	ret = regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, buf,
>  			       sizeof(buf));
> -
>  	if (ret < 0)
>  		return ret;
>  
> @@ -693,6 +694,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]);
> @@ -716,19 +720,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;
> @@ -783,29 +779,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;
> @@ -970,6 +958,19 @@ int bmp280_common_probe(struct device *dev,
>  	if (ret < 0)
>  		return ret;
>  
> +	/*
> +	 * The BMP058 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");
> +			return ret;
> +		}
> +	}
> +
>  	ret = devm_iio_device_register(dev, indio_dev);
>  	if (ret) {
>  		dev_err(dev, "unable to register IIO device\n");
> -- 
> 2.4.11
> 
> --
> 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] 32+ messages in thread

* Re: [PATCH 5/9 v2] iio: pressure: bmp280: split driver in logical parts
  2016-06-26 10:04   ` Jonathan Cameron
@ 2016-06-27 11:29     ` Linus Walleij
  2016-06-27 18:58       ` Jonathan Cameron
  0 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2016-06-27 11:29 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio, Akinobu Mita, H. Nikolaus Schaller, Matt Ranostay,
	Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On Sun, Jun 26, 2016 at 12:04 PM, Jonathan Cameron <jic23@kernel.org> wrote:

> On 22/06/16 21:53, 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>
>
> Few trivial bits inline.
>
> Main thought here is why not roll the regmap bit into the core?  It's hardly
> a huge addition and that would allow you to also pull all of the header
> register defines etc into there..

It's a bit of a matter of taste: the I2C portion needs to call
devm_regmap_init_i2c() supplying the regmap config, so it needs
access to the regmap config. I can either just keep that in the main
file and export the symbol or split it off in a separate file and share
the symbol from there.

With the addition of SPI it becomes hairer: Akinobu noted that the
default SPI regmap cannot be used so SPI support needs a more
complex regmap setup, modifying the configs & such. Then it seems
more natural to split it into a separate file.

But it's your pick, I'm happy to take it either way.

>> +/*
>> + * Returns humidity in percent, resolution is 0.01 percent. Output value of
>> + * "47445" represents 47445/1024 = 46.333 %RH.
>> + *
>> + * Taken from BME280 datasheet, Section 4.2.3, "Compensation formula".
>> + */
>> +
> Guessing this is from the original cut and paste, but it's inconsistent
> to have a blank line here!

Hm I think the big issue is me forgetting to pass -M to to
git format-patch so you have to see all the code already in the
tree again. (I can make a separate patch for this issue if you
like, here I worry that it'd just be confusing.)

>> +#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 },
>
> Fairly obvious, but carry through the empty field from the issue in the
> earlier patch...

Yep fixed in my tree.

Yours,
Linus Walleij

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

* Re: [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once
  2016-06-26 10:21   ` Jonathan Cameron
@ 2016-06-27 12:11     ` Linus Walleij
  2016-06-27 18:59       ` Jonathan Cameron
  0 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2016-06-27 12:11 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio, Akinobu Mita, H. Nikolaus Schaller, Matt Ranostay,
	Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On Sun, Jun 26, 2016 at 12:21 PM, Jonathan Cameron <jic23@kernel.org> wrote:
> On 22/06/16 21:53, 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.
>>
>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
>
> One nitpick inline, but it's minor enough I'm just being grumpy
> about it so don't bother fixing it unless you want to.
>
> On the adding entropy bit, any idea who to sanity check that with?
> It's not something we've done before, so I just want a bit of
> reassurance ideally;)

I've done it in a few places whenever I ran into device-unique numbers,
actually sensors often have device-unique calibration and are thus well
suited to toss into the entropy pool.

The data from devices isn't really trusted to increase entropy: it may,
but it's not relied on by the algorithm, just mixed in, see:
http://lwn.net/Articles/507115/

>>       ret = regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, buf,
>>                              sizeof(buf));
>> -
> Good but unrelated change.  Should have been in a different patch...

Dropped unrelated whitespace fix.

Yours,
Linus Walleij

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

* Re: [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once
  2016-06-27  7:42   ` Vlad Dogaru
@ 2016-06-27 18:57     ` Jonathan Cameron
  2016-06-28  7:34       ` Linus Walleij
  0 siblings, 1 reply; 32+ messages in thread
From: Jonathan Cameron @ 2016-06-27 18:57 UTC (permalink / raw)
  To: Vlad Dogaru, Linus Walleij
  Cc: linux-iio, Akinobu Mita, H. Nikolaus Schaller, Matt Ranostay,
	Christoph Mair, Hartmut Knaack, Marek Belisko, Eric Andersson,
	Neil Brown

On 27/06/16 08:42, Vlad Dogaru wrote:
> On Wed, Jun 22, 2016 at 10:53:39PM +0200, 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.
> 
> I think my initial thought when writing this was that regmap will take
> care of the caching and not hit the i2c bus each time.  But I don't have
> an issue with this change.  Other than that, series looks good to me.
Good point. I must be half asleep.

Linus, are we missing something? If not, I'd go without this one.

J
> 
>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> 
> Reviewed-by: Vlad Dogaru <vlad.dogaru@intel.com>
> 
>> ---
>> ChangeLog v1->v2:
>> - Remove unused dangling "ret" variable.
>> ---
>>  drivers/iio/pressure/bmp280-core.c | 95 +++++++++++++++++++-------------------
>>  1 file changed, 48 insertions(+), 47 deletions(-)
>>
>> diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
>> index 7b2a03d6fd1d..6559455f0335 100644
>> --- a/drivers/iio/pressure/bmp280-core.c
>> +++ b/drivers/iio/pressure/bmp280-core.c
>> @@ -29,9 +29,30 @@
>>  #include <linux/interrupt.h>
>>  #include <linux/irq.h> /* For irq_get_irq_data() */
>>  #include <linux/completion.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;
>> @@ -39,6 +60,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;
>>  
>> @@ -654,26 +676,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)
>>  {
>> @@ -683,7 +685,6 @@ static int bmp180_read_calib(struct bmp280_data *data,
>>  
>>  	ret = regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, buf,
>>  			       sizeof(buf));
>> -
>>  	if (ret < 0)
>>  		return ret;
>>  
>> @@ -693,6 +694,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]);
>> @@ -716,19 +720,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;
>> @@ -783,29 +779,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;
>> @@ -970,6 +958,19 @@ int bmp280_common_probe(struct device *dev,
>>  	if (ret < 0)
>>  		return ret;
>>  
>> +	/*
>> +	 * The BMP058 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");
>> +			return ret;
>> +		}
>> +	}
>> +
>>  	ret = devm_iio_device_register(dev, indio_dev);
>>  	if (ret) {
>>  		dev_err(dev, "unable to register IIO device\n");
>> -- 
>> 2.4.11
>>
>> --
>> 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
> --
> 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] 32+ messages in thread

* Re: [PATCH 5/9 v2] iio: pressure: bmp280: split driver in logical parts
  2016-06-27 11:29     ` Linus Walleij
@ 2016-06-27 18:58       ` Jonathan Cameron
  0 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron @ 2016-06-27 18:58 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-iio, Akinobu Mita, H. Nikolaus Schaller, Matt Ranostay,
	Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 27/06/16 12:29, Linus Walleij wrote:
> On Sun, Jun 26, 2016 at 12:04 PM, Jonathan Cameron <jic23@kernel.org> wrote:
> 
>> On 22/06/16 21:53, 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>
>>
>> Few trivial bits inline.
>>
>> Main thought here is why not roll the regmap bit into the core?  It's hardly
>> a huge addition and that would allow you to also pull all of the header
>> register defines etc into there..
> 
> It's a bit of a matter of taste: the I2C portion needs to call
> devm_regmap_init_i2c() supplying the regmap config, so it needs
> access to the regmap config. I can either just keep that in the main
> file and export the symbol or split it off in a separate file and share
> the symbol from there.
> 
> With the addition of SPI it becomes hairer: Akinobu noted that the
> default SPI regmap cannot be used so SPI support needs a more
> complex regmap setup, modifying the configs & such. Then it seems
> more natural to split it into a separate file.
> 
> But it's your pick, I'm happy to take it either way.
Fair answer, keep it as it stands.

J
> 
>>> +/*
>>> + * Returns humidity in percent, resolution is 0.01 percent. Output value of
>>> + * "47445" represents 47445/1024 = 46.333 %RH.
>>> + *
>>> + * Taken from BME280 datasheet, Section 4.2.3, "Compensation formula".
>>> + */
>>> +
>> Guessing this is from the original cut and paste, but it's inconsistent
>> to have a blank line here!
> 
> Hm I think the big issue is me forgetting to pass -M to to
> git format-patch so you have to see all the code already in the
> tree again. (I can make a separate patch for this issue if you
> like, here I worry that it'd just be confusing.)
> 
>>> +#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 },
>>
>> Fairly obvious, but carry through the empty field from the issue in the
>> earlier patch...
> 
> Yep fixed in my tree.
> 
> Yours,
> Linus Walleij
> --
> 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] 32+ messages in thread

* Re: [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once
  2016-06-27 12:11     ` Linus Walleij
@ 2016-06-27 18:59       ` Jonathan Cameron
  0 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron @ 2016-06-27 18:59 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-iio, Akinobu Mita, H. Nikolaus Schaller, Matt Ranostay,
	Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On 27/06/16 13:11, Linus Walleij wrote:
> On Sun, Jun 26, 2016 at 12:21 PM, Jonathan Cameron <jic23@kernel.org> wrote:
>> On 22/06/16 21:53, 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.
>>>
>>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
>>
>> One nitpick inline, but it's minor enough I'm just being grumpy
>> about it so don't bother fixing it unless you want to.
>>
>> On the adding entropy bit, any idea who to sanity check that with?
>> It's not something we've done before, so I just want a bit of
>> reassurance ideally;)
> 
> I've done it in a few places whenever I ran into device-unique numbers,
> actually sensors often have device-unique calibration and are thus well
> suited to toss into the entropy pool.
> 
> The data from devices isn't really trusted to increase entropy: it may,
> but it's not relied on by the algorithm, just mixed in, see:
> http://lwn.net/Articles/507115/
Fair enough then.

J
> 
>>>       ret = regmap_bulk_read(data->regmap, BMP180_REG_CALIB_START, buf,
>>>                              sizeof(buf));
>>> -
>> Good but unrelated change.  Should have been in a different patch...
> 
> Dropped unrelated whitespace fix.
> 
> Yours,
> Linus Walleij
> 


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

* Re: [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once
  2016-06-27 18:57     ` Jonathan Cameron
@ 2016-06-28  7:34       ` Linus Walleij
  2016-06-28 10:21         ` Vlad Dogaru
  0 siblings, 1 reply; 32+ messages in thread
From: Linus Walleij @ 2016-06-28  7:34 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Vlad Dogaru, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Christoph Mair, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On Mon, Jun 27, 2016 at 8:57 PM, Jonathan Cameron <jic23@kernel.org> wrote:
> On 27/06/16 08:42, Vlad Dogaru wrote:
>> On Wed, Jun 22, 2016 at 10:53:39PM +0200, 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.
>>
>> I think my initial thought when writing this was that regmap will take
>> care of the caching and not hit the i2c bus each time.  But I don't have
>> an issue with this change.  Other than that, series looks good to me.
>
> Good point. I must be half asleep.
>
> Linus, are we missing something? If not, I'd go without this one.

It's true that regmap does cache the contents of the registers,
cutting the I2C bus traffic bottleneck. But reading it out every time
still incurs a bulk read of 22 bytes from regmap, meaning 22 iterations
in regmap where each need to be checked individually for volatileness
etc in the regmap core, then this happens at every conversion.

Compared to just doing this once and keeping a copy around
it is wasteful, so still an optimization worth it IMO.

Don't get me wrong, regmap is optimized
(just check drivers/base/regmap/*) but it can never be as optimized
as reading just once.

Also Vlad seems to OK it?

Yours,
Linus Walleij

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

* Re: [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once
  2016-06-28  7:34       ` Linus Walleij
@ 2016-06-28 10:21         ` Vlad Dogaru
  0 siblings, 0 replies; 32+ messages in thread
From: Vlad Dogaru @ 2016-06-28 10:21 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jonathan Cameron, linux-iio, Akinobu Mita, H. Nikolaus Schaller,
	Matt Ranostay, Christoph Mair, Hartmut Knaack, Marek Belisko,
	Eric Andersson, Neil Brown

On Tue, Jun 28, 2016 at 09:34:34AM +0200, Linus Walleij wrote:
> On Mon, Jun 27, 2016 at 8:57 PM, Jonathan Cameron <jic23@kernel.org> wrote:
> > On 27/06/16 08:42, Vlad Dogaru wrote:
> >> On Wed, Jun 22, 2016 at 10:53:39PM +0200, 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.
> >>
> >> I think my initial thought when writing this was that regmap will take
> >> care of the caching and not hit the i2c bus each time.  But I don't have
> >> an issue with this change.  Other than that, series looks good to me.
> >
> > Good point. I must be half asleep.
> >
> > Linus, are we missing something? If not, I'd go without this one.
> 
> It's true that regmap does cache the contents of the registers,
> cutting the I2C bus traffic bottleneck. But reading it out every time
> still incurs a bulk read of 22 bytes from regmap, meaning 22 iterations
> in regmap where each need to be checked individually for volatileness
> etc in the regmap core, then this happens at every conversion.
> 
> Compared to just doing this once and keeping a copy around
> it is wasteful, so still an optimization worth it IMO.
> 
> Don't get me wrong, regmap is optimized
> (just check drivers/base/regmap/*) but it can never be as optimized
> as reading just once.
> 
> Also Vlad seems to OK it?

Yep, it's not a problem for me.  You're right about reading once being
more efficient and.

Thanks,
Vlad

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

end of thread, other threads:[~2016-06-28 10:21 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-22 20:53 [PATCH 0/9] Improve BMP280 driver v2 Linus Walleij
     [not found] ` <1466628819-29784-1-git-send-email-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-06-22 20:53   ` [PATCH 1/9 v2] iio: pressure: bmp280: augment DT bindings Linus Walleij
2016-06-22 20:53     ` Linus Walleij
2016-06-22 20:53 ` [PATCH 2/9 v2] iio: pressure: bmp280: support device tree initialization Linus Walleij
2016-06-23  8:18   ` H. Nikolaus Schaller
2016-06-24 10:26     ` Linus Walleij
2016-06-26  9:52   ` Jonathan Cameron
2016-06-26 10:27     ` H. Nikolaus Schaller
2016-06-26 10:39       ` Jonathan Cameron
2016-06-22 20:53 ` [PATCH 3/9 v2] iio: pressure: bmp280: add reset GPIO line handling Linus Walleij
2016-06-22 20:53 ` [PATCH 4/9 v2] iio: pressure: bmp280: support supply regulators Linus Walleij
2016-06-23 10:02   ` Mark Brown
2016-06-22 20:53 ` [PATCH 5/9 v2] iio: pressure: bmp280: split driver in logical parts Linus Walleij
2016-06-23  8:18   ` H. Nikolaus Schaller
2016-06-24 10:28     ` Linus Walleij
2016-06-26 10:04   ` Jonathan Cameron
2016-06-27 11:29     ` Linus Walleij
2016-06-27 18:58       ` Jonathan Cameron
2016-06-22 20:53 ` [PATCH 6/9 v2] iio: pressure: bmp280: split off an I2C Kconfig entry Linus Walleij
2016-06-22 20:53 ` [PATCH 7/9 v2] iio: pressure: bmp280: add SPI interface driver Linus Walleij
2016-06-26 10:15   ` Jonathan Cameron
2016-06-22 20:53 ` [PATCH 8/9 v2] iio: pressure: bmp280: add support for BMP085 EOC interrupt Linus Walleij
2016-06-26 10:18   ` Jonathan Cameron
2016-06-22 20:53 ` [PATCH 9/9 v2] iio: pressure: bmp280: read calibration data once Linus Walleij
2016-06-26 10:21   ` Jonathan Cameron
2016-06-27 12:11     ` Linus Walleij
2016-06-27 18:59       ` Jonathan Cameron
2016-06-27  7:42   ` Vlad Dogaru
2016-06-27 18:57     ` Jonathan Cameron
2016-06-28  7:34       ` Linus Walleij
2016-06-28 10:21         ` Vlad Dogaru
2016-06-23  8:17 ` [PATCH 0/9] Improve BMP280 driver v2 H. Nikolaus Schaller

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.