patch "iio:chemical:bme680: Fix SPI read interface" added to staging-linus
Subsystems (2)
This is a note to let you know that I've just added the patch titled
iio:chemical:bme680: Fix SPI read interface
to my staging git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
in the staging-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
From 73f3bc6da506711302bb67572440eb84b1ec4a2c Mon Sep 17 00:00:00 2001
From: Mike Looijmans <[email protected]>
Date: Wed, 6 Mar 2019 08:31:48 +0100
Subject: iio:chemical:bme680: Fix SPI read interface
The SPI interface implementation was completely broken.
When using the SPI interface, there are only 7 address bits, the upper bit is controlled by a page select register. The core needs access to both ranges, so implement register read/write for both regions. The regmap paging functionality didn't agree with a register that needs to be read and modified, so I implemented a custom paging algorithm.
This fixes that the device wouldn't even probe in SPI mode.
The SPI interface then isn't different from I2C, merged them into the core, and the I2C/SPI named registers are no longer needed.
Implemented register value caching for the registers to reduce the I2C/SPI data transfers considerably.
The calibration set reads as all zeroes until some undefined point in time, and I couldn't determine what makes it valid. The datasheet mentions these registers but does not provide any hints on when they become valid, and they aren't even enumerated in the memory map. So check the calibration and retry reading it from the device after each measurement until it provides something valid.
Despite the size this is suitable for a stable backport given that it seems the SPI support never worked.
--- drivers/iio/chemical/bme680.h | 6 +- drivers/iio/chemical/bme680_core.c | 38 ++++++++++ drivers/iio/chemical/bme680_i2c.c | 21 ------ drivers/iio/chemical/bme680_spi.c | 115 +++++++++++++++++++---------- 4 files changed, 118 insertions(+), 62 deletions(-)
drivers/iio/chemical/bme680.h +2 -4
@@ -2,11 +2,9 @@#ifndef BME680_H_ #define BME680_H_ -#define BME680_REG_CHIP_I2C_ID 0xD0 -#define BME680_REG_CHIP_SPI_ID 0x50 +#define BME680_REG_CHIP_ID 0xD0#define BME680_CHIP_ID_VAL 0x61 -#define BME680_REG_SOFT_RESET_I2C 0xE0 -#define BME680_REG_SOFT_RESET_SPI 0x60 +#define BME680_REG_SOFT_RESET 0xE0#define BME680_CMD_SOFTRESET 0xB6#define BME680_REG_STATUS 0x73#define BME680_SPI_MEM_PAGE_BIT BIT(4)
drivers/iio/chemical/bme680_core.c +38 -0
@@ -63,9 +63,23 @@ struct bme680_data {s32 t_fine; }; +static const struct regmap_range bme680_volatile_ranges[] = { +regmap_reg_range (BME680_REG_MEAS_STAT_0 ,BME680_REG_GAS_R_LSB ), +regmap_reg_range (BME680_REG_STATUS ,BME680_REG_STATUS ), +regmap_reg_range (BME680_T2_LSB_REG ,BME680_GH3_REG ), +}; + +static const struct regmap_access_table bme680_volatile_table = { + .yes_ranges = bme680_volatile_ranges, + .n_yes_ranges =ARRAY_SIZE (bme680_volatile_ranges), +}; +const struct regmap_config bme680_regmap_config = { .reg_bits =8 , .val_bits =8 , + .max_register =0xef , + .volatile_table = &bme680_volatile_table, + .cache_type =REGCACHE_RBTREE , };EXPORT_SYMBOL (bme680_regmap_config);
@@ -316,6 +330,10 @@ static s16 bme680_compensate_temp(struct bme680_data *data,s64 var1, var2, var3;s16 calc_temp; +/* If the calibration is invalid, attempt to reload it */ +if (!calib->par_t2) +bme680_read_calib (data, calib); + var1 = (adc_temp >>3 ) - (calib->par_t1 <<1 ); var2 = (var1 * calib->par_t2) >>11 ; var3 = ((var1 >>1 ) * (var1 >>1 )) >>12 ;
@@ -865,8 +883,28 @@ int bme680_core_probe(struct device *dev, struct regmap *regmap, {struct iio_dev *indio_dev;struct bme680_data *data; +unsigned int val;int ret; + ret =regmap_write (regmap,BME680_REG_SOFT_RESET , +BME680_CMD_SOFTRESET ); +if (ret <0 ) { +dev_err (dev,"Failed to reset chip\n" ); +return ret; + } + + ret =regmap_read (regmap,BME680_REG_CHIP_ID , &val); +if (ret <0 ) { +dev_err (dev,"Error reading chip ID\n" ); +return ret; + } + +if (val !=BME680_CHIP_ID_VAL ) { +dev_err (dev,"Wrong chip ID, got %x expected %x\n" , + val,BME680_CHIP_ID_VAL ); +return -ENODEV ; + } + indio_dev =devm_iio_device_alloc (dev,sizeof (*data));if (!indio_dev)return -ENOMEM ;
drivers/iio/chemical/bme680_i2c.c +0 -21
@@ -23,8 +23,6 @@ static int bme680_i2c_probe(struct i2c_client *client, {struct regmap *regmap;const char *name =NULL ; -unsigned int val; -int ret; regmap =devm_regmap_init_i2c (client, &bme680_regmap_config);if (IS_ERR (regmap)) {
@@ -33,25 +31,6 @@ static int bme680_i2c_probe(struct i2c_client *client,return PTR_ERR (regmap); } - ret =regmap_write (regmap,BME680_REG_SOFT_RESET_I2C , -BME680_CMD_SOFTRESET ); -if (ret <0 ) { -dev_err (&client->dev,"Failed to reset chip\n" ); -return ret; - } - - ret =regmap_read (regmap,BME680_REG_CHIP_I2C_ID , &val); -if (ret <0 ) { -dev_err (&client->dev,"Error reading I2C chip ID\n" ); -return ret; - } - -if (val !=BME680_CHIP_ID_VAL ) { -dev_err (&client->dev,"Wrong chip ID, got %x expected %x\n" , - val,BME680_CHIP_ID_VAL ); -return -ENODEV ; - } -if (id) name = id->name;
drivers/iio/chemical/bme680_spi.c +78 -37
159 lines not on this page · raw message
Signature · 1 line
2.21.0