From: Vasileios Amoiridis <vassilisamir@gmail.com>
To: jic23@kernel.org
Cc: lars@metafoo.de, andriy.shevchenko@linux.intel.com,
ang.iglesiasg@gmail.com, mazziesaccount@gmail.com,
ak@it-klinger.de, petre.rodan@subdimension.ro,
phil@raspberrypi.com, 579lpy@gmail.com,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
Vasileios Amoiridis <vassilisamir@gmail.com>
Subject: [PATCH 4/4] iio: pressure: Add triggered buffer support for BMP280 driver
Date: Sun, 3 Mar 2024 17:53:00 +0100 [thread overview]
Message-ID: <20240303165300.468011-5-vassilisamir@gmail.com> (raw)
In-Reply-To: <20240303165300.468011-1-vassilisamir@gmail.com>
Add a buffer struct that will hold the values of the measurements
and will be pushed to userspace. Modify all read_* functions in order
to just read and compensate the data without though converting to the
required IIO measurement units which are used for the oneshot captures.
Signed-off-by: Vasileios Amoiridis <vassilisamir@gmail.com>
---
drivers/iio/pressure/Kconfig | 2 +
drivers/iio/pressure/bmp280-core.c | 155 +++++++++++++++++++++++------
drivers/iio/pressure/bmp280.h | 7 ++
3 files changed, 134 insertions(+), 30 deletions(-)
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index 79adfd059c3a..5145b94b4679 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -31,6 +31,8 @@ config BMP280
select REGMAP
select BMP280_I2C if (I2C)
select BMP280_SPI if (SPI_MASTER)
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Bosch Sensortec BMP180, BMP280, BMP380
and BMP580 pressure and temperature sensors. Also supports the BME280 with
diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index 3bdf6002983f..3b1a159e57ea 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -31,8 +31,12 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
+#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
#include <linux/interrupt.h>
#include <linux/irq.h> /* For irq_get_irq_data() */
#include <linux/module.h>
@@ -457,13 +461,16 @@ static int bmp280_read_temp(struct bmp280_data *data,
/*
* val might be NULL if we're called by the read_press routine,
- * who only cares about the carry over t_fine value.
+ * who only cares about the carry over t_fine value or if we're called
+ * by the buffer handler function.
*/
if (val) {
*val = comp_temp * 10;
return IIO_VAL_INT;
}
+ data->iio_buffer.temperature = comp_temp;
+
return 0;
}
@@ -494,10 +501,16 @@ static int bmp280_read_press(struct bmp280_data *data,
}
comp_press = bmp280_compensate_press(data, adc_press);
- *val = comp_press;
- *val2 = 256000;
+ /* val might be NULL if we're called by the buffer handler */
+ if (val) {
+ *val = comp_press;
+ *val2 = 256000;
+ return IIO_VAL_FRACTIONAL;
+ }
+
+ data->iio_buffer.pressure = comp_press;
- return IIO_VAL_FRACTIONAL;
+ return 0;
}
static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
@@ -526,9 +539,15 @@ static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
}
comp_humidity = bmp280_compensate_humidity(data, adc_humidity);
- *val = comp_humidity * 1000 / 1024;
+ /* val might be NULL if we're called by the buffer handler */
+ if (val) {
+ *val = comp_humidity * 1000 / 1024;
+ return IIO_VAL_INT;
+ }
- return IIO_VAL_INT;
+ data->iio_buffer.humidity = comp_humidity;
+
+ return 0;
}
static int bmp280_read_raw(struct iio_dev *indio_dev,
@@ -1170,7 +1189,8 @@ static int bmp380_read_temp(struct bmp280_data *data, int *val, int *val2)
/*
* Val might be NULL if we're called by the read_press routine,
- * who only cares about the carry over t_fine value.
+ * who only cares about the carry over t_fine value or if we're called
+ * by the buffer handler.
*/
if (val) {
/* IIO reports temperatures in milli Celsius */
@@ -1178,6 +1198,8 @@ static int bmp380_read_temp(struct bmp280_data *data, int *val, int *val2)
return IIO_VAL_INT;
}
+ data->iio_buffer.temperature = comp_temp;
+
return 0;
}
@@ -1206,11 +1228,17 @@ static int bmp380_read_press(struct bmp280_data *data, int *val, int *val2)
}
comp_press = bmp380_compensate_press(data, adc_press);
- *val = comp_press;
- /* Compensated pressure is in cPa (centipascals) */
- *val2 = 100000;
+ /* val might be NULL if we're called by the buffer handler */
+ if (val) {
+ *val = comp_press;
+ /* Compensated pressure is in cPa (centipascals) */
+ *val2 = 100000;
+ return IIO_VAL_FRACTIONAL;
+ }
+
+ data->iio_buffer.pressure = comp_press;
- return IIO_VAL_FRACTIONAL;
+ return 0;
}
static int bmp380_read_calib(struct bmp280_data *data)
@@ -1543,14 +1571,21 @@ static int bmp580_read_temp(struct bmp280_data *data, int *val, int *val2)
return -EIO;
}
- /*
- * Temperature is returned in Celsius degrees in fractional
- * form down 2^16. We rescale by x1000 to return milli Celsius
- * to respect IIO ABI.
- */
- *val = raw_temp * 1000;
- *val2 = 16;
- return IIO_VAL_FRACTIONAL_LOG2;
+ /* val might be NULL if we're called by the buffer handler */
+ if (val) {
+ /*
+ * Temperature is returned in Celsius degrees in fractional
+ * form down 2^16. We rescale by x1000 to return milli Celsius
+ * to respect IIO ABI.
+ */
+ *val = raw_temp * 1000;
+ *val2 = 16;
+ return IIO_VAL_FRACTIONAL_LOG2;
+ }
+
+ data->iio_buffer.temperature = raw_temp;
+
+ return 0;
}
static int bmp580_read_press(struct bmp280_data *data, int *val, int *val2)
@@ -1570,13 +1605,21 @@ static int bmp580_read_press(struct bmp280_data *data, int *val, int *val2)
dev_err(data->dev, "reading pressure skipped\n");
return -EIO;
}
- /*
- * Pressure is returned in Pascals in fractional form down 2^16.
- * We rescale /1000 to convert to kilopascal to respect IIO ABI.
- */
- *val = raw_press;
- *val2 = 64000; /* 2^6 * 1000 */
- return IIO_VAL_FRACTIONAL;
+
+ /* val might be NULL if we're called by the buffer handler */
+ if (val) {
+ /*
+ * Pressure is returned in Pascals in fractional form down 2^16.
+ * We rescale /1000 to convert to kilopascal to respect IIO ABI.
+ */
+ *val = raw_press;
+ *val2 = 64000; /* 2^6 * 1000 */
+ return IIO_VAL_FRACTIONAL;
+ }
+
+ data->iio_buffer.pressure = raw_press;
+
+ return 0;
}
static const int bmp580_odr_table[][2] = {
@@ -2048,13 +2091,16 @@ static int bmp180_read_temp(struct bmp280_data *data, int *val, int *val2)
/*
* val might be NULL if we're called by the read_press routine,
- * who only cares about the carry over t_fine value.
+ * who only cares about the carry over t_fine value or if we're called
+ * by the buffer handler.
*/
if (val) {
*val = comp_temp * 100;
return IIO_VAL_INT;
}
+ data->iio_buffer.temperature = comp_temp;
+
return 0;
}
@@ -2133,10 +2179,16 @@ static int bmp180_read_press(struct bmp280_data *data,
comp_press = bmp180_compensate_press(data, adc_press);
- *val = comp_press;
- *val2 = 1000;
+ /* val might be NULL if we're called by the buffer handler */
+ if (val) {
+ *val = comp_press;
+ *val2 = 1000;
+ return IIO_VAL_FRACTIONAL;
+ }
+
+ data->iio_buffer.pressure = comp_press;
- return IIO_VAL_FRACTIONAL;
+ return 0;
}
static int bmp180_chip_config(struct bmp280_data *data)
@@ -2217,6 +2269,43 @@ static int bmp085_fetch_eoc_irq(struct device *dev,
return 0;
}
+static irqreturn_t bmp280_buffer_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct bmp280_data *data = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&data->lock);
+
+ if (test_bit(BMP280_TEMP, indio_dev->active_scan_mask)) {
+ ret = data->chip_info->read_temp(data, NULL, NULL);
+ if (ret < 0)
+ goto done;
+ }
+
+ if (test_bit(BMP280_PRESS, indio_dev->active_scan_mask)) {
+ ret = data->chip_info->read_press(data, NULL, NULL);
+ if (ret < 0)
+ goto done;
+ }
+
+ if (test_bit(BME280_HUMID, indio_dev->active_scan_mask)) {
+ ret = data->chip_info->read_humid(data, NULL, NULL);
+ if (ret < 0)
+ goto done;
+ }
+
+ iio_push_to_buffers_with_timestamp(indio_dev, &data->iio_buffer,
+ pf->timestamp);
+
+done:
+ mutex_unlock(&data->lock);
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+
+}
static void bmp280_pm_disable(void *data)
{
struct device *dev = data;
@@ -2358,6 +2447,12 @@ int bmp280_common_probe(struct device *dev,
return ret;
}
+ ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
+ iio_pollfunc_store_time,
+ &bmp280_buffer_handler, NULL);
+ if (ret)
+ return dev_err_probe(data->dev, ret,
+ "iio triggered buffer setup failed\n");
/* Enable runtime PM */
pm_runtime_get_noresume(dev);
pm_runtime_set_active(dev);
diff --git a/drivers/iio/pressure/bmp280.h b/drivers/iio/pressure/bmp280.h
index d77402cb3121..d5c0451ebf68 100644
--- a/drivers/iio/pressure/bmp280.h
+++ b/drivers/iio/pressure/bmp280.h
@@ -400,6 +400,13 @@ struct bmp280_data {
*/
s32 t_fine;
+ /* IIO sysfs buffer */
+ struct {
+ s32 temperature;
+ u32 pressure;
+ u32 humidity;
+ s64 timestamp;
+ } iio_buffer;
/*
* DMA (thus cache coherency maintenance) may require the
* transfer buffers to live in their own cache lines.
--
2.25.1
next prev parent reply other threads:[~2024-03-03 16:53 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-03 16:52 [PATCH 0/4] Series to add triggered buffer support to BMP280 driver Vasileios Amoiridis
2024-03-03 16:52 ` [PATCH 1/4] iio: pressure: BMP280 core driver headers sorting Vasileios Amoiridis
2024-03-04 11:36 ` Andy Shevchenko
2024-03-09 18:09 ` Jonathan Cameron
2024-03-03 16:52 ` [PATCH 2/4] iio: pressure: Add scale value for channels Vasileios Amoiridis
2024-03-04 11:42 ` Andy Shevchenko
2024-03-09 18:28 ` Jonathan Cameron
2024-03-03 16:52 ` [PATCH 3/4] iio: pressure: Add timestamp and scan_masks for BMP280 driver Vasileios Amoiridis
2024-03-04 11:47 ` Andy Shevchenko
2024-03-04 18:50 ` Vasileios Amoiridis
2024-03-04 19:07 ` Andy Shevchenko
2024-03-09 18:12 ` Jonathan Cameron
2024-03-03 16:53 ` Vasileios Amoiridis [this message]
2024-03-04 11:52 ` [PATCH 4/4] iio: pressure: Add triggered buffer support " Andy Shevchenko
2024-03-04 19:08 ` Vasileios Amoiridis
2024-03-04 19:18 ` Andy Shevchenko
2024-03-04 20:05 ` Vasileios Amoiridis
2024-03-09 18:19 ` Jonathan Cameron
2024-03-09 18:32 ` Jonathan Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240303165300.468011-5-vassilisamir@gmail.com \
--to=vassilisamir@gmail.com \
--cc=579lpy@gmail.com \
--cc=ak@it-klinger.de \
--cc=andriy.shevchenko@linux.intel.com \
--cc=ang.iglesiasg@gmail.com \
--cc=jic23@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mazziesaccount@gmail.com \
--cc=petre.rodan@subdimension.ro \
--cc=phil@raspberrypi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).