diff mbox series

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

Message ID 7bdfbfeb106acc5560e6cb090131f105b2d2e418.1692805377.git.ang.iglesiasg@gmail.com (mailing list archive)
State Changes Requested
Headers show
Series iio: pressure: bmp280: Add support for BMP390 | expand

Commit Message

Angel Iglesias Aug. 23, 2023, 3:58 p.m. UTC
Improve device detection in certain chip families known to have various
chip ids.

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

Comments

andriy.shevchenko@linux.intel.com Aug. 23, 2023, 4:26 p.m. UTC | #1
On Wed, Aug 23, 2023 at 05:58:06PM +0200, Angel Iglesias wrote:
> Improve device detection in certain chip families known to have various
> chip ids.

IDs

...

>  #include <linux/completion.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/random.h>
> +#include <linux/overflow.h>

Please, preserve ordering.

...

>  	struct bmp280_data *data;
>  	struct gpio_desc *gpiod;
>  	unsigned int chip_id;
> -	int ret;
> +	int ret, i;

	unsigned int i;

...

> +	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);

We almost never do a array allocation for byte sizes. Instead of the above you
need to use

		buf = kmalloc_array(data->chip_info->num_chip_id, 5, GFP_KERNEL);

> +		if (!buf)

This check assumes that num_chip_id is never 0, so...

> +			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';

...this is redundant assignment. sprintf() guarantees the NUL termination.

> +
> +		dev_err(dev, "bad chip id: expected [ %s ] got 0x%x\n", buf, chip_id);

"...expected one of..."

> +		kfree(buf);
> +		return ret;

Oh, I didn't get that you allocated memory only to print a message...


>  	}
Angel Iglesias Aug. 25, 2023, 9:30 a.m. UTC | #2
On Wed, 2023-08-23 at 19:26 +0300, Andy Shevchenko wrote:
> On Wed, Aug 23, 2023 at 05:58:06PM +0200, Angel Iglesias wrote:
> > Improve device detection in certain chip families known to have various
> > chip ids.
> 
> IDs
> 
> ...
> 
> >  #include <linux/completion.h>
> >  #include <linux/pm_runtime.h>
> >  #include <linux/random.h>
> > +#include <linux/overflow.h>
> 
> Please, preserve ordering.
> 
> ...
> 
> >         struct bmp280_data *data;
> >         struct gpio_desc *gpiod;
> >         unsigned int chip_id;
> > -       int ret;
> > +       int ret, i;
> 
>         unsigned int i;
> 
> ...
> 
> > +       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);
> 
> We almost never do a array allocation for byte sizes. Instead of the above you
> need to use
> 
>                 buf = kmalloc_array(data->chip_info->num_chip_id, 5,
> GFP_KERNEL);
> 
> > +               if (!buf)
> 
> This check assumes that num_chip_id is never 0, so...
> 
> > +                       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';
> 
> ...this is redundant assignment. sprintf() guarantees the NUL termination.
> 
> > +
> > +               dev_err(dev, "bad chip id: expected [ %s ] got 0x%x\n", buf,
> > chip_id);
> 
> "...expected one of..."
> 
> > +               kfree(buf);
> > +               return ret;
> 
> Oh, I didn't get that you allocated memory only to print a message...

Yes, I just wanted to print the known IDs like before in a readable manner. If
it is overkill, I'll change it for a more generic error message.

> 
> >         }
> 
Kind regards,
Angel
diff mbox series

Patch

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;