[PATCH v2 2/3] iio: pressure: bmp280: Allow multiple chips id per family of devices

From: Angel Iglesias
Date: Wed Aug 23 2023 - 11:59:02 EST


Improve device detection in certain chip families known to have various
chip ids.

Signed-off-by: Angel Iglesias <ang.iglesiasg@xxxxxxxxx>

diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index 6089f3f9d8f4..4a544a20d6cb 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -40,6 +40,7 @@
#include <linux/completion.h>
#include <linux/pm_runtime.h>
#include <linux/random.h>
+#include <linux/overflow.h>

#include <asm/unaligned.h>

@@ -794,10 +795,12 @@ static int bmp280_chip_config(struct bmp280_data *data)
}

static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 };
+static const uint8_t bmp280_chip_ids[] = { BMP280_CHIP_ID };

const struct bmp280_chip_info bmp280_chip_info = {
.id_reg = BMP280_REG_ID,
- .chip_id = BMP280_CHIP_ID,
+ .chip_id = bmp280_chip_ids,
+ .num_chip_id = ARRAY_SIZE(bmp280_chip_ids),
.regmap_config = &bmp280_regmap_config,
.start_up_time = 2000,
.channels = bmp280_channels,
@@ -846,9 +849,12 @@ static int bme280_chip_config(struct bmp280_data *data)
return bmp280_chip_config(data);
}

+static const uint8_t bme280_chip_ids[] = { BME280_CHIP_ID };
+
const struct bmp280_chip_info bme280_chip_info = {
.id_reg = BMP280_REG_ID,
- .chip_id = BME280_CHIP_ID,
+ .chip_id = bme280_chip_ids,
+ .num_chip_id = ARRAY_SIZE(bme280_chip_ids),
.regmap_config = &bmp280_regmap_config,
.start_up_time = 2000,
.channels = bmp280_channels,
@@ -1220,10 +1226,12 @@ static int bmp380_chip_config(struct bmp280_data *data)

static const int bmp380_oversampling_avail[] = { 1, 2, 4, 8, 16, 32 };
static const int bmp380_iir_filter_coeffs_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128};
+static const uint8_t bmp380_chip_ids[] = { BMP380_CHIP_ID };

const struct bmp280_chip_info bmp380_chip_info = {
.id_reg = BMP380_REG_ID,
- .chip_id = BMP380_CHIP_ID,
+ .chip_id = bmp380_chip_ids,
+ .num_chip_id = ARRAY_SIZE(bmp380_chip_ids),
.regmap_config = &bmp380_regmap_config,
.start_up_time = 2000,
.channels = bmp380_channels,
@@ -1720,10 +1728,12 @@ static int bmp580_chip_config(struct bmp280_data *data)
}

static const int bmp580_oversampling_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+static const uint8_t bmp580_chip_ids[] = { BMP580_CHIP_ID, BMP580_CHIP_ID_ALT };

const struct bmp280_chip_info bmp580_chip_info = {
.id_reg = BMP580_REG_CHIP_ID,
- .chip_id = BMP580_CHIP_ID,
+ .chip_id = bmp580_chip_ids,
+ .num_chip_id = ARRAY_SIZE(bmp580_chip_ids),
.regmap_config = &bmp580_regmap_config,
.start_up_time = 2000,
.channels = bmp380_channels,
@@ -1983,10 +1993,12 @@ static int bmp180_chip_config(struct bmp280_data *data)

static const int bmp180_oversampling_temp_avail[] = { 1 };
static const int bmp180_oversampling_press_avail[] = { 1, 2, 4, 8 };
+static const uint8_t bmp180_chip_ids[] = { BMP180_CHIP_ID };

const struct bmp280_chip_info bmp180_chip_info = {
.id_reg = BMP280_REG_ID,
- .chip_id = BMP180_CHIP_ID,
+ .chip_id = bmp180_chip_ids,
+ .num_chip_id = ARRAY_SIZE(bmp180_chip_ids),
.regmap_config = &bmp180_regmap_config,
.start_up_time = 2000,
.channels = bmp280_channels,
@@ -2077,7 +2089,7 @@ int bmp280_common_probe(struct device *dev,
struct bmp280_data *data;
struct gpio_desc *gpiod;
unsigned int chip_id;
- int ret;
+ int ret, i;

indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
@@ -2142,10 +2154,31 @@ int bmp280_common_probe(struct device *dev,
ret = regmap_read(regmap, data->chip_info->id_reg, &chip_id);
if (ret < 0)
return ret;
- if (chip_id != data->chip_info->chip_id) {
- dev_err(dev, "bad chip id: expected %x got %x\n",
- data->chip_info->chip_id, chip_id);
- return -EINVAL;
+
+ for (i = 0; i < data->chip_info->num_chip_id; i++) {
+ if (chip_id == data->chip_info->chip_id[i])
+ break;
+ }
+
+ if (i == data->chip_info->num_chip_id) {
+ size_t nbuf;
+ char *buf;
+
+ // 0x<id>, so four chars per number plus one space + ENDL
+ if (check_mul_overflow(5, data->chip_info->num_chip_id, &nbuf))
+ return ret;
+
+ buf = kmalloc_array(nbuf, sizeof(char), GFP_KERNEL);
+ if (!buf)
+ return ret;
+
+ for (i = 0; i < data->chip_info->num_chip_id; i++)
+ snprintf(&buf[i*5], nbuf, "0x%x ", data->chip_info->chip_id[i]);
+ buf[nbuf-1] = '\0';
+
+ dev_err(dev, "bad chip id: expected [ %s ] got 0x%x\n", buf, chip_id);
+ kfree(buf);
+ return ret;
}

if (data->chip_info->preinit) {
diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
index ff72e82f55ad..c2acc9315223 100644
--- a/drivers/iio/pressure/bmp280.h
+++ b/drivers/iio/pressure/bmp280.h
@@ -418,7 +418,8 @@ struct bmp280_data {

struct bmp280_chip_info {
unsigned int id_reg;
- uint8_t chip_id;
+ const uint8_t *chip_id;
+ int num_chip_id;

const struct regmap_config *regmap_config;

--
2.42.0