According to the datasheet of BMP38x and BMP390 devices, in SPI operation, the first byte that returns after a read operation is garbage and it needs to be dropped and return the rest of the bytes. Signed-off-by: Vasileios Amoiridis <vassilisamir@xxxxxxxxx> --- drivers/iio/pressure/bmp280-spi.c | 47 ++++++++++++++++++++++++++++++- drivers/iio/pressure/bmp280.h | 2 ++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c index 433d6fac83c4..c4b4a5d67f94 100644 --- a/drivers/iio/pressure/bmp280-spi.c +++ b/drivers/iio/pressure/bmp280-spi.c @@ -35,6 +35,32 @@ static int bmp280_regmap_spi_read(void *context, const void *reg, return spi_write_then_read(spi, reg, reg_size, val, val_size); } +static int bmp380_regmap_spi_read(void *context, const void *reg, + size_t reg_size, void *val, size_t val_size) +{ + struct spi_device *spi = to_spi_device(context); + u8 ret[BMP380_SPI_MAX_REG_COUNT_READ + 1]; + ssize_t status; + u8 buf; + + memcpy(&buf, reg, reg_size); + buf |= 0x80; + + /* + * According to the BMP380, BMP388, BMP390 datasheets, for a basic + * read operation, after the write is done, 2 bytes are received and + * the first one has to be dropped. The 2nd one is the requested + * value. + */ + status = spi_write_then_read(spi, &buf, 1, ret, val_size + 1); + if (status) + return status; + + memcpy(val, ret + 1, val_size); + + return 0; +} + static struct regmap_bus bmp280_regmap_bus = { .write = bmp280_regmap_spi_write, .read = bmp280_regmap_spi_read, @@ -42,10 +68,18 @@ static struct regmap_bus bmp280_regmap_bus = { .val_format_endian_default = REGMAP_ENDIAN_BIG, }; +static struct regmap_bus bmp380_regmap_bus = { + .write = bmp280_regmap_spi_write, + .read = bmp380_regmap_spi_read, + .reg_format_endian_default = REGMAP_ENDIAN_BIG, + .val_format_endian_default = REGMAP_ENDIAN_BIG, +}; + static int bmp280_spi_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); const struct bmp280_chip_info *chip_info; + struct regmap_bus *bmp_regmap_bus; struct regmap *regmap; int ret; @@ -58,8 +92,19 @@ static int bmp280_spi_probe(struct spi_device *spi) chip_info = spi_get_device_match_data(spi); + switch (chip_info->chip_id[0]) { + case BMP380_CHIP_ID: + case BMP390_CHIP_ID: + bmp_regmap_bus = &bmp380_regmap_bus; + break; + default: + bmp_regmap_bus = &bmp280_regmap_bus; + break; + } + + regmap = devm_regmap_init(&spi->dev, - &bmp280_regmap_bus, + bmp_regmap_bus, &spi->dev, chip_info->regmap_config); if (IS_ERR(regmap)) { diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h index 4012387d7956..ca482b7e4295 100644 --- a/drivers/iio/pressure/bmp280.h +++ b/drivers/iio/pressure/bmp280.h @@ -191,6 +191,8 @@ #define BMP380_TEMP_SKIPPED 0x800000 #define BMP380_PRESS_SKIPPED 0x800000 +#define BMP380_SPI_MAX_REG_COUNT_READ 3 + /* BMP280 specific registers */ #define BMP280_REG_HUMIDITY_LSB 0xFE #define BMP280_REG_HUMIDITY_MSB 0xFD -- 2.25.1