Add support for pressure sensor Bosch BMP580
Subsystems (2)
v2 cover Add support for pressure sensor Bosch BMP580
This patchset adds support for the new pressure sensors BMP580 extending the bmp280 driver.
Patch 1 introduces a variant enumeration and refactors sensor verification logic adding a chip_id field to the chip_info struct. This change is required because BMP380 and BMP580 have the same chip_id and values would collide using the chip_id as the driver_data value.
Patch 2 introduces new preinit callback and unifies init logic across all supported variants.
Patch 3 extends the bmp280 driver with the new logic to read measurements and configure the operation parameters for the BMP580 sensors. Patch 4 updates the devicetree binding docs with the new sensor id. Patch 5 adds the NVMEM operations to read and program the NVM user range contained in the non-volatile memory of the BMP580 sensors.
Changes in V2:
* For patch 3, fixed missing retcodes reported by the kernel test robot.
* For patch 5, fixed logic paths that left the sensor mutex locked reported by the kernel test robot.
Angel Iglesias (5):
iio: pressure: bmp280: Add enumeration to handle chip variants
iio: pressure: bmp280: Add preinit callback
iio: pressure: bmp280: Add support for new sensor BMP580
dt-bindings: iio: pressure: bmp085: Add BMP580 compatible string
iio: pressure: bmp280: Add nvmem operations for BMP580
.../bindings/iio/pressure/bmp085.yaml | 2 + drivers/iio/pressure/Kconfig | 6 +- drivers/iio/pressure/bmp280-core.c | 617 +++++++++++++++++- drivers/iio/pressure/bmp280-i2c.c | 33 +- drivers/iio/pressure/bmp280-regmap.c | 60 ++ drivers/iio/pressure/bmp280-spi.c | 23 +- drivers/iio/pressure/bmp280.h | 115 ++++ 7 files changed, 815 insertions(+), 41 deletions(-)
base-commit: e807541c2b273677e82ef50b5747ec7ae7d652b9
Signature · 1 line
2.39.0
PATCH v2 1/5 iio: pressure: bmp280: Add enumeration to handle chip variants
Adds enumeration to improve handling the different supported sensors on driver initialization. This avoid collisions if different variants share the same device idetifier on ID register.
drivers/iio/pressure/bmp280-core.c +11 -6
@@ -186,6 +186,7 @@ struct bmp280_data {struct bmp280_chip_info {unsigned int id_reg; +const unsigned int chip_id;const struct iio_chan_spec *channels;int num_channels;
@@ -907,6 +908,7 @@ static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 };static const struct bmp280_chip_info bmp280_chip_info = { .id_reg =BMP280_REG_ID , + .chip_id =BMP280_CHIP_ID , .start_up_time =2000 , .channels = bmp280_channels, .num_channels =2 ,
@@ -955,6 +957,7 @@ static int bme280_chip_config(struct bmp280_data *data)static const struct bmp280_chip_info bme280_chip_info = { .id_reg =BMP280_REG_ID , + .chip_id =BME280_CHIP_ID , .start_up_time =2000 , .channels = bmp280_channels, .num_channels =3 ,
@@ -1321,6 +1324,7 @@ static const int bmp380_iir_filter_coeffs_avail[] = { 1, 2, 4, 8, 16, 32, 64, 12static const struct bmp280_chip_info bmp380_chip_info = { .id_reg =BMP380_REG_ID , + .chip_id =BMP380_CHIP_ID , .start_up_time =2000 , .channels = bmp380_channels, .num_channels =2 ,
@@ -1581,6 +1585,7 @@ static const int bmp180_oversampling_press_avail[] = { 1, 2, 4, 8 };static const struct bmp280_chip_info bmp180_chip_info = { .id_reg =BMP280_REG_ID , + .chip_id =BMP180_CHIP_ID , .start_up_time =2000 , .channels = bmp280_channels, .num_channels =2 ,
@@ -1685,16 +1690,16 @@ int bmp280_common_probe(struct device *dev, indio_dev->modes =INDIO_DIRECT_MODE ;switch (chip) { -case BMP180_CHIP_ID : +case BMP180 : chip_info = &bmp180_chip_info;break ; -case BMP280_CHIP_ID : +case BMP280 : chip_info = &bmp280_chip_info;break ; -case BME280_CHIP_ID : +case BME280 : chip_info = &bme280_chip_info;break ; -case BMP380_CHIP_ID : +case BMP380 : chip_info = &bmp380_chip_info;break ;default :
@@ -1751,9 +1756,9 @@ 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 != chip) { +if (chip_id != data->chip_info->chip_id) {dev_err (dev,"bad chip id: expected %x got %x\n" , - chip, chip_id); + data->chip_info->chip_id, chip_id);return -EINVAL ; }
drivers/iio/pressure/bmp280-i2c.c +14 -14
@@ -12,14 +12,14 @@ static int bmp280_i2c_probe(struct i2c_client *client)const struct i2c_device_id *id =i2c_client_get_device_id (client);switch (id->driver_data) { -case BMP180_CHIP_ID : +case BMP180 : regmap_config = &bmp180_regmap_config;break ; -case BMP280_CHIP_ID : -case BME280_CHIP_ID : +case BMP280 : +case BME280 : regmap_config = &bmp280_regmap_config;break ; -case BMP380_CHIP_ID : +case BMP380 : regmap_config = &bmp380_regmap_config;break ;default :
@@ -40,21 +40,21 @@ static int bmp280_i2c_probe(struct i2c_client *client) }static const struct of_device_id bmp280_of_i2c_match[] = { - { .compatible ="bosch,bmp085" , .data = (void *)BMP180_CHIP_ID }, - { .compatible ="bosch,bmp180" , .data = (void *)BMP180_CHIP_ID }, - { .compatible ="bosch,bmp280" , .data = (void *)BMP280_CHIP_ID }, - { .compatible ="bosch,bme280" , .data = (void *)BME280_CHIP_ID }, - { .compatible ="bosch,bmp380" , .data = (void *)BMP380_CHIP_ID }, + { .compatible ="bosch,bmp085" , .data = (void *)BMP180 }, + { .compatible ="bosch,bmp180" , .data = (void *)BMP180 }, + { .compatible ="bosch,bmp280" , .data = (void *)BMP280 }, + { .compatible ="bosch,bme280" , .data = (void *)BME280 }, + { .compatible ="bosch,bmp380" , .data = (void *)BMP380 }, { }, };MODULE_DEVICE_TABLE (of, bmp280_of_i2c_match);static const struct i2c_device_id bmp280_i2c_id[] = { - {"bmp085" ,BMP180_CHIP_ID }, - {"bmp180" ,BMP180_CHIP_ID }, - {"bmp280" ,BMP280_CHIP_ID }, - {"bme280" ,BME280_CHIP_ID }, - {"bmp380" ,BMP380_CHIP_ID }, + {"bmp085" ,BMP180 }, + {"bmp180" ,BMP180 }, + {"bmp280" ,BMP280 }, + {"bme280" ,BME280 }, + {"bmp380" ,BMP380 }, { }, };MODULE_DEVICE_TABLE (i2c, bmp280_i2c_id);
drivers/iio/pressure/bmp280-spi.c +9 -9
@@ -59,14 +59,14 @@ static int bmp280_spi_probe(struct spi_device *spi) }switch (id->driver_data) { -case BMP180_CHIP_ID : +case BMP180 : regmap_config = &bmp180_regmap_config;break ; -case BMP280_CHIP_ID : -case BME280_CHIP_ID : +case BMP280 : +case BME280 : regmap_config = &bmp280_regmap_config;break ; -case BMP380_CHIP_ID : +case BMP380 : regmap_config = &bmp380_regmap_config;break ;default :
@@ -101,11 +101,11 @@ static const struct of_device_id bmp280_of_spi_match[] = {MODULE_DEVICE_TABLE (of, bmp280_of_spi_match);static const struct spi_device_id bmp280_spi_id[] = { - {"bmp180" ,BMP180_CHIP_ID }, - {"bmp181" ,BMP180_CHIP_ID }, - {"bmp280" ,BMP280_CHIP_ID }, - {"bme280" ,BME280_CHIP_ID }, - {"bmp380" ,BMP380_CHIP_ID }, + {"bmp180" ,BMP180 }, + {"bmp181" ,BMP180 }, + {"bmp280" ,BMP280 }, + {"bme280" ,BME280 }, + {"bmp380" ,BMP380 }, { } };MODULE_DEVICE_TABLE (spi, bmp280_spi_id);
drivers/iio/pressure/bmp280.h +8 -0
@@ -191,6 +191,14 @@#define BMP280_PRESS_SKIPPED 0x80000#define BMP280_HUMIDITY_SKIPPED 0x8000 +/* Enum with supported pressure sensor models */ +enum bmp280_variant { +BMP180 , +BMP280 , +BME280 , +BMP380 , +}; +/* Regmap configurations */ extern const struct regmap_config bmp180_regmap_config;extern const struct regmap_config bmp280_regmap_config;
Signature · 1 line
2.39.0
Re: [PATCH v2 1/5] iio: pressure: bmp280: Add enumeration to handle chip variants
Quoted 3 lines · Angel Iglesias
Adds enumeration to improve handling the different supported sensors on driver initialization. This avoid collisions if different variants share the same device idetifier on ID register.
As per v1, use pointers in the ID tables.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH v2 1/5] iio: pressure: bmp280: Add enumeration to handle chip variants
Quoted 7 lines · Andy Shevchenko
Quoted 3 lines · Angel Iglesias
Adds enumeration to improve handling the different supported sensors on driver initialization. This avoid collisions if different variants share the same device idetifier on ID register.
As per v1, use pointers in the ID tables.
Taking your suggestion and Jonathan's remarks into account seems to me like the best approach here is using chip_info pointer for each driver as the pointer set on the id tables. As in the i2c and spi drivers, the enum is used to fetch the correct regmap configuration, and later in the shared probe, the chip_info. The logical follow-up would be adding the regmap configuration to the chip_info, right?
Or is there a better solution I'm not seeing right now?
Thanks for your time,
Angel
Jonathan Cameron
maintainerRe: [PATCH v2 1/5] iio: pressure: bmp280: Add enumeration to handle chip variants
Quoted 6 lines · On Sun, 01 Jan 2023 12:04:40 +0100 Angel Iglesias <[email protected]>…
Quoted 5 lines · Andy Shevchenko
Quoted 3 lines · Angel Iglesias
Adds enumeration to improve handling the different supported sensors on driver initialization. This avoid collisions if different variants share the same device idetifier on ID register.
Quoted 6 lines
Quoted 2 lines
As per v1, use pointers in the ID tables.
Taking your suggestion and Jonathan's remarks into account seems to me like the best approach here is using
chip_infopointer for each driver as the pointer set on the id tables.
Yes.
Quoted 4 lines
As in the i2c and spi drivers, the enum is used to fetch the correct regmap configuration, and later in the shared probe, the
chip_info. The logical follow-up would be adding the regmap configuration to thechip_info, right?
Makes sense.
Quoted 1 line
Or is there a better solution I'm not seeing right now?
If I'm understanding what you have above, then this is exactly what we would want to do here.
Thanks,
Jonathan
Quoted 3 lines
Thanks for your time,
Angel
Jonathan Cameron
maintainerRe: [PATCH v2 1/5] iio: pressure: bmp280: Add enumeration to handle chip variants
In reply to Angel IglesiasQuoted 3 lines · On Mon, 26 Dec 2022 15:29:20 +0100 Angel Iglesias <[email protected]>…
Adds enumeration to improve handling the different supported sensors on driver initialization. This avoid collisions if different variants share the same device idetifier on ID register.
If we get two parts with the same ID that need different handling then we should probably be shouting at Bosch. Still I don't mind tidying this up anyway as using the CHIP_IDs is messy - however...
Please be careful to make sure you have responded (either by changes, or by replying to review to say why you aren't making changes). If you are not receiving all emails, then you can always check lore.kernel.org to make sure you didn't miss any reviews.
As Andy suggested, switch over to using pointers to the chip_info structure as the data element in *_device_id tables. It usually ends up neater in the end than messing around with an indirection via an enum value.
Quoted 56 lines
Signed-off-by Angel Iglesias <[email protected]>drivers/iio/pressure/bmp280-core.c +6
-2@@ -186,6 +186,7 @@ struct bmp280_data {struct bmp280_chip_info {unsigned int id_reg; +const unsigned int chip_id;const struct iio_chan_spec *channels;int num_channels;@@ -907,6 +908,7 @@ static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 };static const struct bmp280_chip_info bmp280_chip_info = { .id_reg =BMP280_REG_ID , + .chip_id =BMP280_CHIP_ID , .start_up_time =2000 , .channels = bmp280_channels, .num_channels =2 ,@@ -955,6 +957,7 @@ static int bme280_chip_config(struct bmp280_data *data)static const struct bmp280_chip_info bme280_chip_info = { .id_reg =BMP280_REG_ID , + .chip_id =BME280_CHIP_ID , .start_up_time =2000 , .channels = bmp280_channels, .num_channels =3 ,@@ -1321,6 +1324,7 @@ static const int bmp380_iir_filter_coeffs_avail[] = { 1, 2, 4, 8, 16, 32, 64, 12static const struct bmp280_chip_info bmp380_chip_info = { .id_reg =BMP380_REG_ID , + .chip_id =BMP380_CHIP_ID , .start_up_time =2000 , .channels = bmp380_channels, .num_channels =2 ,@@ -1581,6 +1585,7 @@ static const int bmp180_oversampling_press_avail[] = { 1, 2, 4, 8 };static const struct bmp280_chip_info bmp180_chip_info = { .id_reg =BMP280_REG_ID , + .chip_id =BMP180_CHIP_ID , .start_up_time =2000 , .channels = bmp280_channels, .num_channels =2 ,@@ -1685,16 +1690,16 @@ int bmp280_common_probe(struct device *dev, indio_dev->modes =INDIO_DIRECT_MODE ;switch (chip) { -case BMP180_CHIP_ID : +case BMP180 : chip_info = &bmp180_chip_info;break ; -case BMP280_CHIP_ID :
drivers/iio/pressure/bmp280-core.c int bmp280_common_probe(struct device *dev, · line 1703
Quoted 10 lines
drivers/iio/pressure/bmp280-core.c +3
-2+case BMP280 : chip_info = &bmp280_chip_info;break ; -case BME280_CHIP_ID : +case BME280 : chip_info = &bme280_chip_info;break ; -case BMP380_CHIP_ID : +case BMP380 : chip_info = &bmp380_chip_info;
If you use a pointer directly then no need for this switch statement at all.
Quoted 128 lines
drivers/iio/pressure/bmp280-core.c +2
-2break ;default :@@ -1751,9 +1756,9 @@ 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 != chip) { +if (chip_id != data->chip_info->chip_id) {dev_err (dev,"bad chip id: expected %x got %x\n" , - chip, chip_id); + data->chip_info->chip_id, chip_id);return -EINVAL ; }drivers/iio/pressure/bmp280-i2c.c +14
-14@@ -12,14 +12,14 @@ static int bmp280_i2c_probe(struct i2c_client *client)const struct i2c_device_id *id =i2c_client_get_device_id (client);switch (id->driver_data) { -case BMP180_CHIP_ID : +case BMP180 : regmap_config = &bmp180_regmap_config;break ; -case BMP280_CHIP_ID : -case BME280_CHIP_ID : +case BMP280 : +case BME280 : regmap_config = &bmp280_regmap_config;break ; -case BMP380_CHIP_ID : +case BMP380 : regmap_config = &bmp380_regmap_config;break ;default :@@ -40,21 +40,21 @@ static int bmp280_i2c_probe(struct i2c_client *client) }static const struct of_device_id bmp280_of_i2c_match[] = { - { .compatible ="bosch,bmp085" , .data = (void *)BMP180_CHIP_ID }, - { .compatible ="bosch,bmp180" , .data = (void *)BMP180_CHIP_ID }, - { .compatible ="bosch,bmp280" , .data = (void *)BMP280_CHIP_ID }, - { .compatible ="bosch,bme280" , .data = (void *)BME280_CHIP_ID }, - { .compatible ="bosch,bmp380" , .data = (void *)BMP380_CHIP_ID }, + { .compatible ="bosch,bmp085" , .data = (void *)BMP180 }, + { .compatible ="bosch,bmp180" , .data = (void *)BMP180 }, + { .compatible ="bosch,bmp280" , .data = (void *)BMP280 }, + { .compatible ="bosch,bme280" , .data = (void *)BME280 }, + { .compatible ="bosch,bmp380" , .data = (void *)BMP380 }, { }, };MODULE_DEVICE_TABLE (of, bmp280_of_i2c_match);static const struct i2c_device_id bmp280_i2c_id[] = { - {"bmp085" ,BMP180_CHIP_ID }, - {"bmp180" ,BMP180_CHIP_ID }, - {"bmp280" ,BMP280_CHIP_ID }, - {"bme280" ,BME280_CHIP_ID }, - {"bmp380" ,BMP380_CHIP_ID }, + {"bmp085" ,BMP180 }, + {"bmp180" ,BMP180 }, + {"bmp280" ,BMP280 }, + {"bme280" ,BME280 }, + {"bmp380" ,BMP380 }, { }, };MODULE_DEVICE_TABLE (i2c, bmp280_i2c_id);drivers/iio/pressure/bmp280-spi.c +9
-9@@ -59,14 +59,14 @@ static int bmp280_spi_probe(struct spi_device *spi) }switch (id->driver_data) { -case BMP180_CHIP_ID : +case BMP180 : regmap_config = &bmp180_regmap_config;break ; -case BMP280_CHIP_ID : -case BME280_CHIP_ID : +case BMP280 : +case BME280 : regmap_config = &bmp280_regmap_config;break ; -case BMP380_CHIP_ID : +case BMP380 : regmap_config = &bmp380_regmap_config;break ;default :@@ -101,11 +101,11 @@ static const struct of_device_id bmp280_of_spi_match[] = {MODULE_DEVICE_TABLE (of, bmp280_of_spi_match);static const struct spi_device_id bmp280_spi_id[] = { - {"bmp180" ,BMP180_CHIP_ID }, - {"bmp181" ,BMP180_CHIP_ID }, - {"bmp280" ,BMP280_CHIP_ID }, - {"bme280" ,BME280_CHIP_ID }, - {"bmp380" ,BMP380_CHIP_ID }, + {"bmp180" ,BMP180 }, + {"bmp181" ,BMP180 }, + {"bmp280" ,BMP280 }, + {"bme280" ,BME280 }, + {"bmp380" ,BMP380 }, { } };MODULE_DEVICE_TABLE (spi, bmp280_spi_id);drivers/iio/pressure/bmp280.h +8
-0@@ -191,6 +191,14 @@#define BMP280_PRESS_SKIPPED 0x80000#define BMP280_HUMIDITY_SKIPPED 0x8000 +/* Enum with supported pressure sensor models */ +enum bmp280_variant { +BMP180 , +BMP280 , +BME280 , +BMP380 , +}; +/* Regmap configurations */ extern const struct regmap_config bmp180_regmap_config;extern const struct regmap_config bmp280_regmap_config;
Re: [PATCH v2 1/5] iio: pressure: bmp280: Add enumeration to handle chip variants
Quoted 11 lines · Jonathan Cameron
Quoted 3 lines · On Mon, 26 Dec 2022 15:29:20 +0100 Angel Iglesias <[email protected]>…
Adds enumeration to improve handling the different supported sensors on driver initialization. This avoid collisions if different variants share the same device idetifier on ID register.
If we get two parts with the same ID that need different handling then we should probably be shouting at Bosch. Still I don't mind tidying this up anyway as using the
CHIP_IDsis messy - however...
Quoted 6 lines
Please be careful to make sure you have responded (either by changes, or by replying to review to say why you aren't making changes). If you are not receiving
all emails, then you can always check lore.kernel.org to make sure you didn't miss
any reviews.
I've been away for the week visiting family and friends. Sorry for leaving your reviews lingering unanswered.
Yeah, I kinda rushed this part of the patch to send it before christmas, not my brightest call. I like Andy suggestion, but I have a few questions on handling the regmap and the chip config using the pointers, please refer to the reply I sent to Andy review for the details.
Thanks for your time,
Angel
Quoted 210 lines
As Andy suggested, switch over to using pointers to the
chip_infostructure as the
data element in*_device_idtables. It usually ends up neater in the end than messing around with an indirection via an enum value.Quoted 62 lines
Signed-off-by Angel Iglesias <[email protected]>drivers/iio/pressure/bmp280-core.c +0
-0@@ -186,6 +186,7 @@ struct bmp280_data {
structbmp280_chip_info{
unsigned intid_reg;
+ const unsigned intchip_id;
const structiio_chan_spec*channels;
intnum_channels;drivers/iio/pressure/bmp280-core.c +0
-0@@ -907,6 +908,7 @@ static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 };
static const structbmp280_chip_infobmp280_chip_info= { .id_reg =BMP280_REG_ID,
+ .chip_id =BMP280_CHIP_ID,
.start_up_time = 2000,
.channels =bmp280_channels, .num_channels = 2,drivers/iio/pressure/bmp280-core.c +0
-0@@ -955,6 +957,7 @@ static int bme280_chip_config(struct bmp280_data *data)
static const structbmp280_chip_infobme280_chip_info= { .id_reg =BMP280_REG_ID,
+ .chip_id =BME280_CHIP_ID,
.start_up_time = 2000,
.channels =bmp280_channels, .num_channels = 3,drivers/iio/pressure/bmp280-core.c +0
-0@@ -1321,6 +1324,7 @@ static const int bmp380_iir_filter_coeffs_avail[] = {1, 2, 4, 8, 16, 32, 64, 12
static const structbmp280_chip_infobmp380_chip_info= { .id_reg =BMP380_REG_ID,
+ .chip_id =BMP380_CHIP_ID,
.start_up_time = 2000,
.channels =bmp380_channels, .num_channels = 2,drivers/iio/pressure/bmp280-core.c +0
-0@@ -1581,6 +1585,7 @@ static const int bmp180_oversampling_press_avail[] = { 1, 2, 4, 8 };
static const structbmp280_chip_infobmp180_chip_info= { .id_reg =BMP280_REG_ID,
+ .chip_id =BMP180_CHIP_ID,
.start_up_time = 2000,
.channels =bmp280_channels, .num_channels = 2,drivers/iio/pressure/bmp280-core.c +0
-0@@ -1685,16 +1690,16 @@ int bmp280_common_probe(struct device *dev, indio_dev->modes = INDIO_DIRECT_MODE;
switch (chip) {
- caseBMP180_CHIP_ID:
+ case BMP180:
chip_info =&bmp180_chip_info;
break;
- caseBMP280_CHIP_ID:
+ case BMP280:
chip_info =&bmp280_chip_info;Quoted 8 lines
break;
- caseBME280_CHIP_ID:
+ case BME280:
chip_info =&bme280_chip_info;
break;
- caseBMP380_CHIP_ID:
+ case BMP380:
chip_info =&bmp380_chip_info;If you use a pointer directly then no need for this switch statement at all.
Quoted 131 lines
break;
default:drivers/iio/pressure/bmp280-core.c +2
-2@@ -1751,9 +1756,9 @@ 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 != chip) { + if (chip_id != data->chip_info->chip_id) { dev_err(dev, "bad chip id: expected %x got %x\n", - chip, chip_id); + data->chip_info->chip_id, chip_id); return -EINVAL; }drivers/iio/pressure/bmp280-i2c.c +0
-0@@ -12,14 +12,14 @@ static int bmp280_i2c_probe(struct i2c_client *client) const struct i2c_device_id *id = i2c_client_get_device_id(client);
switch (id->driver_data) {
- caseBMP180_CHIP_ID:
+ case BMP180:
regmap_config =&bmp180_regmap_config; break;
- caseBMP280_CHIP_ID:
- caseBME280_CHIP_ID:
+ case BMP280:
+ case BME280:
regmap_config =&bmp280_regmap_config; break;
- caseBMP380_CHIP_ID:
+ case BMP380:
regmap_config =&bmp380_regmap_config; break;
default:drivers/iio/pressure/bmp280-i2c.c +0
-0@@ -40,21 +40,21 @@ static int bmp280_i2c_probe(struct i2c_client *client) }
static const structof_device_idbmp280_of_i2c_match[] = {
- { .compatible = "bosch,bmp085", .data = (void *)BMP180_CHIP_ID }, - { .compatible = "bosch,bmp180", .data = (void *)BMP180_CHIP_ID }, - { .compatible = "bosch,bmp280", .data = (void *)BMP280_CHIP_ID }, - { .compatible = "bosch,bme280", .data = (void *)BME280_CHIP_ID }, - { .compatible = "bosch,bmp380", .data = (void *)BMP380_CHIP_ID }, + { .compatible = "bosch,bmp085", .data = (void *)BMP180 }, + { .compatible = "bosch,bmp180", .data = (void *)BMP180 }, + { .compatible = "bosch,bmp280", .data = (void *)BMP280 }, + { .compatible = "bosch,bme280", .data = (void *)BME280 }, + { .compatible = "bosch,bmp380", .data = (void *)BMP380 }, { },
};
MODULE_DEVICE_TABLE(of,bmp280_of_i2c_match);
static const structi2c_device_idbmp280_i2c_id[] = {
- {"bmp085",BMP180_CHIP_ID},
- {"bmp180",BMP180_CHIP_ID},
- {"bmp280",BMP280_CHIP_ID},
- {"bme280",BME280_CHIP_ID},
- {"bmp380",BMP380_CHIP_ID},
+ {"bmp085", BMP180 },
+ {"bmp180", BMP180 },
+ {"bmp280", BMP280 },
+ {"bme280", BME280 },
+ {"bmp380", BMP380 },
{ },
};
MODULE_DEVICE_TABLE(i2c,bmp280_i2c_id);drivers/iio/pressure/bmp280-spi.c +0
-0@@ -59,14 +59,14 @@ static int bmp280_spi_probe(struct spi_device *spi) }
switch (id->driver_data) {
- caseBMP180_CHIP_ID:
+ case BMP180:
regmap_config =&bmp180_regmap_config; break;
- caseBMP280_CHIP_ID:
- caseBME280_CHIP_ID:
+ case BMP280:
+ case BME280:
regmap_config =&bmp280_regmap_config; break;
- caseBMP380_CHIP_ID:
+ case BMP380:
regmap_config =&bmp380_regmap_config; break;
default:drivers/iio/pressure/bmp280-spi.c +0
-0@@ -101,11 +101,11 @@ static const struct of_device_id bmp280_of_spi_match[] = { MODULE_DEVICE_TABLE(of, bmp280_of_spi_match);
static const structspi_device_idbmp280_spi_id[] = { - { "bmp180",BMP180_CHIP_ID},
- { "bmp181",BMP180_CHIP_ID},
- { "bmp280",BMP280_CHIP_ID},
- { "bme280",BME280_CHIP_ID},
- { "bmp380",BMP380_CHIP_ID},
+ { "bmp180", BMP180 },
+ { "bmp181", BMP180 },
+ { "bmp280", BMP280 },
+ { "bme280", BME280 },
+ { "bmp380", BMP380 },
{ }
};
MODULE_DEVICE_TABLE(spi,bmp280_spi_id);drivers/iio/pressure/bmp280.h +0
-0@@ -191,6 +191,14 @@ #define BMP280_PRESS_SKIPPED 0x80000 #define BMP280_HUMIDITY_SKIPPED 0x8000drivers/iio/pressure/bmp280.h +8
-0+/* Enum with supported pressure sensor models */ +enum bmp280_variant { + BMP180, + BMP280, + BME280, + BMP380, +}; +/* Regmap configurations */
extern const structregmap_configbmp180_regmap_config; extern const structregmap_configbmp280_regmap_config;
PATCH v2 2/5 iio: pressure: bmp280: Add preinit callback
In reply to Angel IglesiasAdds preinit callback to execute operations on probe before applying initial configuration.
drivers/iio/pressure/bmp280-core.c +18 -3
@@ -217,6 +217,7 @@ struct bmp280_chip_info {int (*read_press)(struct bmp280_data *,int *,int *);int (*read_humid)(struct bmp280_data *,int *,int *);int (*read_calib)(struct bmp280_data *); +int (*preinit)(struct bmp280_data *); };/*
@@ -935,6 +936,7 @@ static const struct bmp280_chip_info bmp280_chip_info = { .read_temp = bmp280_read_temp, .read_press = bmp280_read_press, .read_calib = bmp280_read_calib, + .preinit = NULL, };static int bme280_chip_config (struct bmp280_data *data)
@@ -979,6 +981,7 @@ static const struct bmp280_chip_info bme280_chip_info = { .read_press = bmp280_read_press, .read_humid = bmp280_read_humid, .read_calib = bme280_read_calib, + .preinit = NULL, };/*
@@ -1220,6 +1223,12 @@ static const int bmp380_odr_table[][2] = { [BMP380_ODR_0_0015HZ] = {0, 1526}, }; +static int bmp380_preinit (struct bmp280_data *data) +{ +/* BMP3xx requires soft-reset as part of initialization */ +return bmp380_cmd (data,BMP380_CMD_SOFT_RESET ); +} +static int bmp380_chip_config (struct bmp280_data *data) {bool change = false, aux;
@@ -1349,6 +1358,7 @@ static const struct bmp280_chip_info bmp380_chip_info = { .read_temp = bmp380_read_temp, .read_press = bmp380_read_press, .read_calib = bmp380_read_calib, + .preinit = bmp380_preinit, };static int bmp180_measure (struct bmp280_data *data,u8 ctrl_meas)
@@ -1604,6 +1614,7 @@ static const struct bmp280_chip_info bmp180_chip_info = { .read_temp = bmp180_read_temp, .read_press = bmp180_read_press, .read_calib = bmp180_read_calib, + .preinit = NULL, };static irqreturn_t bmp085_eoc_irq (int irq,void *d)
@@ -1762,9 +1773,13 @@ int bmp280_common_probe(struct device *dev,return -EINVAL ; } -/* BMP3xx requires soft-reset as part of initialization */ -if (chip_id ==BMP380_CHIP_ID ) { - ret =bmp380_cmd (data,BMP380_CMD_SOFT_RESET ); +/* +* Some chips like the BMP3xx have preinit tasks to run +* before applying the initial configuration. +*/ +if (data->chip_info->preinit) { + ret = data->chip_info->preinit (data); +dev_err (dev,"error running preinit tasks" );if (ret <0 )return ret; }
Signature · 1 line
2.39.0
Re: [PATCH v2 2/5] iio: pressure: bmp280: Add preinit callback
Quoted 2 lines · Angel Iglesias
Adds preinit callback to execute operations on probe before applying initial configuration.
...
Quoted 9 lines
drivers/iio/pressure/bmp280-core.c +1
-0@@ -935,6 +936,7 @@ static const struct bmp280_chip_info bmp280_chip_info = { .read_temp = bmp280_read_temp, .read_press = bmp280_read_press, .read_calib = bmp280_read_calib, + .preinit = NULL, };static int bme280_chip_config (struct bmp280_data *data)
drivers/iio/pressure/bmp280-core.c static const struct bmp280_chip_info bme280_chip_info = { · line 985
Quoted 5 lines
drivers/iio/pressure/bmp280-core.c +1
-0@@ -979,6 +981,7 @@ static const struct bmp280_chip_info bme280_chip_info = { .read_press = bmp280_read_press, .read_humid = bmp280_read_humid, .read_calib = bme280_read_calib, + .preinit = NULL, };
Useless changes.
...
drivers/iio/pressure/bmp280-core.c static const struct bmp280_chip_info bmp180_chip_info = { · line 1618
Quoted 6 lines
drivers/iio/pressure/bmp280-core.c +1
-0@@ -1604,6 +1614,7 @@ static const struct bmp280_chip_info bmp180_chip_info = { .read_temp = bmp180_read_temp, .read_press = bmp180_read_press, .read_calib = bmp180_read_calib, + .preinit = NULL, };
Ditto.
...
drivers/iio/pressure/bmp280-core.c int bmp280_common_probe(struct device *dev, · line 1782
Quoted 8 lines
drivers/iio/pressure/bmp280-core.c +7
-0+/* +* Some chips like the BMP3xx have preinit tasks to run +* before applying the initial configuration. +*/ +if (data->chip_info->preinit) { + ret = data->chip_info->preinit (data); +dev_err (dev,"error running preinit tasks" );
Huh?! I guess you wanted
drivers/iio/pressure/bmp280-core.c int bmp280_common_probe(struct device *dev, · line 1784
Quoted 2 lines
drivers/iio/pressure/bmp280-core.c +0
-0if (ret <0 )return ret;
if (ret < 0) return dev_err_probe(...);
Quoted 1 line
}
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH v2 2/5] iio: pressure: bmp280: Add preinit callback
Quoted 46 lines · Andy Shevchenko
Quoted 2 lines · Angel Iglesias
Adds preinit callback to execute operations on probe before applying initial configuration.
...
Quoted 10 lines
drivers/iio/pressure/bmp280-core.c +1
-0@@ -935,6 +936,7 @@ static const struct bmp280_chip_info bmp280_chip_info = { .read_temp = bmp280_read_temp, .read_press = bmp280_read_press, .read_calib = bmp280_read_calib, + .preinit = NULL, };
static intbme280_chip_config(struct bmp280_data *data)drivers/iio/pressure/bmp280-core.c static const struct bmp280_chip_info bme280_chip_info = · line 986
Quoted 6 lines
drivers/iio/pressure/bmp280-core.c +1
-0@@ -979,6 +981,7 @@ static const struct bmp280_chip_info bme280_chip_info = { .read_press = bmp280_read_press, .read_humid = bmp280_read_humid, .read_calib = bme280_read_calib, + .preinit = NULL, };Useless changes.
...
drivers/iio/pressure/bmp280-core.c static const struct bmp280_chip_info bmp180_chip_info · line 1619
Quoted 7 lines
drivers/iio/pressure/bmp280-core.c +1
-0@@ -1604,6 +1614,7 @@ static const struct bmp280_chip_info bmp180_chip_info = { .read_temp = bmp180_read_temp, .read_press = bmp180_read_press, .read_calib = bmp180_read_calib, + .preinit = NULL, };Ditto.
...
Quoted 6 lines
drivers/iio/pressure/bmp280-core.c +6
-0+ /* + * Some chips like the BMP3xx have preinit tasks to run + * before applying the initial configuration. + */ + if (data->chip_info->preinit) { + ret = data->chip_info->preinit(data);
Quoted 3 lines
Quoted 1 line
+ dev_err(dev, "error running preinit tasks");
Huh?! I guess you wanted
The dangers of copying paste and rushing things etc. Sorry for this brain fart!
Thanks for your time,
Angel
Quoted 8 lines
Quoted 2 lines
if (ret < 0)
return ret;if (ret < 0)
returndev_err_probe(...);Quoted 1 line
}
Jonathan Cameron
maintainerRe: [PATCH v2 2/5] iio: pressure: bmp280: Add preinit callback
In reply to Angel IglesiasQuoted 18 lines · On Mon, 26 Dec 2022 15:29:21 +0100 Angel Iglesias <[email protected]>…
Adds preinit callback to execute operations on probe before applying initial configuration.
Signed-off-by Angel Iglesias <[email protected]>drivers/iio/pressure/bmp280-core.c +1
-0@@ -217,6 +217,7 @@ struct bmp280_chip_info {int (*read_press)(struct bmp280_data *,int *,int *);int (*read_humid)(struct bmp280_data *,int *,int *);int (*read_calib)(struct bmp280_data *); +int (*preinit)(struct bmp280_data *); };/*
drivers/iio/pressure/bmp280-core.c static const struct bmp280_chip_info bmp280_chip_info = { · line 939
Quoted 4 lines
drivers/iio/pressure/bmp280-core.c +1
-0@@ -935,6 +936,7 @@ static const struct bmp280_chip_info bmp280_chip_info = { .read_temp = bmp280_read_temp, .read_press = bmp280_read_press, .read_calib = bmp280_read_calib, + .preinit = NULL,
C standard guarantees those are set to NULL anyway + the default is obvious. Hence don't set them to NULL, just leave the automatic initialization of unspecified structure elements to handle it for you.
Quoted 41 lines
drivers/iio/pressure/bmp280-core.c +9
-0};static int bme280_chip_config (struct bmp280_data *data)@@ -979,6 +981,7 @@ static const struct bmp280_chip_info bme280_chip_info = { .read_press = bmp280_read_press, .read_humid = bmp280_read_humid, .read_calib = bme280_read_calib, + .preinit = NULL, };/* @@ -1220,6 +1223,12 @@ static const int bmp380_odr_table[][2] = { [BMP380_ODR_0_0015HZ] = {0, 1526}, }; +static int bmp380_preinit (struct bmp280_data *data) +{ +/* BMP3xx requires soft-reset as part of initialization */ +return bmp380_cmd (data,BMP380_CMD_SOFT_RESET ); +} +static int bmp380_chip_config (struct bmp280_data *data) {bool change = false, aux;@@ -1349,6 +1358,7 @@ static const struct bmp280_chip_info bmp380_chip_info = { .read_temp = bmp380_read_temp, .read_press = bmp380_read_press, .read_calib = bmp380_read_calib, + .preinit = bmp380_preinit, };static int bmp180_measure (struct bmp280_data *data,u8 ctrl_meas)@@ -1604,6 +1614,7 @@ static const struct bmp280_chip_info bmp180_chip_info = { .read_temp = bmp180_read_temp, .read_press = bmp180_read_press, .read_calib = bmp180_read_calib, + .preinit = NULL, };static irqreturn_t bmp085_eoc_irq (int irq,void *d)
drivers/iio/pressure/bmp280-core.c int bmp280_common_probe(struct device *dev, · line 1779
Quoted 10 lines
drivers/iio/pressure/bmp280-core.c +4
-3@@ -1762,9 +1773,13 @@ int bmp280_common_probe(struct device *dev,return -EINVAL ; } -/* BMP3xx requires soft-reset as part of initialization */ -if (chip_id ==BMP380_CHIP_ID ) { - ret =bmp380_cmd (data,BMP380_CMD_SOFT_RESET ); +/* +* Some chips like the BMP3xx have preinit tasks to run +* before applying the initial configuration. +*/
I would drop this comment. It's kind of obvious that some devices need you to call something here - otherwise why have the clearly optional callback? The specific BMP3xx requirements are well commented in your new callback above so don't want to be here as well.
drivers/iio/pressure/bmp280-core.c int bmp280_common_probe(struct device *dev, · line 1782
Quoted 3 lines
drivers/iio/pressure/bmp280-core.c +3
-0+if (data->chip_info->preinit) { + ret = data->chip_info->preinit (data); +dev_err (dev,"error running preinit tasks" );
Error message printed on success...
drivers/iio/pressure/bmp280-core.c int bmp280_common_probe(struct device *dev, · line 1784
Quoted 2 lines
drivers/iio/pressure/bmp280-core.c +0
-0if (ret <0 )return ret;
return dev_err_probe(dev, ret, "error running preinit tasks");
Quoted 1 line
drivers/iio/pressure/bmp280-core.c +0
-0}
Re: [PATCH v2 2/5] iio: pressure: bmp280: Add preinit callback
Quoted 22 lines · Jonathan Cameron
Quoted 19 lines · On Mon, 26 Dec 2022 15:29:21 +0100 Angel Iglesias <[email protected]>…
Adds preinit callback to execute operations on probe before applying initial configuration.
Signed-off-by Angel Iglesias <[email protected]>drivers/iio/pressure/bmp280-core.c +1
-0@@ -217,6 +217,7 @@ struct bmp280_chip_info { int (*read_press)(struct bmp280_data *, int *, int *); int (*read_humid)(struct bmp280_data *, int *, int *); int (*read_calib)(struct bmp280_data *); + int (*preinit)(struct bmp280_data *); };
/*drivers/iio/pressure/bmp280-core.c +0
-0@@ -935,6 +936,7 @@ static const struct bmp280_chip_info bmp280_chip_info =
Quoted 8 lines
drivers/iio/pressure/bmp280-core.c static const struct bmp280_chip_info bmp280_chip_info = { · line 939
Quoted 5 lines
drivers/iio/pressure/bmp280-core.c +1
-0{ .read_temp = bmp280_read_temp, .read_press = bmp280_read_press, .read_calib = bmp280_read_calib, + .preinit = NULL,C standard guarantees those are set to NULL anyway + the default is obvious. Hence don't set them to NULL, just leave the automatic initialization of unspecified structure elements to handle it for you.
OK! Note to self: compiler knows best!
Quoted 59 lines
Quoted 46 lines
drivers/iio/pressure/bmp280-core.c +0
-0};
static intbme280_chip_config(struct bmp280_data *data)drivers/iio/pressure/bmp280-core.c +1
-0@@ -979,6 +981,7 @@ static const struct bmp280_chip_info bme280_chip_info = { .read_press = bmp280_read_press, .read_humid = bmp280_read_humid, .read_calib = bme280_read_calib, + .preinit = NULL, };
/*drivers/iio/pressure/bmp280-core.c +0
-0@@ -1220,6 +1223,12 @@ static const int bmp380_odr_table[][2] = { [BMP380_ODR_0_0015HZ] = {0, 1526}, };drivers/iio/pressure/bmp280-core.c +6
-0+static int bmp380_preinit (struct bmp280_data *data) +{ + /* BMP3xx requires soft-reset as part of initialization */ + return bmp380_cmd(data, BMP380_CMD_SOFT_RESET); +} +static int
bmp380_chip_config(struct bmp280_data *data){
bool change = false, aux;drivers/iio/pressure/bmp280-core.c +1
-0@@ -1349,6 +1358,7 @@ static const struct bmp280_chip_info bmp380_chip_info = { .read_temp = bmp380_read_temp, .read_press = bmp380_read_press, .read_calib = bmp380_read_calib, + .preinit = bmp380_preinit, };
static intbmp180_measure(struct bmp280_data *data, u8 ctrl_meas)drivers/iio/pressure/bmp280-core.c +1
-0@@ -1604,6 +1614,7 @@ static const struct bmp280_chip_info bmp180_chip_info = { .read_temp = bmp180_read_temp, .read_press = bmp180_read_press, .read_calib = bmp180_read_calib, + .preinit = NULL, };
staticirqreturn_tbmp085_eoc_irq(int irq, void *d)drivers/iio/pressure/bmp280-core.c +0
-0@@ -1762,9 +1773,13 @@ int bmp280_common_probe(struct device *dev, return -EINVAL; }Quoted 8 lines
- /* BMP3xx requires soft-reset as part of initialization */ - if (chip_id==BMP380_CHIP_ID) {
- ret =bmp380_cmd(data, BMP380_CMD_SOFT_RESET); + /*
+ * Some chips like the BMP3xx have preinit tasks to run + * before applying the initial configuration.
+ */I would drop this comment. It's kind of obvious that some devices need you to call something here - otherwise why have the clearly optional callback? The specific BMP3xx requirements are well commented in your new callback above so don't want to be here as well.
Quoted 5 lines
Quoted 3 lines
+ if (
data->chip_info->preinit) {
+ ret =data->chip_info->preinit(data); + dev_err(dev, "error running preinit tasks");Error message printed on success...
Yup, sorry about that...
Quoted 9 lines
Quoted 3 lines
if (ret < 0)
return ret;return
dev_err_probe(dev, ret, "error running preinit tasks");Quoted 1 line
}
Thanks for your time!
Angel
PATCH v2 3/5 iio: pressure: bmp280: Add support for new sensor BMP580
In reply to Angel IglesiasAdds compatibility with the new sensor generation, the BMP580.
The measurement and initialization codepaths are adapted from the device datasheet and the repository from manufacturer at
https://github.com/boschsensortec/BMP5-Sensor-API.
drivers/iio/pressure/Kconfig +3 -3
@@ -17,14 +17,14 @@ config ABP060MG will be called abp060mg. config BMP280 - tristate "Bosch Sensortec BMP180/BMP280/BMP380 pressure sensor I2C driver" + tristate "Bosch Sensortec BMP180/BMP280/BMP380/BMP580 pressure sensor I2C driver" depends on (I2C || SPI_MASTER) select REGMAP select BMP280_I2C if (I2C) select BMP280_SPI if (SPI_MASTER) help - Say yes here to build support for Bosch Sensortec BMP180, BMP280 and - BMP380 pressure and temperature sensors. Also supports the BME280 with + Say yes here to build support for Bosch Sensortec BMP180, BMP280, BMP380 + and BMP580 pressure and temperature sensors. Also supports the BME280 with an additional humidity sensor channel. To compile this driver as a module, choose M here: the core module
drivers/iio/pressure/bmp280-core.c +441 -7
485 lines not on this page · raw message
drivers/iio/pressure/bmp280-i2c.c +5 -0
@@ -22,6 +22,9 @@ static int bmp280_i2c_probe(struct i2c_client *client)case BMP380 : regmap_config = &bmp380_regmap_config;break ; +case BMP580 : + regmap_config = &bmp580_regmap_config; +break ;default :return -EINVAL ; }
@@ -45,6 +48,7 @@ static const struct of_device_id bmp280_of_i2c_match[] = { { .compatible = "bosch,bmp280", .data = (void *)BMP280 }, { .compatible = "bosch,bme280", .data = (void *)BME280 }, { .compatible = "bosch,bmp380", .data = (void *)BMP380 }, + { .compatible = "bosch,bmp580", .data = (void *)BMP580 }, { }, };MODULE_DEVICE_TABLE (of, bmp280_of_i2c_match);
@@ -55,6 +59,7 @@ static const struct i2c_device_id bmp280_i2c_id[] = { {"bmp280", BMP280 }, {"bme280", BME280 }, {"bmp380", BMP380 }, + {"bmp580", BMP580 }, { }, };MODULE_DEVICE_TABLE (i2c, bmp280_i2c_id);
drivers/iio/pressure/bmp280-regmap.c +60 -0
69 lines not on this page · raw message
drivers/iio/pressure/bmp280-spi.c +5 -0
@@ -69,6 +69,9 @@ static int bmp280_spi_probe(struct spi_device *spi)case BMP380 : regmap_config = &bmp380_regmap_config;break ; +case BMP580 : + regmap_config = &bmp580_regmap_config; +break ;default :return -EINVAL ; }
@@ -96,6 +99,7 @@ static const struct of_device_id bmp280_of_spi_match[] = { { .compatible = "bosch,bmp280", }, { .compatible = "bosch,bme280", }, { .compatible = "bosch,bmp380", }, + { .compatible = "bosch,bmp580", }, { }, }; MODULE_DEVICE_TABLE(of, bmp280_of_spi_match);
@@ -106,6 +110,7 @@ static const struct spi_device_id bmp280_spi_id[] = { { "bmp280", BMP280 }, { "bme280", BME280 }, { "bmp380", BMP380 }, + { "bmp580", BMP580 }, { } };MODULE_DEVICE_TABLE (spi, bmp280_spi_id);
drivers/iio/pressure/bmp280.h +104 -0
128 lines not on this page · raw message
Signature · 1 line
2.39.0
Re: [PATCH v2 3/5] iio: pressure: bmp280: Add support for new sensor BMP580
Le 26/12/2022 à 15:29, Angel Iglesias a écrit :
Quoted 8 lines
Adds compatibility with the new sensor generation, the BMP580.
The measurement and initialization codepaths are adapted from the device datasheet and the repository from manufacturer at
https://github.com/boschsensortec/BMP5-Sensor-API.Signed-off-by Angel Iglesias <[email protected]>
[...]
Quoted 4 lines
drivers/iio/pressure/bmp280.h +0
-0
[...]
Quoted 2 lines
+#define
BMP580_CHIP_ID0x50
#defineBMP380_CHIP_ID0x50
Hi,
this is maybe correct (I've not been able to find the datasheet to check myself), but it looks odd to have the same ID for 2 different chips.
CJ
Quoted 2 lines
#define BMP180_CHIP_ID 0x55 #define BMP280_CHIP_ID 0x58
Re: [PATCH v2 3/5] iio: pressure: bmp280: Add support for new sensor BMP580
Quoted 20 lines · Christophe JAILLET
Le 26/12/2022 à 15:29, Angel Iglesias a écrit :
Quoted 9 lines
Adds compatibility with the new sensor generation, the BMP580.
The measurement and initialization codepaths are adapted from the device datasheet and the repository from manufacturer at
https://github.com/boschsensortec/BMP5-Sensor-API.Signed-off-by: Angel Iglesias <[email protected]>
[...]
Quoted 4 lines
drivers/iio/pressure/bmp280.h +0
-0[...]
Quoted 7 lines
Quoted 2 lines
+#define BMP580_CHIP_ID 0x50 #define BMP380_CHIP_ID 0x50
Hi,
this is maybe correct (I've not been able to find the datasheet to check myself), but it looks odd to have the same ID for 2 different chips.
Yes, I also couldn't find a datasheet for the BMP580 or a devkit anywhere. I'm developing this using the BMP581, which seems to be a variant almost identical. Something similar happened with the BMP38x; you could find the BMP384 and the BMP388, but the BMP380 was unavailable everywhere, datasheet included. My guess is this is a similar situation. In any case, the datasheet of the BMP581 is available here:
https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp581-ds004.pdf
Regarding the chip id being the same between generations is weird, but at least the datasheet and the sensor I have uses 0x50 as the chip id. After you mentioned this, I checked back on the reference API repository from Bosch and it has both 0x50 and 0x51 as valid IDs:
* https://github.com/boschsensortec/BMP5-Sensor-API/blob/master/bmp5_defs.h#L198
* https://github.com/boschsensortec/BMP5-Sensor-API/blob/master/bmp5.c#L1444
Angel
Quoted 5 lines
CJ
Quoted 2 lines
#define BMP180_CHIP_ID 0x55 #define BMP280_CHIP_ID 0x58
Jonathan Cameron
maintainerRe: [PATCH v2 3/5] iio: pressure: bmp280: Add support for new sensor BMP580
Quoted 37 lines · On Thu, 29 Dec 2022 19:23:16 +0100 Angel Iglesias <[email protected]>…
Quoted 20 lines · Christophe JAILLET
Le 26/12/2022 à 15:29, Angel Iglesias a écrit :
Quoted 9 lines
Adds compatibility with the new sensor generation, the BMP580.
The measurement and initialization codepaths are adapted from the device datasheet and the repository from manufacturer at
https://github.com/boschsensortec/BMP5-Sensor-API.Signed-off-by: Angel Iglesias <[email protected]>
[...]
Quoted 4 lines
drivers/iio/pressure/bmp280.h +0
-0[...]
Quoted 7 lines
Quoted 2 lines
+#define BMP580_CHIP_ID 0x50 #define BMP380_CHIP_ID 0x50
Hi,
this is maybe correct (I've not been able to find the datasheet to check myself), but it looks odd to have the same ID for 2 different chips.
Yes, I also couldn't find a datasheet for the BMP580 or a devkit anywhere. I'm developing this using the BMP581, which seems to be a variant almost identical. Something similar happened with the BMP38x; you could find the BMP384 and the BMP388, but the BMP380 was unavailable everywhere, datasheet included. My guess is this is a similar situation. In any case, the datasheet of the BMP581 is available here:
https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp581-ds004.pdf
Quoted 6 lines
Regarding the chip id being the same between generations is weird, but at least the datasheet and the sensor I have uses
0x50as the chip id. After you mentioned this, I checked back on the reference API repository from Bosch and it has both0x50and0x51as valid IDs:
* https://github.com/boschsensortec/BMP5-Sensor-API/blob/master/bmp5_defs.h#L198
* https://github.com/boschsensortec/BMP5-Sensor-API/blob/master/bmp5.c#L1444
https://github.com/boschsensortec/BMP3-Sensor-API/blob/master/bmp3_defs.h
I was curious on whether we had a wrong value for bmp380, but nope... Same ID.
Huh. As per earlier comment - who wants to moan at Bosch as this is crazy situation?
Jonathan
Quoted 9 lines
Angel
Quoted 5 lines
CJ
Quoted 2 lines
#define BMP180_CHIP_ID 0x55 #define BMP280_CHIP_ID 0x58
Re: [PATCH v2 3/5] iio: pressure: bmp280: Add support for new sensor BMP580
Quoted 54 lines · Jonathan Cameron
Quoted 42 lines · On Thu, 29 Dec 2022 19:23:16 +0100 Angel Iglesias <[email protected]>…
Quoted 21 lines · Christophe JAILLET
Le 26/12/2022 à 15:29, Angel Iglesias a écrit :
Quoted 9 lines
Adds compatibility with the new sensor generation, the BMP580.
The measurement and initialization codepaths are adapted from the device datasheet and the repository from manufacturer at
https://github.com/boschsensortec/BMP5-Sensor-API.Signed-off-by: Angel Iglesias <[email protected]>
[...]
drivers/iio/pressure/bmp280.h
Quoted 5 lines
drivers/iio/pressure/bmp280.h +0
-0[...]
Quoted 7 lines
Quoted 2 lines
+#define BMP580_CHIP_ID 0x50 #define BMP380_CHIP_ID 0x50
Hi,
this is maybe correct (I've not been able to find the datasheet to check myself), but it looks odd to have the same ID for 2 different chips.
Yes, I also couldn't find a datasheet for the BMP580 or a devkit anywhere. I'm
developing this using the BMP581, which seems to be a variant almost identical.
Something similar happened with the BMP38x; you could find the BMP384 and the
BMP388, but the BMP380 was unavailable everywhere, datasheet included. My guess
is this is a similar situation. In any case, the datasheet of the BMP581 is available here:
https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp581-ds004.pdfQuoted 9 lines
Regarding the chip id being the same between generations is weird, but at least
the datasheet and the sensor I have uses0x50as the chip id. After you mentioned this, I checked back on the reference API repository from Bosch and it
has both0x50and0x51as valid IDs:
*
https://github.com/boschsensortec/BMP5-Sensor-API/blob/master/bmp5_defs.h#L198
* https://github.com/boschsensortec/BMP5-Sensor-API/blob/master/bmp5.c#L1444
Quoted 7 lines
https://github.com/boschsensortec/BMP3-Sensor-API/blob/master/bmp3_defs.h
I was curious on whether we had a wrong value for bmp380, but nope... Same ID.Huh. As per earlier comment - who wants to moan at Bosch as this is crazy situation?
Jonathan
Well I'm doing this in my free time beacuse I wanted to setup a meteo station and got annoyed needing to patch-up userspace code for reading pressure and temperature sensors on a very underpowered ARM device when there is a kernel subsystem for this kind of things. The rest is history on the mailing list. I don't think I have any leverage to have Bosch listening to my complaints
Angel
Quoted 11 lines
Quoted 10 lines
Angel
Quoted 5 lines
CJ
Quoted 2 lines
#define BMP180_CHIP_ID 0x55 #define BMP280_CHIP_ID 0x58
Jonathan Cameron
maintainerRe: [PATCH v2 3/5] iio: pressure: bmp280: Add support for new sensor BMP580
Quoted 61 lines · On Sun, 01 Jan 2023 12:16:28 +0100 Angel Iglesias <[email protected]>…
Quoted 60 lines · Jonathan Cameron
Quoted 42 lines · On Thu, 29 Dec 2022 19:23:16 +0100 Angel Iglesias <[email protected]>…
Quoted 21 lines · Christophe JAILLET
Le 26/12/2022 à 15:29, Angel Iglesias a écrit :
Quoted 9 lines
Adds compatibility with the new sensor generation, the BMP580.
The measurement and initialization codepaths are adapted from the device datasheet and the repository from manufacturer at
https://github.com/boschsensortec/BMP5-Sensor-API.Signed-off-by: Angel Iglesias <[email protected]>
[...]
drivers/iio/pressure/bmp280.h
Quoted 5 lines
drivers/iio/pressure/bmp280.h +0
-0[...]
Quoted 7 lines
Quoted 2 lines
+#define BMP580_CHIP_ID 0x50 #define BMP380_CHIP_ID 0x50
Hi,
this is maybe correct (I've not been able to find the datasheet to check myself), but it looks odd to have the same ID for 2 different chips.
Yes, I also couldn't find a datasheet for the BMP580 or a devkit anywhere. I'm
developing this using the BMP581, which seems to be a variant almost identical.
Something similar happened with the BMP38x; you could find the BMP384 and the
BMP388, but the BMP380 was unavailable everywhere, datasheet included. My guess
is this is a similar situation. In any case, the datasheet of the BMP581 is available here:
https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp581-ds004.pdfQuoted 9 lines
Regarding the chip id being the same between generations is weird, but at least
the datasheet and the sensor I have uses0x50as the chip id. After you mentioned this, I checked back on the reference API repository from Bosch and it
has both0x50and0x51as valid IDs:
*
https://github.com/boschsensortec/BMP5-Sensor-API/blob/master/bmp5_defs.h#L198
* https://github.com/boschsensortec/BMP5-Sensor-API/blob/master/bmp5.c#L1444https://github.com/boschsensortec/BMP3-Sensor-API/blob/master/bmp3_defs.h
I was curious on whether we had a wrong value for bmp380, but nope... Same ID.Huh. As per earlier comment - who wants to moan at Bosch as this is crazy situation?
Quoted 7 lines
Quoted 1 line
Jonathan
Well I'm doing this in my free time beacuse I wanted to setup a meteo station and got annoyed needing to patch-up userspace code for reading pressure and temperature sensors on a very underpowered ARM device when there is a kernel subsystem for this kind of things. The rest is history on the mailing list. I don't think I have any leverage to have Bosch listening to my complaints
Sadly I don't have a good contact in Bosch. So all we can do is +CC the contact address.
If anyone else has a good channel to point out this silliness please do!
Jonathan
Quoted 15 lines
Angel
Quoted 11 lines
Quoted 10 lines
Angel
Quoted 5 lines
CJ
Quoted 2 lines
#define BMP180_CHIP_ID 0x55 #define BMP280_CHIP_ID 0x58
RE: [PATCH v2 3/5] iio: pressure: bmp280: Add support for new sensor BMP580
Dear Jonathan and Angel,
Aligned with our product management, we can confirm that the CHIP-IDs are identiacal, this is correct.
Best regards,
Bosch Sensortec Sales Support
Bosch Sensortec GmbH | Gerhard-Kindler-Straße 9 | 72770 Reutlingen | GERMANY | www.bosch-sensortec.com
Sitz: Kusterdingen, Registergericht: Stuttgart HRB 382674, Ust.IdNr. DE 183276693 - Steuer-Nr. 99012/08040 Geschäftsführung: Stefan Finkbeiner, Jens-Knut Fabrowsky
-----Original Message-----
From: Jonathan Cameron <[email protected]>
Sent: Sonntag, 8. Januar 2023 13:35
To: Angel Iglesias <[email protected]>
Cc: Christophe JAILLET <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Contact Bosch-Sensortec (BST/SA) <[email protected]>
Subject: Re: [PATCH v2 3/5] iio: pressure: bmp280: Add support for new sensor BMP580
Quoted 85 lines · On Sun, 01 Jan 2023 12:16:28 +0100 Angel Iglesias <[email protected]>…
Quoted 84 lines · Jonathan Cameron
Quoted 61 lines · On Thu, 29 Dec 2022 19:23:16 +0100 Angel Iglesias <[email protected]>…
Quoted 21 lines · Christophe JAILLET
Le 26/12/2022 à 15:29, Angel Iglesias a écrit :
Quoted 9 lines
Adds compatibility with the new sensor generation, the BMP580.
The measurement and initialization codepaths are adapted from the device datasheet and the repository from manufacturer at
https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fboschsensortec%2FBMP5-Sensor-API&data=05%7C01%7Ccontact%40bosch-sensortec.com%7C5df3784517c940394e8308daf172e38e%7C0ae51e1907c84e4bbb6d648ee58410f4%7C0%7C0%7C638087774478147184%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=YarsZiHIZ%2FBkNNqK%2FunjfVWGgIwOtvf%2BPXs8ipHQdRQ%3D&reserved=0.Signed-off-by: Angel Iglesias <[email protected]>
[...]
drivers/iio/pressure/bmp280.h
Quoted 5 lines
(quoted diff) +0
-0
b/drivers/iio/pressure/bmp280.hindexefc31bc84708..27d2abc17d01100644drivers/iio/pressure/bmp280.h +0
-0[...]
Quoted 7 lines
Quoted 2 lines
+#define BMP580_CHIP_ID 0x50 #define BMP380_CHIP_ID 0x50
Hi,
this is maybe correct (I've not been able to find the datasheet to check myself), but it looks odd to have the same ID for 2 different chips.
Yes, I also couldn't find a datasheet for the BMP580 or a devkit anywhere. I'm
developing this using the BMP581, which seems to be a variant almost identical.
Something similar happened with the BMP38x; you could find the BMP384 and the BMP388, but the BMP380 was unavailable everywhere, datasheet included. My guess is this is a similar situation. In any case, the datasheet of the BMP581 is available here:
https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2F
www.bosch-sensortec.com%2Fmedia%2Fboschsensortec%2Fdownloads%2Fdat asheets%2Fbst-bmp581-ds004.pdf&data=05%7C01%7Ccontact%40bosch-sens ortec.com%7C5df3784517c940394e8308daf172e38e%7C0ae51e1907c84e4bbb6 d648ee58410f4%7C0%7C0%7C638087774478147184%7CUnknown%7CTWFpbGZsb3d 8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3 D%7C3000%7C%7C%7C&sdata=dNnnClouPfqXntLuTWGQovRw39ehaLeuzKuN%2FNWI 8y0%3D&reserved=0Regarding the chip id being the same between generations is weird, but at least the datasheet and the sensor I have uses
0x50as the chip id. After you mentioned this, I checked back on the reference API repository from Bosch and it has both0x50and0x51as valid IDs:
*
https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2F
github.com%2Fboschsensortec%2FBMP5-Sensor-API%2Fblob%2Fmaster%2Fbm p5_defs.h%23L198&data=05%7C01%7Ccontact%40bosch-sensortec.com%7C5d f3784517c940394e8308daf172e38e%7C0ae51e1907c84e4bbb6d648ee58410f4% 7C0%7C0%7C638087774478147184%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wL jAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C %7C&sdata=tZgYdnxpvKIndjtJaaFfcAJbBa4%2FcIgKhb4XH6sAO9A%3D&reserve d=0Quoted 8 lines
*
https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2F
github.com%2Fboschsensortec%2FBMP5-Sensor-API%2Fblob%2Fmaster%2Fbm p5.c%23L1444&data=05%7C01%7Ccontact%40bosch-sensortec.com%7C5df378 4517c940394e8308daf172e38e%7C0ae51e1907c84e4bbb6d648ee58410f4%7C0% 7C0%7C638087774478147184%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwM DAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C& sdata=xU9Yh2zXjol0vyF9iltRmkBK3CUlGGdcjrp3AzwvTNU%3D&reserved=0https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgi
thub.com%2Fboschsensortec%2FBMP3-Sensor-API%2Fblob%2Fmaster%2Fbmp3_d efs.h&data=05%7C01%7Ccontact%40bosch-sensortec.com%7C5df3784517c9403 94e8308daf172e38e%7C0ae51e1907c84e4bbb6d648ee58410f4%7C0%7C0%7C63808 7774478147184%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2 luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=faQZ4qjLF jfYN2US64FbZJo%2B5lOuFw52mIY3XqoXDKU%3D&reserved=0
I was curious on whether we had a wrong value for bmp380, but nope... Same ID.Huh. As per earlier comment - who wants to moan at Bosch as this is crazy situation?
Quoted 8 lines
Quoted 1 line
Jonathan
Well I'm doing this in my free time beacuse I wanted to setup a meteo
station and got annoyed needing to patch-up userspace code for reading
pressure and temperature sensors on a very underpowered ARM device
when there is a kernel subsystem for this kind of things. The rest is history on the mailing list. I don't think I have any leverage to have Bosch listening to my
complaints
Sadly I don't have a good contact in Bosch. So all we can do is +CC the contact address.
If anyone else has a good channel to point out this silliness please do!
Jonathan
Quoted 15 lines
Angel
Quoted 11 lines
Quoted 10 lines
Angel
Quoted 5 lines
CJ
Quoted 2 lines
#define BMP180_CHIP_ID 0x55 #define BMP280_CHIP_ID 0x58
Jonathan Cameron
maintainerRe: [PATCH v2 3/5] iio: pressure: bmp280: Add support for new sensor BMP580
In reply to Angel IglesiasQuoted 7 lines · On Mon, 26 Dec 2022 15:29:22 +0100 Angel Iglesias <[email protected]>…
Adds compatibility with the new sensor generation, the BMP580.
The measurement and initialization codepaths are adapted from the device datasheet and the repository from manufacturer at
https://github.com/boschsensortec/BMP5-Sensor-API.Signed-off-by Angel Iglesias <[email protected]>
Hi Angel,
Some comments inline,
Thanks,
Jonathan
drivers/iio/pressure/Kconfig config ABP060MG · line 20
Quoted 11 lines
drivers/iio/pressure/Kconfig +1
-1@@ -17,14 +17,14 @@ config ABP060MG will be called abp060mg. config BMP280 - tristate "Bosch Sensortec BMP180/BMP280/BMP380 pressure sensor I2C driver" + tristate "Bosch Sensortec BMP180/BMP280/BMP380/BMP580 pressure sensor I2C driver"
Future reference: If this gets much longer we'll have to shorten to "BMP280 and similar" like we have already had to do for a bunch of other drivers that support too many parts to fit in the short description. We carry on listing them all in the help though.
I think this is the last time we can get aways with it.
I2C driver? Looks to be handling SPI as well.
Quoted 12 lines
drivers/iio/pressure/Kconfig +2
-2depends on (I2C || SPI_MASTER) select REGMAP select BMP280_I2C if (I2C) select BMP280_SPI if (SPI_MASTER) help - Say yes here to build support for Bosch Sensortec BMP180, BMP280 and - BMP380 pressure and temperature sensors. Also supports the BME280 with + Say yes here to build support for Bosch Sensortec BMP180, BMP280, BMP380 + and BMP580 pressure and temperature sensors. Also supports the BME280 with an additional humidity sensor channel. To compile this driver as a module, choose M here: the core module
...
drivers/iio/pressure/Kconfig
Quoted 12 lines
drivers/iio/pressure/Kconfig +12
-0+ +/* + * Helper function to send a command to BMP5XX sensors. + * + * BMP5xx sensors have a series of commands actionable + * writing specific sequences on the CMD register: + * SOFT_RESET: performs a reset of the system. + * NVM_READ: read the contents of a user position of the nvm memory. + * NVM_WRITE: write new data to a user position of the nvm memory. + * EXT_MODE: enable extended mode with additional debug pages. + */ +static int bmp580_cmd(struct bmp280_data *data, enum bmp580_commands cmd)
Is there an advantage in rolling these up in one function? There seems to be no real shared code. Also most of this isn't used currently I think, so perhaps should be introduced alongside code that uses it.
Quoted 5 lines
drivers/iio/pressure/Kconfig +5
-0+{ + unsigned long deadline; + unsigned int reg; + int ret; +
drivers/iio/pressure/Kconfig
Quoted 10 lines
drivers/iio/pressure/Kconfig +10
-0+ switch (cmd) { + case BMP580_SOFT_RESET_CMD: + /* Send reset word */ + ret = regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_SOFT_RESET); + if (ret) { + dev_err(data->dev, "failed to send reset command to device\n"); + return ret; + } + /* Wait 2ms for reset completion */ + usleep_range(2000, 2500);
blank line.
drivers/iio/pressure/Kconfig
Quoted 6 lines
drivers/iio/pressure/Kconfig +6
-0+ /* Dummy read of chip_id */ + ret = regmap_read(data->regmap, BMP580_REG_CHIP_ID, ®); + if (ret) { + dev_err(data->dev, "failed to reestablish comms after reset\n"); + return ret; + }
blank line etc. See below for reasoning.
Quoted 83 lines
drivers/iio/pressure/Kconfig +83
-0+ /* Check if POR bit is set on interrupt reg */ + ret = regmap_read(data->regmap, BMP580_REG_INT_STATUS, ®); + if (ret) { + dev_err(data->dev, "error reading interrupt status register\n"); + return ret; + } + if (!(reg & BMP580_INT_STATUS_POR_MASK)) { + dev_err(data->dev, "error resetting sensor\n"); + return -EINVAL; + } + break; + case BMP580_NVM_WRITE_CMD: + case BMP580_NVM_READ_CMD: + /* Check nvm ready flag */ + ret = regmap_read(data->regmap, BMP580_REG_STATUS, ®); + if (ret) { + dev_err(data->dev, "failed to check nvm status\n"); + return ret; + } + if (!(reg & BMP580_STATUS_NVM_RDY_MASK)) { + dev_err(data->dev, "sensor's nvm is not ready\n"); + return -EIO; + } + /* Send NVM operation sequence */ + ret = regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_NVM_OP_SEQ_0); + if (ret) { + dev_err(data->dev, "failed to send nvm operation's first sequence\n"); + return ret; + } + if (cmd == BMP580_NVM_WRITE_CMD) { + /* Send write sequence */ + ret = regmap_write(data->regmap, BMP580_REG_CMD, + BMP580_CMD_NVM_WRITE_SEQ_1); + if (ret) { + dev_err(data->dev, "failed to send nvm write sequence\n"); + return ret; + } + /* Datasheet says on 4.8.1.2 it takes approximately 10ms */ + usleep_range(10000, 10500); + deadline = jiffies + msecs_to_jiffies(10); + } else { + /* Send read sequence */ + ret = regmap_write(data->regmap, BMP580_REG_CMD, + BMP580_CMD_NVM_READ_SEQ_1); + if (ret) { + dev_err(data->dev, "failed to send nvm read sequence\n"); + return ret; + } + /* Datasheet says on 4.8.1.1 it takes approximately 200us */ + usleep_range(200, 250); + deadline = jiffies + usecs_to_jiffies(200); + } + if (ret) { + dev_err(data->dev, "failed to write command sequence\n"); + return -EIO; + } + /* Wait until NVM is ready again */ + do { + ret = regmap_read(data->regmap, BMP580_REG_STATUS, ®); + if (ret) { + dev_err(data->dev, "failed to check nvm status\n"); + reg &= ~BMP580_STATUS_NVM_RDY_MASK; + } + } while (time_before(jiffies, deadline) && !(reg & BMP580_STATUS_NVM_RDY_MASK)); + + if (!(reg & BMP580_STATUS_NVM_RDY_MASK)) { + dev_err(data->dev, + "reached timeout waiting for nvm operation completion\n"); + return -ETIMEDOUT; + } + /* Checks nvm error flags */ + if ((reg & BMP580_STATUS_NVM_ERR_MASK) || (reg & BMP580_STATUS_NVM_CMD_ERR_MASK)) { + dev_err(data->dev, "error processing nvm operation\n"); + return -EIO; + } + break; + case BMP580_EXT_MODE_CMD: + ret = regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_EXTMODE_SEQ_0); + if (ret) { + dev_err(data->dev, "failed to send ext_mode first sequence\n"); + return ret; + } + ret = regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_EXTMODE_SEQ_1);
drivers/iio/pressure/Kconfig
Quoted 10 lines
drivers/iio/pressure/Kconfig +10
-0+ if (ret) { + dev_err(data->dev, "failed to send ext_mode second sequence\n"); + return ret; + } + ret = regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_EXTMODE_SEQ_2); + if (ret) { + dev_err(data->dev, "failed to send ext_mode second sequence\n"); + return ret; + } + break;
Might as well return from each of the instead of break. slightly reduces the code anyone interested in a particular flow needs to look at.
Quoted 4 lines
drivers/iio/pressure/Kconfig +4
-0+ } + + return 0; +}
...
Quoted 14 lines
drivers/iio/pressure/Kconfig +14
-0+ +static int bmp580_read_press(struct bmp280_data *data, int *val, int *val2) +{ + u32 raw_press; + int ret; + + ret = regmap_bulk_read(data->regmap, BMP580_REG_PRESS_XLSB, data->buf, + sizeof(data->buf)); + if (ret) { + dev_err(data->dev, "failed to read pressure\n"); + return ret; + } + + raw_press = get_unaligned_le24(data->buf);
drivers/iio/pressure/Kconfig
Quoted 10 lines
drivers/iio/pressure/Kconfig +10
-0+ if (raw_press == BMP580_PRESS_SKIPPED) { + dev_err(data->dev, "reading pressure skipped\n"); + return -EIO; + } + /* + * Pressure is returned in Pascals in fractional form down 2^16. + * We reescale /1000 to convert to kilopascal to respect IIO ABI. + */ + *val = raw_press; + *val2 = 64000; // 2^6 * 1000
/* */ syntax for comments in IIO.
Quoted 2 lines
drivers/iio/pressure/Kconfig +2
-0+ return IIO_VAL_FRACTIONAL; +}
...
drivers/iio/pressure/Kconfig
Quoted 9 lines
drivers/iio/pressure/Kconfig +9
-0+static int bmp580_preinit(struct bmp280_data *data) +{ + unsigned int reg; + int ret; + + /* Issue soft-reset command */ + ret = bmp580_cmd(data, BMP580_SOFT_RESET_CMD); + if (ret) + return ret;
Blank line here and similar places. Nice to keep unrelated blocks of code separate.
drivers/iio/pressure/Kconfig
Quoted 6 lines
drivers/iio/pressure/Kconfig +6
-0+ /* Post powerup sequence */ + ret = regmap_read(data->regmap, BMP580_REG_CHIP_ID, ®); + if (ret) + return ret; + if (reg != BMP580_CHIP_ID) { + dev_err(data->dev, "preinit: unexpected chip_id\n");
I'd rather this was just an info print and carry on. If Bosch brings another device out that is sufficiently compatible and we use a fallback dt compatible for it - so that it works with older kernels then we might want to indicate we aren't sure we can handle the chip correctly but then assume the DT description was correct and carry on anyway.
Quoted 14 lines
drivers/iio/pressure/Kconfig +14
-0+ return -EINVAL; + } + ret = regmap_read(data->regmap, BMP580_REG_STATUS, ®); + if (ret) + return ret; + /* Check nvm status */ + if (!(reg & BMP580_STATUS_NVM_RDY_MASK) || (reg & BMP580_STATUS_NVM_ERR_MASK)) { + dev_err(data->dev, "preinit: nvm error on powerup sequence\n"); + return -EIO; + } + + return 0; +} +
...
drivers/iio/pressure/Kconfig
Quoted 2 lines
drivers/iio/pressure/Kconfig +2
-0+static const int bmp580_oversampling_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128 }; +static const int bmp580_iir_filter_coeffs_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
Up to you, but you could take advantage of the fact this array matches the bmp380 one. It is arguable that the code is clearer with it not being reused though so your choice.
Quoted 18 lines
drivers/iio/pressure/Kconfig +18
-0+ +static const struct bmp280_chip_info bmp580_chip_info = { + .id_reg = BMP580_REG_CHIP_ID, + .chip_id = BMP580_CHIP_ID, + .start_up_time = 2000, + .channels = bmp380_channels, + .num_channels = 2, + + .oversampling_temp_avail = bmp580_oversampling_avail, + .num_oversampling_temp_avail = ARRAY_SIZE(bmp580_oversampling_avail), + .oversampling_temp_default = ilog2(1), + + .oversampling_press_avail = bmp580_oversampling_avail, + .num_oversampling_press_avail = ARRAY_SIZE(bmp580_oversampling_avail), + .oversampling_press_default = ilog2(4), + + .sampling_freq_avail = bmp580_odr_table, + .num_sampling_freq_avail = ARRAY_SIZE(bmp580_odr_table) * 2,
drivers/iio/pressure/Kconfig
Quoted 10 lines
drivers/iio/pressure/Kconfig +10
-0+ .sampling_freq_default = BMP580_ODR_50HZ, + + .iir_filter_coeffs_avail = bmp580_iir_filter_coeffs_avail, + .num_iir_filter_coeffs_avail = ARRAY_SIZE(bmp580_iir_filter_coeffs_avail), + .iir_filter_coeff_default = 2, + + .chip_config = bmp580_chip_config, + .read_temp = bmp580_read_temp, + .read_press = bmp580_read_press, + .read_calib = NULL,
As in previous patch, I'd prefer not to see explicit NULL being set for optional elements. Their absence should be enough.
Quoted 17 lines
drivers/iio/pressure/Kconfig +6
-0+ .preinit = bmp580_preinit, +}; + static int bmp180_measure(struct bmp280_data *data, u8 ctrl_meas) { const int conversion_time_max[] = { 4500, 7500, 13500, 25500 };@@ -1713,6 +2142,9 @@ int bmp280_common_probe(struct device *dev, case BMP380: chip_info = &bmp380_chip_info; break; + case BMP580: + chip_info = &bmp580_chip_info; + break; default: return -EINVAL; }
drivers/iio/pressure/Kconfig int bmp280_common_probe(struct device *dev, · line 2216
Quoted 8 lines
drivers/iio/pressure/Kconfig +2
-2@@ -1779,9 +2211,10 @@ int bmp280_common_probe(struct device *dev, */ if (data->chip_info->preinit) { ret = data->chip_info->preinit(data); - dev_err(dev, "error running preinit tasks"); - if (ret < 0) + if (ret) { + dev_err(dev, "error running preinit tasks\n"); return ret;
Wrong patch. + use dev_error_probe() like the case below already does.
Quoted 5 lines
drivers/iio/pressure/Kconfig +1
-0+ } } ret = data->chip_info->chip_config(data);
drivers/iio/pressure/Kconfig int bmp280_common_probe(struct device *dev, · line 2231
Quoted 9 lines
drivers/iio/pressure/Kconfig +1
-5@@ -1795,11 +2228,12 @@ int bmp280_common_probe(struct device *dev, * non-volatile memory during production". Let's read them out at probe * time once. They will not change. */ - - ret = data->chip_info->read_calib(data); - if (ret < 0) - return dev_err_probe(data->dev, ret, - "failed to read calibration coefficients\n"); + if (data->chip_info->read_calib) {
Small thing, but ideally this no op refactoring should have been a precursor patch rather than buried in here. It's small enough though that I don't care enough to insist you break it out.
Quoted 13 lines
drivers/iio/pressure/Kconfig +5
-0+ ret = data->chip_info->read_calib(data); + if (ret < 0) + return dev_err_probe(data->dev, ret, + "failed to read calibration coefficients\n"); + } /* * Attempt to grab an optional EOC IRQ - only the BMP085 has thisdrivers/iio/pressure/bmp280-i2c.c +0
-0
drivers/iio/pressure/bmp280-i2c.c static int bmp280_i2c_probe(struct i2c_client *client) · line 26
Quoted 5 lines
drivers/iio/pressure/bmp280-i2c.c +2
-0@@ -22,6 +22,9 @@ static int bmp280_i2c_probe(struct i2c_client *client)case BMP380 : regmap_config = &bmp380_regmap_config;break ; +case BMP580 : + regmap_config = &bmp580_regmap_config;
whilst here, similar to below, it would be nice to switch to generic firmware methods as default way to get the match data then fallback to the i2c_device_id table if that fails (as we did old school i2c probing from a board file or from userspace).
Quoted 26 lines
drivers/iio/pressure/bmp280-i2c.c +3
-0+break ;default :return -EINVAL ; }@@ -45,6 +48,7 @@ static const struct of_device_id bmp280_of_i2c_match[] = { { .compatible = "bosch,bmp280", .data = (void *)BMP280 }, { .compatible = "bosch,bme280", .data = (void *)BME280 }, { .compatible = "bosch,bmp380", .data = (void *)BMP380 }, + { .compatible = "bosch,bmp580", .data = (void *)BMP580 }, { }, };MODULE_DEVICE_TABLE (of, bmp280_of_i2c_match);@@ -55,6 +59,7 @@ static const struct i2c_device_id bmp280_i2c_id[] = { {"bmp280", BMP280 }, {"bme280", BME280 }, {"bmp380", BMP380 }, + {"bmp580", BMP580 }, { }, };MODULE_DEVICE_TABLE (i2c, bmp280_i2c_id);drivers/iio/pressure/bmp280-spi.c +0
-0
drivers/iio/pressure/bmp280-spi.c static int bmp280_spi_probe(struct spi_device *spi) · line 73
Quoted 5 lines
drivers/iio/pressure/bmp280-spi.c +2
-0@@ -69,6 +69,9 @@ static int bmp280_spi_probe(struct spi_device *spi)case BMP380 : regmap_config = &bmp380_regmap_config;break ; +case BMP580 : + regmap_config = &bmp580_regmap_config;
If using a pointer as suggested you'd get this for free :)
I'd also like to see this driver move to using the of_device_id table via device_get_match_data() first then fallback to the spi_device_id table
only if that fails. Otherwise for dt supprot, we are relying on a match
based on stripping the bosch prefix of the of compatible and that is nasty.
Quoted 25 lines
drivers/iio/pressure/bmp280-spi.c +3
-0+break ;default :return -EINVAL ; }@@ -96,6 +99,7 @@ static const struct of_device_id bmp280_of_spi_match[] = { { .compatible = "bosch,bmp280", }, { .compatible = "bosch,bme280", }, { .compatible = "bosch,bmp380", }, + { .compatible = "bosch,bmp580", }, { }, }; MODULE_DEVICE_TABLE(of, bmp280_of_spi_match);@@ -106,6 +110,7 @@ static const struct spi_device_id bmp280_spi_id[] = { { "bmp280", BMP280 }, { "bme280", BME280 }, { "bmp380", BMP380 }, + { "bmp580", BMP580 }, { } };MODULE_DEVICE_TABLE (spi, bmp280_spi_id);drivers/iio/pressure/bmp280.h +0
-0@@ -3,6 +3,107 @@
...
Quoted 2 lines
+#define
BMP580_CHIP_ID0x50
#defineBMP380_CHIP_ID0x50
Well given we can't order them by ID value, probably best to have the set with a given ID in alphabetical order. So swap the two above.
Quoted 17 lines
#define
BMP180_CHIP_ID0x55
#defineBMP280_CHIP_ID0x58drivers/iio/pressure/bmp280.h +2
-0@@ -197,12 +299,14 @@ enum bmp280_variant {BMP280 ,BME280 ,BMP380 , + BMP580, };/* Regmap configurations */ extern const struct regmap_config bmp180_regmap_config;extern const struct regmap_config bmp280_regmap_config;extern const struct regmap_config bmp380_regmap_config; +extern const struct regmap_config bmp580_regmap_config;/* Probe called from different transports */ int bmp280_common_probe(struct device *dev,
Re: [PATCH v2 3/5] iio: pressure: bmp280: Add support for new sensor BMP580
Quoted 39 lines · Jonathan Cameron
Quoted 7 lines · On Mon, 26 Dec 2022 15:29:22 +0100 Angel Iglesias <[email protected]>…
Adds compatibility with the new sensor generation, the BMP580.
The measurement and initialization codepaths are adapted from the device datasheet and the repository from manufacturer at
https://github.com/boschsensortec/BMP5-Sensor-API.Signed-off-by Angel Iglesias <[email protected]>Hi Angel,
Some comments inline,
Thanks,
Jonathan
Quoted 6 lines
drivers/iio/pressure/Kconfig +0
-0@@ -17,14 +17,14 @@ config ABP060MGQuoted 7 lines
will be called abp060mg.
config BMP280
- tristate "Bosch Sensortec BMP180/BMP280/BMP380 pressure sensor I2C driver"
+ tristate "Bosch Sensortec BMP180/BMP280/BMP380/BMP580 pressure sensor I2C driver"Future reference: If this gets much longer we'll have to shorten to "BMP280 and similar" like we have already had to do for a bunch of other drivers
that support too many parts to fit in the short description. We carry on listing
them all in the help though.
Quoted 3 lines
I think this is the last time we can get aways with it.
I2C driver? Looks to be handling SPI as well.
Welp, you're right, last time I was here forgot to update the wording.
Quoted 30 lines
Quoted 16 lines
depends on (I2C ||
SPI_MASTER)
select REGMAP
selectBMP280_I2Cif (I2C)
selectBMP280_SPIif (SPI_MASTER)
help
- Say yes here to build support for Bosch Sensortec BMP180, BMP280 and
- BMP380 pressure and temperature sensors. Also supports the BME280 with
+ Say yes here to build support for Bosch Sensortec BMP180, BMP280, BMP380
+ and BMP580 pressure and temperature sensors. Also supports the BME280 with
an additional humidity sensor channel.
To compile this driver as a module, choose M here: the core module...
Quoted 10 lines
drivers/iio/pressure/Kconfig +10
-0+ +/* + * Helper function to send a command to BMP5XX sensors. + * + * BMP5xx sensors have a series of commands actionable + * writing specific sequences on the CMD register: + * SOFT_RESET: performs a reset of the system. + * NVM_READ: read the contents of a user position of the nvm memory. + * NVM_WRITE: write new data to a user position of the nvm memory. + * EXT_MODE: enable extended mode with additional debug pages.
Quoted 8 lines
Quoted 2 lines
+ */
+static intbmp580_cmd(struct bmp280_data *data, enum bmp580_commands cmd)Is there an advantage in rolling these up in one function? There seems to be no real
shared code. Also most of this isn't used currently I think, so perhaps should be
introduced alongside code that uses it.
Probably, would be best to break up this code in two helpers functions for reset and NVM operations and drop the code to setup debugging ext_mode. I'm not using the ext_mode and there's no documentation about the new registers exposed in that mode.
Quoted 209 lines
Quoted 9 lines
drivers/iio/pressure/Kconfig +9
-0+{ + unsigned long deadline; + unsigned int reg; + int ret; + + switch (cmd) { + case BMP580_SOFT_RESET_CMD: + /* Send reset word */ + ret = regmap_write(data->regmap, BMP580_REG_CMD,Quoted 8 lines
BMP580_CMD_SOFT_RESET);
+ if (ret) {
+ dev_err(data->dev, "failed to send reset command to device\n");
+ return ret;
+ }
+ /* Wait 2ms for reset completion */
+ usleep_range(2000, 2500);blank line.
Quoted 7 lines
+ /* Dummy read of
chip_id*/
+ ret =regmap_read(data->regmap, BMP580_REG_CHIP_ID, ®); + if (ret) {
+ dev_err(data->dev, "failed to reestablish comms after reset\n");
+ return ret;
+ }blank line etc. See below for reasoning.
Quoted 106 lines
+ /* Check if POR bit is set on interrupt reg */
+ ret =regmap_read(data->regmap, BMP580_REG_INT_STATUS, ®);
+ if (ret) {
+ dev_err(data->dev, "error reading interrupt status register\n");
+ return ret;
+ }
+ if (!(reg &BMP580_INT_STATUS_POR_MASK)) {
+ dev_err(data->dev, "error resetting sensor\n"); + return-EINVAL;
+ }
+ break;
+ caseBMP580_NVM_WRITE_CMD:
+ caseBMP580_NVM_READ_CMD:
+ /* Check nvm ready flag */
+ ret =regmap_read(data->regmap, BMP580_REG_STATUS, ®); + if (ret) {
+ dev_err(data->dev, "failed to check nvm status\n"); + return ret;
+ }
+ if (!(reg &BMP580_STATUS_NVM_RDY_MASK)) {
+ dev_err(data->dev, "sensor's nvm is not ready\n"); + return-EIO;
+ }
+ /* Send NVM operation sequence */
+ ret =regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_NVM_OP_SEQ_0);
+ if (ret) {
+ dev_err(data->dev, "failed to send nvm operation's first sequence\n");
+ return ret;
+ }
+ if (cmd ==BMP580_NVM_WRITE_CMD) {
+ /* Send write sequence */
+ ret = regmap_write(data->regmap,BMP580_REG_CMD, +BMP580_CMD_NVM_WRITE_SEQ_1); + if (ret) {
+ dev_err(data->dev, "failed to send nvm write sequence\n");
+ return ret;
+ }
+ /* Datasheet says on 4.8.1.2 it takes approximately 10ms */
+ usleep_range(10000, 10500);
+ deadline = jiffies +msecs_to_jiffies(10); + } else {
+ /* Send read sequence */
+ ret = regmap_write(data->regmap,BMP580_REG_CMD, +BMP580_CMD_NVM_READ_SEQ_1); + if (ret) {
+ dev_err(data->dev, "failed to send nvm read sequence\n");
+ return ret;
+ }
+ /* Datasheet says on 4.8.1.1 it takes approximately 200us */
+ usleep_range(200, 250);
+ deadline = jiffies +usecs_to_jiffies(200); + }
+ if (ret) {
+ dev_err(data->dev, "failed to write command sequence\n");
+ return-EIO;
+ }
+ /* Wait until NVM is ready again */
+ do {
+ ret =regmap_read(data->regmap, BMP580_REG_STATUS, ®);
+ if (ret) {
+ dev_err(data->dev, "failed to check nvm status\n");
+ reg &= ~BMP580_STATUS_NVM_RDY_MASK; + }
+ } while (time_before(jiffies, deadline)&& !(reg &BMP580_STATUS_NVM_RDY_MASK));
+
+ if (!(reg &BMP580_STATUS_NVM_RDY_MASK)) {
+ dev_err(data->dev,
+ "reached timeout waiting for nvm operation completion\n");
+ return-ETIMEDOUT;
+ }
+ /* Checks nvm error flags */
+ if ((reg &BMP580_STATUS_NVM_ERR_MASK) || (reg &BMP580_STATUS_NVM_CMD_ERR_MASK)) {
+ dev_err(data->dev, "error processing nvm operation\n");
+ return-EIO;
+ }
+ break;
+ caseBMP580_EXT_MODE_CMD:
+ ret =regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_EXTMODE_SEQ_0);
+ if (ret) {
+ dev_err(data->dev, "failed to sendext_modefirst sequence\n");
+ return ret;
+ }
+ ret =regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_EXTMODE_SEQ_1);
+ if (ret) {
+ dev_err(data->dev, "failed to sendext_modesecond sequence\n");
+ return ret;
+ }Quoted 8 lines
+ ret =
regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_EXTMODE_SEQ_2);
+ if (ret) {
+ dev_err(data->dev, "failed to sendext_modesecond sequence\n");
+ return ret;
+ }
+ break;Might as well return from each of the instead of break. slightly reduces the code
anyone interested in a particular flow needs to look at.Quoted 4 lines
+ }
drivers/iio/pressure/Kconfig +3
-0+ + return 0; +}...
Quoted 17 lines
drivers/iio/pressure/Kconfig +7
-0+ +static int bmp580_read_press(struct bmp280_data *data, int *val, int *val2) +{ + u32 raw_press; + int ret; + + ret = regmap_bulk_read(data->regmap, BMP580_REG_PRESS_XLSB, data-Quoted 1 line
buf,
+
sizeof(data->buf));
+ if (ret) {
+ dev_err(data->dev, "failed to read pressure\n"); + return ret;
+ }
+
+ raw_press =get_unaligned_le24(data->buf);
+ if (raw_press==BMP580_PRESS_SKIPPED) {
+ dev_err(data->dev, "reading pressure skipped\n");Quoted 8 lines
+ return
-EIO;
+ }
+ /*
+ * Pressure is returned in Pascals in fractional form down 2^16. + * We reescale /1000 to convert to kilopascal to respect IIO ABI. + */
+ *val =raw_press;
+ *val2 = 64000; // 2^6 * 1000/* */ syntax for comments in IIO.
Quoted 2 lines
+ return
IIO_VAL_FRACTIONAL;
+}...
drivers/iio/pressure/Kconfig
Quoted 9 lines
drivers/iio/pressure/Kconfig +9
-0+static int bmp580_preinit(struct bmp280_data *data) +{ + unsigned int reg; + int ret; + + /* Issue soft-reset command */ + ret = bmp580_cmd(data, BMP580_SOFT_RESET_CMD); + if (ret) + return ret;Blank line here and similar places. Nice to keep unrelated blocks of code separate.
Quoted 6 lines
+ /* Post powerup sequence */
+ ret =regmap_read(data->regmap, BMP580_REG_CHIP_ID, ®); + if (ret)
+ return ret;
+ if (reg !=BMP580_CHIP_ID) {
+ dev_err(data->dev, "preinit: unexpected chip_id\n");
Quoted 5 lines
I'd rather this was just an info print and carry on. If Bosch brings another device out that is sufficiently compatible and we use a fallback dt compatible for it - so that it works with older kernels then we might want to indicate we aren't sure we can handle the chip correctly but then assume
This sounds a great idea, but this would need a few extra changes to work as intended here:
* In the common probe, before calling to preinit, the device ID is read and compared to expected ID stored in the chip_info. If the IDs are different, we stop initialization with an error
* I should backport this, at least, to the BMP380 preinit call, as I have pending testing if this works well with the BMP390, and sounds like a good candidate. Which, after looking to datasheet, seems to have 0x60 as its chip ID!
Quoted 21 lines
the DT description was correct and carry on anyway.
Quoted 16 lines
+ return
-EINVAL;
+ }
+ ret =regmap_read(data->regmap, BMP580_REG_STATUS, ®); + if (ret)
+ return ret;
+ /* Check nvm status */
+ if (!(reg &BMP580_STATUS_NVM_RDY_MASK) || (reg &BMP580_STATUS_NVM_ERR_MASK)) {
+ dev_err(data->dev, "preinit: nvm error on powerup sequence\n");
+ return-EIO;
+ }drivers/iio/pressure/Kconfig +4
-0+ + return 0; +} +...
Quoted 9 lines
Quoted 4 lines
+static const int bmp580_oversampling_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+static const int bmp580_iir_filter_coeffs_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128 };Up to you, but you could take advantage of the fact this array matches the bmp380 one.
It is arguable that the code is clearer with it not being reused though so your choice.
Hum yes, I could reuse the array for the BMP380, maybe a should use a more generic name for that array to avoid confusion? Something like bmp280_iir_filter_coeffs_avail, refering to the driver name instead of the concrete sensor?
Quoted 77 lines
Quoted 25 lines
drivers/iio/pressure/Kconfig +10
-0+ +static const struct bmp280_chip_info bmp580_chip_info = { + .id_reg = BMP580_REG_CHIP_ID, + .chip_id = BMP580_CHIP_ID, + .start_up_time = 2000, + .channels = bmp380_channels, + .num_channels = 2, + + .oversampling_temp_avail = bmp580_oversampling_avail, + .num_oversampling_temp_avail =
ARRAY_SIZE(bmp580_oversampling_avail),
+ .oversampling_temp_default = ilog2(1),
+
+ .oversampling_press_avail =bmp580_oversampling_avail, + .num_oversampling_press_avail =ARRAY_SIZE(bmp580_oversampling_avail),
+ .oversampling_press_default = ilog2(4),drivers/iio/pressure/Kconfig +7
-0+ + .sampling_freq_avail = bmp580_odr_table, + .num_sampling_freq_avail = ARRAY_SIZE(bmp580_odr_table) * 2, + .sampling_freq_default = BMP580_ODR_50HZ, + + .iir_filter_coeffs_avail = bmp580_iir_filter_coeffs_avail, + .num_iir_filter_coeffs_avail =Quoted 7 lines
ARRAY_SIZE(bmp580_iir_filter_coeffs_avail),
+ .iir_filter_coeff_default = 2,
+
+ .chip_config =bmp580_chip_config,
+ .read_temp =bmp580_read_temp,
+ .read_press =bmp580_read_press,
+ .read_calib = NULL,As in previous patch, I'd prefer not to see explicit NULL being set for optional elements. Their absence should be enough.
Quoted 17 lines
+ .preinit =
bmp580_preinit,drivers/iio/pressure/Kconfig +2
-0+}; +static int
bmp180_measure(struct bmp280_data *data, u8 ctrl_meas){
const int conversion_time_max[] = { 4500, 7500, 13500, 25500 };drivers/iio/pressure/Kconfig +0
-0@@ -1713,6 +2142,9 @@ int bmp280_common_probe(struct device *dev,case BMP380:
chip_info =&bmp380_chip_info;
break;
+ case BMP580:
+ chip_info =&bmp580_chip_info;
+ break;
default:
return-EINVAL;
}drivers/iio/pressure/Kconfig int bmp280_common_probe(struct device *dev, · line 2216
Quoted 8 lines
drivers/iio/pressure/Kconfig +2
-2@@ -1779,9 +2211,10 @@ int bmp280_common_probe(struct device *dev, */ if (data->chip_info->preinit) { ret = data->chip_info->preinit(data); - dev_err(dev, "error running preinit tasks"); - if (ret < 0) + if (ret) { + dev_err(dev, "error running preinit tasks\n"); return ret;Wrong patch. + use
dev_error_probe()like the case below already does.Quoted 14 lines
drivers/iio/pressure/Kconfig +1
-0+ } }
ret =data->chip_info->chip_config(data);drivers/iio/pressure/Kconfig +0
-0@@ -1795,11 +2228,12 @@ int bmp280_common_probe(struct device *dev, * non-volatile memory during production". Let's read them out atprobe
* time once. They will not change.
*/
-
- ret =data->chip_info->read_calib(data);
- if (ret < 0)
- return dev_err_probe(data->dev, ret,
- "failed to read calibration
Quoted 8 lines
Quoted 2 lines
coefficients\n");
+ if (data->chip_info->read_calib) {Small thing, but ideally this no op refactoring should have been a precursor patch
rather than buried in here. It's small enough though that I don't care enough to insist
you break it out.
Sure
Quoted 62 lines
Quoted 16 lines
+ ret =
data->chip_info->read_calib(data);
+ if (ret < 0)
+ return dev_err_probe(data->dev, ret, + "failed to read calibration coefficients\n");
+ }
/*
* Attempt to grab an optional EOC IRQ - only the BMP085 has thisdrivers/iio/pressure/bmp280-i2c.c +0
-0@@ -22,6 +22,9 @@ static int bmp280_i2c_probe(struct i2c_client *client)Quoted 5 lines
case BMP380:
regmap_config =&bmp380_regmap_config; break;
+ case BMP580:
+ regmap_config =&bmp580_regmap_config;whilst here, similar to below, it would be nice to switch to generic firmware methods as default way to get the match data then fallback to the
i2c_device_idtable if that fails (as we did old school i2c probing from a board file or from userspace).Quoted 27 lines
+ break;
default:
return-EINVAL;
}drivers/iio/pressure/bmp280-i2c.c +2
-0@@ -45,6 +48,7 @@ static const struct of_device_id bmp280_of_i2c_match[] = { { .compatible = "bosch,bmp280", .data = (void *)BMP280 }, { .compatible = "bosch,bme280", .data = (void *)BME280 }, { .compatible = "bosch,bmp380", .data = (void *)BMP380 }, + { .compatible = "bosch,bmp580", .data = (void *)BMP580 }, { }, }; MODULE_DEVICE_TABLE(of, bmp280_of_i2c_match);@@ -55,6 +59,7 @@ static const struct i2c_device_id bmp280_i2c_id[] = { {"bmp280", BMP280 }, {"bme280", BME280 }, {"bmp380", BMP380 }, + {"bmp580", BMP580 }, { }, }; MODULE_DEVICE_TABLE(i2c, bmp280_i2c_id);drivers/iio/pressure/bmp280-spi.c +0
-0@@ -69,6 +69,9 @@ static int bmp280_spi_probe(struct spi_device *spi)Quoted 5 lines
case BMP380:
regmap_config =&bmp380_regmap_config; break;
+ case BMP580:
+ regmap_config =&bmp580_regmap_config;If using a pointer as suggested you'd get this for free :)
Quoted 4 lines
I'd also like to see this driver move to using the
of_device_idtable viadevice_get_match_data()first then fallback to thespi_device_idtable only if that fails. Otherwise for dt supprot, we are relying on a match based on stripping the bosch prefix of the of compatible and that is nasty.
Ok! I'll have a look at it and add this as a precursor patch.
Quoted 29 lines
Quoted 26 lines
+ break;
default:
return-EINVAL;
}drivers/iio/pressure/bmp280-spi.c +2
-0@@ -96,6 +99,7 @@ static const struct of_device_id bmp280_of_spi_match[] = { { .compatible = "bosch,bmp280", }, { .compatible = "bosch,bme280", }, { .compatible = "bosch,bmp380", }, + { .compatible = "bosch,bmp580", }, { }, }; MODULE_DEVICE_TABLE(of, bmp280_of_spi_match);@@ -106,6 +110,7 @@ static const struct spi_device_id bmp280_spi_id[] = { { "bmp280", BMP280 }, { "bme280", BME280 }, { "bmp380", BMP380 }, + { "bmp580", BMP580 }, { } }; MODULE_DEVICE_TABLE(spi, bmp280_spi_id);drivers/iio/pressure/bmp280.h +0
-0@@ -3,6 +3,107 @@...
Quoted 6 lines
Quoted 2 lines
+#define BMP580_CHIP_ID 0x50
#define BMP380_CHIP_ID 0x50Well given we can't order them by ID value, probably best to have the set with a given ID in alphabetical order. So swap the two above.
Got it
Quoted 10 lines
Quoted 10 lines
#define BMP180_CHIP_ID 0x55
#define BMP280_CHIP_ID 0x58drivers/iio/pressure/bmp280.h +1
-0@@ -197,12 +299,14 @@ enum bmp280_variant { BMP280, BME280, BMP380, + BMP580, };
Quoted 9 lines
Quoted 8 lines
/* Regmap configurations */
extern const structregmap_configbmp180_regmap_config; extern const structregmap_configbmp280_regmap_config; extern const structregmap_configbmp380_regmap_config; +extern const structregmap_configbmp580_regmap_config;
/* Probe called from different transports */ int bmp280_common_probe(struct device *dev,
Thanks for your time!
Angel
Jonathan Cameron
maintainerRe: [PATCH v2 3/5] iio: pressure: bmp280: Add support for new sensor BMP580
Quoted 11 lines
Quoted 10 lines
Quoted 5 lines
+static const int bmp580_oversampling_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+static const int bmp580_iir_filter_coeffs_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128 };Up to you, but you could take advantage of the fact this array matches the bmp380 one.
It is arguable that the code is clearer with it not being reused though so your choice.
Quoted 4 lines
Hum yes, I could reuse the array for the BMP380, maybe a should use a more generic name for that array to avoid confusion? Something like
bmp280_iir_filter_coeffs_avail, refering to the driver name instead of the concrete sensor?
Don't worry about the naming. Anything clever just tends to cause problems as more parts are added. Just stick to the name of the first part that used it. We've made the mistake of trying for generic names in the past and it bites back!
Jonathan
PATCH v2 4/5 dt-bindings: iio: pressure: bmp085: Add BMP580 compatible string
In reply to Angel IglesiasAdd bosch,bmp580 to compatible string for the new family of sensors. This family includes the BMP580 and BMP581 sensors. The register map in this family presents significant departures from previous generations.
Documentation/devicetree/bindings/iio/pressure/bmp085.yaml +2 -0
@@ -17,6 +17,7 @@ description: | https://www.bosch-sensortec.com/bst/products/all_products/bmp280 https://www.bosch-sensortec.com/bst/products/all_products/bme280 https://www.bosch-sensortec.com/bst/products/all_products/bmp380 + https://www.bosch-sensortec.com/bst/products/all_products/bmp580 properties: compatible:
@@ -26,6 +27,7 @@ properties: - bosch,bmp280 - bosch,bme280 - bosch,bmp380 + - bosch,bmp580 reg: maxItems: 1
Signature · 1 line
2.39.0
Re: [PATCH v2 4/5] dt-bindings: iio: pressure: bmp085: Add BMP580 compatible string
Quoted 5 lines · Angel Iglesias
Add bosch,bmp580 to compatible string for the new family of sensors. This family includes the BMP580 and BMP581 sensors. The register map in this family presents significant departures from previous generations.
Signed-off-by Angel Iglesias <[email protected]>
This is a friendly reminder during the review process.
It looks like you received a tag and forgot to add it.
If you do not know the process, here is a short explanation:
Please add Acked-by/Reviewed-by/Tested-by tags when posting new versions. However, there's no need to repost patches *only* to add the tags. The upstream maintainer will do that for acks received on the version they apply.
https://elixir.bootlin.com/linux/v5.17/source/Documentation/process/submitting-patches.rst#L540
If a tag was not added on purpose, please state why and what changed.
Best regards,
Krzysztof
PATCH v2 5/5 iio: pressure: bmp280: Add nvmem operations for BMP580
In reply to Angel IglesiasThe pressure sensor BMP580 contains a non-volatile memory that stores trimming and configuration params. That memory provides an programmable user range of three 2-byte words.
drivers/iio/pressure/bmp280-core.c +135 -2
@@ -28,6 +28,7 @@#include <linux/bitfield.h> #include <linux/device.h> #include <linux/module.h> +#include <linux/nvmem-provider.h> #include <linux/regmap.h> #include <linux/delay.h> #include <linux/iio/iio.h>
@@ -1628,8 +1629,140 @@ static const int bmp580_odr_table[][2] = { [BMP580_ODR_0_125HZ] = {0, 125000}, }; +const int bmp580_nvmem_addrs[] = {0x20 ,0x21 ,0x22 }; + +static int bmp580_nvmem_read (void *priv,unsigned int offset,void *val, +size_t bytes) +{ +struct bmp280_data *data = priv; +u16 *dst = val; +int ret, addr; + +pm_runtime_get_sync (data->dev); +mutex_lock (&data->lock); + +/* Set sensor in standby mode */ + ret =regmap_update_bits (data->regmap,BMP580_REG_ODR_CONFIG , +BMP580_MODE_MASK |BMP580_ODR_DEEPSLEEP_DIS , +BMP580_ODR_DEEPSLEEP_DIS | +FIELD_PREP (BMP580_MODE_MASK ,BMP580_MODE_SLEEP )); +if (ret) { +dev_err (data->dev,"failed to change sensor to standby mode\n" ); + goto exit; + } +/* Wait standby transition time */ +usleep_range (2500 ,3000 ); + +while (bytes >=sizeof (u16)) { + addr = bmp580_nvmem_addrs[offset /sizeof (u16)]; + + ret =regmap_write (data->regmap,BMP580_REG_NVM_ADDR , +FIELD_PREP (BMP580_NVM_ROW_ADDR_MASK , addr)); +if (ret) { +dev_err (data->dev,"error writing nvm address\n" ); + goto exit; + } + + ret =bmp580_cmd (data,BMP580_NVM_READ_CMD ); +if (ret) + goto exit; + + ret =regmap_bulk_read (data->regmap,BMP580_REG_NVM_DATA_LSB , &data->le16, +sizeof (data->le16)); +if (ret) { +dev_err (data->dev,"error reading nvm data regs\n" ); + goto exit; + } + + *dst++ =le16_to_cpu (data->le16); + bytes -=sizeof (u16); + offset +=sizeof (u16); + } +exit: +/* Restore chip config */ + data->chip_info->chip_config (data); +mutex_unlock (&data->lock); +pm_runtime_mark_last_busy (data->dev); +pm_runtime_put_autosuspend (data->dev); +return ret; +} + +static int bmp580_nvmem_write (void *priv,unsigned int offset,void *val, +size_t bytes) +{ +struct bmp280_data *data = priv; +u16 *buf = val; +int ret, addr; + +pm_runtime_get_sync (data->dev); +mutex_lock (&data->lock); + +/* Set sensor in standby mode */ + ret =regmap_update_bits (data->regmap,BMP580_REG_ODR_CONFIG , +BMP580_MODE_MASK |BMP580_ODR_DEEPSLEEP_DIS , +BMP580_ODR_DEEPSLEEP_DIS | +FIELD_PREP (BMP580_MODE_MASK ,BMP580_MODE_SLEEP )); +if (ret) { +dev_err (data->dev,"failed to change sensor to standby mode\n" ); + goto exit; + } +/* Wait standby transition time */ +usleep_range (2500 ,3000 ); + +while (bytes >=sizeof (u16)) { + addr = bmp580_nvmem_addrs[offset /sizeof (u16)]; + + ret =regmap_write (data->regmap,BMP580_REG_NVM_ADDR ,BMP580_NVM_PROG_EN | +FIELD_PREP (BMP580_NVM_ROW_ADDR_MASK , addr)); +if (ret) { +dev_err (data->dev,"error writing nvm address\n" ); + goto exit; + } + data->le16 =cpu_to_le16 (*buf++); + + ret =regmap_bulk_write (data->regmap,BMP580_REG_NVM_DATA_LSB , &data->le16, +sizeof (data->le16)); +if (ret) { +dev_err (data->dev,"error writing LSB NVM data regs\n" ); + goto exit; + } + + ret =bmp580_cmd (data,BMP580_NVM_WRITE_CMD ); +if (ret) + goto exit; + +/* Disable programming mode bit */ + ret =regmap_update_bits (data->regmap,BMP580_REG_NVM_ADDR , +BMP580_NVM_PROG_EN ,0 ); +if (ret) { +dev_err (data->dev,"error resetting nvm write\n" ); + goto exit; + } + + bytes -=sizeof (u16); + offset +=sizeof (u16); + } +exit: +/* Restore chip config */ + data->chip_info->chip_config (data); +mutex_unlock (&data->lock); +pm_runtime_mark_last_busy (data->dev); +pm_runtime_put_autosuspend (data->dev); +return ret; +} +static int bmp580_preinit (struct bmp280_data *data) { +struct nvmem_config config = { + .dev = data->dev, + .priv = data, + .name ="bmp580_nvmem" , + .word_size =sizeof (u16), + .stride =sizeof (u16), + .size =3 *sizeof (u16), + .reg_read = bmp580_nvmem_read, + .reg_write = bmp580_nvmem_write, + };unsigned int reg;int ret;
@@ -1653,8 +1786,8 @@ static int bmp580_preinit(struct bmp280_data *data)dev_err (data->dev,"preinit: nvm error on powerup sequence\n" );return -EIO ; } - -return 0 ; +/* Register nvmem device */ +return PTR_ERR_OR_ZERO (devm_nvmem_register (config.dev, &config)); }static int bmp580_chip_config (struct bmp280_data *data)
drivers/iio/pressure/bmp280.h +3 -0
@@ -101,6 +101,9 @@#define BMP580_FILTER_63X 6#define BMP580_FILTER_127X 7 +#define BMP580_NVM_ROW_ADDR_MASK GENMASK(5, 0) +#define BMP580_NVM_PROG_EN BIT(6) +#define BMP580_TEMP_SKIPPED 0x7f7f7f#define BMP580_PRESS_SKIPPED 0x7f7f7f
Signature · 1 line
2.39.0
Jonathan Cameron
maintainerRe: [PATCH v2 5/5] iio: pressure: bmp280: Add nvmem operations for BMP580
Quoted 5 lines · On Mon, 26 Dec 2022 15:29:24 +0100 Angel Iglesias <[email protected]>…
The pressure sensor BMP580 contains a non-volatile memory that stores trimming and configuration params. That memory provides an programmable user range of three 2-byte words.
Signed-off-by Angel Iglesias <[email protected]>
Not much in this one from me other than follow on from earlier patch. Thanks,
Jonathan
Quoted 42 lines
drivers/iio/pressure/bmp280-core.c +26
-0@@ -28,6 +28,7 @@#include <linux/bitfield.h> #include <linux/device.h> #include <linux/module.h> +#include <linux/nvmem-provider.h> #include <linux/regmap.h> #include <linux/delay.h> #include <linux/iio/iio.h> @@ -1628,8 +1629,140 @@ static const int bmp580_odr_table[][2] = { [BMP580_ODR_0_125HZ] = {0, 125000}, }; +const int bmp580_nvmem_addrs[] = {0x20 ,0x21 ,0x22 }; + +static int bmp580_nvmem_read (void *priv,unsigned int offset,void *val, +size_t bytes) +{ +struct bmp280_data *data = priv; +u16 *dst = val; +int ret, addr; + +pm_runtime_get_sync (data->dev); +mutex_lock (&data->lock); + +/* Set sensor in standby mode */ + ret =regmap_update_bits (data->regmap,BMP580_REG_ODR_CONFIG , +BMP580_MODE_MASK |BMP580_ODR_DEEPSLEEP_DIS , +BMP580_ODR_DEEPSLEEP_DIS | +FIELD_PREP (BMP580_MODE_MASK ,BMP580_MODE_SLEEP )); +if (ret) { +dev_err (data->dev,"failed to change sensor to standby mode\n" ); + goto exit; + } +/* Wait standby transition time */ +usleep_range (2500 ,3000 ); + +while (bytes >=sizeof (u16)) {
drivers/iio/pressure/bmp280-core.c static const int bmp580_odr_table[][2] = { · line 1666
Quoted 10 lines
drivers/iio/pressure/bmp280-core.c +10
-0+ addr = bmp580_nvmem_addrs[offset /sizeof (u16)]; + + ret =regmap_write (data->regmap,BMP580_REG_NVM_ADDR , +FIELD_PREP (BMP580_NVM_ROW_ADDR_MASK , addr)); +if (ret) { +dev_err (data->dev,"error writing nvm address\n" ); + goto exit; + } + + ret =bmp580_cmd (data,BMP580_NVM_READ_CMD );
Ah. Here is the command being used. Good to pull that code forwards to this patch.
drivers/iio/pressure/bmp280-core.c static const int bmp580_odr_table[][2] = { · line 1678
Quoted 12 lines
drivers/iio/pressure/bmp280-core.c +12
-0+if (ret) + goto exit; + + ret =regmap_bulk_read (data->regmap,BMP580_REG_NVM_DATA_LSB , &data->le16, +sizeof (data->le16)); +if (ret) { +dev_err (data->dev,"error reading nvm data regs\n" ); + goto exit; + } + + *dst++ =le16_to_cpu (data->le16); + bytes -=sizeof (u16);
sizeof(le16) seems more appropriate (obviously it's the same value).
Quoted 54 lines
drivers/iio/pressure/bmp280-core.c +54
-0+ offset +=sizeof (u16); + } +exit: +/* Restore chip config */ + data->chip_info->chip_config (data); +mutex_unlock (&data->lock); +pm_runtime_mark_last_busy (data->dev); +pm_runtime_put_autosuspend (data->dev); +return ret; +} + +static int bmp580_nvmem_write (void *priv,unsigned int offset,void *val, +size_t bytes) +{ +struct bmp280_data *data = priv; +u16 *buf = val; +int ret, addr; + +pm_runtime_get_sync (data->dev); +mutex_lock (&data->lock); + +/* Set sensor in standby mode */ + ret =regmap_update_bits (data->regmap,BMP580_REG_ODR_CONFIG , +BMP580_MODE_MASK |BMP580_ODR_DEEPSLEEP_DIS , +BMP580_ODR_DEEPSLEEP_DIS | +FIELD_PREP (BMP580_MODE_MASK ,BMP580_MODE_SLEEP )); +if (ret) { +dev_err (data->dev,"failed to change sensor to standby mode\n" ); + goto exit; + } +/* Wait standby transition time */ +usleep_range (2500 ,3000 ); + +while (bytes >=sizeof (u16)) { + addr = bmp580_nvmem_addrs[offset /sizeof (u16)]; + + ret =regmap_write (data->regmap,BMP580_REG_NVM_ADDR ,BMP580_NVM_PROG_EN | +FIELD_PREP (BMP580_NVM_ROW_ADDR_MASK , addr)); +if (ret) { +dev_err (data->dev,"error writing nvm address\n" ); + goto exit; + } + data->le16 =cpu_to_le16 (*buf++); + + ret =regmap_bulk_write (data->regmap,BMP580_REG_NVM_DATA_LSB , &data->le16, +sizeof (data->le16)); +if (ret) { +dev_err (data->dev,"error writing LSB NVM data regs\n" ); + goto exit; + } + + ret =bmp580_cmd (data,BMP580_NVM_WRITE_CMD ); +if (ret) + goto exit;
drivers/iio/pressure/bmp280-core.c static const int bmp580_odr_table[][2] = { · line 1742
Quoted 10 lines
drivers/iio/pressure/bmp280-core.c +10
-0+ +/* Disable programming mode bit */ + ret =regmap_update_bits (data->regmap,BMP580_REG_NVM_ADDR , +BMP580_NVM_PROG_EN ,0 ); +if (ret) { +dev_err (data->dev,"error resetting nvm write\n" ); + goto exit; + } + + bytes -=sizeof (u16);
As above, maybe sizeof(le16)
Quoted 11 lines
drivers/iio/pressure/bmp280-core.c +11
-0+ offset +=sizeof (u16); + } +exit: +/* Restore chip config */ + data->chip_info->chip_config (data); +mutex_unlock (&data->lock); +pm_runtime_mark_last_busy (data->dev); +pm_runtime_put_autosuspend (data->dev); +return ret; +} +
Re: [PATCH v2 5/5] iio: pressure: bmp280: Add nvmem operations for BMP580
Quoted 164 lines · Jonathan Cameron
Quoted 5 lines · On Mon, 26 Dec 2022 15:29:24 +0100 Angel Iglesias <[email protected]>…
The pressure sensor BMP580 contains a non-volatile memory that stores trimming and configuration params. That memory provides an programmable user range of three 2-byte words.
Signed-off-by Angel Iglesias <[email protected]>Not much in this one from me other than follow on from earlier patch. Thanks,
Jonathan
Quoted 50 lines
drivers/iio/pressure/bmp280-core.c +1
-0@@ -28,6 +28,7 @@ #include <linux/bitfield.h> #include <linux/device.h> #include <linux/module.h> +#include <linux/nvmem-provider.h> #include <linux/regmap.h> #include <linux/delay.h> #include <linux/iio/iio.h>@@ -1628,8 +1629,140 @@ static const int bmp580_odr_table[][2] = { [BMP580_ODR_0_125HZ] = {0, 125000}, };drivers/iio/pressure/bmp280-core.c +15
-0+const int bmp580_nvmem_addrs[] = {0x20 ,0x21 ,0x22 }; + +static int bmp580_nvmem_read (void *priv,unsigned int offset,void *val, + size_t bytes) +{ + struct bmp280_data *data = priv; + u16 *dst = val; + int ret, addr; + + pm_runtime_get_sync(data->dev); + mutex_lock(&data->lock); + + /* Set sensor in standby mode */ + ret = regmap_update_bits(data->regmap, BMP580_REG_ODR_CONFIG, + BMP580_MODE_MASK |
BMP580_ODR_DEEPSLEEP_DIS,
+BMP580_ODR_DEEPSLEEP_DIS| +FIELD_PREP(BMP580_MODE_MASK, BMP580_MODE_SLEEP));
+ if (ret) {
+ dev_err(data->dev, "failed to change sensor to standby mode\n");
+ goto exit;
+ }
+ /* Wait standby transition time */
+ usleep_range(2500, 3000);drivers/iio/pressure/bmp280-core.c +6
-0+ + while (bytes >= sizeof(u16)) { + addr = bmp580_nvmem_addrs[offset / sizeof(u16)]; + + ret = regmap_write(data->regmap, BMP580_REG_NVM_ADDR, + FIELD_PREP(BMP580_NVM_ROW_ADDR_MASK,Quoted 7 lines
addr));
+ if (ret) {
+ dev_err(data->dev, "error writing nvm address\n"); + goto exit;
+ }
+
+ ret =bmp580_cmd(data, BMP580_NVM_READ_CMD);Ah. Here is the command being used. Good to pull that code forwards to this patch.
Quoted 5 lines
+ if (ret)
+ goto exit;
+
+ ret = regmap_bulk_read(data->regmap,BMP580_REG_NVM_DATA_LSB,&data->le16,Quoted 8 lines
+
sizeof(data->le16));
+ if (ret) {
+ dev_err(data->dev, "error reading nvm data regs\n"); + goto exit;
+ }
+
+ *dst++ =le16_to_cpu(data->le16);
+ bytes -= sizeof(u16);sizeof(le16) seems more appropriate (obviously it's the same value).
Quoted 61 lines
+ offset += sizeof(u16);
+ }drivers/iio/pressure/bmp280-core.c +22
-0+exit: + /* Restore chip config */ + data->chip_info->chip_config(data); + mutex_unlock(&data->lock); + pm_runtime_mark_last_busy(data->dev); + pm_runtime_put_autosuspend(data->dev); + return ret; +} + +static int bmp580_nvmem_write (void *priv,unsigned int offset,void *val, + size_t bytes) +{ + struct bmp280_data *data = priv; + u16 *buf = val; + int ret, addr; + + pm_runtime_get_sync(data->dev); + mutex_lock(&data->lock); + + /* Set sensor in standby mode */ + ret = regmap_update_bits(data->regmap, BMP580_REG_ODR_CONFIG, + BMP580_MODE_MASK |
BMP580_ODR_DEEPSLEEP_DIS,
+BMP580_ODR_DEEPSLEEP_DIS| +FIELD_PREP(BMP580_MODE_MASK, BMP580_MODE_SLEEP));
+ if (ret) {
+ dev_err(data->dev, "failed to change sensor to standby mode\n");
+ goto exit;
+ }
+ /* Wait standby transition time */
+ usleep_range(2500, 3000);drivers/iio/pressure/bmp280-core.c +5
-0+ + while (bytes >= sizeof(u16)) { + addr = bmp580_nvmem_addrs[offset / sizeof(u16)]; + + ret = regmap_write(data->regmap, BMP580_REG_NVM_ADDR,
BMP580_NVM_PROG_EN|
+FIELD_PREP(BMP580_NVM_ROW_ADDR_MASK, addr));
+ if (ret) {
+ dev_err(data->dev, "error writing nvm address\n"); + goto exit;
+ }
+ data->le16 =cpu_to_le16(*buf++);
+
+ ret = regmap_bulk_write(data->regmap,BMP580_REG_NVM_DATA_LSB,&data->le16,
+ sizeof(data->le16));
+ if (ret) {
+ dev_err(data->dev, "error writing LSB NVM data regs\n");
+ goto exit;
+ }drivers/iio/pressure/bmp280-core.c +4
-0+ + ret = bmp580_cmd(data, BMP580_NVM_WRITE_CMD); + if (ret) + goto exit;drivers/iio/pressure/bmp280-core.c static const int bmp580_odr_table[][2] = { · line 1742
Quoted 10 lines
drivers/iio/pressure/bmp280-core.c +10
-0+ + /* Disable programming mode bit */ + ret = regmap_update_bits(data->regmap, BMP580_REG_NVM_ADDR, + BMP580_NVM_PROG_EN, 0); + if (ret) { + dev_err(data->dev, "error resetting nvm write\n"); + goto exit; + } + + bytes -= sizeof(u16);As above, maybe sizeof(le16)
Quoted 13 lines
drivers/iio/pressure/bmp280-core.c static const int bmp580_odr_table[][2] = { · line 1689
Quoted 11 lines
+ offset += sizeof(u16);
+ }drivers/iio/pressure/bmp280-core.c +9
-0+exit: + /* Restore chip config */ + data->chip_info->chip_config(data); + mutex_unlock(&data->lock); + pm_runtime_mark_last_busy(data->dev); + pm_runtime_put_autosuspend(data->dev); + return ret; +} +
Got it,
Thanks for your time,
Angel
Re: [PATCH v2 4/5] dt-bindings: iio: pressure: bmp085: Add BMP580 compatible string
In reply to Angel IglesiasQuoted 6 lines · Angel Iglesias
Add bosch,bmp580 to compatible string for the new family of sensors. This family includes the BMP580 and BMP581 sensors. The register map in this family presents significant departures from previous generations.
Signed-off-by Angel Iglesias <[email protected]>