Skip to content

Commit 80b9f3a

Browse files
vamoiridjic23
authored andcommitted
iio: chemical: bme680: Add triggered buffer support
Add triggered buffer and soft timestamp support. The available scan mask enables all the channels of the sensor in order to follow the operation of the sensor. The sensor basically starts to capture from all channels as long as it enters into FORCED mode. The bulk read, reads a total of 15 registers from the sensor, 0x1D..0x2B. Even though some of those registers are not reported in the register map of the device, this is how the BME680 Sensor API [1] proposes to do it. This allows to have one bulk read instead of multiple ones. Link: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L1200 Signed-off-by: Vasileios Amoiridis <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jonathan Cameron <[email protected]>
1 parent f51171c commit 80b9f3a

File tree

3 files changed

+139
-1
lines changed

3 files changed

+139
-1
lines changed

drivers/iio/chemical/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ config BME680
5050
select REGMAP
5151
select BME680_I2C if I2C
5252
select BME680_SPI if SPI
53+
select IIO_BUFFER
54+
select IIO_TRIGGERED_BUFFER
5355
help
5456
Say yes here to build support for Bosch Sensortec BME680 sensor with
5557
temperature, pressure, humidity and gas sensing capability.

drivers/iio/chemical/bme680.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@
6666
/* Datasheet Section 1.1, Table 1 */
6767
#define BME680_STARTUP_TIME_US 2000
6868

69+
#define BME680_NUM_CHANNELS 4
70+
#define BME680_NUM_BULK_READ_REGS 15
71+
6972
/* Calibration Parameters */
7073
#define BME680_T2_LSB_REG 0x8A
7174
#define BME680_H2_MSB_REG 0xE1

drivers/iio/chemical/bme680_core.c

Lines changed: 134 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
#include <linux/module.h>
1717
#include <linux/regmap.h>
1818

19+
#include <linux/iio/buffer.h>
1920
#include <linux/iio/iio.h>
2021
#include <linux/iio/sysfs.h>
22+
#include <linux/iio/trigger_consumer.h>
23+
#include <linux/iio/triggered_buffer.h>
2124

2225
#include <linux/unaligned.h>
2326

@@ -101,6 +104,13 @@ enum bme680_op_mode {
101104
BME680_MODE_FORCED = 1,
102105
};
103106

