* [PATCH 1/9] iio: pressure: bmp280: augment DT bindings
2016-06-19 18:33 [PATCH 0/9] iio: bmp280: improve driver Linus Walleij
@ 2016-06-19 18:33 ` Linus Walleij
2016-06-19 18:33 ` [PATCH 2/9] iio: pressure: bmp280: support device tree initialization Linus Walleij
` (9 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Linus Walleij @ 2016-06-19 18:33 UTC (permalink / raw)
To: Jonathan Cameron, linux-iio
Cc: Akinobu Mita, Christoph Mair, Vlad Dogaru, Hartmut Knaack,
Marek Belisko, H. Nikolaus Schaller, 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
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Documentation/devicetree/bindings/iio/pressure/bmp085.txt | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/iio/pressure/bmp085.txt b/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
index d7a6deb6b21e..06ad5feaea28 100644
--- a/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
+++ b/Documentation/devicetree/bindings/iio/pressure/bmp085.txt
@@ -1,7 +1,7 @@
-BMP085/BMP18x digital pressure sensors
+BMP085/BMP18x/BMP28x digital pressure sensors
Required properties:
-- compatible: bosch,bmp085
+- compatible: "bosch,bmp085" or "bosch,bmp180" or "bosch,bmp280"
Optional properties:
- chip-id: configurable chip id for non-default chip revisions
@@ -10,6 +10,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 +25,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] 18+ messages in thread* [PATCH 2/9] iio: pressure: bmp280: support device tree initialization
2016-06-19 18:33 [PATCH 0/9] iio: bmp280: improve driver Linus Walleij
2016-06-19 18:33 ` [PATCH 1/9] iio: pressure: bmp280: augment DT bindings Linus Walleij
@ 2016-06-19 18:33 ` Linus Walleij
2016-06-19 18:33 ` [PATCH 3/9] iio: pressure: bmp280: add reset GPIO line handling Linus Walleij
` (8 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Linus Walleij @ 2016-06-19 18:33 UTC (permalink / raw)
To: Jonathan Cameron, linux-iio
Cc: Akinobu Mita, Christoph Mair, Vlad Dogaru, Hartmut Knaack,
Marek Belisko, H. Nikolaus Schaller, 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.
---
drivers/iio/pressure/bmp280.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
index 2f1498e12bb2..6b0482cd376f 100644
--- a/drivers/iio/pressure/bmp280.c
+++ b/drivers/iio/pressure/bmp280.c
@@ -17,6 +17,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>
@@ -899,6 +900,17 @@ 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,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 },
@@ -911,6 +923,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] 18+ messages in thread* [PATCH 3/9] iio: pressure: bmp280: add reset GPIO line handling
2016-06-19 18:33 [PATCH 0/9] iio: bmp280: improve driver Linus Walleij
2016-06-19 18:33 ` [PATCH 1/9] iio: pressure: bmp280: augment DT bindings Linus Walleij
2016-06-19 18:33 ` [PATCH 2/9] iio: pressure: bmp280: support device tree initialization Linus Walleij
@ 2016-06-19 18:33 ` Linus Walleij
2016-06-19 18:33 ` [PATCH 4/9] iio: pressure: bmp280: support optional supply regulators Linus Walleij
` (7 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Linus Walleij @ 2016-06-19 18:33 UTC (permalink / raw)
To: Jonathan Cameron, linux-iio
Cc: Akinobu Mita, Christoph Mair, Vlad Dogaru, Hartmut Knaack,
Marek Belisko, H. Nikolaus Schaller, 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 6b0482cd376f..bde21c532fc7 100644
--- a/drivers/iio/pressure/bmp280.c
+++ b/drivers/iio/pressure/bmp280.c
@@ -22,6 +22,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_TEMP_XLSB 0xFC
@@ -838,6 +839,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)
@@ -869,6 +871,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] 18+ messages in thread* [PATCH 4/9] iio: pressure: bmp280: support optional supply regulators
2016-06-19 18:33 [PATCH 0/9] iio: bmp280: improve driver Linus Walleij
` (2 preceding siblings ...)
2016-06-19 18:33 ` [PATCH 3/9] iio: pressure: bmp280: add reset GPIO line handling Linus Walleij
@ 2016-06-19 18:33 ` Linus Walleij
2016-06-19 18:33 ` [PATCH 5/9] iio: pressure: bmp280: split driver in logical parts Linus Walleij
` (6 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Linus Walleij @ 2016-06-19 18:33 UTC (permalink / raw)
To: Jonathan Cameron, linux-iio
Cc: Akinobu Mita, Christoph Mair, Vlad Dogaru, Hartmut Knaack,
Marek Belisko, H. Nikolaus Schaller, Eric Andersson, Neil Brown,
Linus Walleij
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.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/iio/pressure/bmp280.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
index bde21c532fc7..343e97efad19 100644
--- a/drivers/iio/pressure/bmp280.c
+++ b/drivers/iio/pressure/bmp280.c
@@ -23,6 +23,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_TEMP_XLSB 0xFC
@@ -101,6 +102,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;
@@ -871,6 +874,20 @@ static int bmp280_probe(struct i2c_client *client,
return -EINVAL;
}
+ /* Optionally bring up regulators */
+ data->vddd = devm_regulator_get_optional(&client->dev, "vddd");
+ if (!IS_ERR(data->vddd)) {
+ ret = regulator_enable(data->vddd);
+ if (ret)
+ dev_err(&client->dev, "failed to enable VDDD\n");
+ }
+ data->vdda = devm_regulator_get_optional(&client->dev, "vdda");
+ if (!IS_ERR(data->vdda)) {
+ ret = regulator_enable(data->vdda);
+ if (ret)
+ dev_err(&client->dev, "failed to enable VDDA\n");
+ }
+
/* 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] 18+ messages in thread* [PATCH 5/9] iio: pressure: bmp280: split driver in logical parts
2016-06-19 18:33 [PATCH 0/9] iio: bmp280: improve driver Linus Walleij
` (3 preceding siblings ...)
2016-06-19 18:33 ` [PATCH 4/9] iio: pressure: bmp280: support optional supply regulators Linus Walleij
@ 2016-06-19 18:33 ` Linus Walleij
2016-06-19 18:33 ` [PATCH 6/9] iio: pressure: bmp280: split off an I2C Kconfig entry Linus Walleij
` (5 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Linus Walleij @ 2016-06-19 18:33 UTC (permalink / raw)
To: Jonathan Cameron, linux-iio
Cc: Akinobu Mita, Christoph Mair, Vlad Dogaru, Hartmut Knaack,
Marek Belisko, H. Nikolaus Schaller, 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>
---
drivers/iio/pressure/Makefile | 1 +
drivers/iio/pressure/{bmp280.c => bmp280-core.c} | 263 +++--------------------
drivers/iio/pressure/bmp280-i2c.c | 78 +++++++
drivers/iio/pressure/bmp280-regmap.c | 78 +++++++
drivers/iio/pressure/bmp280.h | 85 ++++++++
5 files changed, 274 insertions(+), 231 deletions(-)
rename drivers/iio/pressure/{bmp280.c => bmp280-core.c} (71%)
create mode 100644 drivers/iio/pressure/bmp280-i2c.c
create mode 100644 drivers/iio/pressure/bmp280-regmap.c
create mode 100644 drivers/iio/pressure/bmp280.h
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index 17d6e7afa1ff..2d98a7ff77a8 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -4,6 +4,7 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_BMP280) += bmp280.o
+bmp280-objs := bmp280-core.o bmp280-regmap.o bmp280-i2c.o
obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o
obj-$(CONFIG_HP03) += hp03.o
obj-$(CONFIG_MPL115) += mpl115.o
diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280-core.c
similarity index 71%
rename from drivers/iio/pressure/bmp280.c
rename to drivers/iio/pressure/bmp280-core.c
index 343e97efad19..5455e9c44953 100644
--- a/drivers/iio/pressure/bmp280.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -14,10 +14,7 @@
#define pr_fmt(fmt) "bmp280: " fmt
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/acpi.h>
-#include <linux/of.h>
+#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
@@ -25,80 +22,10 @@
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
-/* BMP280 specific registers */
-#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_STATUS 0xF3
-
-#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_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 BMP280_SOFT_RESET_VAL 0xB6
+#include "bmp280.h"
struct bmp280_data {
- struct i2c_client *client;
+ struct device *dev;
struct mutex lock;
struct regmap *regmap;
const struct bmp280_chip_info *chip_info;
@@ -117,8 +44,6 @@ struct bmp280_data {
};
struct bmp280_chip_info {
- const struct regmap_config *regmap_config;
-
const int *oversampling_temp_avail;
int num_oversampling_temp_avail;
@@ -150,45 +75,6 @@ static const struct iio_chan_spec bmp280_channels[] = {
},
};
-static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case BMP280_REG_CONFIG:
- case BMP280_REG_CTRL_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_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_TEMP_XLSB,
- .cache_type = REGCACHE_RBTREE,
-
- .writeable_reg = bmp280_is_writeable_reg,
- .volatile_reg = bmp280_is_volatile_reg,
-};
-
/*
* Returns temperature in DegC, resolution is 0.01 DegC. Output value of
* "5123" equals 51.23 DegC. t_fine carries fine temperature as global
@@ -206,7 +92,7 @@ static s32 bmp280_compensate_temp(struct bmp280_data *data,
ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START,
buf, BMP280_COMP_TEMP_REG_COUNT);
if (ret < 0) {
- dev_err(&data->client->dev,
+ dev_err(data->dev,
"failed to read temperature calibration parameters\n");
return ret;
}
@@ -246,7 +132,7 @@ static u32 bmp280_compensate_press(struct bmp280_data *data,
ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
buf, BMP280_COMP_PRESS_REG_COUNT);
if (ret < 0) {
- dev_err(&data->client->dev,
+ dev_err(data->dev,
"failed to read pressure calibration parameters\n");
return ret;
}
@@ -281,7 +167,7 @@ static int bmp280_read_temp(struct bmp280_data *data,
ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB,
(u8 *) &tmp, 3);
if (ret < 0) {
- dev_err(&data->client->dev, "failed to read temperature\n");
+ dev_err(data->dev, "failed to read temperature\n");
return ret;
}
@@ -316,7 +202,7 @@ static int bmp280_read_press(struct bmp280_data *data,
ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB,
(u8 *) &tmp, 3);
if (ret < 0) {
- dev_err(&data->client->dev, "failed to read pressure\n");
+ dev_err(data->dev, "failed to read pressure\n");
return ret;
}
@@ -507,7 +393,7 @@ static int bmp280_chip_config(struct bmp280_data *data)
BMP280_MODE_MASK,
osrs | BMP280_MODE_NORMAL);
if (ret < 0) {
- dev_err(&data->client->dev,
+ dev_err(data->dev,
"failed to write ctrl_meas register\n");
return ret;
}
@@ -516,7 +402,7 @@ static int bmp280_chip_config(struct bmp280_data *data)
BMP280_FILTER_MASK,
BMP280_FILTER_4X);
if (ret < 0) {
- dev_err(&data->client->dev,
+ dev_err(data->dev,
"failed to write config register\n");
return ret;
}
@@ -527,8 +413,6 @@ static int bmp280_chip_config(struct bmp280_data *data)
static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 };
static const struct bmp280_chip_info bmp280_chip_info = {
- .regmap_config = &bmp280_regmap_config,
-
.oversampling_temp_avail = bmp280_oversampling_avail,
.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
@@ -540,41 +424,6 @@ static const struct bmp280_chip_info bmp280_chip_info = {
.read_press = bmp280_read_press,
};
-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;
@@ -690,7 +539,7 @@ static s32 bmp180_compensate_temp(struct bmp280_data *data, s32 adc_temp)
ret = bmp180_read_calib(data, &calib);
if (ret < 0) {
- dev_err(&data->client->dev,
+ dev_err(data->dev,
"failed to read calibration coefficients\n");
return ret;
}
@@ -760,7 +609,7 @@ static u32 bmp180_compensate_press(struct bmp280_data *data, s32 adc_press)
ret = bmp180_read_calib(data, &calib);
if (ret < 0) {
- dev_err(&data->client->dev,
+ dev_err(data->dev,
"failed to read calibration coefficients\n");
return ret;
}
@@ -820,8 +669,6 @@ static const int bmp180_oversampling_temp_avail[] = { 1 };
static const int bmp180_oversampling_press_avail[] = { 1, 2, 4, 8 };
static const struct bmp280_chip_info bmp180_chip_info = {
- .regmap_config = &bmp180_regmap_config,
-
.oversampling_temp_avail = bmp180_oversampling_temp_avail,
.num_oversampling_temp_avail =
ARRAY_SIZE(bmp180_oversampling_temp_avail),
@@ -835,8 +682,10 @@ static const struct bmp280_chip_info bmp180_chip_info = {
.read_press = bmp180_read_press,
};
-static int bmp280_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+int bmp280_common_probe(struct device *dev,
+ struct regmap *regmap,
+ unsigned int chip,
+ const char *name)
{
int ret;
struct iio_dev *indio_dev;
@@ -844,22 +693,22 @@ static int bmp280_probe(struct i2c_client *client,
unsigned int chip_id;
struct gpio_desc *gpiod;
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
mutex_init(&data->lock);
- data->client = client;
+ data->dev = dev;
- indio_dev->dev.parent = &client->dev;
- indio_dev->name = id->name;
+ indio_dev->dev.parent = dev;
+ indio_dev->name = name;
indio_dev->channels = bmp280_channels;
indio_dev->num_channels = ARRAY_SIZE(bmp280_channels);
indio_dev->info = &bmp280_info;
indio_dev->modes = INDIO_DIRECT_MODE;
- switch (id->driver_data) {
+ switch (chip) {
case BMP180_CHIP_ID:
data->chip_info = &bmp180_chip_info;
data->oversampling_press = ilog2(8);
@@ -875,40 +724,34 @@ static int bmp280_probe(struct i2c_client *client,
}
/* Optionally bring up regulators */
- data->vddd = devm_regulator_get_optional(&client->dev, "vddd");
+ data->vddd = devm_regulator_get_optional(dev, "vddd");
if (!IS_ERR(data->vddd)) {
ret = regulator_enable(data->vddd);
if (ret)
- dev_err(&client->dev, "failed to enable VDDD\n");
+ dev_err(dev, "failed to enable VDDD\n");
}
- data->vdda = devm_regulator_get_optional(&client->dev, "vdda");
+ data->vdda = devm_regulator_get_optional(dev, "vdda");
if (!IS_ERR(data->vdda)) {
ret = regulator_enable(data->vdda);
if (ret)
- dev_err(&client->dev, "failed to enable VDDA\n");
+ dev_err(dev, "failed to enable VDDA\n");
}
/* Bring chip out of reset if there is an assigned GPIO line */
- gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+ gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
/* Deassert the signal */
if (!IS_ERR(gpiod)) {
- dev_info(&client->dev, "release reset\n");
+ dev_info(dev, "release reset\n");
gpiod_set_value(gpiod, 0);
}
- data->regmap = devm_regmap_init_i2c(client,
- data->chip_info->regmap_config);
- if (IS_ERR(data->regmap)) {
- dev_err(&client->dev, "failed to allocate register map\n");
- return PTR_ERR(data->regmap);
- }
-
- ret = regmap_read(data->regmap, BMP280_REG_ID, &chip_id);
+ data->regmap = regmap;
+ ret = regmap_read(regmap, BMP280_REG_ID, &chip_id);
if (ret < 0)
return ret;
- if (chip_id != id->driver_data) {
- dev_err(&client->dev, "bad chip id. expected %x got %x\n",
- BMP280_CHIP_ID, chip_id);
+ if (chip_id != chip) {
+ dev_err(dev, "bad chip id: expected %x got %x\n",
+ chip, chip_id);
return -EINVAL;
}
@@ -916,47 +759,5 @@ static int bmp280_probe(struct i2c_client *client,
if (ret < 0)
return ret;
- return devm_iio_device_register(&client->dev, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
-
-static const struct acpi_device_id bmp280_acpi_match[] = {
- {"BMP0280", BMP280_CHIP_ID },
- {"BMP0180", BMP180_CHIP_ID },
- {"BMP0085", BMP180_CHIP_ID },
- { },
-};
-MODULE_DEVICE_TABLE(acpi, bmp280_acpi_match);
-
-#ifdef CONFIG_OF
-static const struct of_device_id bmp280_of_match[] = {
- { .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 },
- { },
-};
-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-i2c.c b/drivers/iio/pressure/bmp280-i2c.c
new file mode 100644
index 000000000000..b422600f34e0
--- /dev/null
+++ b/drivers/iio/pressure/bmp280-i2c.c
@@ -0,0 +1,78 @@
+#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:
+ 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 },
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, bmp280_acpi_i2c_match);
+
+#ifdef CONFIG_OF
+static const struct of_device_id bmp280_of_i2c_match[] = {
+ { .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 },
+ { },
+};
+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..8c04e9a630ce
--- /dev/null
+++ b/drivers/iio/pressure/bmp280-regmap.c
@@ -0,0 +1,78 @@
+#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_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_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_TEMP_XLSB,
+ .cache_type = REGCACHE_RBTREE,
+
+ .writeable_reg = bmp280_is_writeable_reg,
+ .volatile_reg = bmp280_is_volatile_reg,
+};
diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
new file mode 100644
index 000000000000..9249956bc8bf
--- /dev/null
+++ b/drivers/iio/pressure/bmp280.h
@@ -0,0 +1,85 @@
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+/* BMP280 specific registers */
+#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_STATUS 0xF3
+
+#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_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 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] 18+ messages in thread* [PATCH 6/9] iio: pressure: bmp280: split off an I2C Kconfig entry
2016-06-19 18:33 [PATCH 0/9] iio: bmp280: improve driver Linus Walleij
` (4 preceding siblings ...)
2016-06-19 18:33 ` [PATCH 5/9] iio: pressure: bmp280: split driver in logical parts Linus Walleij
@ 2016-06-19 18:33 ` Linus Walleij
2016-06-19 18:34 ` [PATCH 7/9] iio: pressure: bmp280: add SPI interface driver Linus Walleij
` (4 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Linus Walleij @ 2016-06-19 18:33 UTC (permalink / raw)
To: Jonathan Cameron, linux-iio
Cc: Akinobu Mita, Christoph Mair, Vlad Dogaru, Hartmut Knaack,
Marek Belisko, H. Nikolaus Schaller, 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 cda9f128f3a4..40aaf4295d30 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -6,16 +6,22 @@
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.
+ pressure and temperature sensors mounted on the I2C bus.
- 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] 18+ messages in thread* [PATCH 7/9] iio: pressure: bmp280: add SPI interface driver
2016-06-19 18:33 [PATCH 0/9] iio: bmp280: improve driver Linus Walleij
` (5 preceding siblings ...)
2016-06-19 18:33 ` [PATCH 6/9] iio: pressure: bmp280: split off an I2C Kconfig entry Linus Walleij
@ 2016-06-19 18:34 ` Linus Walleij
2016-06-20 11:06 ` Akinobu Mita
2016-06-19 18:34 ` [PATCH 8/9] iio: pressure: bmp280: add support for the BMP058 EOC interrupt Linus Walleij
` (3 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Linus Walleij @ 2016-06-19 18:34 UTC (permalink / raw)
To: Jonathan Cameron, linux-iio
Cc: Akinobu Mita, Christoph Mair, Vlad Dogaru, Hartmut Knaack,
Marek Belisko, H. Nikolaus Schaller, 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.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/iio/pressure/Kconfig | 15 ++++++--
drivers/iio/pressure/Makefile | 1 +
drivers/iio/pressure/bmp280-core.c | 4 ++
drivers/iio/pressure/bmp280-spi.c | 78 ++++++++++++++++++++++++++++++++++++++
4 files changed, 95 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 40aaf4295d30..ff94f6b77f72 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -7,14 +7,16 @@ 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 mounted on the I2C bus.
- 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
@@ -23,6 +25,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 5455e9c44953..af422d224db4 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..a24ea5f62c5e
--- /dev/null
+++ b/drivers/iio/pressure/bmp280-spi.c
@@ -0,0 +1,78 @@
+/*
+ * 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_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:
+ regmap_config = &bmp280_regmap_config;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ regmap = devm_regmap_init_spi(spi, 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", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, bmp085_of_spi_match);
+
+static const struct spi_device_id bmp280_spi_id[] = {
+ { "bmp180", BMP180_CHIP_ID },
+ { "bmp181", BMP180_CHIP_ID },
+ { "bmp280", BMP280_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] 18+ messages in thread* Re: [PATCH 7/9] iio: pressure: bmp280: add SPI interface driver
2016-06-19 18:34 ` [PATCH 7/9] iio: pressure: bmp280: add SPI interface driver Linus Walleij
@ 2016-06-20 11:06 ` Akinobu Mita
2016-06-22 19:04 ` Linus Walleij
0 siblings, 1 reply; 18+ messages in thread
From: Akinobu Mita @ 2016-06-20 11:06 UTC (permalink / raw)
To: Linus Walleij
Cc: Jonathan Cameron, linux-iio, Christoph Mair, Vlad Dogaru,
Hartmut Knaack, Marek Belisko, H. Nikolaus Schaller,
Eric Andersson, Neil Brown
2016-06-20 3:34 GMT+09:00 Linus Walleij <linus.walleij@linaro.org>:
> 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.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
...
> +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:
> + regmap_config = &bmp280_regmap_config;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + regmap = devm_regmap_init_spi(spi, regmap_config);
I was also trying to support SPI interface for this driver and found
that we can't simply use regmap_init_spi().
Quote from 5.3 SPI interface in BMP280 datasheet:
In SPI mode, only 7 bits of the register addresses are used; the MSB of
register address is not used and replaced by a read/write bit (RW = ‘0’
for write and RW = ‘1’ for read). Example: address 0xF7 is accessed by
using SPI register address 0x77. For write access, the byte 0x77 is
transferred, for read access, the byte 0xF7 is transferred.
The write operation used by regmap_init_spi() doesn't replace the RW bit.
So we need custom regmap_bus like below.
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_spi = {
.write = bmp280_regmap_spi_write,
.read = bmp280_regmap_spi_read,
};
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH 7/9] iio: pressure: bmp280: add SPI interface driver
2016-06-20 11:06 ` Akinobu Mita
@ 2016-06-22 19:04 ` Linus Walleij
2016-06-25 10:27 ` Akinobu Mita
0 siblings, 1 reply; 18+ messages in thread
From: Linus Walleij @ 2016-06-22 19:04 UTC (permalink / raw)
To: Akinobu Mita
Cc: Jonathan Cameron, linux-iio@vger.kernel.org, Christoph Mair,
Vlad Dogaru, Hartmut Knaack, Marek Belisko, H. Nikolaus Schaller,
Eric Andersson, Neil Brown
On Mon, Jun 20, 2016 at 1:06 PM, Akinobu Mita <akinobu.mita@gmail.com> wrote:
> I was also trying to support SPI interface for this driver and found
> that we can't simply use regmap_init_spi().
>
> Quote from 5.3 SPI interface in BMP280 datasheet:
>
> In SPI mode, only 7 bits of the register addresses are used; the MSB of
> register address is not used and replaced by a read/write bit (RW = ‘0’
> for write and RW = ‘1’ for read). Example: address 0xF7 is accessed by
> using SPI register address 0x77. For write access, the byte 0x77 is
> transferred, for read access, the byte 0xF7 is transferred.
>
> The write operation used by regmap_init_spi() doesn't replace the RW bit.
> So we need custom regmap_bus like below.
Aha! OK I added your bus implementation and will add your Signed-off to
the patch as well, OK?
It would be great if you could also test the result.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 7/9] iio: pressure: bmp280: add SPI interface driver
2016-06-22 19:04 ` Linus Walleij
@ 2016-06-25 10:27 ` Akinobu Mita
0 siblings, 0 replies; 18+ messages in thread
From: Akinobu Mita @ 2016-06-25 10:27 UTC (permalink / raw)
To: Linus Walleij
Cc: Jonathan Cameron, linux-iio@vger.kernel.org, Christoph Mair,
Vlad Dogaru, Hartmut Knaack, Marek Belisko, H. Nikolaus Schaller,
Eric Andersson, Neil Brown
2016-06-23 4:04 GMT+09:00 Linus Walleij <linus.walleij@linaro.org>:
> On Mon, Jun 20, 2016 at 1:06 PM, Akinobu Mita <akinobu.mita@gmail.com> wrote:
>
>> I was also trying to support SPI interface for this driver and found
>> that we can't simply use regmap_init_spi().
>>
>> Quote from 5.3 SPI interface in BMP280 datasheet:
>>
>> In SPI mode, only 7 bits of the register addresses are used; the MSB of
>> register address is not used and replaced by a read/write bit (RW = ‘0’
>> for write and RW = ‘1’ for read). Example: address 0xF7 is accessed by
>> using SPI register address 0x77. For write access, the byte 0x77 is
>> transferred, for read access, the byte 0xF7 is transferred.
>>
>> The write operation used by regmap_init_spi() doesn't replace the RW bit.
>> So we need custom regmap_bus like below.
>
> Aha! OK I added your bus implementation and will add your Signed-off to
> the patch as well, OK?
OK
> It would be great if you could also test the result.
I've tested v2 patches with fixing undefined symbols error, missing
NULL entry in of_device_id, and missing MODULE_LICENSE in bmp280.ko.
The SPI interface for BMP280 works fine as well as I2C interface.
Tested-by: Akinobu Mita <akinobu.mita@gmail.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 8/9] iio: pressure: bmp280: add support for the BMP058 EOC interrupt
2016-06-19 18:33 [PATCH 0/9] iio: bmp280: improve driver Linus Walleij
` (6 preceding siblings ...)
2016-06-19 18:34 ` [PATCH 7/9] iio: pressure: bmp280: add SPI interface driver Linus Walleij
@ 2016-06-19 18:34 ` Linus Walleij
2016-06-20 4:58 ` H. Nikolaus Schaller
2016-06-19 18:34 ` [PATCH 9/9] iio: pressure: bmp280: read calibration data once Linus Walleij
` (2 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Linus Walleij @ 2016-06-19 18:34 UTC (permalink / raw)
To: Jonathan Cameron, linux-iio
Cc: Akinobu Mita, Christoph Mair, Vlad Dogaru, Hartmut Knaack,
Marek Belisko, H. Nikolaus Schaller, Eric Andersson, Neil Brown,
Linus Walleij
The first version of this sensor, BMP058, supports sending an
End-of-Conversion (EOC) interrupt. Add code to support this using
a completion, in a similar vein as drivers/misc/bmp058.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>
---
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 af422d224db4..ca9ed843efcc 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -25,6 +25,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"
@@ -32,6 +35,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;
@@ -435,16 +440,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)
@@ -686,16 +707,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)
@@ -763,5 +796,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 b422600f34e0..eb2b727109b8 100644
--- a/drivers/iio/pressure/bmp280-i2c.c
+++ b/drivers/iio/pressure/bmp280-i2c.c
@@ -32,7 +32,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 a24ea5f62c5e..cfb6248ceb1f 100644
--- a/drivers/iio/pressure/bmp280-spi.c
+++ b/drivers/iio/pressure/bmp280-spi.c
@@ -44,7 +44,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 9249956bc8bf..ad0e5778c6b5 100644
--- a/drivers/iio/pressure/bmp280.h
+++ b/drivers/iio/pressure/bmp280.h
@@ -82,4 +82,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] 18+ messages in thread* Re: [PATCH 8/9] iio: pressure: bmp280: add support for the BMP058 EOC interrupt
2016-06-19 18:34 ` [PATCH 8/9] iio: pressure: bmp280: add support for the BMP058 EOC interrupt Linus Walleij
@ 2016-06-20 4:58 ` H. Nikolaus Schaller
0 siblings, 0 replies; 18+ messages in thread
From: H. Nikolaus Schaller @ 2016-06-20 4:58 UTC (permalink / raw)
To: Linus Walleij
Cc: Jonathan Cameron, linux-iio, Akinobu Mita, Christoph Mair,
Vlad Dogaru, Hartmut Knaack, Marek Belisko, Eric Andersson,
Neil Brown
> Am 19.06.2016 um 20:34 schrieb Linus Walleij <linus.walleij@linaro.org>:
>
> The first version of this sensor, BMP058, supports sending an
s/058/085/
and in subject line and commit messages in some other patches.
> End-of-Conversion (EOC) interrupt. Add code to support this using
> a completion, in a similar vein as drivers/misc/bmp058.c does.
s/058.c/085.c/
> 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>
> ---
> 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 af422d224db4..ca9ed843efcc 100644
> --- a/drivers/iio/pressure/bmp280-core.c
> +++ b/drivers/iio/pressure/bmp280-core.c
> @@ -25,6 +25,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"
>
> @@ -32,6 +35,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;
> @@ -435,16 +440,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)
> @@ -686,16 +707,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)
> @@ -763,5 +796,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 b422600f34e0..eb2b727109b8 100644
> --- a/drivers/iio/pressure/bmp280-i2c.c
> +++ b/drivers/iio/pressure/bmp280-i2c.c
> @@ -32,7 +32,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 a24ea5f62c5e..cfb6248ceb1f 100644
> --- a/drivers/iio/pressure/bmp280-spi.c
> +++ b/drivers/iio/pressure/bmp280-spi.c
> @@ -44,7 +44,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 9249956bc8bf..ad0e5778c6b5 100644
> --- a/drivers/iio/pressure/bmp280.h
> +++ b/drivers/iio/pressure/bmp280.h
> @@ -82,4 +82,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 [flat|nested] 18+ messages in thread
* [PATCH 9/9] iio: pressure: bmp280: read calibration data once
2016-06-19 18:33 [PATCH 0/9] iio: bmp280: improve driver Linus Walleij
` (7 preceding siblings ...)
2016-06-19 18:34 ` [PATCH 8/9] iio: pressure: bmp280: add support for the BMP058 EOC interrupt Linus Walleij
@ 2016-06-19 18:34 ` Linus Walleij
2016-06-20 4:56 ` [PATCH 0/9] iio: bmp280: improve driver H. Nikolaus Schaller
2016-06-22 7:31 ` Matt Ranostay
10 siblings, 0 replies; 18+ messages in thread
From: Linus Walleij @ 2016-06-19 18:34 UTC (permalink / raw)
To: Jonathan Cameron, linux-iio
Cc: Akinobu Mita, Christoph Mair, Vlad Dogaru, Hartmut Knaack,
Marek Belisko, H. Nikolaus Schaller, 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>
---
drivers/iio/pressure/bmp280-core.c | 94 +++++++++++++++++++-------------------
1 file changed, 48 insertions(+), 46 deletions(-)
diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index ca9ed843efcc..41f65c8cb84e 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -28,9 +28,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;
@@ -38,6 +59,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;
@@ -496,26 +518,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)
{
@@ -525,7 +527,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;
@@ -535,6 +536,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]);
@@ -558,19 +562,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;
-
- 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;
- 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;
@@ -630,24 +626,17 @@ static u32 bmp180_compensate_press(struct bmp280_data *data, s32 adc_press)
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;
@@ -796,6 +785,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] 18+ messages in thread* Re: [PATCH 0/9] iio: bmp280: improve driver
2016-06-19 18:33 [PATCH 0/9] iio: bmp280: improve driver Linus Walleij
` (8 preceding siblings ...)
2016-06-19 18:34 ` [PATCH 9/9] iio: pressure: bmp280: read calibration data once Linus Walleij
@ 2016-06-20 4:56 ` H. Nikolaus Schaller
2016-06-22 7:31 ` Matt Ranostay
10 siblings, 0 replies; 18+ messages in thread
From: H. Nikolaus Schaller @ 2016-06-20 4:56 UTC (permalink / raw)
To: Linus Walleij
Cc: Jonathan Cameron, linux-iio, Akinobu Mita, Christoph Mair,
Vlad Dogaru, Hartmut Knaack, Marek Belisko, Eric Andersson,
Neil Brown
Hi,
> Am 19.06.2016 um 20:33 schrieb Linus Walleij <linus.walleij@linaro.org>:
>
> The goal of the original exercise to enable the driver for my
> Dragonboard expanded when I found the *second* driver for this
> sensor in drivers/misc/bmp085.
>
> So I wrote a patch series to bring the features of the IIO driver
> on par with the misc driver, and beyond it:
>
> - The first patch set stuff augmenting DT bindings and adding
> regulators and a reset GPIO.
>
> - Split transport from core driver (separate I2C module)
>
> - Added SPI support (which I cannot test, grateful for any help,
> but pretty sure it works).
>
> - Support for the BMP085 EOC interrupt mechanism rather than
> waiting for the conversion to happen.
>
> - Do not re-read calibration data all the time, also toss the
> calibration into the entropy pool.
>
> After this I think the misc driver can be replaced with this
> driver, but I'd love to hear from the maintainers of that driver
> if I've missed something. One of the patches adds all the authors
> of the misc driver listed there as I can clearly see code was
> copied into this driver at several points.
>
> The only thing missing from the misc driver is the sysfs
> interface. If there is real userspace out there using it, we
> can implement a compatibility sysfs ABI. But then I'd like
> to know what userspace it is, so I can test it.
I will test on GTA04 as soon as I find a little time for it. We use
the sysfs only for debugging and this can also be done through
iio. So AFAIK there will be no functionality missing.
BR,
Nikolaus
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH 0/9] iio: bmp280: improve driver
2016-06-19 18:33 [PATCH 0/9] iio: bmp280: improve driver Linus Walleij
` (9 preceding siblings ...)
2016-06-20 4:56 ` [PATCH 0/9] iio: bmp280: improve driver H. Nikolaus Schaller
@ 2016-06-22 7:31 ` Matt Ranostay
2016-06-22 15:18 ` Linus Walleij
10 siblings, 1 reply; 18+ messages in thread
From: Matt Ranostay @ 2016-06-22 7:31 UTC (permalink / raw)
To: Linus Walleij
Cc: Jonathan Cameron, linux-iio@vger.kernel.org, Akinobu Mita,
Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
H. Nikolaus Schaller, Eric Andersson, Neil Brown
On Sun, Jun 19, 2016 at 11:33 AM, Linus Walleij
<linus.walleij@linaro.org> wrote:
> The goal of the original exercise to enable the driver for my
> Dragonboard expanded when I found the *second* driver for this
> sensor in drivers/misc/bmp085.
>
> So I wrote a patch series to bring the features of the IIO driver
> on par with the misc driver, and beyond it:
>
> - The first patch set stuff augmenting DT bindings and adding
> regulators and a reset GPIO.
>
> - Split transport from core driver (separate I2C module)
>
> - Added SPI support (which I cannot test, grateful for any help,
> but pretty sure it works).
>
> - Support for the BMP085 EOC interrupt mechanism rather than
> waiting for the conversion to happen.
>
> - Do not re-read calibration data all the time, also toss the
> calibration into the entropy pool.
>
> After this I think the misc driver can be replaced with this
> driver, but I'd love to hear from the maintainers of that driver
> if I've missed something. One of the patches adds all the authors
> of the misc driver listed there as I can clearly see code was
> copied into this driver at several points.
>
> The only thing missing from the misc driver is the sysfs
> interface. If there is real userspace out there using it, we
> can implement a compatibility sysfs ABI. But then I'd like
> to know what userspace it is, so I can test it.
Ok looks okay overall but you are dropping my BME280 part changes here
-> https://git.kernel.org/cgit/linux/kernel/git/jic23/iio.git/commit/?h=testing&id=14beaa8f5ab11b881c5e822e2474f5278d0946d5
>
> 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 optional 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 the BMP058 EOC interrupt
> iio: pressure: bmp280: read calibration data once
>
> .../devicetree/bindings/iio/pressure/bmp085.txt | 11 +-
> drivers/iio/pressure/Kconfig | 27 +-
> drivers/iio/pressure/Makefile | 3 +
> drivers/iio/pressure/{bmp280.c => bmp280-core.c} | 428 ++++++++-------------
> drivers/iio/pressure/bmp280-i2c.c | 79 ++++
> drivers/iio/pressure/bmp280-regmap.c | 78 ++++
> drivers/iio/pressure/bmp280-spi.c | 79 ++++
> drivers/iio/pressure/bmp280.h | 86 +++++
> 8 files changed, 526 insertions(+), 265 deletions(-)
> rename drivers/iio/pressure/{bmp280.c => bmp280-core.c} (70%)
> create mode 100644 drivers/iio/pressure/bmp280-i2c.c
> create mode 100644 drivers/iio/pressure/bmp280-regmap.c
> create mode 100644 drivers/iio/pressure/bmp280-spi.c
> create mode 100644 drivers/iio/pressure/bmp280.h
>
> --
> 2.4.11
>
> --
> 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] 18+ messages in thread* Re: [PATCH 0/9] iio: bmp280: improve driver
2016-06-22 7:31 ` Matt Ranostay
@ 2016-06-22 15:18 ` Linus Walleij
2016-06-22 19:15 ` Linus Walleij
0 siblings, 1 reply; 18+ messages in thread
From: Linus Walleij @ 2016-06-22 15:18 UTC (permalink / raw)
To: Matt Ranostay
Cc: Jonathan Cameron, linux-iio@vger.kernel.org, Akinobu Mita,
Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
H. Nikolaus Schaller, Eric Andersson, Neil Brown
On Wed, Jun 22, 2016 at 9:31 AM, Matt Ranostay <mranostay@gmail.com> wrote:
> Ok looks okay overall but you are dropping my BME280 part changes here
> -> https://git.kernel.org/cgit/linux/kernel/git/jic23/iio.git/commit/?h=testing&id=14beaa8f5ab11b881c5e822e2474f5278d0946d5
I'm not the maintainer of this driver, so I have not looked to see if
there are new patches for it around. My patches are simply based
on mainline.
Do you want me to include this patch in my patch series and
push towards Jonathan?
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 0/9] iio: bmp280: improve driver
2016-06-22 15:18 ` Linus Walleij
@ 2016-06-22 19:15 ` Linus Walleij
0 siblings, 0 replies; 18+ messages in thread
From: Linus Walleij @ 2016-06-22 19:15 UTC (permalink / raw)
To: Matt Ranostay
Cc: Jonathan Cameron, linux-iio@vger.kernel.org, Akinobu Mita,
Christoph Mair, Vlad Dogaru, Hartmut Knaack, Marek Belisko,
H. Nikolaus Schaller, Eric Andersson, Neil Brown
On Wed, Jun 22, 2016 at 5:18 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Wed, Jun 22, 2016 at 9:31 AM, Matt Ranostay <mranostay@gmail.com> wrote:
>
>> Ok looks okay overall but you are dropping my BME280 part changes here
>> -> https://git.kernel.org/cgit/linux/kernel/git/jic23/iio.git/commit/?h=testing&id=14beaa8f5ab11b881c5e822e2474f5278d0946d5
>
> I'm not the maintainer of this driver, so I have not looked to see if
> there are new patches for it around. My patches are simply based
> on mainline.
>
> Do you want me to include this patch in my patch series and
> push towards Jonathan?
Aha I see there is stuff queued in Jonathan's tree that I need to rebase
on. OK I will base a revised patch series on Jonathan's iio-for-4.8a
branch.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 18+ messages in thread