Commit 80cd23f4 authored by Vasileios Amoiridis's avatar Vasileios Amoiridis Committed by Jonathan Cameron

iio: pressure: bmp280: Add triggered buffer support

BMP2xx, BME280, BMP3xx, and BMP5xx use continuous buffers for their
temperature, pressure and humidity readings. This facilitates the
use of burst/bulk reads in order to acquire data faster. The
approach is different from the one used in oneshot captures.

BMP085 & BMP1xx devices use a completely different measurement
process that is well defined and is used in their buffer_handler().
Suggested-by: default avatarAngel Iglesias <ang.iglesiasg@gmail.com>
Signed-off-by: default avatarVasileios Amoiridis <vassilisamir@gmail.com>
Link: https://lore.kernel.org/r/20240512230524.53990-6-vassilisamir@gmail.com
Link: https://patch.msgid.link/20240628171726.124852-4-vassilisamir@gmail.comSigned-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 479e67ac
......@@ -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
......
......@@ -41,7 +41,10 @@
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <asm/unaligned.h>
......@@ -134,6 +137,12 @@ enum {
BMP380_P11 = 20,
};
enum bmp280_scan {
BMP280_PRESS,
BMP280_TEMP,
BME280_HUMID,
};
static const struct iio_chan_spec bmp280_channels[] = {
{
.type = IIO_PRESSURE,
......@@ -142,6 +151,13 @@ static const struct iio_chan_spec bmp280_channels[] = {
BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.scan_index = 0,
.scan_type = {
.sign = 'u',
.realbits = 32,
.storagebits = 32,
.endianness = IIO_CPU,
},
},
{
.type = IIO_TEMP,
......@@ -150,7 +166,15 @@ static const struct iio_chan_spec bmp280_channels[] = {
BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.scan_index = 1,
.scan_type = {
.sign = 's',
.realbits = 32,
.storagebits = 32,
.endianness = IIO_CPU,
},
},
IIO_CHAN_SOFT_TIMESTAMP(2),
};
static const struct iio_chan_spec bme280_channels[] = {
......@@ -161,6 +185,13 @@ static const struct iio_chan_spec bme280_channels[] = {
BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.scan_index = 0,
.scan_type = {
.sign = 'u',
.realbits = 32,
.storagebits = 32,
.endianness = IIO_CPU,
},
},
{
.type = IIO_TEMP,
......@@ -169,6 +200,13 @@ static const struct iio_chan_spec bme280_channels[] = {
BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.scan_index = 1,
.scan_type = {
.sign = 's',
.realbits = 32,
.storagebits = 32,
.endianness = IIO_CPU,
},
},
{
.type = IIO_HUMIDITYRELATIVE,
......@@ -177,7 +215,15 @@ static const struct iio_chan_spec bme280_channels[] = {
BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.scan_index = 2,
.scan_type = {
.sign = 'u',
.realbits = 32,
.storagebits = 32,
.endianness = IIO_CPU,
},
},
IIO_CHAN_SOFT_TIMESTAMP(3),
};
static const struct iio_chan_spec bmp380_channels[] = {
......@@ -190,6 +236,51 @@ static const struct iio_chan_spec bmp380_channels[] = {
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
.scan_index = 0,
.scan_type = {
.sign = 'u',
.realbits = 32,
.storagebits = 32,
.endianness = IIO_CPU,
},
},
{
.type = IIO_TEMP,
/* PROCESSED maintained for ABI backwards compatibility */
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
.scan_index = 1,
.scan_type = {
.sign = 's',
.realbits = 32,
.storagebits = 32,
.endianness = IIO_CPU,
},
},
IIO_CHAN_SOFT_TIMESTAMP(2),
};
static const struct iio_chan_spec bmp580_channels[] = {
{
.type = IIO_PRESSURE,
/* PROCESSED maintained for ABI backwards compatibility */
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
.scan_index = 0,
.scan_type = {
.sign = 'u',
.realbits = 24,
.storagebits = 32,
.endianness = IIO_LE,
},
},
{
.type = IIO_TEMP,
......@@ -200,7 +291,15 @@ static const struct iio_chan_spec bmp380_channels[] = {
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
.scan_index = 1,
.scan_type = {
.sign = 's',
.realbits = 24,
.storagebits = 32,
.endianness = IIO_LE,
},
},
IIO_CHAN_SOFT_TIMESTAMP(2),
};
static int bmp280_read_calib(struct bmp280_data *data)
......@@ -316,7 +415,7 @@ static int bme280_read_humid_adc(struct bmp280_data *data, u16 *adc_humidity)
int ret;
ret = regmap_bulk_read(data->regmap, BME280_REG_HUMIDITY_MSB,
&data->be16, sizeof(data->be16));
&data->be16, BME280_NUM_HUMIDITY_BYTES);
if (ret) {
dev_err(data->dev, "failed to read humidity\n");
return ret;
......@@ -362,7 +461,7 @@ static int bmp280_read_temp_adc(struct bmp280_data *data, u32 *adc_temp)
int ret;
ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB,
data->buf, sizeof(data->buf));
data->buf, BMP280_NUM_TEMP_BYTES);
if (ret) {
dev_err(data->dev, "failed to read temperature\n");
return ret;
......@@ -423,7 +522,7 @@ static int bmp280_read_press_adc(struct bmp280_data *data, u32 *adc_press)
int ret;
ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB,
data->buf, sizeof(data->buf));
data->buf, BMP280_NUM_PRESS_BYTES);
if (ret) {
dev_err(data->dev, "failed to read pressure\n");
return ret;
......@@ -874,6 +973,16 @@ static const struct iio_info bmp280_info = {
.write_raw = &bmp280_write_raw,
};
static const unsigned long bmp280_avail_scan_masks[] = {
BIT(BMP280_TEMP) | BIT(BMP280_PRESS),
0
};
static const unsigned long bme280_avail_scan_masks[] = {
BIT(BME280_HUMID) | BIT(BMP280_TEMP) | BIT(BMP280_PRESS),
0
};
static int bmp280_chip_config(struct bmp280_data *data)
{
u8 osrs = FIELD_PREP(BMP280_OSRS_TEMP_MASK, data->oversampling_temp + 1) |
......@@ -901,6 +1010,53 @@ static int bmp280_chip_config(struct bmp280_data *data)
return ret;
}
static irqreturn_t bmp280_trigger_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);
s32 adc_temp, adc_press, t_fine;
int ret;
guard(mutex)(&data->lock);
/* Burst read data registers */
ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB,
data->buf, BMP280_BURST_READ_BYTES);
if (ret) {
dev_err(data->dev, "failed to burst read sensor data\n");
goto out;
}
/* Temperature calculations */
adc_temp = FIELD_GET(BMP280_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[3]));
if (adc_temp == BMP280_TEMP_SKIPPED) {
dev_err(data->dev, "reading temperature skipped\n");
goto out;
}
data->sensor_data[1] = bmp280_compensate_temp(data, adc_temp);
/* Pressure calculations */
adc_press = FIELD_GET(BMP280_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[0]));
if (adc_press == BMP280_PRESS_SKIPPED) {
dev_err(data->dev, "reading pressure skipped\n");
goto out;
}
t_fine = bmp280_calc_t_fine(data, adc_temp);
data->sensor_data[0] = bmp280_compensate_press(data, adc_press, t_fine);
iio_push_to_buffers_with_timestamp(indio_dev, &data->sensor_data,
iio_get_time_ns(indio_dev));
out:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static const int bmp280_oversampling_avail[] = { 1, 2, 4, 8, 16 };
static const u8 bmp280_chip_ids[] = { BMP280_CHIP_ID };
static const int bmp280_temp_coeffs[] = { 10, 1 };
......@@ -914,6 +1070,7 @@ const struct bmp280_chip_info bmp280_chip_info = {
.start_up_time = 2000,
.channels = bmp280_channels,
.num_channels = ARRAY_SIZE(bmp280_channels),
.avail_scan_masks = bmp280_avail_scan_masks,
.oversampling_temp_avail = bmp280_oversampling_avail,
.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
......@@ -942,6 +1099,8 @@ const struct bmp280_chip_info bmp280_chip_info = {
.read_temp = bmp280_read_temp,
.read_press = bmp280_read_press,
.read_calib = bmp280_read_calib,
.trigger_handler = bmp280_trigger_handler,
};
EXPORT_SYMBOL_NS(bmp280_chip_info, IIO_BMP280);
......@@ -964,6 +1123,62 @@ static int bme280_chip_config(struct bmp280_data *data)
return bmp280_chip_config(data);
}
static irqreturn_t bme280_trigger_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);
s32 adc_temp, adc_press, adc_humidity, t_fine;
int ret;
guard(mutex)(&data->lock);
/* Burst read data registers */
ret = regmap_bulk_read(data->regmap, BMP280_REG_PRESS_MSB,
data->buf, BME280_BURST_READ_BYTES);
if (ret) {
dev_err(data->dev, "failed to burst read sensor data\n");
goto out;
}
/* Temperature calculations */
adc_temp = FIELD_GET(BMP280_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[3]));
if (adc_temp == BMP280_TEMP_SKIPPED) {
dev_err(data->dev, "reading temperature skipped\n");
goto out;
}
data->sensor_data[1] = bmp280_compensate_temp(data, adc_temp);
/* Pressure calculations */
adc_press = FIELD_GET(BMP280_MEAS_TRIM_MASK, get_unaligned_be24(&data->buf[0]));
if (adc_press == BMP280_PRESS_SKIPPED) {
dev_err(data->dev, "reading pressure skipped\n");
goto out;
}
t_fine = bmp280_calc_t_fine(data, adc_temp);
data->sensor_data[0] = bmp280_compensate_press(data, adc_press, t_fine);
/* Humidity calculations */
adc_humidity = get_unaligned_be16(&data->buf[6]);
if (adc_humidity == BMP280_HUMIDITY_SKIPPED) {
dev_err(data->dev, "reading humidity skipped\n");
goto out;
}
data->sensor_data[2] = bme280_compensate_humidity(data, adc_humidity, t_fine);
iio_push_to_buffers_with_timestamp(indio_dev, &data->sensor_data,
iio_get_time_ns(indio_dev));
out:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static const u8 bme280_chip_ids[] = { BME280_CHIP_ID };
static const int bme280_humid_coeffs[] = { 1000, 1024 };
......@@ -975,6 +1190,7 @@ const struct bmp280_chip_info bme280_chip_info = {
.start_up_time = 2000,
.channels = bme280_channels,
.num_channels = ARRAY_SIZE(bme280_channels),
.avail_scan_masks = bme280_avail_scan_masks,
.oversampling_temp_avail = bmp280_oversampling_avail,
.num_oversampling_temp_avail = ARRAY_SIZE(bmp280_oversampling_avail),
......@@ -1000,6 +1216,8 @@ const struct bmp280_chip_info bme280_chip_info = {
.read_press = bmp280_read_press,
.read_humid = bme280_read_humid,
.read_calib = bme280_read_calib,
.trigger_handler = bme280_trigger_handler,
};
EXPORT_SYMBOL_NS(bme280_chip_info, IIO_BMP280);
......@@ -1054,7 +1272,7 @@ static int bmp380_read_temp_adc(struct bmp280_data *data, u32 *adc_temp)
int ret;
ret = regmap_bulk_read(data->regmap, BMP380_REG_TEMP_XLSB,
data->buf, sizeof(data->buf));
data->buf, BMP280_NUM_TEMP_BYTES);
if (ret) {
dev_err(data->dev, "failed to read temperature\n");
return ret;
......@@ -1123,7 +1341,7 @@ static int bmp380_read_press_adc(struct bmp280_data *data, u32 *adc_press)
int ret;
ret = regmap_bulk_read(data->regmap, BMP380_REG_PRESS_XLSB,
data->buf, sizeof(data->buf));
data->buf, BMP280_NUM_PRESS_BYTES);
if (ret) {
dev_err(data->dev, "failed to read pressure\n");
return ret;
......@@ -1384,6 +1602,53 @@ static int bmp380_chip_config(struct bmp280_data *data)
return 0;
}
static irqreturn_t bmp380_trigger_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);
s32 adc_temp, adc_press, t_fine;
int ret;
guard(mutex)(&data->lock);
/* Burst read data registers */
ret = regmap_bulk_read(data->regmap, BMP380_REG_PRESS_XLSB,
data->buf, BMP280_BURST_READ_BYTES);
if (ret) {
dev_err(data->dev, "failed to burst read sensor data\n");
goto out;
}
/* Temperature calculations */
adc_temp = get_unaligned_le24(&data->buf[3]);
if (adc_temp == BMP380_TEMP_SKIPPED) {
dev_err(data->dev, "reading temperature skipped\n");
goto out;
}
data->sensor_data[1] = bmp380_compensate_temp(data, adc_temp);
/* Pressure calculations */
adc_press = get_unaligned_le24(&data->buf[0]);
if (adc_press == BMP380_PRESS_SKIPPED) {
dev_err(data->dev, "reading pressure skipped\n");
goto out;
}
t_fine = bmp380_calc_t_fine(data, adc_temp);
data->sensor_data[0] = bmp380_compensate_press(data, adc_press, t_fine);
iio_push_to_buffers_with_timestamp(indio_dev, &data->sensor_data,
iio_get_time_ns(indio_dev));
out:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static const int bmp380_oversampling_avail[] = { 1, 2, 4, 8, 16, 32 };
static const int bmp380_iir_filter_coeffs_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128};
static const u8 bmp380_chip_ids[] = { BMP380_CHIP_ID, BMP390_CHIP_ID };
......@@ -1399,6 +1664,7 @@ const struct bmp280_chip_info bmp380_chip_info = {
.start_up_time = 2000,
.channels = bmp380_channels,
.num_channels = ARRAY_SIZE(bmp380_channels),
.avail_scan_masks = bmp280_avail_scan_masks,
.oversampling_temp_avail = bmp380_oversampling_avail,
.num_oversampling_temp_avail = ARRAY_SIZE(bmp380_oversampling_avail),
......@@ -1426,6 +1692,8 @@ const struct bmp280_chip_info bmp380_chip_info = {
.read_press = bmp380_read_press,
.read_calib = bmp380_read_calib,
.preinit = bmp380_preinit,
.trigger_handler = bmp380_trigger_handler,
};
EXPORT_SYMBOL_NS(bmp380_chip_info, IIO_BMP280);
......@@ -1546,8 +1814,8 @@ static int bmp580_read_temp(struct bmp280_data *data, s32 *raw_temp)
s32 value_temp;
int ret;
ret = regmap_bulk_read(data->regmap, BMP580_REG_TEMP_XLSB, data->buf,
sizeof(data->buf));
ret = regmap_bulk_read(data->regmap, BMP580_REG_TEMP_XLSB,
data->buf, BMP280_NUM_TEMP_BYTES);
if (ret) {
dev_err(data->dev, "failed to read temperature\n");
return ret;
......@@ -1568,8 +1836,8 @@ static int bmp580_read_press(struct bmp280_data *data, u32 *raw_press)
u32 value_press;
int ret;
ret = regmap_bulk_read(data->regmap, BMP580_REG_PRESS_XLSB, data->buf,
sizeof(data->buf));
ret = regmap_bulk_read(data->regmap, BMP580_REG_PRESS_XLSB,
data->buf, BMP280_NUM_PRESS_BYTES);
if (ret) {
dev_err(data->dev, "failed to read pressure\n");
return ret;
......@@ -1916,6 +2184,38 @@ static int bmp580_chip_config(struct bmp280_data *data)
return 0;
}
static irqreturn_t bmp580_trigger_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;
guard(mutex)(&data->lock);
/* Burst read data registers */
ret = regmap_bulk_read(data->regmap, BMP580_REG_TEMP_XLSB,
data->buf, BMP280_BURST_READ_BYTES);
if (ret) {
dev_err(data->dev, "failed to burst read sensor data\n");
goto out;
}
/* Temperature calculations */
memcpy(&data->sensor_data[1], &data->buf[0], 3);
/* Pressure calculations */
memcpy(&data->sensor_data[0], &data->buf[3], 3);
iio_push_to_buffers_with_timestamp(indio_dev, &data->sensor_data,
iio_get_time_ns(indio_dev));
out:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static const int bmp580_oversampling_avail[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
static const u8 bmp580_chip_ids[] = { BMP580_CHIP_ID, BMP580_CHIP_ID_ALT };
/* Instead of { 1000, 16 } we do this, to avoid overflow issues */
......@@ -1928,8 +2228,9 @@ const struct bmp280_chip_info bmp580_chip_info = {
.num_chip_id = ARRAY_SIZE(bmp580_chip_ids),
.regmap_config = &bmp580_regmap_config,
.start_up_time = 2000,
.channels = bmp380_channels,
.num_channels = ARRAY_SIZE(bmp380_channels),
.channels = bmp580_channels,
.num_channels = ARRAY_SIZE(bmp580_channels),
.avail_scan_masks = bmp280_avail_scan_masks,
.oversampling_temp_avail = bmp580_oversampling_avail,
.num_oversampling_temp_avail = ARRAY_SIZE(bmp580_oversampling_avail),
......@@ -1956,6 +2257,8 @@ const struct bmp280_chip_info bmp580_chip_info = {
.read_temp = bmp580_read_temp,
.read_press = bmp580_read_press,
.preinit = bmp580_preinit,
.trigger_handler = bmp580_trigger_handler,
};
EXPORT_SYMBOL_NS(bmp580_chip_info, IIO_BMP280);
......@@ -2134,7 +2437,7 @@ static int bmp180_read_press_adc(struct bmp280_data *data, u32 *adc_press)
return ret;
ret = regmap_bulk_read(data->regmap, BMP180_REG_OUT_MSB,
data->buf, sizeof(data->buf));
data->buf, BMP280_NUM_PRESS_BYTES);
if (ret) {
dev_err(data->dev, "failed to read pressure\n");
return ret;
......@@ -2205,6 +2508,36 @@ static int bmp180_chip_config(struct bmp280_data *data)
return 0;
}
static irqreturn_t bmp180_trigger_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, chan_value;
guard(mutex)(&data->lock);
ret = bmp180_read_temp(data, &chan_value);
if (ret)
goto out;
data->sensor_data[1] = chan_value;
ret = bmp180_read_press(data, &chan_value);
if (ret)
goto out;
data->sensor_data[0] = chan_value;
iio_push_to_buffers_with_timestamp(indio_dev, &data->sensor_data,
iio_get_time_ns(indio_dev));
out:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static const int bmp180_oversampling_temp_avail[] = { 1 };
static const int bmp180_oversampling_press_avail[] = { 1, 2, 4, 8 };
static const u8 bmp180_chip_ids[] = { BMP180_CHIP_ID };
......@@ -2219,6 +2552,7 @@ const struct bmp280_chip_info bmp180_chip_info = {
.start_up_time = 2000,
.channels = bmp280_channels,
.num_channels = ARRAY_SIZE(bmp280_channels),
.avail_scan_masks = bmp280_avail_scan_masks,
.oversampling_temp_avail = bmp180_oversampling_temp_avail,
.num_oversampling_temp_avail =
......@@ -2239,6 +2573,8 @@ const struct bmp280_chip_info bmp180_chip_info = {
.read_temp = bmp180_read_temp,
.read_press = bmp180_read_press,
.read_calib = bmp180_read_calib,
.trigger_handler = bmp180_trigger_handler,
};
EXPORT_SYMBOL_NS(bmp180_chip_info, IIO_BMP280);
......@@ -2284,6 +2620,30 @@ static int bmp085_fetch_eoc_irq(struct device *dev,
return 0;
}
static int bmp280_buffer_preenable(struct iio_dev *indio_dev)
{
struct bmp280_data *data = iio_priv(indio_dev);
pm_runtime_get_sync(data->dev);
return 0;
}
static int bmp280_buffer_postdisable(struct iio_dev *indio_dev)
{
struct bmp280_data *data = iio_priv(indio_dev);
pm_runtime_mark_last_busy(data->dev);
pm_runtime_put_autosuspend(data->dev);
return 0;
}
static const struct iio_buffer_setup_ops bmp280_buffer_setup_ops = {
.preenable = bmp280_buffer_preenable,
.postdisable = bmp280_buffer_postdisable,
};
static void bmp280_pm_disable(void *data)
{
struct device *dev = data;
......@@ -2330,6 +2690,7 @@ int bmp280_common_probe(struct device *dev,
/* Apply initial values from chip info structure */
indio_dev->channels = chip_info->channels;
indio_dev->num_channels = chip_info->num_channels;
indio_dev->available_scan_masks = chip_info->avail_scan_masks;
data->oversampling_press = chip_info->oversampling_press_default;
data->oversampling_humid = chip_info->oversampling_humid_default;
data->oversampling_temp = chip_info->oversampling_temp_default;
......@@ -2415,6 +2776,14 @@ int bmp280_common_probe(struct device *dev,
"failed to read calibration coefficients\n");
}
ret = devm_iio_triggered_buffer_setup(data->dev, indio_dev,
iio_pollfunc_store_time,
data->chip_info->trigger_handler,
&bmp280_buffer_setup_ops);
if (ret)
return dev_err_probe(data->dev, ret,
"iio triggered buffer setup failed\n");
/*
* Attempt to grab an optional EOC IRQ - only the BMP085 has this
* however as it happens, the BMP085 shares the chip ID of BMP180
......
......@@ -40,14 +40,10 @@ 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 rx_buf[4];
u8 rx_buf[BME280_BURST_READ_BYTES + 1];
ssize_t status;
/*
* Maximum number of consecutive bytes read for a temperature or
* pressure measurement is 3.
*/
if (val_size > 3)
if (val_size > BME280_BURST_READ_BYTES)
return -EINVAL;
/*
......
......@@ -304,6 +304,16 @@
#define BMP280_PRESS_SKIPPED 0x80000
#define BMP280_HUMIDITY_SKIPPED 0x8000
/* Number of bytes for each value */
#define BMP280_NUM_PRESS_BYTES 3
#define BMP280_NUM_TEMP_BYTES 3
#define BME280_NUM_HUMIDITY_BYTES 2
#define BMP280_BURST_READ_BYTES (BMP280_NUM_PRESS_BYTES + \
BMP280_NUM_TEMP_BYTES)
#define BME280_BURST_READ_BYTES (BMP280_NUM_PRESS_BYTES + \
BMP280_NUM_TEMP_BYTES + \
BME280_NUM_HUMIDITY_BYTES)
/* Core exported structs */
static const char *const bmp280_supply_names[] = {
......@@ -397,13 +407,19 @@ struct bmp280_data {
*/
int sampling_freq;
/*
* Data to push to userspace triggered buffer. Up to 3 channels and
* s64 timestamp, aligned.
*/
s32 sensor_data[6] __aligned(8);
/*
* DMA (thus cache coherency maintenance) may require the
* transfer buffers to live in their own cache lines.
*/
union {
/* Sensor data buffer */
u8 buf[3];
u8 buf[BME280_BURST_READ_BYTES];
/* Calibration data buffers */
__le16 bmp280_cal_buf[BMP280_CONTIGUOUS_CALIB_REGS / 2];
__be16 bmp180_cal_buf[BMP180_REG_CALIB_COUNT / 2];
......@@ -425,6 +441,7 @@ struct bmp280_chip_info {
const struct iio_chan_spec *channels;
int num_channels;
unsigned int start_up_time;
const unsigned long *avail_scan_masks;
const int *oversampling_temp_avail;
int num_oversampling_temp_avail;
......@@ -459,6 +476,8 @@ struct bmp280_chip_info {
int (*read_humid)(struct bmp280_data *data, u32 *adc_humidity);
int (*read_calib)(struct bmp280_data *data);
int (*preinit)(struct bmp280_data *data);
irqreturn_t (*trigger_handler)(int irq, void *p);
};
/* Chip infos for each variant */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment