[PATCH v2 08/12] iio: accel: adxl313: add FIFO watermark

Lothar Rubusch posted 12 patches 7 months ago
Only 11 patches received!
There is a newer version of this series
[PATCH v2 08/12] iio: accel: adxl313: add FIFO watermark
Posted by Lothar Rubusch 7 months ago
Add FIFO watermark configuration and evaluation. Let a watermark to be
configured. Evaluate the interrupt accordingly. Read out the FIFO content
and push the values to the IIO channel.

Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
 drivers/iio/accel/adxl313.h      |  1 +
 drivers/iio/accel/adxl313_core.c | 59 ++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/drivers/iio/accel/adxl313.h b/drivers/iio/accel/adxl313.h
index 4cb1fe1f2616..9c7aedf7da7a 100644
--- a/drivers/iio/accel/adxl313.h
+++ b/drivers/iio/accel/adxl313.h
@@ -89,6 +89,7 @@ struct adxl313_data {
 	const struct adxl313_chip_info *chip_info;
 	struct mutex	lock; /* lock to protect transf_buf */
 	int irq;
+	u8 watermark;
 	u8 fifo_mode;
 	__le16		transf_buf __aligned(IIO_DMA_MINALIGN);
 	__le16		fifo_buf[ADXL313_NUM_AXIS * ADXL313_FIFO_SIZE + 1];
diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_core.c
index 8eecd2851512..da89e13a100d 100644
--- a/drivers/iio/accel/adxl313_core.c
+++ b/drivers/iio/accel/adxl313_core.c
@@ -374,6 +374,25 @@ static int adxl313_write_raw(struct iio_dev *indio_dev,
 	}
 }
 
+static int adxl313_set_watermark(struct iio_dev *indio_dev, unsigned int value)
+{
+	struct adxl313_data *data = iio_priv(indio_dev);
+	const unsigned int fifo_mask = 0x1f, watermark_mask  = 0x02;
+	int ret;
+
+	value = min(value, ADXL313_FIFO_SIZE - 1);
+
+	ret = regmap_update_bits(data->regmap, ADXL313_REG_FIFO_CTL,
+				 fifo_mask, value);
+	if (ret)
+		return ret;
+
+	data->watermark = value;
+
+	return regmap_update_bits(data->regmap, ADXL313_REG_INT_ENABLE,
+				  watermark_mask, ADXL313_INT_WATERMARK);
+}
+
 static int adxl313_get_samples(struct adxl313_data *data)
 {
 	unsigned int regval = 0;
@@ -400,6 +419,7 @@ static int adxl313_set_fifo(struct adxl313_data *data)
 		return ret;
 
 	ret = regmap_write(data->regmap, ADXL313_REG_FIFO_CTL,
+			   FIELD_PREP(ADXL313_REG_FIFO_CTL_SAMPLES_MSK,	data->watermark) |
 			   FIELD_PREP(ADXL313_REG_FIFO_CTL_MODE_MSK, data->fifo_mode));
 
 	return adxl313_set_measure_en(data, true);
@@ -465,6 +485,41 @@ static const struct iio_buffer_setup_ops adxl313_buffer_ops = {
 	.predisable = adxl313_buffer_predisable,
 };
 
+static int adxl313_fifo_push(struct iio_dev *indio_dev, int samples)
+{
+	struct adxl313_data *data = iio_priv(indio_dev);
+	int i, ret;
+
+	if (samples <= 0)
+		return -EINVAL;
+
+	ret = adxl313_fifo_transfer(data, samples);
+	if (ret)
+		return ret;
+
+	for (i = 0; i  < ADXL313_NUM_AXIS * samples; i += ADXL313_NUM_AXIS)
+		iio_push_to_buffers(indio_dev, &data->fifo_buf[i]);
+
+	return 0;
+}
+
+static int adxl313_push_event(struct iio_dev *indio_dev, int int_stat)
+{
+	struct adxl313_data *data =  iio_priv(indio_dev);
+	int samples;
+	int ret = -ENOENT;
+
+	if (FIELD_GET(ADXL313_INT_WATERMARK, int_stat)) {
+		samples = adxl313_get_samples(data);
+		if (samples < 0)
+			return -EINVAL;
+
+		ret = adxl313_fifo_push(indio_dev, samples);
+	}
+
+	return ret;
+}
+
 static irqreturn_t adxl313_irq_handler(int irq, void *p)
 {
 	struct iio_dev *indio_dev = p;
@@ -474,6 +529,9 @@ static irqreturn_t adxl313_irq_handler(int irq, void *p)
 	if (regmap_read(data->regmap, ADXL313_REG_INT_SOURCE, &int_stat))
 		return IRQ_NONE;
 
+	if (adxl313_push_event(indio_dev, int_stat))
+		goto err;
+
 	if (FIELD_GET(ADXL313_INT_OVERRUN, int_stat))
 		goto err;
 
@@ -498,6 +556,7 @@ static const struct iio_info adxl313_info = {
 	.read_raw	= adxl313_read_raw,
 	.write_raw	= adxl313_write_raw,
 	.read_avail	= adxl313_read_freq_avail,
+	.hwfifo_set_watermark = adxl313_set_watermark,
 	.debugfs_reg_access = &adxl313_reg_access,
 };
 
-- 
2.39.5
Re: [PATCH v2 08/12] iio: accel: adxl313: add FIFO watermark
Posted by Andy Shevchenko 7 months ago
On Tue, May 20, 2025 at 10:50:03PM +0000, Lothar Rubusch wrote:
> Add FIFO watermark configuration and evaluation. Let a watermark to be
> configured. Evaluate the interrupt accordingly. Read out the FIFO content
> and push the values to the IIO channel.

...

> +	const unsigned int fifo_mask = 0x1f, watermark_mask  = 0x02;

Seems you have some (wrong) setting in the text editor?
One space too many again...

...

> +static int adxl313_fifo_push(struct iio_dev *indio_dev, int samples)
> +{
> +	struct adxl313_data *data = iio_priv(indio_dev);
> +	int i, ret;

Why is 'i' signed?

> +	if (samples <= 0)

What is the semantics of the negative samples? Is it an error code? Why not?
I believe it's ignored again from my previous review.

> +		return -EINVAL;
> +
> +	ret = adxl313_fifo_transfer(data, samples);
> +	if (ret)
> +		return ret;
> +
> +	for (i = 0; i  < ADXL313_NUM_AXIS * samples; i += ADXL313_NUM_AXIS)

Ouch, one space too many, *again*!

> +		iio_push_to_buffers(indio_dev, &data->fifo_buf[i]);
> +
> +	return 0;
> +}

...

> +static int adxl313_push_event(struct iio_dev *indio_dev, int int_stat)
> +{
> +	struct adxl313_data *data =  iio_priv(indio_dev);
> +	int samples;
> +	int ret = -ENOENT;
> +
> +	if (FIELD_GET(ADXL313_INT_WATERMARK, int_stat)) {
> +		samples = adxl313_get_samples(data);
> +		if (samples < 0)
> +			return -EINVAL;
> +
> +		ret = adxl313_fifo_push(indio_dev, samples);
> +	}
> +
> +	return ret;
> +}

...and again... If you are going to ignore most of the comments, do not expect
your patches to be applied. I'm stopping here.

...

Also note, try to avoid sending a new version until the review is settled down
on a previous round.

...

With this being said, I stopped here. Take your time (you have now a few weeks)
and carefully address / discuss all mentioned pieces of the code in both review
rounds.

-- 
With Best Regards,
Andy Shevchenko