Based on fixes-togreg as the 4 first commits are already applied
Patch 1/15: Added comment for explanation of what mutex is used for
Patch 2/15: Removed fixes tag
Patch 3-15/15: Reworded the commit messages to come close to convention
of 75 chars per line.
v2: https://lore.kernel.org/linux-iio/[email protected]/
Patch 4/19:
- Combined the bme680_conversion_time_us() and bme680_wait_for_eoc()
into one function.
- Added better comment for the calculation.
- Added checks in the bme680_wait_for_eoc() function.
Patch 5/19:
- Fixed typo in commit message.
Patch 6/19:
- Added a fixes tag since without the mutexes, read operations can be
broken.
Patch 10/19:
- Converted shifting operation to FIELD_GET()
Patch 11/19:
- Changed convention from &data->bufer[0] to data->buffer.
- Removed IIO_DMA_MINALIGN as it is not needed anymore.
Patch 13/19:
- Removed IIO_DMA_MINALIGN
Patch 14/19:
- Splitted from Patch v1 14/19
Patch 15/19:
- Splitted from Patch v1 14/19
Patch 16/19: **NEW**
- Use dev_err_probe() where applicable.
v1: https://lore.kernel.org/linux-iio/[email protected]/
This started as a series to add support for buffers and the new
BME688 but it ended up being just a cleaning series. These might
be quite some patches for such a thing but I feel that they are
are well split, in order to allow for better review.
The patches are mostly small changes but essential for the correct use
of the driver. The first patches looked like fixes that should be
marked for the stable. Patches [11,17/17] might be a bit bigger but 11/17
is quite straightforward and 17/17 is basically a duplication of a
very similar commit coming from the BMP280 driver [1].
In general, the datasheet [2] of the driver is not very descriptive,
and it redirects the user to the BME68x Sensor API [3]. All the things
that were identified from the BME68x Sensor API have been marked with
links to the original locations of the GitHub code. If this is too much
and we don't want this type of information on the commit message, please
let me know and I will fix it.
[1]: https://lore.kernel.org/linux-iio/[email protected]/T/#mc6f814e9a4f8c2b39015909d174c7013b3648b9b
[2]: https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme680-ds001.pdf
[3]: https://github.com/boschsensortec/BME68x_SensorAPI/tree/master
Vasileios Amoiridis (15):
iio: chemical: bme680: Fix read/write ops to device by adding mutexes
iio: chemical: bme680: Fix typo in define
iio: chemical: bme680: Drop unnecessary casts and correct adc data
types
iio: chemical: bme680: Remove remaining ACPI-only stuff
iio: chemical: bme680: Sort headers alphabetically
iio: chemical: bme680: Remove duplicate register read
iio: chemical: bme680: Use bulk reads for calibration data
iio: chemical: bme680: Allocate IIO device before chip initialization
iio: chemical: bme680: Add read buffers in read/write buffer union
iio: chemical: bme680: Make error checks consistent
iio: chemical: bme680: Modify startup procedure
iio: chemical: bme680: Move probe errors to dev_err_probe()
iio: chemical: bme680: Remove redundant gas configuration
iio: chemical: bme680: Move forced mode setup in ->read_raw()
iio: chemical: bme680: Refactorize reading functions
drivers/iio/chemical/bme680.h | 41 +-
drivers/iio/chemical/bme680_core.c | 631 +++++++++++++----------------
2 files changed, 291 insertions(+), 381 deletions(-)
base-commit: 4241665e6ea063a9c1d734de790121a71db763fc
--
2.25.1
Add mutexes in the {read/write}_raw() functions of the device to guard the
read/write of data from/to the device. This is necessary because for any
operation other than temperature, multiple reads need to take place from
the device. Even though regmap has a locking by itself, it won't protect us
from multiple applications trying to read at the same time temperature and
pressure since the pressure reading includes an internal temperature
reading and there is nothing to ensure that this temperature+pressure
reading will happen sequentially without any other operation interfering
in the meantime.
Fixes: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor")
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680_core.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 500f56834b01..a6bf689833da 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -10,6 +10,7 @@
*/
#include <linux/acpi.h>
#include <linux/bitfield.h>
+#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/module.h>
@@ -52,6 +53,7 @@ struct bme680_calib {
struct bme680_data {
struct regmap *regmap;
struct bme680_calib bme680;
+ struct mutex lock; /* Protect multiple serial R/W ops to device. */
u8 oversampling_temp;
u8 oversampling_press;
u8 oversampling_humid;
@@ -827,6 +829,8 @@ static int bme680_read_raw(struct iio_dev *indio_dev,
{
struct bme680_data *data = iio_priv(indio_dev);
+ guard(mutex)(&data->lock);
+
switch (mask) {
case IIO_CHAN_INFO_PROCESSED:
switch (chan->type) {
@@ -871,6 +875,8 @@ static int bme680_write_raw(struct iio_dev *indio_dev,
{
struct bme680_data *data = iio_priv(indio_dev);
+ guard(mutex)(&data->lock);
+
if (val2 != 0)
return -EINVAL;
@@ -967,6 +973,7 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
name = bme680_match_acpi_device(dev);
data = iio_priv(indio_dev);
+ mutex_init(&data->lock);
dev_set_drvdata(dev, indio_dev);
data->regmap = regmap;
indio_dev->name = name;
--
2.25.1
Fix a define typo that instead of BME680_... it is saying BM6880_...
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680.h | 2 +-
drivers/iio/chemical/bme680_core.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/chemical/bme680.h b/drivers/iio/chemical/bme680.h
index f959252a4fe6..c51bf2bdf504 100644
--- a/drivers/iio/chemical/bme680.h
+++ b/drivers/iio/chemical/bme680.h
@@ -12,7 +12,7 @@
#define BME680_REG_TEMP_MSB 0x22
#define BME680_REG_PRESS_MSB 0x1F
-#define BM6880_REG_HUMIDITY_MSB 0x25
+#define BME680_REG_HUMIDITY_MSB 0x25
#define BME680_REG_GAS_MSB 0x2A
#define BME680_REG_GAS_R_LSB 0x2B
#define BME680_GAS_STAB_BIT BIT(4)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index a6bf689833da..c1a9ead1397e 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -740,7 +740,7 @@ static int bme680_read_humid(struct bme680_data *data,
if (ret < 0)
return ret;
- ret = regmap_bulk_read(data->regmap, BM6880_REG_HUMIDITY_MSB,
+ ret = regmap_bulk_read(data->regmap, BME680_REG_HUMIDITY_MSB,
&tmp, sizeof(tmp));
if (ret < 0) {
dev_err(dev, "failed to read humidity\n");
--
2.25.1
Delete any redundant casts in the code and use unsigned integers for the
raw adc values.
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680_core.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index c1a9ead1397e..577237d4c9f3 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -335,7 +335,7 @@ static int bme680_read_calib(struct bme680_data *data,
* output value of "3233" represents 32.33 DegC.
*/
static s16 bme680_compensate_temp(struct bme680_data *data,
- s32 adc_temp)
+ u32 adc_temp)
{
struct bme680_calib *calib = &data->bme680;
s64 var1, var2, var3;
@@ -345,7 +345,7 @@ static s16 bme680_compensate_temp(struct bme680_data *data,
if (!calib->par_t2)
bme680_read_calib(data, calib);
- var1 = (adc_temp >> 3) - ((s32)calib->par_t1 << 1);
+ var1 = ((s32)adc_temp >> 3) - ((s32)calib->par_t1 << 1);
var2 = (var1 * calib->par_t2) >> 11;
var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
var3 = (var3 * ((s32)calib->par_t3 << 4)) >> 14;
@@ -410,9 +410,9 @@ static u32 bme680_compensate_humid(struct bme680_data *data,
s32 var1, var2, var3, var4, var5, var6, temp_scaled, calc_hum;
temp_scaled = (data->t_fine * 5 + 128) >> 8;
- var1 = (adc_humid - ((s32) ((s32) calib->par_h1 * 16))) -
- (((temp_scaled * (s32) calib->par_h3) / 100) >> 1);
- var2 = ((s32) calib->par_h2 *
+ var1 = (adc_humid - (((s32)calib->par_h1 * 16))) -
+ (((temp_scaled * calib->par_h3) / 100) >> 1);
+ var2 = (calib->par_h2 *
(((temp_scaled * calib->par_h4) / 100) +
(((temp_scaled * ((temp_scaled * calib->par_h5) / 100))
>> 6) / 100) + (1 << 14))) >> 10;
@@ -654,7 +654,7 @@ static int bme680_read_temp(struct bme680_data *data, int *val)
struct device *dev = regmap_get_device(data->regmap);
int ret;
__be32 tmp = 0;
- s32 adc_temp;
+ u32 adc_temp;
s16 comp_temp;
/* set forced mode to trigger measurement */
@@ -700,7 +700,7 @@ static int bme680_read_press(struct bme680_data *data,
struct device *dev = regmap_get_device(data->regmap);
int ret;
__be32 tmp = 0;
- s32 adc_press;
+ u32 adc_press;
/* Read and compensate temperature to get a reading of t_fine */
ret = bme680_read_temp(data, NULL);
@@ -732,7 +732,7 @@ static int bme680_read_humid(struct bme680_data *data,
struct device *dev = regmap_get_device(data->regmap);
int ret;
__be16 tmp = 0;
- s32 adc_humidity;
+ u16 adc_humidity;
u32 comp_humidity;
/* Read and compensate temperature to get a reading of t_fine */
--
2.25.1
The ACPI ID table was removed with the following 2 commits:
Commit b73d21dccf68 ("iio: bme680_i2c: Remove acpi_device_id table")
Commit f0e4057e97c1 ("iio: bme680_spi: Remove acpi_device_id table")
Remove the remaining ACPI related stuff to this driver since they are
not directly used.
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680_core.c | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 577237d4c9f3..1d2d5920fb23 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -8,7 +8,6 @@
* Datasheet:
* https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME680-DS001-00.pdf
*/
-#include <linux/acpi.h>
#include <linux/bitfield.h>
#include <linux/cleanup.h>
#include <linux/delay.h>
@@ -927,17 +926,6 @@ static const struct iio_info bme680_info = {
.attrs = &bme680_attribute_group,
};
-static const char *bme680_match_acpi_device(struct device *dev)
-{
- const struct acpi_device_id *id;
-
- id = acpi_match_device(dev->driver->acpi_match_table, dev);
- if (!id)
- return NULL;
-
- return dev_name(dev);
-}
-
int bme680_core_probe(struct device *dev, struct regmap *regmap,
const char *name)
{
@@ -969,9 +957,6 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
if (!indio_dev)
return -ENOMEM;
- if (!name && ACPI_HANDLE(dev))
- name = bme680_match_acpi_device(dev);
-
data = iio_priv(indio_dev);
mutex_init(&data->lock);
dev_set_drvdata(dev, indio_dev);
--
2.25.1
Sort headers in alphabetical order and split the iio specific functions
with a blank line
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680_core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 1d2d5920fb23..72bd5445b6c0 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -12,9 +12,10 @@
#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/device.h>
-#include <linux/module.h>
#include <linux/log2.h>
+#include <linux/module.h>
#include <linux/regmap.h>
+
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
--
2.25.1
The LSB of the gas register was read first to check if the following
check was correct and then the MSB+LSB were read together. Simplify this
by reading together the MSB+LSB immediately.
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680.h | 2 +-
drivers/iio/chemical/bme680_core.c | 21 ++++++++-------------
2 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/iio/chemical/bme680.h b/drivers/iio/chemical/bme680.h
index c51bf2bdf504..b5f16ca81e70 100644
--- a/drivers/iio/chemical/bme680.h
+++ b/drivers/iio/chemical/bme680.h
@@ -46,7 +46,7 @@
#define BME680_RSERROR_MASK GENMASK(7, 4)
#define BME680_REG_RES_HEAT_0 0x5A
#define BME680_REG_GAS_WAIT_0 0x64
-#define BME680_ADC_GAS_RES_SHIFT 6
+#define BME680_ADC_GAS_RES GENMASK(15, 6)
#define BME680_AMB_TEMP 25
#define BME680_REG_CTRL_GAS_1 0x71
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 72bd5445b6c0..9660ec3854a1 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -767,7 +767,7 @@ static int bme680_read_gas(struct bme680_data *data,
int ret;
__be16 tmp = 0;
unsigned int check;
- u16 adc_gas_res;
+ u16 adc_gas_res, gas_regs_val;
u8 gas_range;
/* Set heater settings */
@@ -792,11 +792,14 @@ static int bme680_read_gas(struct bme680_data *data,
return -EBUSY;
}
- ret = regmap_read(data->regmap, BME680_REG_GAS_R_LSB, &check);
+ ret = regmap_bulk_read(data->regmap, BME680_REG_GAS_MSB,
+ &tmp, sizeof(tmp));
if (ret < 0) {
- dev_err(dev, "failed to read gas_r_lsb register\n");
+ dev_err(dev, "failed to read gas resistance\n");
return ret;
}
+ gas_regs_val = be16_to_cpu(tmp);
+ adc_gas_res = FIELD_GET(BME680_ADC_GAS_RES, gas_regs_val);
/*
* occurs if either the gas heating duration was insuffient
@@ -804,20 +807,12 @@ static int bme680_read_gas(struct bme680_data *data,
* heater temperature was too high for the heater sink to
* reach.
*/
- if ((check & BME680_GAS_STAB_BIT) == 0) {
+ if ((gas_regs_val & BME680_GAS_STAB_BIT) == 0) {
dev_err(dev, "heater failed to reach the target temperature\n");
return -EINVAL;
}
- ret = regmap_bulk_read(data->regmap, BME680_REG_GAS_MSB,
- &tmp, sizeof(tmp));
- if (ret < 0) {
- dev_err(dev, "failed to read gas resistance\n");
- return ret;
- }
-
- gas_range = check & BME680_GAS_RANGE_MASK;
- adc_gas_res = be16_to_cpu(tmp) >> BME680_ADC_GAS_RES_SHIFT;
+ gas_range = FIELD_GET(BME680_GAS_RANGE_MASK, gas_regs_val);
*val = bme680_compensate_gas(data, adc_gas_res, gas_range);
return IIO_VAL_INT;
--
2.25.1
Move the IIO device allocation before the actual initialization of the
chip to be more consistent with most IIO drivers and also to have the
ability to use any driver specific data for the chip initialization.
While at it, fix also a misaligned line.
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680_core.c | 38 +++++++++++++++---------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 493d190f4461..7dfe4bf2f2ae 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -837,25 +837,6 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
unsigned int val;
int ret;
- ret = regmap_write(regmap, BME680_REG_SOFT_RESET,
- BME680_CMD_SOFTRESET);
- if (ret < 0) {
- dev_err(dev, "Failed to reset chip\n");
- return ret;
- }
-
- ret = regmap_read(regmap, BME680_REG_CHIP_ID, &val);
- if (ret < 0) {
- dev_err(dev, "Error reading chip ID\n");
- return ret;
- }
-
- if (val != BME680_CHIP_ID_VAL) {
- dev_err(dev, "Wrong chip ID, got %x expected %x\n",
- val, BME680_CHIP_ID_VAL);
- return -ENODEV;
- }
-
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
@@ -877,6 +858,25 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
data->heater_temp = 320; /* degree Celsius */
data->heater_dur = 150; /* milliseconds */
+ ret = regmap_write(regmap, BME680_REG_SOFT_RESET,
+ BME680_CMD_SOFTRESET);
+ if (ret < 0) {
+ dev_err(dev, "Failed to reset chip\n");
+ return ret;
+ }
+
+ ret = regmap_read(regmap, BME680_REG_CHIP_ID, &val);
+ if (ret < 0) {
+ dev_err(dev, "Error reading chip ID\n");
+ return ret;
+ }
+
+ if (val != BME680_CHIP_ID_VAL) {
+ dev_err(dev, "Wrong chip ID, got %x expected %x\n",
+ val, BME680_CHIP_ID_VAL);
+ return -ENODEV;
+ }
+
ret = bme680_chip_config(data);
if (ret < 0) {
dev_err(dev, "failed to set chip_config data\n");
--
2.25.1
Calibration data are located in contiguous-ish registers inside the chip.
For that reason we can use bulk reads as is done as well in the BME68x
Sensor API [1].
The arrays that are used for reading the data out of the sensor
are located inside DMA safe buffer.
Link: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L1769 # [1]
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680.h | 28 +--
drivers/iio/chemical/bme680_core.c | 279 ++++++++++-------------------
2 files changed, 97 insertions(+), 210 deletions(-)
diff --git a/drivers/iio/chemical/bme680.h b/drivers/iio/chemical/bme680.h
index b5f16ca81e70..8d0f53c05d7d 100644
--- a/drivers/iio/chemical/bme680.h
+++ b/drivers/iio/chemical/bme680.h
@@ -39,10 +39,8 @@
#define BME680_HUM_REG_SHIFT_VAL 4
#define BME680_BIT_H1_DATA_MASK GENMASK(3, 0)
-#define BME680_REG_RES_HEAT_RANGE 0x02
#define BME680_RHRANGE_MASK GENMASK(5, 4)
#define BME680_REG_RES_HEAT_VAL 0x00
-#define BME680_REG_RANGE_SW_ERR 0x04
#define BME680_RSERROR_MASK GENMASK(7, 4)
#define BME680_REG_RES_HEAT_0 0x5A
#define BME680_REG_GAS_WAIT_0 0x64
@@ -60,31 +58,13 @@
/* Calibration Parameters */
#define BME680_T2_LSB_REG 0x8A
-#define BME680_T3_REG 0x8C
-#define BME680_P1_LSB_REG 0x8E
-#define BME680_P2_LSB_REG 0x90
-#define BME680_P3_REG 0x92
-#define BME680_P4_LSB_REG 0x94
-#define BME680_P5_LSB_REG 0x96
-#define BME680_P7_REG 0x98
-#define BME680_P6_REG 0x99
-#define BME680_P8_LSB_REG 0x9C
-#define BME680_P9_LSB_REG 0x9E
-#define BME680_P10_REG 0xA0
-#define BME680_H2_LSB_REG 0xE2
#define BME680_H2_MSB_REG 0xE1
-#define BME680_H1_MSB_REG 0xE3
-#define BME680_H1_LSB_REG 0xE2
-#define BME680_H3_REG 0xE4
-#define BME680_H4_REG 0xE5
-#define BME680_H5_REG 0xE6
-#define BME680_H6_REG 0xE7
-#define BME680_H7_REG 0xE8
-#define BME680_T1_LSB_REG 0xE9
-#define BME680_GH2_LSB_REG 0xEB
-#define BME680_GH1_REG 0xED
#define BME680_GH3_REG 0xEE
+#define BME680_CALIB_RANGE_1_LEN 23
+#define BME680_CALIB_RANGE_2_LEN 14
+#define BME680_CALIB_RANGE_3_LEN 5
+
extern const struct regmap_config bme680_regmap_config;
int bme680_core_probe(struct device *dev, struct regmap *regmap,
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 9660ec3854a1..493d190f4461 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -19,8 +19,53 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <asm/unaligned.h>
+
#include "bme680.h"
+/* 1st set of calibration data */
+enum {
+ /* Temperature calib indexes */
+ T2_LSB = 0,
+ T3 = 2,
+ /* Pressure calib indexes */
+ P1_LSB = 4,
+ P2_LSB = 6,
+ P3 = 8,
+ P4_LSB = 10,
+ P5_LSB = 12,
+ P7 = 14,
+ P6 = 15,
+ P8_LSB = 18,
+ P9_LSB = 20,
+ P10 = 22,
+};
+
+/* 2nd set of calibration data */
+enum {
+ /* Humidity calib indexes */
+ H2_MSB = 0,
+ H1_LSB = 1,
+ H3 = 3,
+ H4 = 4,
+ H5 = 5,
+ H6 = 6,
+ H7 = 7,
+ /* Stray T1 calib index */
+ T1_LSB = 8,
+ /* Gas heater calib indexes */
+ GH2_LSB = 10,
+ GH1 = 12,
+ GH3 = 13,
+};
+
+/* 3rd set of calibration data */
+enum {
+ RES_HEAT_VAL = 0,
+ RES_HEAT_RANGE = 2,
+ RANGE_SW_ERR = 4,
+};
+
struct bme680_calib {
u16 par_t1;
s16 par_t2;
@@ -64,6 +109,12 @@ struct bme680_data {
* and humidity compensation calculations.
*/
s32 t_fine;
+
+ union {
+ u8 bme680_cal_buf_1[BME680_CALIB_RANGE_1_LEN];
+ u8 bme680_cal_buf_2[BME680_CALIB_RANGE_2_LEN];
+ u8 bme680_cal_buf_3[BME680_CALIB_RANGE_3_LEN];
+ };
};
static const struct regmap_range bme680_volatile_ranges[] = {
@@ -112,217 +163,73 @@ static int bme680_read_calib(struct bme680_data *data,
struct bme680_calib *calib)
{
struct device *dev = regmap_get_device(data->regmap);
- unsigned int tmp, tmp_msb, tmp_lsb;
+ unsigned int tmp_msb, tmp_lsb;
int ret;
- __le16 buf;
-
- /* Temperature related coefficients */
- ret = regmap_bulk_read(data->regmap, BME680_T1_LSB_REG,
- &buf, sizeof(buf));
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_T1_LSB_REG\n");
- return ret;
- }
- calib->par_t1 = le16_to_cpu(buf);
ret = regmap_bulk_read(data->regmap, BME680_T2_LSB_REG,
- &buf, sizeof(buf));
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_T2_LSB_REG\n");
- return ret;
- }
- calib->par_t2 = le16_to_cpu(buf);
-
- ret = regmap_read(data->regmap, BME680_T3_REG, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_T3_REG\n");
- return ret;
- }
- calib->par_t3 = tmp;
-
- /* Pressure related coefficients */
- ret = regmap_bulk_read(data->regmap, BME680_P1_LSB_REG,
- &buf, sizeof(buf));
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_P1_LSB_REG\n");
- return ret;
- }
- calib->par_p1 = le16_to_cpu(buf);
-
- ret = regmap_bulk_read(data->regmap, BME680_P2_LSB_REG,
- &buf, sizeof(buf));
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_P2_LSB_REG\n");
- return ret;
- }
- calib->par_p2 = le16_to_cpu(buf);
-
- ret = regmap_read(data->regmap, BME680_P3_REG, &tmp);
+ data->bme680_cal_buf_1,
+ sizeof(data->bme680_cal_buf_1));
if (ret < 0) {
- dev_err(dev, "failed to read BME680_P3_REG\n");
+ dev_err(dev, "failed to read 1st set of calib data;\n");
return ret;
}
- calib->par_p3 = tmp;
- ret = regmap_bulk_read(data->regmap, BME680_P4_LSB_REG,
- &buf, sizeof(buf));
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_P4_LSB_REG\n");
- return ret;
- }
- calib->par_p4 = le16_to_cpu(buf);
+ calib->par_t2 = get_unaligned_le16(&data->bme680_cal_buf_1[T2_LSB]);
+ calib->par_t3 = data->bme680_cal_buf_1[T3];
+ calib->par_p1 = get_unaligned_le16(&data->bme680_cal_buf_1[P1_LSB]);
+ calib->par_p2 = get_unaligned_le16(&data->bme680_cal_buf_1[P2_LSB]);
+ calib->par_p3 = data->bme680_cal_buf_1[P3];
+ calib->par_p4 = get_unaligned_le16(&data->bme680_cal_buf_1[P4_LSB]);
+ calib->par_p5 = get_unaligned_le16(&data->bme680_cal_buf_1[P5_LSB]);
+ calib->par_p7 = data->bme680_cal_buf_1[P7];
+ calib->par_p6 = data->bme680_cal_buf_1[P6];
+ calib->par_p8 = get_unaligned_le16(&data->bme680_cal_buf_1[P8_LSB]);
+ calib->par_p9 = get_unaligned_le16(&data->bme680_cal_buf_1[P9_LSB]);
+ calib->par_p10 = data->bme680_cal_buf_1[P10];
- ret = regmap_bulk_read(data->regmap, BME680_P5_LSB_REG,
- &buf, sizeof(buf));
+ ret = regmap_bulk_read(data->regmap, BME680_H2_MSB_REG,
+ data->bme680_cal_buf_2,
+ sizeof(data->bme680_cal_buf_2));
if (ret < 0) {
- dev_err(dev, "failed to read BME680_P5_LSB_REG\n");
+ dev_err(dev, "failed to read 2nd set of calib data;\n");
return ret;
}
- calib->par_p5 = le16_to_cpu(buf);
- ret = regmap_read(data->regmap, BME680_P6_REG, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_P6_REG\n");
- return ret;
- }
- calib->par_p6 = tmp;
-
- ret = regmap_read(data->regmap, BME680_P7_REG, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_P7_REG\n");
- return ret;
- }
- calib->par_p7 = tmp;
-
- ret = regmap_bulk_read(data->regmap, BME680_P8_LSB_REG,
- &buf, sizeof(buf));
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_P8_LSB_REG\n");
- return ret;
- }
- calib->par_p8 = le16_to_cpu(buf);
-
- ret = regmap_bulk_read(data->regmap, BME680_P9_LSB_REG,
- &buf, sizeof(buf));
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_P9_LSB_REG\n");
- return ret;
- }
- calib->par_p9 = le16_to_cpu(buf);
-
- ret = regmap_read(data->regmap, BME680_P10_REG, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_P10_REG\n");
- return ret;
- }
- calib->par_p10 = tmp;
-
- /* Humidity related coefficients */
- ret = regmap_read(data->regmap, BME680_H1_MSB_REG, &tmp_msb);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_H1_MSB_REG\n");
- return ret;
- }
- ret = regmap_read(data->regmap, BME680_H1_LSB_REG, &tmp_lsb);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_H1_LSB_REG\n");
- return ret;
- }
+ tmp_lsb = data->bme680_cal_buf_2[H1_LSB];
+ tmp_msb = data->bme680_cal_buf_2[H1_LSB + 1];
calib->par_h1 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) |
(tmp_lsb & BME680_BIT_H1_DATA_MASK);
- ret = regmap_read(data->regmap, BME680_H2_MSB_REG, &tmp_msb);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_H2_MSB_REG\n");
- return ret;
- }
- ret = regmap_read(data->regmap, BME680_H2_LSB_REG, &tmp_lsb);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_H2_LSB_REG\n");
- return ret;
- }
+ tmp_msb = data->bme680_cal_buf_2[H2_MSB];
+ tmp_lsb = data->bme680_cal_buf_2[H2_MSB + 1];
calib->par_h2 = (tmp_msb << BME680_HUM_REG_SHIFT_VAL) |
(tmp_lsb >> BME680_HUM_REG_SHIFT_VAL);
- ret = regmap_read(data->regmap, BME680_H3_REG, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_H3_REG\n");
- return ret;
- }
- calib->par_h3 = tmp;
+ calib->par_h3 = data->bme680_cal_buf_2[H3];
+ calib->par_h4 = data->bme680_cal_buf_2[H4];
+ calib->par_h5 = data->bme680_cal_buf_2[H5];
+ calib->par_h6 = data->bme680_cal_buf_2[H6];
+ calib->par_h7 = data->bme680_cal_buf_2[H7];
+ calib->par_t1 = get_unaligned_le16(&data->bme680_cal_buf_2[T1_LSB]);
+ calib->par_gh2 = get_unaligned_le16(&data->bme680_cal_buf_2[GH2_LSB]);
+ calib->par_gh1 = data->bme680_cal_buf_2[GH1];
+ calib->par_gh3 = data->bme680_cal_buf_2[GH3];
- ret = regmap_read(data->regmap, BME680_H4_REG, &tmp);
+ ret = regmap_bulk_read(data->regmap, BME680_REG_RES_HEAT_VAL,
+ data->bme680_cal_buf_3,
+ sizeof(data->bme680_cal_buf_3));
if (ret < 0) {
- dev_err(dev, "failed to read BME680_H4_REG\n");
+ dev_err(dev, "failed to read 3rd set of calib data;\n");
return ret;
}
- calib->par_h4 = tmp;
- ret = regmap_read(data->regmap, BME680_H5_REG, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_H5_REG\n");
- return ret;
- }
- calib->par_h5 = tmp;
+ calib->res_heat_val = data->bme680_cal_buf_3[RES_HEAT_VAL];
- ret = regmap_read(data->regmap, BME680_H6_REG, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_H6_REG\n");
- return ret;
- }
- calib->par_h6 = tmp;
+ calib->res_heat_range = FIELD_GET(BME680_RHRANGE_MASK,
+ data->bme680_cal_buf_3[RES_HEAT_RANGE]);
- ret = regmap_read(data->regmap, BME680_H7_REG, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_H7_REG\n");
- return ret;
- }
- calib->par_h7 = tmp;
-
- /* Gas heater related coefficients */
- ret = regmap_read(data->regmap, BME680_GH1_REG, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_GH1_REG\n");
- return ret;
- }
- calib->par_gh1 = tmp;
-
- ret = regmap_bulk_read(data->regmap, BME680_GH2_LSB_REG,
- &buf, sizeof(buf));
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_GH2_LSB_REG\n");
- return ret;
- }
- calib->par_gh2 = le16_to_cpu(buf);
-
- ret = regmap_read(data->regmap, BME680_GH3_REG, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read BME680_GH3_REG\n");
- return ret;
- }
- calib->par_gh3 = tmp;
-
- /* Other coefficients */
- ret = regmap_read(data->regmap, BME680_REG_RES_HEAT_RANGE, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read resistance heat range\n");
- return ret;
- }
- calib->res_heat_range = FIELD_GET(BME680_RHRANGE_MASK, tmp);
-
- ret = regmap_read(data->regmap, BME680_REG_RES_HEAT_VAL, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read resistance heat value\n");
- return ret;
- }
- calib->res_heat_val = tmp;
-
- ret = regmap_read(data->regmap, BME680_REG_RANGE_SW_ERR, &tmp);
- if (ret < 0) {
- dev_err(dev, "failed to read range software error\n");
- return ret;
- }
- calib->range_sw_err = FIELD_GET(BME680_RSERROR_MASK, tmp);
+ calib->range_sw_err = FIELD_GET(BME680_RSERROR_MASK,
+ data->bme680_cal_buf_3[RANGE_SW_ERR]);
return 0;
}
--
2.25.1
Move the buffers that are used in order to read data from the device in
the union which handles all the device read/write buffers. Also create
defines for the number of bytes that are being read from the device and
don't use magic numbers.
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680.h | 7 +++++
drivers/iio/chemical/bme680_core.c | 45 +++++++++++++++---------------
2 files changed, 29 insertions(+), 23 deletions(-)
diff --git a/drivers/iio/chemical/bme680.h b/drivers/iio/chemical/bme680.h
index 8d0f53c05d7d..7d0ff294725a 100644
--- a/drivers/iio/chemical/bme680.h
+++ b/drivers/iio/chemical/bme680.h
@@ -56,6 +56,13 @@
#define BME680_GAS_MEAS_BIT BIT(6)
#define BME680_MEAS_BIT BIT(5)
+#define BME680_TEMP_NUM_BYTES 3
+#define BME680_PRESS_NUM_BYTES 3
+#define BME680_HUMID_NUM_BYTES 2
+#define BME680_GAS_NUM_BYTES 2
+
+#define BME680_MEAS_TRIM_MASK GENMASK(24, 4)
+
/* Calibration Parameters */
#define BME680_T2_LSB_REG 0x8A
#define BME680_H2_MSB_REG 0xE1
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 7dfe4bf2f2ae..415816a6cc9b 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -111,6 +111,9 @@ struct bme680_data {
s32 t_fine;
union {
+ u8 buf[3];
+ unsigned int check;
+ __be16 be16;
u8 bme680_cal_buf_1[BME680_CALIB_RANGE_1_LEN];
u8 bme680_cal_buf_2[BME680_CALIB_RANGE_2_LEN];
u8 bme680_cal_buf_3[BME680_CALIB_RANGE_3_LEN];
@@ -449,7 +452,6 @@ static u8 bme680_oversampling_to_reg(u8 val)
static int bme680_wait_for_eoc(struct bme680_data *data)
{
struct device *dev = regmap_get_device(data->regmap);
- unsigned int check;
int ret;
/*
* (Sum of oversampling ratios * time per oversampling) +
@@ -462,16 +464,16 @@ static int bme680_wait_for_eoc(struct bme680_data *data)
usleep_range(wait_eoc_us, wait_eoc_us + 100);
- ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check);
+ ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &data->check);
if (ret) {
dev_err(dev, "failed to read measurement status register.\n");
return ret;
}
- if (check & BME680_MEAS_BIT) {
+ if (data->check & BME680_MEAS_BIT) {
dev_err(dev, "Device measurement cycle incomplete.\n");
return -EBUSY;
}
- if (!(check & BME680_NEW_DATA_BIT)) {
+ if (!(data->check & BME680_NEW_DATA_BIT)) {
dev_err(dev, "No new data available from the device.\n");
return -ENODATA;
}
@@ -560,7 +562,6 @@ static int bme680_read_temp(struct bme680_data *data, int *val)
{
struct device *dev = regmap_get_device(data->regmap);
int ret;
- __be32 tmp = 0;
u32 adc_temp;
s16 comp_temp;
@@ -574,13 +575,14 @@ static int bme680_read_temp(struct bme680_data *data, int *val)
return ret;
ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB,
- &tmp, 3);
+ data->buf, BME680_TEMP_NUM_BYTES);
if (ret < 0) {
dev_err(dev, "failed to read temperature\n");
return ret;
}
- adc_temp = be32_to_cpu(tmp) >> 12;
+ adc_temp = FIELD_GET(BME680_MEAS_TRIM_MASK,
+ get_unaligned_be24(data->buf));
if (adc_temp == BME680_MEAS_SKIPPED) {
/* reading was skipped */
dev_err(dev, "reading temperature skipped\n");
@@ -606,7 +608,6 @@ static int bme680_read_press(struct bme680_data *data,
{
struct device *dev = regmap_get_device(data->regmap);
int ret;
- __be32 tmp = 0;
u32 adc_press;
/* Read and compensate temperature to get a reading of t_fine */
@@ -615,13 +616,14 @@ static int bme680_read_press(struct bme680_data *data,
return ret;
ret = regmap_bulk_read(data->regmap, BME680_REG_PRESS_MSB,
- &tmp, 3);
+ data->buf, BME680_PRESS_NUM_BYTES);
if (ret < 0) {
dev_err(dev, "failed to read pressure\n");
return ret;
}
- adc_press = be32_to_cpu(tmp) >> 12;
+ adc_press = FIELD_GET(BME680_MEAS_TRIM_MASK,
+ get_unaligned_be24(data->buf));
if (adc_press == BME680_MEAS_SKIPPED) {
/* reading was skipped */
dev_err(dev, "reading pressure skipped\n");
@@ -638,7 +640,6 @@ static int bme680_read_humid(struct bme680_data *data,
{
struct device *dev = regmap_get_device(data->regmap);
int ret;
- __be16 tmp = 0;
u16 adc_humidity;
u32 comp_humidity;
@@ -648,13 +649,13 @@ static int bme680_read_humid(struct bme680_data *data,
return ret;
ret = regmap_bulk_read(data->regmap, BME680_REG_HUMIDITY_MSB,
- &tmp, sizeof(tmp));
+ &data->be16, BME680_HUMID_NUM_BYTES);
if (ret < 0) {
dev_err(dev, "failed to read humidity\n");
return ret;
}
- adc_humidity = be16_to_cpu(tmp);
+ adc_humidity = be16_to_cpu(data->be16);
if (adc_humidity == BME680_MEAS_SKIPPED) {
/* reading was skipped */
dev_err(dev, "reading humidity skipped\n");
@@ -672,8 +673,6 @@ static int bme680_read_gas(struct bme680_data *data,
{
struct device *dev = regmap_get_device(data->regmap);
int ret;
- __be16 tmp = 0;
- unsigned int check;
u16 adc_gas_res, gas_regs_val;
u8 gas_range;
@@ -693,19 +692,20 @@ static int bme680_read_gas(struct bme680_data *data,
if (ret)
return ret;
- ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check);
- if (check & BME680_GAS_MEAS_BIT) {
+ ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &data->check);
+ if (data->check & BME680_GAS_MEAS_BIT) {
dev_err(dev, "gas measurement incomplete\n");
return -EBUSY;
}
ret = regmap_bulk_read(data->regmap, BME680_REG_GAS_MSB,
- &tmp, sizeof(tmp));
+ &data->be16, BME680_GAS_NUM_BYTES);
if (ret < 0) {
dev_err(dev, "failed to read gas resistance\n");
return ret;
}
- gas_regs_val = be16_to_cpu(tmp);
+
+ gas_regs_val = be16_to_cpu(data->be16);
adc_gas_res = FIELD_GET(BME680_ADC_GAS_RES, gas_regs_val);
/*
@@ -834,7 +834,6 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
{
struct iio_dev *indio_dev;
struct bme680_data *data;
- unsigned int val;
int ret;
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
@@ -865,15 +864,15 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
return ret;
}
- ret = regmap_read(regmap, BME680_REG_CHIP_ID, &val);
+ ret = regmap_read(regmap, BME680_REG_CHIP_ID, &data->check);
if (ret < 0) {
dev_err(dev, "Error reading chip ID\n");
return ret;
}
- if (val != BME680_CHIP_ID_VAL) {
+ if (data->check != BME680_CHIP_ID_VAL) {
dev_err(dev, "Wrong chip ID, got %x expected %x\n",
- val, BME680_CHIP_ID_VAL);
+ data->check, BME680_CHIP_ID_VAL);
return -ENODEV;
}
--
2.25.1
In the majority of the error checks after a regmap_{read,write}()
operation the following coding style is used:
ret = regmap_{read,write}(data->regmap, ...);
if (ret < 0) {
dev_err(dev, ...);
return ret;
}
In this particular case it was different so change it for consistency.
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680_core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 415816a6cc9b..a54460fddc91 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -517,10 +517,12 @@ static int bme680_chip_config(struct bme680_data *data)
ret = regmap_write_bits(data->regmap, BME680_REG_CTRL_MEAS,
BME680_OSRS_TEMP_MASK | BME680_OSRS_PRESS_MASK,
osrs);
- if (ret < 0)
+ if (ret < 0) {
dev_err(dev, "failed to write ctrl_meas register\n");
+ return ret;
+ }
- return ret;
+ return 0;
}
static int bme680_gas_config(struct bme680_data *data)
--
2.25.1
Modify the startup procedure to reflect the procedure of the Bosch BME68x
Sensor API. The initial readings and configuration of the sensor need to
happen in the following order:
1) Read calibration data [1,2]
2) Chip general configuration [3]
3) Gas configuration [4]
After the chip configuration it is necessary to ensure that the sensor is
in sleeping mode, in order to apply the gas configuration settings [5].
Also, after the soft reset, it is advised to wait for 5ms [6].
Link: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L162 # [1]
Link: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/examples/forced_mode/forced_mode.c#L44 # [2]
Link: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/examples/forced_mode/forced_mode.c#L53 # [3]
Link: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/examples/forced_mode/forced_mode.c#L60 # [4]
Link: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L640 # [5]
Link: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L294 # [6]
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680.h | 2 ++
drivers/iio/chemical/bme680_core.c | 21 ++++++++++++++-------
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/chemical/bme680.h b/drivers/iio/chemical/bme680.h
index 7d0ff294725a..b2c547ac8d34 100644
--- a/drivers/iio/chemical/bme680.h
+++ b/drivers/iio/chemical/bme680.h
@@ -63,6 +63,8 @@
#define BME680_MEAS_TRIM_MASK GENMASK(24, 4)
+#define BME680_STARTUP_TIME_US 5000
+
/* Calibration Parameters */
#define BME680_T2_LSB_REG 0x8A
#define BME680_H2_MSB_REG 0xE1
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index a54460fddc91..0390c298fdd8 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -531,6 +531,11 @@ static int bme680_gas_config(struct bme680_data *data)
int ret;
u8 heatr_res, heatr_dur;
+ /* Go to sleep */
+ ret = bme680_set_mode(data, false);
+ if (ret < 0)
+ return ret;
+
heatr_res = bme680_calc_heater_res(data, data->heater_temp);
/* set target heater temperature */
@@ -866,6 +871,8 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
return ret;
}
+ usleep_range(BME680_STARTUP_TIME_US, BME680_STARTUP_TIME_US + 1000);
+
ret = regmap_read(regmap, BME680_REG_CHIP_ID, &data->check);
if (ret < 0) {
dev_err(dev, "Error reading chip ID\n");
@@ -878,22 +885,22 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
return -ENODEV;
}
- ret = bme680_chip_config(data);
+ ret = bme680_read_calib(data, &data->bme680);
if (ret < 0) {
- dev_err(dev, "failed to set chip_config data\n");
+ dev_err(dev,
+ "failed to read calibration coefficients at probe\n");
return ret;
}
- ret = bme680_gas_config(data);
+ ret = bme680_chip_config(data);
if (ret < 0) {
- dev_err(dev, "failed to set gas config data\n");
+ dev_err(dev, "failed to set chip_config data\n");
return ret;
}
- ret = bme680_read_calib(data, &data->bme680);
+ ret = bme680_gas_config(data);
if (ret < 0) {
- dev_err(dev,
- "failed to read calibration coefficients at probe\n");
+ dev_err(dev, "failed to set gas config data\n");
return ret;
}
--
2.25.1
There are multiple cases in the probe function that dev_err_probe() fits
the needs, so use it.
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680_core.c | 29 +++++++++++------------------
1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 0390c298fdd8..b357871ef601 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -866,18 +866,14 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
ret = regmap_write(regmap, BME680_REG_SOFT_RESET,
BME680_CMD_SOFTRESET);
- if (ret < 0) {
- dev_err(dev, "Failed to reset chip\n");
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to reset chip\n");
usleep_range(BME680_STARTUP_TIME_US, BME680_STARTUP_TIME_US + 1000);
ret = regmap_read(regmap, BME680_REG_CHIP_ID, &data->check);
- if (ret < 0) {
- dev_err(dev, "Error reading chip ID\n");
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Error reading chip ID\n");
if (data->check != BME680_CHIP_ID_VAL) {
dev_err(dev, "Wrong chip ID, got %x expected %x\n",
@@ -887,22 +883,19 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
ret = bme680_read_calib(data, &data->bme680);
if (ret < 0) {
- dev_err(dev,
+ return dev_err_probe(dev, ret,
"failed to read calibration coefficients at probe\n");
- return ret;
}
ret = bme680_chip_config(data);
- if (ret < 0) {
- dev_err(dev, "failed to set chip_config data\n");
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(dev, ret,
+ "failed to set chip_config data\n");
ret = bme680_gas_config(data);
- if (ret < 0) {
- dev_err(dev, "failed to set gas config data\n");
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(dev, ret,
+ "failed to set gas config data\n");
return devm_iio_device_register(dev, indio_dev);
}
--
2.25.1
There is no need to explicitly configure the gas measurement registers
every time a gas measurement takes place. These are initial configurations
which are written in the beginning and they are not changed throughout
the lifetime of the driver.
If in the future, the device starts to support multiple configuration
profiles with variable heater duration and heater temperature, then they
could become members of the ->read_avail().
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680_core.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index b357871ef601..d08f32ecd139 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -683,13 +683,6 @@ static int bme680_read_gas(struct bme680_data *data,
u16 adc_gas_res, gas_regs_val;
u8 gas_range;
- /* Set heater settings */
- ret = bme680_gas_config(data);
- if (ret < 0) {
- dev_err(dev, "failed to set gas config\n");
- return ret;
- }
-
/* set forced mode to trigger measurement */
ret = bme680_set_mode(data, true);
if (ret < 0)
--
2.25.1
Whenever the sensor is set to forced mode, a TPHG cycle is triggered and
the values of temperature, pressure, humidity and gas become ready to be
read.
The setup of the forced mode to trigger measurements was located inside
the read_{temp/gas}() functions. This was not posing a functional problem
since read_{humid/press}() are internally calling read_temp() so the
forced mode is set through this call.
This is not very clear and it is kind of hidden that regardless of the
measurement, the setup of the forced mode needs to happen before any
measurement.
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680_core.c | 28 ++++++++++------------------
1 file changed, 10 insertions(+), 18 deletions(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index d08f32ecd139..3785b4d014db 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -572,15 +572,6 @@ static int bme680_read_temp(struct bme680_data *data, int *val)
u32 adc_temp;
s16 comp_temp;
- /* set forced mode to trigger measurement */
- ret = bme680_set_mode(data, true);
- if (ret < 0)
- return ret;
-
- ret = bme680_wait_for_eoc(data);
- if (ret)
- return ret;
-
ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB,
data->buf, BME680_TEMP_NUM_BYTES);
if (ret < 0) {
@@ -683,15 +674,6 @@ static int bme680_read_gas(struct bme680_data *data,
u16 adc_gas_res, gas_regs_val;
u8 gas_range;
- /* set forced mode to trigger measurement */
- ret = bme680_set_mode(data, true);
- if (ret < 0)
- return ret;
-
- ret = bme680_wait_for_eoc(data);
- if (ret)
- return ret;
-
ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &data->check);
if (data->check & BME680_GAS_MEAS_BIT) {
dev_err(dev, "gas measurement incomplete\n");
@@ -730,9 +712,19 @@ static int bme680_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
{
struct bme680_data *data = iio_priv(indio_dev);
+ int ret;
guard(mutex)(&data->lock);
+ /* set forced mode to trigger measurement */
+ ret = bme680_set_mode(data, true);
+ if (ret < 0)
+ return ret;
+
+ ret = bme680_wait_for_eoc(data);
+ if (ret)
+ return ret;
+
switch (mask) {
case IIO_CHAN_INFO_PROCESSED:
switch (chan->type) {
--
2.25.1
The reading of the pressure and humidity value, requires an update of the
t_fine variable which happens by reading the temperature value.
So the bme680_read_{press/humid}() functions of the above sensors are
internally calling the equivalent bme680_read_temp() function in order to
update the t_fine value. By just looking at the code this relation is a
bit hidden and is not easy to understand why those channels are not
independent.
This commit tries to clear these thing a bit by splitting the
bme680_{read/compensate}_{temp/press/humid}() to the following:
i. bme680_read_{temp/press/humid}_adc(): read the raw value from the
sensor.
ii. bme680_calc_t_fine(): calculate the t_fine variable.
iii. bme680_get_t_fine(): get the t_fine variable.
iv. bme680_compensate_{temp/press/humid}(): compensate the adc values and
return the calculated value.
v. bme680_read_{temp/press/humid}(): combine calls of the aforementioned
functions to return the requested value.
Signed-off-by: Vasileios Amoiridis <[email protected]>
---
drivers/iio/chemical/bme680_core.c | 192 +++++++++++++++++------------
1 file changed, 116 insertions(+), 76 deletions(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 3785b4d014db..74ac887d8d8e 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -104,11 +104,6 @@ struct bme680_data {
u8 oversampling_humid;
u16 heater_dur;
u16 heater_temp;
- /*
- * Carryover value from temperature conversion, used in pressure
- * and humidity compensation calculations.
- */
- s32 t_fine;
union {
u8 buf[3];
@@ -237,6 +232,31 @@ static int bme680_read_calib(struct bme680_data *data,
return 0;
}
+static int bme680_read_temp_adc(struct bme680_data *data, u32 *adc_temp)
+{
+ struct device *dev = regmap_get_device(data->regmap);
+ u32 value_temp;
+ int ret;
+
+ ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB,
+ data->buf, BME680_TEMP_NUM_BYTES);
+ if (ret < 0) {
+ dev_err(dev, "failed to read temperature\n");
+ return ret;
+ }
+
+ value_temp = FIELD_GET(BME680_MEAS_TRIM_MASK,
+ get_unaligned_be24(data->buf));
+ if (value_temp == BME680_MEAS_SKIPPED) {
+ /* reading was skipped */
+ dev_err(dev, "reading temperature skipped\n");
+ return -EINVAL;
+ }
+ *adc_temp = value_temp;
+
+ return 0;
+}
+
/*
* Taken from Bosch BME680 API:
* https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L876
@@ -244,12 +264,10 @@ static int bme680_read_calib(struct bme680_data *data,
* Returns temperature measurement in DegC, resolutions is 0.01 DegC. Therefore,
* output value of "3233" represents 32.33 DegC.
*/
-static s16 bme680_compensate_temp(struct bme680_data *data,
- u32 adc_temp)
+static s32 bme680_calc_t_fine(struct bme680_data *data, u32 adc_temp)
{
struct bme680_calib *calib = &data->bme680;
s64 var1, var2, var3;
- s16 calc_temp;
/* If the calibration is invalid, attempt to reload it */
if (!calib->par_t2)
@@ -259,10 +277,52 @@ static s16 bme680_compensate_temp(struct bme680_data *data,
var2 = (var1 * calib->par_t2) >> 11;
var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
var3 = (var3 * ((s32)calib->par_t3 << 4)) >> 14;
- data->t_fine = var2 + var3;
- calc_temp = (data->t_fine * 5 + 128) >> 8;
+ return var2 + var3; /* t_fine = var2 + var3 */
+}
+
+static int bme680_get_t_fine(struct bme680_data *data, s32 *t_fine)
+{
+ u32 adc_temp;
+ int ret;
+
+ ret = bme680_read_temp_adc(data, &adc_temp);
+ if (ret)
+ return ret;
+
+ *t_fine = bme680_calc_t_fine(data, adc_temp);
+
+ return 0;
+}
- return calc_temp;
+static s16 bme680_compensate_temp(struct bme680_data *data,
+ u32 adc_temp)
+{
+ return (bme680_calc_t_fine(data, adc_temp) * 5 + 128) / 256;
+}
+
+static int bme680_read_press_adc(struct bme680_data *data, u32 *adc_press)
+{
+ struct device *dev = regmap_get_device(data->regmap);
+ u32 value_press;
+ int ret;
+
+ ret = regmap_bulk_read(data->regmap, BME680_REG_PRESS_MSB,
+ data->buf, BME680_PRESS_NUM_BYTES);
+ if (ret < 0) {
+ dev_err(dev, "failed to read pressure\n");
+ return ret;
+ }
+
+ value_press = FIELD_GET(BME680_MEAS_TRIM_MASK,
+ get_unaligned_be24(data->buf));
+ if (value_press == BME680_MEAS_SKIPPED) {
+ /* reading was skipped */
+ dev_err(dev, "reading pressure skipped\n");
+ return -EINVAL;
+ }
+ *adc_press = value_press;
+
+ return 0;
}
/*
@@ -273,12 +333,12 @@ static s16 bme680_compensate_temp(struct bme680_data *data,
* 97356 Pa = 973.56 hPa.
*/
static u32 bme680_compensate_press(struct bme680_data *data,
- u32 adc_press)
+ u32 adc_press, s32 t_fine)
{
struct bme680_calib *calib = &data->bme680;
s32 var1, var2, var3, press_comp;
- var1 = (data->t_fine >> 1) - 64000;
+ var1 = (t_fine >> 1) - 64000;
var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calib->par_p6) >> 2;
var2 = var2 + (var1 * calib->par_p5 << 1);
var2 = (var2 >> 2) + ((s32)calib->par_p4 << 16);
@@ -306,6 +366,30 @@ static u32 bme680_compensate_press(struct bme680_data *data,
return press_comp;
}
+static int bme680_read_humid_adc(struct bme680_data *data, u32 *adc_humidity)
+{
+ struct device *dev = regmap_get_device(data->regmap);
+ u32 value_humidity;
+ int ret;
+
+ ret = regmap_bulk_read(data->regmap, BME680_REG_HUMIDITY_MSB,
+ &data->be16, BME680_HUMID_NUM_BYTES);
+ if (ret < 0) {
+ dev_err(dev, "failed to read humidity\n");
+ return ret;
+ }
+
+ value_humidity = be16_to_cpu(data->be16);
+ if (value_humidity == BME680_MEAS_SKIPPED) {
+ /* reading was skipped */
+ dev_err(dev, "reading humidity skipped\n");
+ return -EINVAL;
+ }
+ *adc_humidity = value_humidity;
+
+ return 0;
+}
+
/*
* Taken from Bosch BME680 API:
* https://github.com/BoschSensortec/BME680_driver/blob/63bb5336/bme680.c#L937
@@ -314,12 +398,12 @@ static u32 bme680_compensate_press(struct bme680_data *data,
* value of "43215" represents 43.215 %rH.
*/
static u32 bme680_compensate_humid(struct bme680_data *data,
- u16 adc_humid)
+ u16 adc_humid, s32 t_fine)
{
struct bme680_calib *calib = &data->bme680;
s32 var1, var2, var3, var4, var5, var6, temp_scaled, calc_hum;
- temp_scaled = (data->t_fine * 5 + 128) >> 8;
+ temp_scaled = (t_fine * 5 + 128) >> 8;
var1 = (adc_humid - (((s32)calib->par_h1 * 16))) -
(((temp_scaled * calib->par_h3) / 100) >> 1);
var2 = (calib->par_h2 *
@@ -567,68 +651,35 @@ static int bme680_gas_config(struct bme680_data *data)
static int bme680_read_temp(struct bme680_data *data, int *val)
{
- struct device *dev = regmap_get_device(data->regmap);
int ret;
u32 adc_temp;
s16 comp_temp;
- ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB,
- data->buf, BME680_TEMP_NUM_BYTES);
- if (ret < 0) {
- dev_err(dev, "failed to read temperature\n");
+ ret = bme680_read_temp_adc(data, &adc_temp);
+ if (ret)
return ret;
- }
- adc_temp = FIELD_GET(BME680_MEAS_TRIM_MASK,
- get_unaligned_be24(data->buf));
- if (adc_temp == BME680_MEAS_SKIPPED) {
- /* reading was skipped */
- dev_err(dev, "reading temperature skipped\n");
- return -EINVAL;
- }
comp_temp = bme680_compensate_temp(data, adc_temp);
- /*
- * val might be NULL if we're called by the read_press/read_humid
- * routine which is called to get t_fine value used in
- * compensate_press/compensate_humid to get compensated
- * pressure/humidity readings.
- */
- if (val) {
- *val = comp_temp * 10; /* Centidegrees to millidegrees */
- return IIO_VAL_INT;
- }
-
- return ret;
+ *val = comp_temp * 10; /* Centidegrees to millidegrees */
+ return IIO_VAL_INT;
}
static int bme680_read_press(struct bme680_data *data,
int *val, int *val2)
{
- struct device *dev = regmap_get_device(data->regmap);
int ret;
u32 adc_press;
+ s32 t_fine;
- /* Read and compensate temperature to get a reading of t_fine */
- ret = bme680_read_temp(data, NULL);
- if (ret < 0)
+ ret = bme680_get_t_fine(data, &t_fine);
+ if (ret)
return ret;
- ret = regmap_bulk_read(data->regmap, BME680_REG_PRESS_MSB,
- data->buf, BME680_PRESS_NUM_BYTES);
- if (ret < 0) {
- dev_err(dev, "failed to read pressure\n");
+ ret = bme680_read_press_adc(data, &adc_press);
+ if (ret)
return ret;
- }
-
- adc_press = FIELD_GET(BME680_MEAS_TRIM_MASK,
- get_unaligned_be24(data->buf));
- if (adc_press == BME680_MEAS_SKIPPED) {
- /* reading was skipped */
- dev_err(dev, "reading pressure skipped\n");
- return -EINVAL;
- }
- *val = bme680_compensate_press(data, adc_press);
+ *val = bme680_compensate_press(data, adc_press, t_fine);
*val2 = 1000;
return IIO_VAL_FRACTIONAL;
}
@@ -636,30 +687,19 @@ static int bme680_read_press(struct bme680_data *data,
static int bme680_read_humid(struct bme680_data *data,
int *val, int *val2)
{
- struct device *dev = regmap_get_device(data->regmap);
int ret;
- u16 adc_humidity;
- u32 comp_humidity;
+ u32 adc_humidity, comp_humidity;
+ s32 t_fine;
- /* Read and compensate temperature to get a reading of t_fine */
- ret = bme680_read_temp(data, NULL);
- if (ret < 0)
+ ret = bme680_get_t_fine(data, &t_fine);
+ if (ret)
return ret;
- ret = regmap_bulk_read(data->regmap, BME680_REG_HUMIDITY_MSB,
- &data->be16, BME680_HUMID_NUM_BYTES);
- if (ret < 0) {
- dev_err(dev, "failed to read humidity\n");
+ ret = bme680_read_humid_adc(data, &adc_humidity);
+ if (ret)
return ret;
- }
- adc_humidity = be16_to_cpu(data->be16);
- if (adc_humidity == BME680_MEAS_SKIPPED) {
- /* reading was skipped */
- dev_err(dev, "reading humidity skipped\n");
- return -EINVAL;
- }
- comp_humidity = bme680_compensate_humid(data, adc_humidity);
+ comp_humidity = bme680_compensate_humid(data, adc_humidity, t_fine);
*val = comp_humidity;
*val2 = 1000;
--
2.25.1