* [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup
@ 2024-06-06 21:22 Vasileios Amoiridis
2024-06-06 21:22 ` [PATCH v2 01/19] iio: chemical: bme680: Fix pressure value output Vasileios Amoiridis
` (20 more replies)
0 siblings, 21 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:22 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
Changes in v2:
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/20240527183805.311501-1-vassilisamir@gmail.com/
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/20240512230524.53990-1-vassilisamir@gmail.com/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 (19):
iio: chemical: bme680: Fix pressure value output
iio: chemical: bme680: Fix calibration data variable
iio: chemical: bme680: Fix overflows in compensate() functions
iio: chemical: bme680: Fix sensor data read operation
iio: chemical: bme680: Fix typo in define
iio: chemical: bme680: Fix read/write ops to device by adding mutexes
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 DMA safe region
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 | 43 +-
drivers/iio/chemical/bme680_core.c | 669 ++++++++++++++---------------
2 files changed, 337 insertions(+), 375 deletions(-)
base-commit: b3019fcdeb286b2cfe45e44bccb44dbcd8ff66dd
--
2.25.1
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 01/19] iio: chemical: bme680: Fix pressure value output
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
@ 2024-06-06 21:22 ` Vasileios Amoiridis
2024-06-09 11:00 ` Jonathan Cameron
2024-06-06 21:22 ` [PATCH v2 02/19] iio: chemical: bme680: Fix calibration data variable Vasileios Amoiridis
` (19 subsequent siblings)
20 siblings, 1 reply; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:22 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
The IIO standard units are measured in kPa while the driver
is using hPa.
Apart from checking the userspace value itself, it is mentioned also
in the Bosch API [1] that the pressure value is in Pascal.
[1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x_defs.h#L742
Fixes: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor")
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
drivers/iio/chemical/bme680_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index ef5e0e46fd34..2c40c13fe97a 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -678,7 +678,7 @@ static int bme680_read_press(struct bme680_data *data,
}
*val = bme680_compensate_press(data, adc_press);
- *val2 = 100;
+ *val2 = 1000;
return IIO_VAL_FRACTIONAL;
}
base-commit: b3019fcdeb286b2cfe45e44bccb44dbcd8ff66dd
--
2.25.1
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 02/19] iio: chemical: bme680: Fix calibration data variable
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
2024-06-06 21:22 ` [PATCH v2 01/19] iio: chemical: bme680: Fix pressure value output Vasileios Amoiridis
@ 2024-06-06 21:22 ` Vasileios Amoiridis
2024-06-09 11:00 ` Jonathan Cameron
2024-06-06 21:22 ` [PATCH v2 03/19] iio: chemical: bme680: Fix overflows in compensate() functions Vasileios Amoiridis
` (18 subsequent siblings)
20 siblings, 1 reply; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:22 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
According to the BME68x Sensor API [1], the h6 calibration
data variable should be an unsigned integer of size 8.
[1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x_defs.h#L789
Fixes: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor")
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
drivers/iio/chemical/bme680_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 2c40c13fe97a..812829841733 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -38,7 +38,7 @@ struct bme680_calib {
s8 par_h3;
s8 par_h4;
s8 par_h5;
- s8 par_h6;
+ u8 par_h6;
s8 par_h7;
s8 par_gh1;
s16 par_gh2;
--
2.25.1
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 03/19] iio: chemical: bme680: Fix overflows in compensate() functions
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
2024-06-06 21:22 ` [PATCH v2 01/19] iio: chemical: bme680: Fix pressure value output Vasileios Amoiridis
2024-06-06 21:22 ` [PATCH v2 02/19] iio: chemical: bme680: Fix calibration data variable Vasileios Amoiridis
@ 2024-06-06 21:22 ` Vasileios Amoiridis
2024-06-09 11:01 ` Jonathan Cameron
2024-06-06 21:22 ` [PATCH v2 04/19] iio: chemical: bme680: Fix sensor data read operation Vasileios Amoiridis
` (17 subsequent siblings)
20 siblings, 1 reply; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:22 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
There are cases in the compensate functions of the driver that
there could be overflows of variables due to bit shifting ops.
These implications were initially discussed here [1] and they
were mentioned in log message of Commit 1b3bd8592780 ("iio:
chemical: Add support for Bosch BME680 sensor").
[1]: https://lore.kernel.org/linux-iio/20180728114028.3c1bbe81@archlinux/
Fixes: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor")
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
drivers/iio/chemical/bme680_core.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 812829841733..5db48f6d646c 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -342,10 +342,10 @@ static s16 bme680_compensate_temp(struct bme680_data *data,
if (!calib->par_t2)
bme680_read_calib(data, calib);
- var1 = (adc_temp >> 3) - (calib->par_t1 << 1);
+ var1 = (adc_temp >> 3) - ((s32)calib->par_t1 << 1);
var2 = (var1 * calib->par_t2) >> 11;
var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
- var3 = (var3 * (calib->par_t3 << 4)) >> 14;
+ var3 = (var3 * ((s32)calib->par_t3 << 4)) >> 14;
data->t_fine = var2 + var3;
calc_temp = (data->t_fine * 5 + 128) >> 8;
@@ -368,9 +368,9 @@ static u32 bme680_compensate_press(struct bme680_data *data,
var1 = (data->t_fine >> 1) - 64000;
var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calib->par_p6) >> 2;
var2 = var2 + (var1 * calib->par_p5 << 1);
- var2 = (var2 >> 2) + (calib->par_p4 << 16);
+ var2 = (var2 >> 2) + ((s32)calib->par_p4 << 16);
var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) *
- (calib->par_p3 << 5)) >> 3) +
+ ((s32)calib->par_p3 << 5)) >> 3) +
((calib->par_p2 * var1) >> 1);
var1 = var1 >> 18;
var1 = ((32768 + var1) * calib->par_p1) >> 15;
@@ -388,7 +388,7 @@ static u32 bme680_compensate_press(struct bme680_data *data,
var3 = ((press_comp >> 8) * (press_comp >> 8) *
(press_comp >> 8) * calib->par_p10) >> 17;
- press_comp += (var1 + var2 + var3 + (calib->par_p7 << 7)) >> 4;
+ press_comp += (var1 + var2 + var3 + ((s32)calib->par_p7 << 7)) >> 4;
return press_comp;
}
@@ -414,7 +414,7 @@ static u32 bme680_compensate_humid(struct bme680_data *data,
(((temp_scaled * ((temp_scaled * calib->par_h5) / 100))
>> 6) / 100) + (1 << 14))) >> 10;
var3 = var1 * var2;
- var4 = calib->par_h6 << 7;
+ var4 = (s32)calib->par_h6 << 7;
var4 = (var4 + ((temp_scaled * calib->par_h7) / 100)) >> 4;
var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
var6 = (var4 * var5) >> 1;
--
2.25.1
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 04/19] iio: chemical: bme680: Fix sensor data read operation
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (2 preceding siblings ...)
2024-06-06 21:22 ` [PATCH v2 03/19] iio: chemical: bme680: Fix overflows in compensate() functions Vasileios Amoiridis
@ 2024-06-06 21:22 ` Vasileios Amoiridis
2024-06-09 11:03 ` Jonathan Cameron
2024-06-06 21:22 ` [PATCH v2 05/19] iio: chemical: bme680: Fix typo in define Vasileios Amoiridis
` (16 subsequent siblings)
20 siblings, 1 reply; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:22 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor")
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
drivers/iio/chemical/bme680.h | 2 ++
drivers/iio/chemical/bme680_core.c | 46 ++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/drivers/iio/chemical/bme680.h b/drivers/iio/chemical/bme680.h
index 4edc5d21cb9f..f959252a4fe6 100644
--- a/drivers/iio/chemical/bme680.h
+++ b/drivers/iio/chemical/bme680.h
@@ -54,7 +54,9 @@
#define BME680_NB_CONV_MASK GENMASK(3, 0)
#define BME680_REG_MEAS_STAT_0 0x1D
+#define BME680_NEW_DATA_BIT BIT(7)
#define BME680_GAS_MEAS_BIT BIT(6)
+#define BME680_MEAS_BIT BIT(5)
/* Calibration Parameters */
#define BME680_T2_LSB_REG 0x8A
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 5db48f6d646c..500f56834b01 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/delay.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/log2.h>
@@ -532,6 +533,43 @@ static u8 bme680_oversampling_to_reg(u8 val)
return ilog2(val) + 1;
}
+/*
+ * Taken from Bosch BME680 API:
+ * https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490
+ */
+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) +
+ * TPH measurement + gas measurement + wait transition from forced mode
+ * + heater duration
+ */
+ int wait_eoc_us = ((data->oversampling_temp + data->oversampling_press +
+ data->oversampling_humid) * 1936) + (477 * 4) +
+ (477 * 5) + 1000 + (data->heater_dur * 1000);
+
+ usleep_range(wait_eoc_us, wait_eoc_us + 100);
+
+ ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check);
+ if (ret) {
+ dev_err(dev, "failed to read measurement status register.\n");
+ return ret;
+ }
+ if (check & BME680_MEAS_BIT) {
+ dev_err(dev, "Device measurement cycle incomplete.\n");
+ return -EBUSY;
+ }
+ if (!(check & BME680_NEW_DATA_BIT)) {
+ dev_err(dev, "No new data available from the device.\n");
+ return -ENODATA;
+ }
+
+ return 0;
+}
+
static int bme680_chip_config(struct bme680_data *data)
{
struct device *dev = regmap_get_device(data->regmap);
@@ -622,6 +660,10 @@ static int bme680_read_temp(struct bme680_data *data, int *val)
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,
&tmp, 3);
if (ret < 0) {
@@ -738,6 +780,10 @@ static int bme680_read_gas(struct bme680_data *data,
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, &check);
if (check & BME680_GAS_MEAS_BIT) {
dev_err(dev, "gas measurement incomplete\n");
--
2.25.1
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 05/19] iio: chemical: bme680: Fix typo in define
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (3 preceding siblings ...)
2024-06-06 21:22 ` [PATCH v2 04/19] iio: chemical: bme680: Fix sensor data read operation Vasileios Amoiridis
@ 2024-06-06 21:22 ` Vasileios Amoiridis
2024-06-06 21:22 ` [PATCH v2 06/19] iio: chemical: bme680: Fix read/write ops to device by adding mutexes Vasileios Amoiridis
` (15 subsequent siblings)
20 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:22 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
Fix a define typo that instead of BME680_... it is
saying BM6880_...
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
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 500f56834b01..66177f7e94a8 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -738,7 +738,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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 06/19] iio: chemical: bme680: Fix read/write ops to device by adding mutexes
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (4 preceding siblings ...)
2024-06-06 21:22 ` [PATCH v2 05/19] iio: chemical: bme680: Fix typo in define Vasileios Amoiridis
@ 2024-06-06 21:22 ` Vasileios Amoiridis
2024-06-09 10:56 ` Jonathan Cameron
2024-06-06 21:22 ` [PATCH v2 07/19] iio: chemical: bme680: Drop unnecessary casts and correct adc data types Vasileios Amoiridis
` (14 subsequent siblings)
20 siblings, 1 reply; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:22 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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 <vassilisamir@gmail.com>
---
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 66177f7e94a8..92359032254a 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;
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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 07/19] iio: chemical: bme680: Drop unnecessary casts and correct adc data types
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (5 preceding siblings ...)
2024-06-06 21:22 ` [PATCH v2 06/19] iio: chemical: bme680: Fix read/write ops to device by adding mutexes Vasileios Amoiridis
@ 2024-06-06 21:22 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 08/19] iio: chemical: bme680: Remove remaining ACPI-only stuff Vasileios Amoiridis
` (13 subsequent siblings)
20 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:22 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
Delete any redundant casts in the code and use unsigned integers for
the raw adc values.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
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 92359032254a..acca2e516157 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 08/19] iio: chemical: bme680: Remove remaining ACPI-only stuff
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (6 preceding siblings ...)
2024-06-06 21:22 ` [PATCH v2 07/19] iio: chemical: bme680: Drop unnecessary casts and correct adc data types Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 09/19] iio: chemical: bme680: Sort headers alphabetically Vasileios Amoiridis
` (12 subsequent siblings)
20 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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 <vassilisamir@gmail.com>
---
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 acca2e516157..1956b456141d 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 09/19] iio: chemical: bme680: Sort headers alphabetically
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (7 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 08/19] iio: chemical: bme680: Remove remaining ACPI-only stuff Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 10/19] iio: chemical: bme680: Remove duplicate register read Vasileios Amoiridis
` (11 subsequent siblings)
20 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
Sort headers in alphabetical order and split the iio specific
functions with a blank line
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
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 1956b456141d..2466398aad05 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 10/19] iio: chemical: bme680: Remove duplicate register read
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (8 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 09/19] iio: chemical: bme680: Sort headers alphabetically Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 11/19] iio: chemical: bme680: Use bulk reads for calibration data Vasileios Amoiridis
` (10 subsequent siblings)
20 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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 <vassilisamir@gmail.com>
---
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 2466398aad05..c1e191ed4955 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 11/19] iio: chemical: bme680: Use bulk reads for calibration data
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (9 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 10/19] iio: chemical: bme680: Remove duplicate register read Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 12/19] iio: chemical: bme680: Allocate IIO device before chip initialization Vasileios Amoiridis
` (9 subsequent siblings)
20 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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.
[1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L1769
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
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 c1e191ed4955..f96cd4157c95 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 12/19] iio: chemical: bme680: Allocate IIO device before chip initialization
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (10 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 11/19] iio: chemical: bme680: Use bulk reads for calibration data Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in DMA safe region Vasileios Amoiridis
` (8 subsequent siblings)
20 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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 <vassilisamir@gmail.com>
---
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 f96cd4157c95..9d33952e5d01 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in DMA safe region
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (11 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 12/19] iio: chemical: bme680: Allocate IIO device before chip initialization Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-07 16:11 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in read/write buffer union Vasileios Amoiridis
` (7 subsequent siblings)
20 siblings, 1 reply; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
Move the buffers that are used in order to read data from the
device in a DMA-safe region. 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 <vassilisamir@gmail.com>
---
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 538696ac4205..99259d0cf13d 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -115,6 +115,9 @@ struct bme680_data {
* transfer buffers to live in their own cache lines.
*/
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];
@@ -453,7 +456,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) +
@@ -466,16 +468,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;
}
@@ -564,7 +566,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;
@@ -578,13 +579,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");
@@ -610,7 +612,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 */
@@ -619,13 +620,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");
@@ -642,7 +644,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;
@@ -652,13 +653,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");
@@ -676,8 +677,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;
@@ -697,19 +696,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);
/*
@@ -838,7 +838,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));
@@ -869,15 +868,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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in read/write buffer union
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (12 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in DMA safe region Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in union Vasileios Amoiridis
` (6 subsequent siblings)
20 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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 <vassilisamir@gmail.com>
---
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 9d33952e5d01..3c33c21b5d6a 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in union
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (13 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in read/write buffer union Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-07 16:12 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 14/19] iio: chemical: bme680: Make error checks consistent Vasileios Amoiridis
` (5 subsequent siblings)
20 siblings, 1 reply; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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 <vassilisamir@gmail.com>
---
drivers/iio/chemical/bme680.h | 7 +++++
drivers/iio/chemical/bme680_core.c | 47 +++++++++++++++---------------
2 files changed, 30 insertions(+), 24 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 b13797f7d873..3c33c21b5d6a 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -111,10 +111,13 @@ 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];
- };
+ };
};
static const struct regmap_range bme680_volatile_ranges[] = {
@@ -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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 14/19] iio: chemical: bme680: Make error checks consistent
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (14 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in union Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 15/19] iio: chemical: bme680: Modify startup procedure Vasileios Amoiridis
` (4 subsequent siblings)
20 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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 <vassilisamir@gmail.com>
---
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 3c33c21b5d6a..25d128e1ddcf 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 15/19] iio: chemical: bme680: Modify startup procedure
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (15 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 14/19] iio: chemical: bme680: Make error checks consistent Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-09 11:07 ` Jonathan Cameron
2024-06-06 21:23 ` [PATCH v2 16/19] iio: chemical: bme680: Move probe errors to dev_err_probe() Vasileios Amoiridis
` (3 subsequent siblings)
20 siblings, 1 reply; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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].
[1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L162
[2]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/examples/forced_mode/forced_mode.c#L44
[3]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/examples/forced_mode/forced_mode.c#L53
[4]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/examples/forced_mode/forced_mode.c#L60
[5]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L640
[6]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L294
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
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 25d128e1ddcf..e354eaa34d59 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 16/19] iio: chemical: bme680: Move probe errors to dev_err_probe()
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (16 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 15/19] iio: chemical: bme680: Modify startup procedure Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 17/19] iio: chemical: bme680: Remove redundant gas configuration Vasileios Amoiridis
` (2 subsequent siblings)
20 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
There are multiple cases in the probe function that dev_err_probe()
fits the needs, so use it.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
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 e354eaa34d59..1cf375904b8d 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 17/19] iio: chemical: bme680: Remove redundant gas configuration
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (17 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 16/19] iio: chemical: bme680: Move probe errors to dev_err_probe() Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-09 11:08 ` Jonathan Cameron
2024-06-06 21:23 ` [PATCH v2 18/19] iio: chemical: bme680: Move forced mode setup in ->read_raw() Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 19/19] iio: chemical: bme680: Refactorize reading functions Vasileios Amoiridis
20 siblings, 1 reply; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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 <vassilisamir@gmail.com>
---
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 1cf375904b8d..76b96993120f 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 18/19] iio: chemical: bme680: Move forced mode setup in ->read_raw()
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (18 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 17/19] iio: chemical: bme680: Remove redundant gas configuration Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 19/19] iio: chemical: bme680: Refactorize reading functions Vasileios Amoiridis
20 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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 <vassilisamir@gmail.com>
---
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 76b96993120f..b654a8cd31aa 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 19/19] iio: chemical: bme680: Refactorize reading functions
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
` (19 preceding siblings ...)
2024-06-06 21:23 ` [PATCH v2 18/19] iio: chemical: bme680: Move forced mode setup in ->read_raw() Vasileios Amoiridis
@ 2024-06-06 21:23 ` Vasileios Amoiridis
2024-06-09 11:12 ` Jonathan Cameron
20 siblings, 1 reply; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-06 21:23 UTC (permalink / raw)
To: jic23
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans, vassilisamir
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 <vassilisamir@gmail.com>
---
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 b654a8cd31aa..6d0069d2dfb2 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
^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in DMA safe region
2024-06-06 21:23 ` [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in DMA safe region Vasileios Amoiridis
@ 2024-06-07 16:11 ` Vasileios Amoiridis
0 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-07 16:11 UTC (permalink / raw)
To: Vasileios Amoiridis
Cc: jic23, dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans
On Thu, Jun 06, 2024 at 11:23:05PM +0200, Vasileios Amoiridis wrote:
> Move the buffers that are used in order to read data from the
> device in a DMA-safe region. Also create defines for the number
> of bytes that are being read from the device and don't use
> magic numbers.
>
Well this commit shouldn't have been here, I changed the title and
forgot to delete it from the folder...
Vasilis
> Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
> ---
> 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 538696ac4205..99259d0cf13d 100644
> --- a/drivers/iio/chemical/bme680_core.c
> +++ b/drivers/iio/chemical/bme680_core.c
> @@ -115,6 +115,9 @@ struct bme680_data {
> * transfer buffers to live in their own cache lines.
> */
> 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];
> @@ -453,7 +456,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) +
> @@ -466,16 +468,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;
> }
> @@ -564,7 +566,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;
>
> @@ -578,13 +579,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");
> @@ -610,7 +612,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 */
> @@ -619,13 +620,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");
> @@ -642,7 +644,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;
>
> @@ -652,13 +653,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");
> @@ -676,8 +677,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;
>
> @@ -697,19 +696,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);
>
> /*
> @@ -838,7 +838,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));
> @@ -869,15 +868,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
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in union
2024-06-06 21:23 ` [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in union Vasileios Amoiridis
@ 2024-06-07 16:12 ` Vasileios Amoiridis
0 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-07 16:12 UTC (permalink / raw)
To: Vasileios Amoiridis
Cc: jic23, dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans
On Thu, Jun 06, 2024 at 11:23:07PM +0200, Vasileios Amoiridis wrote:
> 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.
>
Also this shouldn't have been here for the same reason. Ah, should
have been more careful...
The rest are fine though, so let me know and I submit a v3 with any
new potential changes.
Vasilis
> Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
> ---
> drivers/iio/chemical/bme680.h | 7 +++++
> drivers/iio/chemical/bme680_core.c | 47 +++++++++++++++---------------
> 2 files changed, 30 insertions(+), 24 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 b13797f7d873..3c33c21b5d6a 100644
> --- a/drivers/iio/chemical/bme680_core.c
> +++ b/drivers/iio/chemical/bme680_core.c
> @@ -111,10 +111,13 @@ 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];
> - };
> + };
> };
>
> static const struct regmap_range bme680_volatile_ranges[] = {
> @@ -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
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 06/19] iio: chemical: bme680: Fix read/write ops to device by adding mutexes
2024-06-06 21:22 ` [PATCH v2 06/19] iio: chemical: bme680: Fix read/write ops to device by adding mutexes Vasileios Amoiridis
@ 2024-06-09 10:56 ` Jonathan Cameron
0 siblings, 0 replies; 33+ messages in thread
From: Jonathan Cameron @ 2024-06-09 10:56 UTC (permalink / raw)
To: Vasileios Amoiridis
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans
On Thu, 6 Jun 2024 23:22:58 +0200
Vasileios Amoiridis <vassilisamir@gmail.com> wrote:
> 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 <vassilisamir@gmail.com>
> ---
> 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 66177f7e94a8..92359032254a 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;
Comment needed here on what data this lock protects.
It is far to easy to make wrong assumptions about locks so convention is
to always document their scope.
Otherwise lgtm (as do patches 1-5)
> + struct mutex lock;
> 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;
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 01/19] iio: chemical: bme680: Fix pressure value output
2024-06-06 21:22 ` [PATCH v2 01/19] iio: chemical: bme680: Fix pressure value output Vasileios Amoiridis
@ 2024-06-09 11:00 ` Jonathan Cameron
0 siblings, 0 replies; 33+ messages in thread
From: Jonathan Cameron @ 2024-06-09 11:00 UTC (permalink / raw)
To: Vasileios Amoiridis
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans
On Thu, 6 Jun 2024 23:22:53 +0200
Vasileios Amoiridis <vassilisamir@gmail.com> wrote:
> The IIO standard units are measured in kPa while the driver
> is using hPa.
>
> Apart from checking the userspace value itself, it is mentioned also
> in the Bosch API [1] that the pressure value is in Pascal.
>
> [1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x_defs.h#L742
> Fixes: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor")
> Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Given we are early in the cycle I'm going to take the fixes via
the fixes-togreg branch of iio.git.
Thanks will slow down the rest a little but we still have time that
that should not matter and we'll get these fixes into stable much sooner.
Applied to the fixes-togreg branch of iio.git and marked for stable.
Thanks,
Jonathan
> ---
> drivers/iio/chemical/bme680_core.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
> index ef5e0e46fd34..2c40c13fe97a 100644
> --- a/drivers/iio/chemical/bme680_core.c
> +++ b/drivers/iio/chemical/bme680_core.c
> @@ -678,7 +678,7 @@ static int bme680_read_press(struct bme680_data *data,
> }
>
> *val = bme680_compensate_press(data, adc_press);
> - *val2 = 100;
> + *val2 = 1000;
> return IIO_VAL_FRACTIONAL;
> }
>
>
> base-commit: b3019fcdeb286b2cfe45e44bccb44dbcd8ff66dd
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 02/19] iio: chemical: bme680: Fix calibration data variable
2024-06-06 21:22 ` [PATCH v2 02/19] iio: chemical: bme680: Fix calibration data variable Vasileios Amoiridis
@ 2024-06-09 11:00 ` Jonathan Cameron
0 siblings, 0 replies; 33+ messages in thread
From: Jonathan Cameron @ 2024-06-09 11:00 UTC (permalink / raw)
To: Vasileios Amoiridis
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans
On Thu, 6 Jun 2024 23:22:54 +0200
Vasileios Amoiridis <vassilisamir@gmail.com> wrote:
> According to the BME68x Sensor API [1], the h6 calibration
> data variable should be an unsigned integer of size 8.
>
> [1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x_defs.h#L789
> Fixes: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor")
> Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Applied to the fixes-togreg branch of iio.git and marked for stable.
> ---
> drivers/iio/chemical/bme680_core.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
> index 2c40c13fe97a..812829841733 100644
> --- a/drivers/iio/chemical/bme680_core.c
> +++ b/drivers/iio/chemical/bme680_core.c
> @@ -38,7 +38,7 @@ struct bme680_calib {
> s8 par_h3;
> s8 par_h4;
> s8 par_h5;
> - s8 par_h6;
> + u8 par_h6;
> s8 par_h7;
> s8 par_gh1;
> s16 par_gh2;
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 03/19] iio: chemical: bme680: Fix overflows in compensate() functions
2024-06-06 21:22 ` [PATCH v2 03/19] iio: chemical: bme680: Fix overflows in compensate() functions Vasileios Amoiridis
@ 2024-06-09 11:01 ` Jonathan Cameron
0 siblings, 0 replies; 33+ messages in thread
From: Jonathan Cameron @ 2024-06-09 11:01 UTC (permalink / raw)
To: Vasileios Amoiridis
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans
On Thu, 6 Jun 2024 23:22:55 +0200
Vasileios Amoiridis <vassilisamir@gmail.com> wrote:
> There are cases in the compensate functions of the driver that
> there could be overflows of variables due to bit shifting ops.
> These implications were initially discussed here [1] and they
> were mentioned in log message of Commit 1b3bd8592780 ("iio:
> chemical: Add support for Bosch BME680 sensor").
>
> [1]: https://lore.kernel.org/linux-iio/20180728114028.3c1bbe81@archlinux/
> Fixes: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor")
> Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Applied and marked for stable
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 04/19] iio: chemical: bme680: Fix sensor data read operation
2024-06-06 21:22 ` [PATCH v2 04/19] iio: chemical: bme680: Fix sensor data read operation Vasileios Amoiridis
@ 2024-06-09 11:03 ` Jonathan Cameron
0 siblings, 0 replies; 33+ messages in thread
From: Jonathan Cameron @ 2024-06-09 11:03 UTC (permalink / raw)
To: Vasileios Amoiridis
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans
On Thu, 6 Jun 2024 23:22:56 +0200
Vasileios Amoiridis <vassilisamir@gmail.com> wrote:
> 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: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor")
> Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Applied and marked for stable.
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 15/19] iio: chemical: bme680: Modify startup procedure
2024-06-06 21:23 ` [PATCH v2 15/19] iio: chemical: bme680: Modify startup procedure Vasileios Amoiridis
@ 2024-06-09 11:07 ` Jonathan Cameron
0 siblings, 0 replies; 33+ messages in thread
From: Jonathan Cameron @ 2024-06-09 11:07 UTC (permalink / raw)
To: Vasileios Amoiridis
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans
On Thu, 6 Jun 2024 23:23:09 +0200
Vasileios Amoiridis <vassilisamir@gmail.com> wrote:
> 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].
>
Trivial but oddly short line wrapping. Target 75ish chars for commit messages
> Also, after the soft reset, it is advised to wait for 5ms [6].
>
> [1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L162
> [2]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/examples/forced_mode/forced_mode.c#L44
> [3]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/examples/forced_mode/forced_mode.c#L53
> [4]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/examples/forced_mode/forced_mode.c#L60
> [5]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L640
> [6]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L294
Either make these Link tags or add a blank line here.
I'd prefer link tags with # [1] etc after them for the cross references.
> Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
> ---
> 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 25d128e1ddcf..e354eaa34d59 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;
> }
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 17/19] iio: chemical: bme680: Remove redundant gas configuration
2024-06-06 21:23 ` [PATCH v2 17/19] iio: chemical: bme680: Remove redundant gas configuration Vasileios Amoiridis
@ 2024-06-09 11:08 ` Jonathan Cameron
0 siblings, 0 replies; 33+ messages in thread
From: Jonathan Cameron @ 2024-06-09 11:08 UTC (permalink / raw)
To: Vasileios Amoiridis
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans
On Thu, 6 Jun 2024 23:23:11 +0200
Vasileios Amoiridis <vassilisamir@gmail.com> wrote:
> 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().
Similar oddly short line wrap. Fix them all up for v3.
Thanks
Jonathan
>
> Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
> ---
> 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 1cf375904b8d..76b96993120f 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)
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 19/19] iio: chemical: bme680: Refactorize reading functions
2024-06-06 21:23 ` [PATCH v2 19/19] iio: chemical: bme680: Refactorize reading functions Vasileios Amoiridis
@ 2024-06-09 11:12 ` Jonathan Cameron
2024-06-09 23:02 ` Vasileios Amoiridis
0 siblings, 1 reply; 33+ messages in thread
From: Jonathan Cameron @ 2024-06-09 11:12 UTC (permalink / raw)
To: Vasileios Amoiridis
Cc: dpfrey, himanshujha199640, lars, linux-iio, linux-kernel,
mike.looijmans
On Thu, 6 Jun 2024 23:23:13 +0200
Vasileios Amoiridis <vassilisamir@gmail.com> wrote:
> 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 <vassilisamir@gmail.com>
LGTM. All the other patches I didn't comment on are fine.
5 can wait for the non fix part of the series as it's just a typo.
7-14 look fine but probably have to wait for 1-4 and (v3 of) 6
to get into the upstream of iio.git.
16,18,19 all look good.
Note given you have two series that are dependent on fixes
I might take v3 of patch 6 then send another fixes pull request
before I rebase the main togreg branch on char-next (once it
has those fixes).
Getting complicated this cycle as a lot in flight!
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 19/19] iio: chemical: bme680: Refactorize reading functions
2024-06-09 11:12 ` Jonathan Cameron
@ 2024-06-09 23:02 ` Vasileios Amoiridis
0 siblings, 0 replies; 33+ messages in thread
From: Vasileios Amoiridis @ 2024-06-09 23:02 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Vasileios Amoiridis, dpfrey, himanshujha199640, lars, linux-iio,
linux-kernel, mike.looijmans
On Sun, Jun 09, 2024 at 12:12:34PM +0100, Jonathan Cameron wrote:
> On Thu, 6 Jun 2024 23:23:13 +0200
> Vasileios Amoiridis <vassilisamir@gmail.com> wrote:
>
> > 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 <vassilisamir@gmail.com>
>
> LGTM. All the other patches I didn't comment on are fine.
> 5 can wait for the non fix part of the series as it's just a typo.
> 7-14 look fine but probably have to wait for 1-4 and (v3 of) 6
> to get into the upstream of iio.git.
>
> 16,18,19 all look good.
>
> Note given you have two series that are dependent on fixes
> I might take v3 of patch 6 then send another fixes pull request
> before I rebase the main togreg branch on char-next (once it
> has those fixes).
>
> Getting complicated this cycle as a lot in flight!
>
> Thanks,
>
> Jonathan
Hi Jonathan,
Thank you very much again for the review, I will come back with the
requested fixes! I would appreciate a lot if you could push this fix
a bit forward, thanks!
Cheers,
Vasilis
^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2024-06-09 23:02 UTC | newest]
Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-06 21:22 [PATCH v2 00/19] iio: chemical: bme680: Driver fixes and cleanup Vasileios Amoiridis
2024-06-06 21:22 ` [PATCH v2 01/19] iio: chemical: bme680: Fix pressure value output Vasileios Amoiridis
2024-06-09 11:00 ` Jonathan Cameron
2024-06-06 21:22 ` [PATCH v2 02/19] iio: chemical: bme680: Fix calibration data variable Vasileios Amoiridis
2024-06-09 11:00 ` Jonathan Cameron
2024-06-06 21:22 ` [PATCH v2 03/19] iio: chemical: bme680: Fix overflows in compensate() functions Vasileios Amoiridis
2024-06-09 11:01 ` Jonathan Cameron
2024-06-06 21:22 ` [PATCH v2 04/19] iio: chemical: bme680: Fix sensor data read operation Vasileios Amoiridis
2024-06-09 11:03 ` Jonathan Cameron
2024-06-06 21:22 ` [PATCH v2 05/19] iio: chemical: bme680: Fix typo in define Vasileios Amoiridis
2024-06-06 21:22 ` [PATCH v2 06/19] iio: chemical: bme680: Fix read/write ops to device by adding mutexes Vasileios Amoiridis
2024-06-09 10:56 ` Jonathan Cameron
2024-06-06 21:22 ` [PATCH v2 07/19] iio: chemical: bme680: Drop unnecessary casts and correct adc data types Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 08/19] iio: chemical: bme680: Remove remaining ACPI-only stuff Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 09/19] iio: chemical: bme680: Sort headers alphabetically Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 10/19] iio: chemical: bme680: Remove duplicate register read Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 11/19] iio: chemical: bme680: Use bulk reads for calibration data Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 12/19] iio: chemical: bme680: Allocate IIO device before chip initialization Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in DMA safe region Vasileios Amoiridis
2024-06-07 16:11 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in read/write buffer union Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 13/19] iio: chemical: bme680: Add read buffers in union Vasileios Amoiridis
2024-06-07 16:12 ` Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 14/19] iio: chemical: bme680: Make error checks consistent Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 15/19] iio: chemical: bme680: Modify startup procedure Vasileios Amoiridis
2024-06-09 11:07 ` Jonathan Cameron
2024-06-06 21:23 ` [PATCH v2 16/19] iio: chemical: bme680: Move probe errors to dev_err_probe() Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 17/19] iio: chemical: bme680: Remove redundant gas configuration Vasileios Amoiridis
2024-06-09 11:08 ` Jonathan Cameron
2024-06-06 21:23 ` [PATCH v2 18/19] iio: chemical: bme680: Move forced mode setup in ->read_raw() Vasileios Amoiridis
2024-06-06 21:23 ` [PATCH v2 19/19] iio: chemical: bme680: Refactorize reading functions Vasileios Amoiridis
2024-06-09 11:12 ` Jonathan Cameron
2024-06-09 23:02 ` Vasileios Amoiridis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox