Add functionality to inject a specified amount of current to the heating
plate before the start of the gas measurement to allow the sensor to reach
faster to the requested temperature.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20241102131311.36210-5-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Add triggered buffer and soft timestamp support. The available scan mask
enables all the channels of the sensor in order to follow the operation of
the sensor. The sensor basically starts to capture from all channels
as long as it enters into FORCED mode.
The bulk read, reads a total of 15 registers from the sensor, 0x1D..0x2B.
Even though some of those registers are not reported in the register map
of the device, this is how the BME680 Sensor API [1] proposes to do it.
This allows to have one bulk read instead of multiple ones.
Link: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L1200
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20241102131311.36210-4-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Add SCALE,RAW channels to the device. Even though PROCESSED should be
kept for backwards compatibility add comment to avoid using it if the
value is not actually reported in IIO values.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20241102131311.36210-3-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Refactorize the set_mode() function to use an external enum that
describes the possible modes of the BME680 device instead of using
true/false variables for selecting SLEEPING/FORCED mode.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20241102131311.36210-2-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Use local s16 variable for the temperature channel to avoid casting it
later before passing it to the bme680_read_temp() function. This way,
possible endianness and initialization issues are avoided.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20241030235424.214935-2-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Remove the IIO specific scaling measurement units from the read functions
and add them inside the ->read_raw() function to keep the read_*() generic.
This way they can be used in other parts of the driver.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20241021195316.58911-8-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Fix indentation issues, line breaking and unnecessary spaces
reported by checkpatch.pl. Reduce type casts by defining constants
to be LL.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20241021195316.58911-7-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Rename camel case variable, as checkpatch.pl complains.
While at it, fix also the indentation of the array for readability.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20241021195316.58911-4-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
asm/unaligned.h is always an include of asm-generic/unaligned.h;
might as well move that thing to linux/unaligned.h and include
that - there's nothing arch-specific in that header.
auto-generated by the following:
for i in `git grep -l -w asm/unaligned.h`; do
sed -i -e "s/asm\/unaligned.h/linux\/unaligned.h/" $i
done
for i in `git grep -l -w asm-generic/unaligned.h`; do
sed -i -e "s/asm-generic\/unaligned.h/linux\/unaligned.h/" $i
done
git mv include/asm-generic/unaligned.h include/linux/unaligned.h
git mv tools/include/asm-generic/unaligned.h tools/include/linux/unaligned.h
sed -i -e "/unaligned.h/d" include/asm-generic/Kbuild
sed -i -e "s/__ASM_GENERIC/__LINUX/" include/linux/unaligned.h tools/include/linux/unaligned.h
By converting it to static, we ensure that this will be placed by the
compiler in the read-only area.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240725231818.615530-1-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
The reading of the pressure and humidity value, requires an update of the
t_fine variable which happens by reading the temperature value.
So the bme680_read_{press/humid}() functions of the above sensors are
internally calling the equivalent bme680_read_temp() function in order to
update the t_fine value. By just looking at the code this relation is a
bit hidden and is not easy to understand why those channels are not
independent.
This commit tries to clear these thing a bit by splitting the
bme680_{read/compensate}_{temp/press/humid}() to the following:
i. bme680_read_{temp/press/humid}_adc(): read the raw value from the
sensor.
ii. bme680_calc_t_fine(): calculate the t_fine variable.
iii. bme680_get_t_fine(): get the t_fine variable.
iv. bme680_compensate_{temp/press/humid}(): compensate the adc values and
return the calculated value.
v. bme680_read_{temp/press/humid}(): combine calls of the aforementioned
functions to return the requested value.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-16-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Whenever the sensor is set to forced mode, a TPHG cycle is triggered and
the values of temperature, pressure, humidity and gas become ready to be
read.
The setup of the forced mode to trigger measurements was located inside
the read_{temp/gas}() functions. This was not posing a functional problem
since read_{humid/press}() are internally calling read_temp() so the
forced mode is set through this call.
This is not very clear and it is kind of hidden that regardless of the
measurement, the setup of the forced mode needs to happen before any
measurement.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-15-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
There is no need to explicitly configure the gas measurement registers
every time a gas measurement takes place. These are initial configurations
which are written in the beginning and they are not changed throughout
the lifetime of the driver.
If in the future, the device starts to support multiple configuration
profiles with variable heater duration and heater temperature, then they
could become members of the ->read_avail().
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-14-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
There are multiple cases in the probe function that dev_err_probe() fits
the needs, so use it.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-13-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
In the majority of the error checks after a regmap_{read,write}()
operation the following coding style is used:
ret = regmap_{read,write}(data->regmap, ...);
if (ret < 0) {
dev_err(dev, ...);
return ret;
}
In this particular case it was different so change it for consistency.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-11-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Move the buffers that are used in order to read data from the device in
the union which handles all the device read/write buffers. Also create
defines for the number of bytes that are being read from the device and
don't use magic numbers.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-10-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Move the IIO device allocation before the actual initialization of the
chip to be more consistent with most IIO drivers and also to have the
ability to use any driver specific data for the chip initialization.
While at it, fix also a misaligned line.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-9-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
The LSB of the gas register was read first to check if the following
check was correct and then the MSB+LSB were read together. Simplify this
by reading together the MSB+LSB immediately.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-7-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Sort headers in alphabetical order and split the iio specific functions
with a blank line
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-6-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
The ACPI ID table was removed with the following 2 commits:
Commit b73d21dccf ("iio: bme680_i2c: Remove acpi_device_id table")
Commit f0e4057e97 ("iio: bme680_spi: Remove acpi_device_id table")
Remove the remaining ACPI related stuff to this driver since they are
not directly used.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-5-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Delete any redundant casts in the code and use unsigned integers for the
raw adc values.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-4-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Add mutexes in the {read/write}_raw() functions of the device to guard the
read/write of data from/to the device. This is necessary because for any
operation other than temperature, multiple reads need to take place from
the device. Even though regmap has a locking by itself, it won't protect us
from multiple applications trying to read at the same time temperature and
pressure since the pressure reading includes an internal temperature
reading and there is nothing to ensure that this temperature+pressure
reading will happen sequentially without any other operation interfering
in the meantime.
Fixes: 1b3bd85927 ("iio: chemical: Add support for Bosch BME680 sensor")
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://patch.msgid.link/20240609233826.330516-2-vassilisamir@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
A read operation is happening as follows:
a) Set sensor to forced mode
b) Sensor measures values and update data registers and sleeps again
c) Read data registers
In the current implementation the read operation happens immediately
after the sensor is set to forced mode so the sensor does not have
the time to update properly the registers. This leads to the following
2 problems:
1) The first ever value which is read by the register is always wrong
2) Every read operation, puts the register into forced mode and reads
the data that were calculated in the previous conversion.
This behaviour was tested in 2 ways:
1) The internal meas_status_0 register was read before and after every
read operation in order to verify that the data were ready even before
the register was set to forced mode and also to check that after the
forced mode was set the new data were not yet ready.
2) Physically changing the temperature and measuring the temperature
This commit adds the waiting time in between the set of the forced mode
and the read of the data. The function is taken from the Bosch BME68x
Sensor API [1].
[1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490
Fixes: 1b3bd85927 ("iio: chemical: Add support for Bosch BME680 sensor")
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://lore.kernel.org/r/20240606212313.207550-5-vassilisamir@gmail.com
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
There are cases in the compensate functions of the driver that
there could be overflows of variables due to bit shifting ops.
These implications were initially discussed here [1] and they
were mentioned in log message of Commit 1b3bd85927 ("iio:
chemical: Add support for Bosch BME680 sensor").
[1]: https://lore.kernel.org/linux-iio/20180728114028.3c1bbe81@archlinux/
Fixes: 1b3bd85927 ("iio: chemical: Add support for Bosch BME680 sensor")
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
Link: https://lore.kernel.org/r/20240606212313.207550-4-vassilisamir@gmail.com
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
In order to avoid unnecessary pollution of the global symbol namespace
move the common/library functions into a specific namespace and import
that into the bus specific device drivers that use them.
For more information see https://lwn.net/Articles/760045/
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: Himanshu Jha <himanshujha199640@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20220130205701.334592-17-jic23@kernel.org
Use DIV_ROUND_CLOSEST() instead of open-coding it. This documents intent
and makes it more clear what is going on for the casual reviewer.
Generated using the following the Coccinelle semantic patch.
// <smpl>
@r1@
expression x;
constant C1;
constant C2;
@@
((x) + C1) / C2
@script:python@
C1 << r1.C1;
C2 << r1.C2;
@@
try:
if int(C1) * 2 != int(C2):
cocci.include_match(False)
except:
cocci.include_match(False)
@@
expression r1.x;
constant r1.C1;
constant r1.C2;
@@
-(((x) + C1) / C2)
+DIV_ROUND_CLOSEST(x, C2)
// </smpl>
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Link: https://lore.kernel.org/r/20201227171126.28216-2-lars@metafoo.de
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This patch applies the semantic patch:
@@
expression I, P, SP;
@@
I = devm_iio_device_alloc(P, SP);
...
- I->dev.parent = P;
It updates 302 files and does 307 deletions.
This semantic patch also removes some comments like
'/* Establish that the iio_dev is a child of the i2c device */'
But this is is only done in case where the block is left empty.
The patch does not seem to cover all cases. It looks like in some cases a
different variable is used in some cases to assign the parent, but it
points to the same reference.
In other cases, the block covered by ... may be just too big to be covered
by the semantic patch.
However, this looks pretty good as well, as it does cover a big bulk of the
drivers that should remove the parent assignment.
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
A mixture of:
* Unnecessary casts of val parameter to u8 * which makes little sense as
the function take a void *.
* Explicit sizes where we can use the destination type to define that.
Note that's not true in all cases as we do read 3 bytes into 4 byte
destinations.
Note that noting was broken here, I'm just trying to ensure this doesn't
get cut and paste into more drivers so cleaning these out subsystem wide.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Acked-by: Himanshu Jha <himanshujha199640@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
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.
Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
Fixes: 1b3bd85927 ("iio: chemical: Add support for Bosch BME680 sensor");
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
The standard unit for temperature is millidegrees Celcius. Adapt the
driver to report in millidegrees instead of degrees.
Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
Fixes: 1b3bd85927 ("iio: chemical: Add support for Bosch BME680 sensor");
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Remove BME680_RUN_GAS_EN_BIT and BME680_NB_CONV_0_VAL field value
definitions because the fields are simply boolean and integer
respectively.
Signed-off-by: David Frey <dpfrey@gmail.com>
Reviewed-by: Himanshu Jha <himanshujha199640@gmail.com>
Tested-by: Himanshu Jha <himanshujha199640@gmail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
val2 is responsible for the floating part of the number to be
written to the device. We don't need the floating part
while writing the oversampling ratio for BME680 since the
available oversampling ratios are pure natural numbers.
So, add a sanity check to make sure val2 is 0.
Signed-off-by: Himanshu Jha <himanshujha199640@gmail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Temperature, pressure and humidity all expose and oversampling setting
that works in the same way. Provide common handling for the
oversampling sysfs attributes.
Signed-off-by: David Frey <dpfrey@gmail.com>
Reviewed-by: Himanshu Jha <himanshujha199640@gmail.com>
Tested-by: Himanshu Jha <himanshujha199640@gmail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Use the FIELD_GET macro instead of explicit mask and shift.
Signed-off-by: David Frey <dpfrey@gmail.com>
Reviewed-by: Himanshu Jha <himanshujha199640@gmail.com>
Tested-by: Himanshu Jha <himanshujha199640@gmail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Convert all defines to use "MASK" instead of a mix of "MSK" and "MASK"
Signed-off-by: David Frey <dpfrey@gmail.com>
Reviewed-by: Himanshu Jha <himanshujha199640@gmail.com>
Tested-by: Himanshu Jha <himanshujha199640@gmail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Use the full 80 char width to reduce the number of lines taken
by function calls.
Remove blank lines where it aids clarity by bringing together related
code blocks (such as read hi and low bytes and then combine them into
one value).
Signed-off-by: David Frey <dpfrey@gmail.com>
Reviewed-by: Himanshu Jha <himanshujha199640@gmail.com>
Tested-by: Himanshu Jha <himanshujha199640@gmail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
fix spelling mistake in dev_err error message text
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Reviewed-by: Himanshu Jha <himanshujha199640@gmail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Bosch BME680 is a 4-in-1 sensor with temperature, pressure, humidity
and gas sensing capability. It supports both I2C and SPI communication
protocol for effective data communication.
The device supports two modes:
1. Sleep mode
2. Forced mode
The measurements only takes place when forced mode is triggered and a
single TPHG cycle is performed by the sensor. The sensor automatically
goes to sleep after afterwards.
The device has various calibration constants/parameters programmed into
devices' non-volatile memory(NVM) during production and can't be altered
by the user. These constants are used in the compensation functions to
get the required compensated readings along with the raw data. The
compensation functions/algorithms are provided by Bosch Sensortec GmbH
via their API[1]. As these don't change during the measurement cycle,
therefore we read and store them at the probe. The default configs
supplied by Bosch are also set at probe.
0-day tested with build success.
GSoC-2018: https://summerofcode.withgoogle.com/projects/#6691473790074880
Mentor: Daniel Baluta
[1] https://github.com/BoschSensortec/BME680_driver
Datasheet:
https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME680-DS001-00.pdf
Note from Jonathan: The compensation functions are 'interesting' and
could do with a tidy up in future. However, they work so we can leave that
for another day.
Cc: Daniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: Himanshu Jha <himanshujha199640@gmail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>