Skip to content

Commit 4241665

Browse files
vamoiridjic23
authored andcommitted
iio: chemical: bme680: Fix sensor data read operation
A read operation is happening as follows: a) Set sensor to forced mode b) Sensor measures values and update data registers and sleeps again c) Read data registers In the current implementation the read operation happens immediately after the sensor is set to forced mode so the sensor does not have the time to update properly the registers. This leads to the following 2 problems: 1) The first ever value which is read by the register is always wrong 2) Every read operation, puts the register into forced mode and reads the data that were calculated in the previous conversion. This behaviour was tested in 2 ways: 1) The internal meas_status_0 register was read before and after every read operation in order to verify that the data were ready even before the register was set to forced mode and also to check that after the forced mode was set the new data were not yet ready. 2) Physically changing the temperature and measuring the temperature This commit adds the waiting time in between the set of the forced mode and the read of the data. The function is taken from the Bosch BME68x Sensor API [1]. [1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490 Fixes: 1b3bd85 ("iio: chemical: Add support for Bosch BME680 sensor") Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com> Link: https://lore.kernel.org/r/20240606212313.207550-5-vassilisamir@gmail.com Cc: <Stable@vger.kernel.org> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
1 parent fdd478c commit 4241665

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

drivers/iio/chemical/bme680.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@
5454
#define BME680_NB_CONV_MASK GENMASK(3, 0)
5555

5656
#define BME680_REG_MEAS_STAT_0 0x1D
57+
#define BME680_NEW_DATA_BIT BIT(7)
5758
#define BME680_GAS_MEAS_BIT BIT(6)
59+
#define BME680_MEAS_BIT BIT(5)
5860

5961
/* Calibration Parameters */
6062
#define BME680_T2_LSB_REG 0x8A

drivers/iio/chemical/bme680_core.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*/
1111
#include <linux/acpi.h>
1212
#include <linux/bitfield.h>
13+
#include <linux/delay.h>
1314
#include <linux/device.h>
1415
#include <linux/module.h>
1516
#include <linux/log2.h>
@@ -532,6 +533,43 @@ static u8 bme680_oversampling_to_reg(u8 val)
532533
return ilog2(val) + 1;
533534
}
534535

536+
/*
537+
* Taken from Bosch BME680 API:
538+
* https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490
539+
*/
540+
static int bme680_wait_for_eoc(struct bme680_data *data)
541+
{
542+
struct device *dev = regmap_get_device(data->regmap);
543+
unsigned int check;
544+
int ret;
545+
/*
546+
* (Sum of oversampling ratios * time per oversampling) +
547+
* TPH measurement + gas measurement + wait transition from forced mode
548+
* + heater duration
549+
*/
550+
int wait_eoc_us = ((data->oversampling_temp + data->oversampling_press +
551+
data->oversampling_humid) * 1936) + (477 * 4) +
552+
(477 * 5) + 1000 + (data->heater_dur * 1000);
553+
554+
usleep_range(wait_eoc_us, wait_eoc_us + 100);
555+
556+
ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check);
557+
if (ret) {
558+
dev_err(dev, "failed to read measurement status register.\n");
559+
return ret;
560+
}
561+
if (check & BME680_MEAS_BIT) {
562+
dev_err(dev, "Device measurement cycle incomplete.\n");
563+
return -EBUSY;
564+
}
565+
if (!(check & BME680_NEW_DATA_BIT)) {
566+
dev_err(dev, "No new data available from the device.\n");
567+
return -ENODATA;
568+
}
569+
570+
return 0;
571+
}
572+
535573
static int bme680_chip_config(struct bme680_data *data)
536574
{
537575
struct device *dev = regmap_get_device(data->regmap);
@@ -622,6 +660,10 @@ static int bme680_read_temp(struct bme680_data *data, int *val)
622660
if (ret < 0)
623661
return ret;
624662

663+
ret = bme680_wait_for_eoc(data);
664+
if (ret)
665+
return ret;
666+
625667
ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB,
626668
&tmp, 3);
627669
if (ret < 0) {
@@ -738,6 +780,10 @@ static int bme680_read_gas(struct bme680_data *data,
738780
if (ret < 0)
739781
return ret;
740782

783+
ret = bme680_wait_for_eoc(data);
784+
if (ret)
785+
return ret;
786+
741787
ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check);
742788
if (check & BME680_GAS_MEAS_BIT) {
743789
dev_err(dev, "gas measurement incomplete\n");

0 commit comments

Comments
 (0)