iio: chemical: bme680: Use bulk reads for calibration data
Calibration data are located in contiguous-ish registers inside the chip. For that reason we can use bulk reads as is done as well in the BME68x Sensor API [1]. The arrays that are used for reading the data out of the sensor are located inside DMA safe buffer. Link: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L1769 # [1] Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com> Link: https://patch.msgid.link/20240609233826.330516-8-vassilisamir@gmail.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
parent
5a38766897
commit
a4f765e72e
@ -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,
|
||||
|
@ -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));
|
||||
data->bme680_cal_buf_1,
|
||||
sizeof(data->bme680_cal_buf_1));
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to read BME680_T2_LSB_REG\n");
|
||||
dev_err(dev, "failed to read 1st set of calib data;\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;
|
||||
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];
|
||||
|
||||
/* Pressure related coefficients */
|
||||
ret = regmap_bulk_read(data->regmap, BME680_P1_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_P1_LSB_REG\n");
|
||||
dev_err(dev, "failed to read 2nd set of calib data;\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);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to read BME680_P3_REG\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);
|
||||
|
||||
ret = regmap_bulk_read(data->regmap, BME680_P5_LSB_REG,
|
||||
&buf, sizeof(buf));
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to read BME680_P5_LSB_REG\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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user