107+
enum bme680_scan {
108+
BME680_TEMP,
109+
BME680_PRESS,
110+
BME680_HUMID,
111+
BME680_GAS,
112+
};
113+
104114
struct bme680_data {
105115
struct regmap *regmap;
106116
struct bme680_calib bme680;
@@ -111,8 +121,13 @@ struct bme680_data {
111121
u16 heater_dur;
112122
u16 heater_temp;
113123

124+
struct {
125+
s32 chan[4];
126+
aligned_s64 ts;
127+
} scan;
128+
114129
union {
115-
u8 buf[3];
130+
u8 buf[BME680_NUM_BULK_READ_REGS];
116131
unsigned int check;
117132
__be16 be16;
118133
u8 bme680_cal_buf_1[BME680_CALIB_RANGE_1_LEN];
@@ -149,6 +164,13 @@ static const struct iio_chan_spec bme680_channels[] = {
149164
BIT(IIO_CHAN_INFO_RAW) |
150165
BIT(IIO_CHAN_INFO_SCALE) |
151166
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
167+
.scan_index = 0,
168+
.scan_type = {
169+
.sign = 's',
170+
.realbits = 16,
171+
.storagebits = 16,
172+
.endianness = IIO_CPU,
173+
},
152174
},
153175
{
154176
.type = IIO_PRESSURE,
@@ -157,6 +179,13 @@ static const struct iio_chan_spec bme680_channels[] = {
157179
BIT(IIO_CHAN_INFO_RAW) |
158180
BIT(IIO_CHAN_INFO_SCALE) |
159181
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
182+
.scan_index = 1,
183+
.scan_type = {
184+
.sign = 'u',
185+
.realbits = 32,
186+
.storagebits = 32,
187+
.endianness = IIO_CPU,
188+
},
160189
},
161190
{
162191
.type = IIO_HUMIDITYRELATIVE,
@@ -165,11 +194,26 @@ static const struct iio_chan_spec bme680_channels[] = {
165194
BIT(IIO_CHAN_INFO_RAW) |
166195
BIT(IIO_CHAN_INFO_SCALE) |
167196
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
197+
.scan_index = 2,
198+
.scan_type = {
199+
.sign = 'u',
200+
.realbits = 32,
201+
.storagebits = 32,
202+
.endianness = IIO_CPU,
203+
},
168204
},
169205
{
170206
.type = IIO_RESISTANCE,
171207
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
208+
.scan_index = 3,
209+
.scan_type = {
210+
.sign = 'u',
211+
.realbits = 32,
212+
.storagebits = 32,
213+
.endianness = IIO_CPU,
214+
},
172215
},
216+
IIO_CHAN_SOFT_TIMESTAMP(4),
173217
};
174218

175219
static int bme680_read_calib(struct bme680_data *data,
@@ -920,6 +964,86 @@ static const struct iio_info bme680_info = {
920964
.attrs = &bme680_attribute_group,
921965
};
922966

967+
static const unsigned long bme680_avail_scan_masks[] = {
968+
BIT(BME680_GAS) | BIT(BME680_HUMID) | BIT(BME680_PRESS) | BIT(BME680_TEMP),
969+
0
970+
};
971+
972+
static irqreturn_t bme680_trigger_handler(int irq, void *p)
973+
{
974+
struct iio_poll_func *pf = p;
975+
struct iio_dev *indio_dev = pf->indio_dev;
976+
struct bme680_data *data = iio_priv(indio_dev);
977+
struct device *dev = regmap_get_device(data->regmap);
978+
u32 adc_temp, adc_press, adc_humid;
979+
u16 adc_gas_res, gas_regs_val;
980+
u8 gas_range;
981+
s32 t_fine;
982+
int ret;
983+
984+
guard(mutex)(&data->lock);
985+
986+
ret = bme680_set_mode(data, BME680_MODE_FORCED);
987+
if (ret < 0)
988+
goto out;
989+
990+
ret = bme680_wait_for_eoc(data);
991+
if (ret)
992+
goto out;
993+
994+
ret = regmap_bulk_read(data->regmap, BME680_REG_MEAS_STAT_0,
995+
data->buf, sizeof(data->buf));
996+
if (ret) {
997+
dev_err(dev, "failed to burst read sensor data\n");
998+
goto out;
999+
}
1000+
if (data->buf[0] & BME680_GAS_MEAS_BIT) {
1001+
dev_err(dev, "gas measurement incomplete\n");
1002+
goto out;
1003+
}
1004+
1005+
/* Temperature calculations */
1006+
adc_temp = FIELD_GET(BME680_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[5]));
1007+
if (adc_temp == BME680_MEAS_SKIPPED) {
1008+
dev_err(dev, "reading temperature skipped\n");
1009+
goto out;
1010+
}
1011+
data->scan.chan[0] = bme680_compensate_temp(data, adc_temp);
1012+
t_fine = bme680_calc_t_fine(data, adc_temp);
1013+
1014+
/* Pressure calculations */
1015+
adc_press = FIELD_GET(BME680_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[2]));
1016+
if (adc_press == BME680_MEAS_SKIPPED) {
1017+
dev_err(dev, "reading pressure skipped\n");
1018+
goto out;
1019+
}
1020+
data->scan.chan[1] = bme680_compensate_press(data, adc_press, t_fine);
1021+
1022+
/* Humidity calculations */
1023+
adc_humid = get_unaligned_be16(&data->buf[8]);
1024+
if (adc_humid == BME680_MEAS_SKIPPED) {
1025+
dev_err(dev, "reading humidity skipped\n");
1026+
goto out;
1027+
}
1028+
data->scan.chan[2] = bme680_compensate_humid(data, adc_humid, t_fine);
1029+
1030+
/* Gas calculations */
1031+
gas_regs_val = get_unaligned_be16(&data->buf[13]);
1032+
adc_gas_res = FIELD_GET(BME680_ADC_GAS_RES, gas_regs_val);
1033+
if ((gas_regs_val & BME680_GAS_STAB_BIT) == 0) {
1034+
dev_err(dev, "heater failed to reach the target temperature\n");
1035+
goto out;
1036+
}
1037+
gas_range = FIELD_GET(BME680_GAS_RANGE_MASK, gas_regs_val);
1038+
data->scan.chan[3] = bme680_compensate_gas(data, adc_gas_res, gas_range);
1039+
1040+
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
1041+
iio_get_time_ns(indio_dev));
1042+
out:
1043+
iio_trigger_notify_done(indio_dev->trig);
1044+
return IRQ_HANDLED;
1045+
}
1046+
9231047
int bme680_core_probe(struct device *dev, struct regmap *regmap,
9241048
const char *name)
9251049
{
@@ -938,6 +1062,7 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
9381062
indio_dev->name = name;
9391063
indio_dev->channels = bme680_channels;
9401064
indio_dev->num_channels = ARRAY_SIZE(bme680_channels);
1065+
indio_dev->available_scan_masks = bme680_avail_scan_masks;
9411066
indio_dev->info = &bme680_info;
9421067
indio_dev->modes = INDIO_DIRECT_MODE;
9431068

@@ -980,6 +1105,14 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap,
9801105
return dev_err_probe(dev, ret,
9811106
"failed to set gas config data\n");
9821107

1108+
ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
1109+
iio_pollfunc_store_time,
1110+
bme680_trigger_handler,
1111+
NULL);
1112+
if (ret)
1113+
return dev_err_probe(dev, ret,
1114+
"iio triggered buffer setup failed\n");
1115+
9831116
return devm_iio_device_register(dev, indio_dev);
9841117
}
9851118
EXPORT_SYMBOL_NS_GPL(bme680_core_probe, IIO_BME680);

0 commit comments

Comments
 (0)