Convert individual reads to a bulk read for the humidity calibration data.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
drivers/iio/pressure/bmp280-core.c | 64 +++++++++++-------------------
drivers/iio/pressure/bmp280.h | 6 +++
2 files changed, 29 insertions(+), 41 deletions(-)
diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index 8383d1a73cf9..c23515048081 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -340,10 +340,19 @@ static int bmp280_read_calib(struct bmp280_data *data)
return 0;
}
+/*
+ * These enums are used for indexing into the array of humidity parameters
+ * for BME280. Due to some weird indexing, unaligned BE/LE accesses co-exist in
+ * order to prepare the FIELD_{GET/PREP}() fields. Table 16 in Section 4.2.2 of
+ * the datasheet.
+ */
+enum { H2 = 0, H3 = 2, H4 = 3, H5 = 4, H6 = 6 };
+
static int bme280_read_calib(struct bmp280_data *data)
{
struct bmp280_calib *calib = &data->calib.bmp280;
struct device *dev = data->dev;
+ s16 h4_upper, h4_lower;
unsigned int tmp;
int ret;
@@ -352,14 +361,6 @@ static int bme280_read_calib(struct bmp280_data *data)
if (ret)
return ret;
- /*
- * Read humidity calibration values.
- * Due to some odd register addressing we cannot just
- * do a big bulk read. Instead, we have to read each Hx
- * value separately and sometimes do some bit shifting...
- * Humidity data is only available on BME280.
- */
-
ret = regmap_read(data->regmap, BME280_REG_COMP_H1, &tmp);
if (ret) {
dev_err(dev, "failed to read H1 comp value\n");
@@ -368,43 +369,24 @@ static int bme280_read_calib(struct bmp280_data *data)
calib->H1 = tmp;
ret = regmap_bulk_read(data->regmap, BME280_REG_COMP_H2,
- &data->le16, sizeof(data->le16));
- if (ret) {
- dev_err(dev, "failed to read H2 comp value\n");
- return ret;
- }
- calib->H2 = sign_extend32(le16_to_cpu(data->le16), 15);
-
- ret = regmap_read(data->regmap, BME280_REG_COMP_H3, &tmp);
- if (ret) {
- dev_err(dev, "failed to read H3 comp value\n");
- return ret;
- }
- calib->H3 = tmp;
-
- ret = regmap_bulk_read(data->regmap, BME280_REG_COMP_H4,
- &data->be16, sizeof(data->be16));
+ data->bme280_humid_cal_buf,
+ sizeof(data->bme280_humid_cal_buf));
if (ret) {
- dev_err(dev, "failed to read H4 comp value\n");
+ dev_err(dev, "failed to read humidity calibration values\n");
return ret;
}
- calib->H4 = sign_extend32(((be16_to_cpu(data->be16) >> 4) & 0xff0) |
- (be16_to_cpu(data->be16) & 0xf), 11);
- ret = regmap_bulk_read(data->regmap, BME280_REG_COMP_H5,
- &data->le16, sizeof(data->le16));
- if (ret) {
- dev_err(dev, "failed to read H5 comp value\n");
- return ret;
- }
- calib->H5 = sign_extend32(FIELD_GET(BME280_COMP_H5_MASK, le16_to_cpu(data->le16)), 11);
-
- ret = regmap_read(data->regmap, BME280_REG_COMP_H6, &tmp);
- if (ret) {
- dev_err(dev, "failed to read H6 comp value\n");
- return ret;
- }
- calib->H6 = sign_extend32(tmp, 7);
+ calib->H2 = get_unaligned_le16(&data->bme280_humid_cal_buf[H2]);
+ calib->H3 = data->bme280_humid_cal_buf[H3];
+ h4_upper = FIELD_GET(BME280_COMP_H4_GET_MASK_UP,
+ get_unaligned_be16(&data->bme280_humid_cal_buf[H4]));
+ h4_upper = FIELD_PREP(BME280_COMP_H4_PREP_MASK_UP, h4_upper);
+ h4_lower = FIELD_GET(BME280_COMP_H4_MASK_LOW,
+ get_unaligned_be16(&data->bme280_humid_cal_buf[H4]));
+ calib->H4 = sign_extend32(h4_upper | h4_lower, 11);
+ calib->H5 = sign_extend32(FIELD_GET(BME280_COMP_H5_MASK,
+ get_unaligned_le16(&data->bme280_humid_cal_buf[H5])), 11);
+ calib->H6 = data->bme280_humid_cal_buf[H6];
return 0;
}
diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
index a853b6d5bdfa..4e675401d61b 100644
--- a/drivers/iio/pressure/bmp280.h
+++ b/drivers/iio/pressure/bmp280.h
@@ -257,8 +257,13 @@
#define BME280_REG_COMP_H5 0xE5
#define BME280_REG_COMP_H6 0xE7
+#define BME280_COMP_H4_GET_MASK_UP GENMASK(15, 8)
+#define BME280_COMP_H4_PREP_MASK_UP GENMASK(11, 4)
+#define BME280_COMP_H4_MASK_LOW GENMASK(3, 0)
#define BME280_COMP_H5_MASK GENMASK(15, 4)
+#define BME280_CONTIGUOUS_CALIB_REGS 7
+
#define BME280_OSRS_HUMIDITY_MASK GENMASK(2, 0)
#define BME280_OSRS_HUMIDITY_SKIP 0
#define BME280_OSRS_HUMIDITY_1X 1
@@ -426,6 +431,7 @@ struct bmp280_data {
/* Calibration data buffers */
__le16 bmp280_cal_buf[BMP280_CONTIGUOUS_CALIB_REGS / 2];
__be16 bmp180_cal_buf[BMP180_REG_CALIB_COUNT / 2];
+ u8 bme280_humid_cal_buf[BME280_CONTIGUOUS_CALIB_REGS];
u8 bmp380_cal_buf[BMP380_CALIB_REG_COUNT];
/* Miscellaneous, endianness-aware data buffers */
__le16 le16;
--
2.25.1
On Fri, Aug 23, 2024 at 08:17:08PM +0200, Vasileios Amoiridis wrote: > Convert individual reads to a bulk read for the humidity calibration data. ... > + calib->H2 = get_unaligned_le16(&data->bme280_humid_cal_buf[H2]); > + calib->H3 = data->bme280_humid_cal_buf[H3]; > + h4_upper = FIELD_GET(BME280_COMP_H4_GET_MASK_UP, > + get_unaligned_be16(&data->bme280_humid_cal_buf[H4])); > + h4_upper = FIELD_PREP(BME280_COMP_H4_PREP_MASK_UP, h4_upper); This is a bit confusing. I would add a tmp variable and have this as tmp = FIELD_GET(BME280_COMP_H4_GET_MASK_UP, get_unaligned_be16(&data->bme280_humid_cal_buf[H4])); h4_upper = FIELD_PREP(BME280_COMP_H4_PREP_MASK_UP, tmp); Also note indentation issues. > + h4_lower = FIELD_GET(BME280_COMP_H4_MASK_LOW, > + get_unaligned_be16(&data->bme280_humid_cal_buf[H4])); > + calib->H4 = sign_extend32(h4_upper | h4_lower, 11); > + calib->H5 = sign_extend32(FIELD_GET(BME280_COMP_H5_MASK, > + get_unaligned_le16(&data->bme280_humid_cal_buf[H5])), 11); > + calib->H6 = data->bme280_humid_cal_buf[H6]; ... > /* Calibration data buffers */ > __le16 bmp280_cal_buf[BMP280_CONTIGUOUS_CALIB_REGS / 2]; > __be16 bmp180_cal_buf[BMP180_REG_CALIB_COUNT / 2]; Side note: I would see rather sizeof(__Xe16) than 2:s in the above definitions. > + u8 bme280_humid_cal_buf[BME280_CONTIGUOUS_CALIB_REGS]; -- With Best Regards, Andy Shevchenko
On Fri, Aug 23, 2024 at 09:47:22PM +0300, Andy Shevchenko wrote: > On Fri, Aug 23, 2024 at 08:17:08PM +0200, Vasileios Amoiridis wrote: > > Convert individual reads to a bulk read for the humidity calibration data. > > ... > > > + calib->H2 = get_unaligned_le16(&data->bme280_humid_cal_buf[H2]); > > + calib->H3 = data->bme280_humid_cal_buf[H3]; > > > + h4_upper = FIELD_GET(BME280_COMP_H4_GET_MASK_UP, > > + get_unaligned_be16(&data->bme280_humid_cal_buf[H4])); > > + h4_upper = FIELD_PREP(BME280_COMP_H4_PREP_MASK_UP, h4_upper); > > This is a bit confusing. I would add a tmp variable and have this as > > tmp = FIELD_GET(BME280_COMP_H4_GET_MASK_UP, > get_unaligned_be16(&data->bme280_humid_cal_buf[H4])); > h4_upper = FIELD_PREP(BME280_COMP_H4_PREP_MASK_UP, tmp); > > Also note indentation issues. > Hi Andy, It's been a long time since you last reviewed code of mine, thanks for finding the time to do this, I appreciate it a lot! You are right, it looks confusing, I can do what you proposed. I don't know how I didn't see it before. Cheers, Vasilis > > + h4_lower = FIELD_GET(BME280_COMP_H4_MASK_LOW, > > + get_unaligned_be16(&data->bme280_humid_cal_buf[H4])); > > + calib->H4 = sign_extend32(h4_upper | h4_lower, 11); > > + calib->H5 = sign_extend32(FIELD_GET(BME280_COMP_H5_MASK, > > + get_unaligned_le16(&data->bme280_humid_cal_buf[H5])), 11); > > + calib->H6 = data->bme280_humid_cal_buf[H6]; > > ... > > > /* Calibration data buffers */ > > __le16 bmp280_cal_buf[BMP280_CONTIGUOUS_CALIB_REGS / 2]; > > __be16 bmp180_cal_buf[BMP180_REG_CALIB_COUNT / 2]; > > Side note: I would see rather sizeof(__Xe16) than 2:s in the above definitions. > > > + u8 bme280_humid_cal_buf[BME280_CONTIGUOUS_CALIB_REGS]; > > -- > With Best Regards, > Andy Shevchenko > >
© 2016 - 2026 Red Hat, Inc.