devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/7] iio: accel: adxl345: add FIFO operating with IRQ triggered watermark events
@ 2024-12-11 23:06 Lothar Rubusch
  2024-12-11 23:06 ` [PATCH v6 1/7] iio: accel: adxl345: add function to switch measuring mode Lothar Rubusch
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: Lothar Rubusch @ 2024-12-11 23:06 UTC (permalink / raw)
  To: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt
  Cc: devicetree, linux-iio, linux-kernel, eraretuya, l.rubusch

The adxl345 sensor offers several features. Most of them are based on
using the hardware FIFO and reacting on events coming in on an interrupt
line. Add access to configure and read out the FIFO, handling of interrupts
and configuration and application of the watermark feature on that FIFO.

Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
v5 -> v6:
- dropped justify patch, since unnecessary change to format mask
- added separate dt-bindings patch to remove required interrupts property
- merged FIFO watermark patches
- reworked bitfield handling
- group irq setup in probe()
- several type fixes by smatch and tools
v4 -> v5:
- fix dt-binding for enum array of INT1 and INT2
v3 -> v4:
- fix dt-binding indention 
v2 -> v3:
- reorganize commits, merge the watermark handling
- INT lines are defined by binding
- kfifo is prepared by devm_iio_kfifo_buffer_setup()
- event handler is registered w/ devm_request_threaded_irq()
v1 -> v2:
Fix comments according to Documentation/doc-guide/kernel-doc.rst
and missing static declaration of function.
---

Lothar Rubusch (7):
  iio: accel: adxl345: add function to switch measuring mode
  iio: accel: adxl345: complete the list of defines
  dt-bindings: iio: accel: adxl345: add interrupt-names
  dt-bindings: iio: accel: adxl345: make interrupts not a required
    property
  iio: accel: adxl345: introduce interrupt handling
  iio: accel: adxl345: initialize FIFO delay value for SPI
  iio: accel: adxl345: add FIFO with watermark events

 .../bindings/iio/accel/adi,adxl345.yaml       |   7 +-
 drivers/iio/accel/adxl345.h                   |  95 ++++-
 drivers/iio/accel/adxl345_core.c              | 383 +++++++++++++++++-
 drivers/iio/accel/adxl345_i2c.c               |   2 +-
 drivers/iio/accel/adxl345_spi.c               |   7 +-
 5 files changed, 461 insertions(+), 33 deletions(-)

-- 
2.39.5


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v6 1/7] iio: accel: adxl345: add function to switch measuring mode
  2024-12-11 23:06 [PATCH v6 0/7] iio: accel: adxl345: add FIFO operating with IRQ triggered watermark events Lothar Rubusch
@ 2024-12-11 23:06 ` Lothar Rubusch
  2024-12-11 23:06 ` [PATCH v6 2/7] iio: accel: adxl345: complete the list of defines Lothar Rubusch
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Lothar Rubusch @ 2024-12-11 23:06 UTC (permalink / raw)
  To: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt
  Cc: devicetree, linux-iio, linux-kernel, eraretuya, l.rubusch

Replace the powerup / powerdown functions by a generic function to put
the sensor in STANDBY, or MEASURE mode. When configuring the FIFO for
several features of the accelerometer, it is recommended to put
measuring in STANDBY mode.

Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
 drivers/iio/accel/adxl345_core.c | 42 +++++++++++++++++++++++---------
 1 file changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 88df9547b..b48bc838c 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -138,6 +138,34 @@ static int adxl345_write_raw_get_fmt(struct iio_dev *indio_dev,
 	}
 }
 
+/**
+ * adxl345_set_measure_en() - Enable and disable measuring.
+ *
+ * @st: The device data.
+ * @en: Enable measurements, else standby mode.
+ *
+ * For lowest power operation, standby mode can be used. In standby mode,
+ * current consumption is supposed to be reduced to 0.1uA (typical). In this
+ * mode no measurements are made. Placing the device into standby mode
+ * preserves the contents of FIFO.
+ *
+ * Return: Returns 0 if successful, or a negative error value.
+ */
+static int adxl345_set_measure_en(struct adxl345_state *st, bool en)
+{
+	unsigned int val = 0;
+
+	val = (en) ? ADXL345_POWER_CTL_MEASURE : ADXL345_POWER_CTL_STANDBY;
+	return regmap_write(st->regmap, ADXL345_REG_POWER_CTL, val);
+}
+
+static void adxl345_powerdown(void *ptr)
+{
+	struct adxl345_state *st = ptr;
+
+	adxl345_set_measure_en(st, false);
+}
+
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
 "0.09765625 0.1953125 0.390625 0.78125 1.5625 3.125 6.25 12.5 25 50 100 200 400 800 1600 3200"
 );
@@ -158,16 +186,6 @@ static const struct iio_info adxl345_info = {
 	.write_raw_get_fmt	= adxl345_write_raw_get_fmt,
 };
 
-static int adxl345_powerup(void *regmap)
-{
-	return regmap_write(regmap, ADXL345_REG_POWER_CTL, ADXL345_POWER_CTL_MEASURE);
-}
-
-static void adxl345_powerdown(void *regmap)
-{
-	regmap_write(regmap, ADXL345_REG_POWER_CTL, ADXL345_POWER_CTL_STANDBY);
-}
-
 /**
  * adxl345_core_probe() - Probe and setup for the accelerometer.
  * @dev:	Driver model representation of the device
@@ -237,11 +255,11 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
 				     regval, ADXL345_DEVID);
 
 	/* Enable measurement mode */
-	ret = adxl345_powerup(st->regmap);
+	ret = adxl345_set_measure_en(st, true);
 	if (ret < 0)
 		return dev_err_probe(dev, ret, "Failed to enable measurement mode\n");
 
-	ret = devm_add_action_or_reset(dev, adxl345_powerdown, st->regmap);
+	ret = devm_add_action_or_reset(dev, adxl345_powerdown, st);
 	if (ret < 0)
 		return ret;
 
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 2/7] iio: accel: adxl345: complete the list of defines
  2024-12-11 23:06 [PATCH v6 0/7] iio: accel: adxl345: add FIFO operating with IRQ triggered watermark events Lothar Rubusch
  2024-12-11 23:06 ` [PATCH v6 1/7] iio: accel: adxl345: add function to switch measuring mode Lothar Rubusch
@ 2024-12-11 23:06 ` Lothar Rubusch
  2024-12-12  8:07   ` Krzysztof Kozlowski
  2024-12-11 23:06 ` [PATCH v6 3/7] dt-bindings: iio: accel: adxl345: add interrupt-names Lothar Rubusch
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Lothar Rubusch @ 2024-12-11 23:06 UTC (permalink / raw)
  To: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt
  Cc: devicetree, linux-iio, linux-kernel, eraretuya, l.rubusch

Extend the list of constants. Keep them the header file for readability.
The defines allow the implementation of events like watermark, single
tap, double tap, freefall, etc.

Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
 drivers/iio/accel/adxl345.h | 92 +++++++++++++++++++++++++++++++------
 1 file changed, 79 insertions(+), 13 deletions(-)

diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
index 3d5c8719d..9c73474c6 100644
--- a/drivers/iio/accel/adxl345.h
+++ b/drivers/iio/accel/adxl345.h
@@ -9,37 +9,103 @@
 #define _ADXL345_H_
 
 #define ADXL345_REG_DEVID		0x00
+#define ADXL345_REG_THRESH_TAP	0x1D
 #define ADXL345_REG_OFSX		0x1E
 #define ADXL345_REG_OFSY		0x1F
 #define ADXL345_REG_OFSZ		0x20
 #define ADXL345_REG_OFS_AXIS(index)	(ADXL345_REG_OFSX + (index))
+
+/* Tap duration */
+#define ADXL345_REG_DUR		0x21
+/* Tap latency */
+#define ADXL345_REG_LATENT		0x22
+/* Tap window */
+#define ADXL345_REG_WINDOW		0x23
+/* Activity threshold */
+#define ADXL345_REG_THRESH_ACT		0x24
+/* Inactivity threshold */
+#define ADXL345_REG_THRESH_INACT	0x25
+/* Inactivity time */
+#define ADXL345_REG_TIME_INACT	0x26
+/* Axis enable control for activity and inactivity detection */
+#define ADXL345_REG_ACT_INACT_CTRL	0x27
+/* Free-fall threshold */
+#define ADXL345_REG_THRESH_FF		0x28
+/* Free-fall time */
+#define ADXL345_REG_TIME_FF		0x29
+/* Axis control for single tap or double tap */
+#define ADXL345_REG_TAP_AXIS		0x2A
+/* Source of single tap or double tap */
+#define ADXL345_REG_ACT_TAP_STATUS	0x2B
+/* Data rate and power mode control */
 #define ADXL345_REG_BW_RATE		0x2C
 #define ADXL345_REG_POWER_CTL		0x2D
+#define ADXL345_REG_INT_ENABLE		0x2E
+#define ADXL345_REG_INT_MAP		0x2F
+#define ADXL345_REG_INT_SOURCE		0x30
 #define ADXL345_REG_DATA_FORMAT		0x31
-#define ADXL345_REG_DATAX0		0x32
-#define ADXL345_REG_DATAY0		0x34
-#define ADXL345_REG_DATAZ0		0x36
-#define ADXL345_REG_DATA_AXIS(index)	\
-	(ADXL345_REG_DATAX0 + (index) * sizeof(__le16))
+#define ADXL345_REG_XYZ_BASE		0x32
+#define ADXL345_REG_DATA_AXIS(index)				\
+	(ADXL345_REG_XYZ_BASE + (index) * sizeof(__le16))
+
+#define ADXL345_REG_FIFO_CTL		0x38
+#define ADXL345_REG_FIFO_STATUS		0x39
+
+#define ADXL345_DEVID			0xE5
 
+#define ADXL345_FIFO_CTL_SAMPLES(x)	FIELD_PREP(GENMASK(4, 0), x)
+/* 0: INT1, 1: INT2 */
+#define ADXL345_FIFO_CTL_TRIGGER(x)	FIELD_PREP(BIT(5), x)
+#define ADXL345_FIFO_CTL_MODE(x)	FIELD_PREP(GENMASK(7, 6), x)
+
+#define ADXL345_INT_DATA_READY		BIT(7)
+#define ADXL345_INT_SINGLE_TAP		BIT(6)
+#define ADXL345_INT_DOUBLE_TAP		BIT(5)
+#define ADXL345_INT_ACTIVITY		BIT(4)
+#define ADXL345_INT_INACTIVITY		BIT(3)
+#define ADXL345_INT_FREE_FALL		BIT(2)
+#define ADXL345_INT_WATERMARK		BIT(1)
+#define ADXL345_INT_OVERRUN		BIT(0)
+
+#define ADXL345_S_TAP_MSK	ADXL345_INT_SINGLE_TAP
+#define ADXL345_D_TAP_MSK	ADXL345_INT_DOUBLE_TAP
+
+/*
+ * BW_RATE bits - Bandwidth and output data rate. The default value is
+ * 0x0A, which translates to a 100 Hz output data rate
+ */
 #define ADXL345_BW_RATE			GENMASK(3, 0)
+#define ADXL345_BW_LOW_POWER	BIT(4)
 #define ADXL345_BASE_RATE_NANO_HZ	97656250LL
 
-#define ADXL345_POWER_CTL_MEASURE	BIT(3)
 #define ADXL345_POWER_CTL_STANDBY	0x00
+#define ADXL345_POWER_CTL_WAKEUP	GENMASK(1, 0)
+#define ADXL345_POWER_CTL_SLEEP	BIT(2)
+#define ADXL345_POWER_CTL_MEASURE	BIT(3)
+#define ADXL345_POWER_CTL_AUTO_SLEEP	BIT(4)
+#define ADXL345_POWER_CTL_LINK	BIT(5)
 
-#define ADXL345_DATA_FORMAT_RANGE	GENMASK(1, 0)	/* Set the g range */
-#define ADXL345_DATA_FORMAT_JUSTIFY	BIT(2)	/* Left-justified (MSB) mode */
-#define ADXL345_DATA_FORMAT_FULL_RES	BIT(3)	/* Up to 13-bits resolution */
-#define ADXL345_DATA_FORMAT_SPI_3WIRE	BIT(6)	/* 3-wire SPI mode */
-#define ADXL345_DATA_FORMAT_SELF_TEST	BIT(7)	/* Enable a self test */
-
+/* Set the g range */
+#define ADXL345_DATA_FORMAT_RANGE	GENMASK(1, 0)
+/* Data is left justified */
+#define ADXL345_DATA_FORMAT_JUSTIFY	BIT(2)
+/* Up to 13-bits resolution */
+#define ADXL345_DATA_FORMAT_FULL_RES	BIT(3)
+#define ADXL345_DATA_FORMAT_SPI_3WIRE	BIT(6)
+#define ADXL345_DATA_FORMAT_SELF_TEST	BIT(7)
 #define ADXL345_DATA_FORMAT_2G		0
 #define ADXL345_DATA_FORMAT_4G		1
 #define ADXL345_DATA_FORMAT_8G		2
 #define ADXL345_DATA_FORMAT_16G		3
 
-#define ADXL345_DEVID			0xE5
+/*
+ * FIFO stores a maximum of 32 entries, which equates to a maximum of 33 entries
+ * available at any given time because an additional entry is available at the
+ * output filter of the device.
+ *
+ * (see datasheet FIFO_STATUS description on "Entries Bits")
+ */
+#define ADXL345_FIFO_SIZE  33
 
 /*
  * In full-resolution mode, scale factor is maintained at ~4 mg/LSB
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 3/7] dt-bindings: iio: accel: adxl345: add interrupt-names
  2024-12-11 23:06 [PATCH v6 0/7] iio: accel: adxl345: add FIFO operating with IRQ triggered watermark events Lothar Rubusch
  2024-12-11 23:06 ` [PATCH v6 1/7] iio: accel: adxl345: add function to switch measuring mode Lothar Rubusch
  2024-12-11 23:06 ` [PATCH v6 2/7] iio: accel: adxl345: complete the list of defines Lothar Rubusch
@ 2024-12-11 23:06 ` Lothar Rubusch
  2024-12-12  8:08   ` Krzysztof Kozlowski
  2024-12-14 11:59   ` Jonathan Cameron
  2024-12-11 23:06 ` [PATCH v6 4/7] dt-bindings: iio: accel: adxl345: make interrupts not a required property Lothar Rubusch
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 17+ messages in thread
From: Lothar Rubusch @ 2024-12-11 23:06 UTC (permalink / raw)
  To: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt
  Cc: devicetree, linux-iio, linux-kernel, eraretuya, l.rubusch

Add interrupt-names INT1 and INT2 for the two interrupt lines of the
sensor. Only one line will be connected for incoming events. The driver
needs to be configured accordingly. If no interrupt line is set up, the
sensor will fall back to FIFO bypass mode and still measure, but no
interrupt based events are possible.

Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
 .../devicetree/bindings/iio/accel/adi,adxl345.yaml          | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
index 280ed479e..0fe878473 100644
--- a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
+++ b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
@@ -37,6 +37,10 @@ properties:
   interrupts:
     maxItems: 1
 
+  interrupt-names:
+    items:
+      - enum: [INT1, INT2]
+
 required:
   - compatible
   - reg
@@ -61,6 +65,7 @@ examples:
             reg = <0x2a>;
             interrupt-parent = <&gpio0>;
             interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+            interrupt-names = "INT1";
         };
     };
   - |
@@ -79,5 +84,6 @@ examples:
             spi-cpha;
             interrupt-parent = <&gpio0>;
             interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+            interrupt-names = "INT2";
         };
     };
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 4/7] dt-bindings: iio: accel: adxl345: make interrupts not a required property
  2024-12-11 23:06 [PATCH v6 0/7] iio: accel: adxl345: add FIFO operating with IRQ triggered watermark events Lothar Rubusch
                   ` (2 preceding siblings ...)
  2024-12-11 23:06 ` [PATCH v6 3/7] dt-bindings: iio: accel: adxl345: add interrupt-names Lothar Rubusch
@ 2024-12-11 23:06 ` Lothar Rubusch
  2024-12-12  8:11   ` Krzysztof Kozlowski
  2024-12-11 23:06 ` [PATCH v6 5/7] iio: accel: adxl345: introduce interrupt handling Lothar Rubusch
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Lothar Rubusch @ 2024-12-11 23:06 UTC (permalink / raw)
  To: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt
  Cc: devicetree, linux-iio, linux-kernel, eraretuya, l.rubusch

Remove interrupts from the list of required properties. The ADXL345
provides two interrupt lines. Anyway, the interrupts are an option, to
be used for additional event features. The driver can measure without
interrupts. Hence, interrupts should never have been required for the
ADXL345. Thus having interrupts required can be considered to be a
mistake.

Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
 Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
index 0fe878473..30ba4d3fb 100644
--- a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
+++ b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
@@ -44,7 +44,6 @@ properties:
 required:
   - compatible
   - reg
-  - interrupts
 
 allOf:
   - $ref: /schemas/spi/spi-peripheral-props.yaml#
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 5/7] iio: accel: adxl345: introduce interrupt handling
  2024-12-11 23:06 [PATCH v6 0/7] iio: accel: adxl345: add FIFO operating with IRQ triggered watermark events Lothar Rubusch
                   ` (3 preceding siblings ...)
  2024-12-11 23:06 ` [PATCH v6 4/7] dt-bindings: iio: accel: adxl345: make interrupts not a required property Lothar Rubusch
@ 2024-12-11 23:06 ` Lothar Rubusch
  2024-12-11 23:06 ` [PATCH v6 6/7] iio: accel: adxl345: initialize FIFO delay value for SPI Lothar Rubusch
  2024-12-11 23:06 ` [PATCH v6 7/7] iio: accel: adxl345: add FIFO with watermark events Lothar Rubusch
  6 siblings, 0 replies; 17+ messages in thread
From: Lothar Rubusch @ 2024-12-11 23:06 UTC (permalink / raw)
  To: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt
  Cc: devicetree, linux-iio, linux-kernel, eraretuya, l.rubusch

Add the possibility to claim an interrupt. Init the state structure
with an interrupt line obtained from the DT. The adxl345 can use
two different interrupt lines for event handling. Only one is used.

Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
 drivers/iio/accel/adxl345_core.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index b48bc838c..fb3b45d99 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -11,15 +11,22 @@
 #include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/units.h>
+#include <linux/interrupt.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 
 #include "adxl345.h"
 
+#define ADXL345_INT_NONE		0xff
+#define ADXL345_INT1			0
+#define ADXL345_INT2			1
+
 struct adxl345_state {
+	int irq;
 	const struct adxl345_chip_info *info;
 	struct regmap *regmap;
+	u8 intio;
 };
 
 #define ADXL345_CHANNEL(index, axis) {					\
@@ -213,6 +220,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
 
 	st = iio_priv(indio_dev);
 	st->regmap = regmap;
+
 	st->info = device_get_match_data(dev);
 	if (!st->info)
 		return -ENODEV;
@@ -263,6 +271,15 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
 	if (ret < 0)
 		return ret;
 
+	st->intio = ADXL345_INT1;
+	st->irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT1");
+	if (st->irq < 0) {
+		st->intio = ADXL345_INT2;
+		st->irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT2");
+		if (st->irq < 0)
+			st->intio = ADXL345_INT_NONE;
+	}
+
 	return devm_iio_device_register(dev, indio_dev);
 }
 EXPORT_SYMBOL_NS_GPL(adxl345_core_probe, IIO_ADXL345);
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 6/7] iio: accel: adxl345: initialize FIFO delay value for SPI
  2024-12-11 23:06 [PATCH v6 0/7] iio: accel: adxl345: add FIFO operating with IRQ triggered watermark events Lothar Rubusch
                   ` (4 preceding siblings ...)
  2024-12-11 23:06 ` [PATCH v6 5/7] iio: accel: adxl345: introduce interrupt handling Lothar Rubusch
@ 2024-12-11 23:06 ` Lothar Rubusch
  2024-12-11 23:06 ` [PATCH v6 7/7] iio: accel: adxl345: add FIFO with watermark events Lothar Rubusch
  6 siblings, 0 replies; 17+ messages in thread
From: Lothar Rubusch @ 2024-12-11 23:06 UTC (permalink / raw)
  To: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt
  Cc: devicetree, linux-iio, linux-kernel, eraretuya, l.rubusch

Add the possibility to delay FIFO access when SPI is used. According to
the datasheet this is needed for the adxl345. When initialization
happens over SPI the need for delay is to be signalized, and the delay
will be used.

Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
 drivers/iio/accel/adxl345.h      |  1 +
 drivers/iio/accel/adxl345_core.c | 12 ++++++++++++
 drivers/iio/accel/adxl345_i2c.c  |  2 +-
 drivers/iio/accel/adxl345_spi.c  |  7 +++++--
 4 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
index 9c73474c6..3c2e12452 100644
--- a/drivers/iio/accel/adxl345.h
+++ b/drivers/iio/accel/adxl345.h
@@ -128,6 +128,7 @@ struct adxl345_chip_info {
 };
 
 int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+		       bool fifo_delay_default,
 		       int (*setup)(struct device*, struct regmap*));
 
 #endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index fb3b45d99..fc4f89f22 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -26,6 +26,7 @@ struct adxl345_state {
 	int irq;
 	const struct adxl345_chip_info *info;
 	struct regmap *regmap;
+	bool fifo_delay; /* delay: delay is needed for SPI */
 	u8 intio;
 };
 
@@ -197,12 +198,21 @@ static const struct iio_info adxl345_info = {
  * adxl345_core_probe() - Probe and setup for the accelerometer.
  * @dev:	Driver model representation of the device
  * @regmap:	Regmap instance for the device
+ * @fifo_delay_default: Using FIFO with SPI needs delay
  * @setup:	Setup routine to be executed right before the standard device
  *		setup
  *
+ * For SPI operation greater than 1.6 MHz, it is necessary to deassert the CS
+ * pin to ensure a total delay of 5 us; otherwise, the delay is not sufficient.
+ * The total delay necessary for 5 MHz operation is at most 3.4 us. This is not
+ * a concern when using I2C mode because the communication rate is low enough
+ * to ensure a sufficient delay between FIFO reads.
+ * Ref: "Retrieving Data from FIFO", p. 21 of 36, Data Sheet ADXL345 Rev. G
+ *
  * Return: 0 on success, negative errno on error
  */
 int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+		       bool fifo_delay_default,
 		       int (*setup)(struct device*, struct regmap*))
 {
 	struct adxl345_state *st;
@@ -225,6 +235,8 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
 	if (!st->info)
 		return -ENODEV;
 
+	st->fifo_delay = fifo_delay_default;
+
 	indio_dev->name = st->info->name;
 	indio_dev->info = &adxl345_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
diff --git a/drivers/iio/accel/adxl345_i2c.c b/drivers/iio/accel/adxl345_i2c.c
index 4065b8f7c..28d997c58 100644
--- a/drivers/iio/accel/adxl345_i2c.c
+++ b/drivers/iio/accel/adxl345_i2c.c
@@ -27,7 +27,7 @@ static int adxl345_i2c_probe(struct i2c_client *client)
 	if (IS_ERR(regmap))
 		return dev_err_probe(&client->dev, PTR_ERR(regmap), "Error initializing regmap\n");
 
-	return adxl345_core_probe(&client->dev, regmap, NULL);
+	return adxl345_core_probe(&client->dev, regmap, false, NULL);
 }
 
 static const struct adxl345_chip_info adxl345_i2c_info = {
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
index 61fd9a6f5..e03915ece 100644
--- a/drivers/iio/accel/adxl345_spi.c
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -12,6 +12,7 @@
 #include "adxl345.h"
 
 #define ADXL345_MAX_SPI_FREQ_HZ		5000000
+#define ADXL345_MAX_FREQ_NO_FIFO_DELAY	1500000
 
 static const struct regmap_config adxl345_spi_regmap_config = {
 	.reg_bits = 8,
@@ -28,6 +29,7 @@ static int adxl345_spi_setup(struct device *dev, struct regmap *regmap)
 static int adxl345_spi_probe(struct spi_device *spi)
 {
 	struct regmap *regmap;
+	bool needs_delay;
 
 	/* Bail out if max_speed_hz exceeds 5 MHz */
 	if (spi->max_speed_hz > ADXL345_MAX_SPI_FREQ_HZ)
@@ -38,10 +40,11 @@ static int adxl345_spi_probe(struct spi_device *spi)
 	if (IS_ERR(regmap))
 		return dev_err_probe(&spi->dev, PTR_ERR(regmap), "Error initializing regmap\n");
 
+	needs_delay = spi->max_speed_hz > ADXL345_MAX_FREQ_NO_FIFO_DELAY;
 	if (spi->mode & SPI_3WIRE)
-		return adxl345_core_probe(&spi->dev, regmap, adxl345_spi_setup);
+		return adxl345_core_probe(&spi->dev, regmap, needs_delay, adxl345_spi_setup);
 	else
-		return adxl345_core_probe(&spi->dev, regmap, NULL);
+		return adxl345_core_probe(&spi->dev, regmap, needs_delay, NULL);
 }
 
 static const struct adxl345_chip_info adxl345_spi_info = {
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v6 7/7] iio: accel: adxl345: add FIFO with watermark events
  2024-12-11 23:06 [PATCH v6 0/7] iio: accel: adxl345: add FIFO operating with IRQ triggered watermark events Lothar Rubusch
                   ` (5 preceding siblings ...)
  2024-12-11 23:06 ` [PATCH v6 6/7] iio: accel: adxl345: initialize FIFO delay value for SPI Lothar Rubusch
@ 2024-12-11 23:06 ` Lothar Rubusch
  6 siblings, 0 replies; 17+ messages in thread
From: Lothar Rubusch @ 2024-12-11 23:06 UTC (permalink / raw)
  To: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt
  Cc: devicetree, linux-iio, linux-kernel, eraretuya, l.rubusch

Add a basic setup for FIFO with configurable watermark. Add a handler
for watermark interrupt events and extend the channel for the
scan_index needed for the iio channel. The sensor is configurable to use
a FIFO_BYPASSED mode or a FIFO_STREAM mode. For the FIFO_STREAM mode now
a watermark can be configured, or disabled by setting 0. Further features
require a working FIFO setup.

Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
 drivers/iio/accel/adxl345.h      |   2 +
 drivers/iio/accel/adxl345_core.c | 314 ++++++++++++++++++++++++++++++-
 2 files changed, 311 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
index 3c2e12452..1faad1c8c 100644
--- a/drivers/iio/accel/adxl345.h
+++ b/drivers/iio/accel/adxl345.h
@@ -43,6 +43,7 @@
 #define ADXL345_REG_INT_ENABLE		0x2E
 #define ADXL345_REG_INT_MAP		0x2F
 #define ADXL345_REG_INT_SOURCE		0x30
+#define ADXL345_REG_INT_SOURCE_MSK	0xFF
 #define ADXL345_REG_DATA_FORMAT		0x31
 #define ADXL345_REG_XYZ_BASE		0x32
 #define ADXL345_REG_DATA_AXIS(index)				\
@@ -50,6 +51,7 @@
 
 #define ADXL345_REG_FIFO_CTL		0x38
 #define ADXL345_REG_FIFO_STATUS		0x39
+#define ADXL345_REG_FIFO_STATUS_MSK	0x3F
 
 #define ADXL345_DEVID			0xE5
 
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index fc4f89f22..f429b8f56 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -15,9 +15,17 @@
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/kfifo_buf.h>
 
 #include "adxl345.h"
 
+#define ADXL345_FIFO_BYPASS	0
+#define ADXL345_FIFO_FIFO	1
+#define ADXL345_FIFO_STREAM	2
+
+#define ADXL345_DIRS 3
+
 #define ADXL345_INT_NONE		0xff
 #define ADXL345_INT1			0
 #define ADXL345_INT2			1
@@ -26,27 +34,68 @@ struct adxl345_state {
 	int irq;
 	const struct adxl345_chip_info *info;
 	struct regmap *regmap;
+	__le16 fifo_buf[ADXL345_DIRS * ADXL345_FIFO_SIZE];
 	bool fifo_delay; /* delay: delay is needed for SPI */
 	u8 intio;
+	u8 int_map;
+	u8 watermark;
+	u8 fifo_mode;
 };
 
-#define ADXL345_CHANNEL(index, axis) {					\
+#define ADXL345_CHANNEL(index, reg, axis) {					\
 	.type = IIO_ACCEL,						\
 	.modified = 1,							\
 	.channel2 = IIO_MOD_##axis,					\
-	.address = index,						\
+	.address = (reg),						\
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |			\
 		BIT(IIO_CHAN_INFO_CALIBBIAS),				\
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |		\
 		BIT(IIO_CHAN_INFO_SAMP_FREQ),				\
+	.scan_index = (index),				\
+	.scan_type = {					\
+		.sign = 's',				\
+		.realbits = 13,				\
+		.storagebits = 16,			\
+		.endianness = IIO_LE,			\
+	},						\
 }
 
+enum adxl345_chans {
+	chan_x, chan_y, chan_z,
+};
+
 static const struct iio_chan_spec adxl345_channels[] = {
-	ADXL345_CHANNEL(0, X),
-	ADXL345_CHANNEL(1, Y),
-	ADXL345_CHANNEL(2, Z),
+	ADXL345_CHANNEL(0, chan_x, X),
+	ADXL345_CHANNEL(1, chan_y, Y),
+	ADXL345_CHANNEL(2, chan_z, Z),
 };
 
+static const unsigned long adxl345_scan_masks[] = {
+	BIT(chan_x) | BIT(chan_y) | BIT(chan_z),
+	0,
+};
+
+static int adxl345_set_interrupts(struct adxl345_state *st)
+{
+	int ret;
+	unsigned int int_enable = st->int_map;
+	unsigned int int_map;
+
+	/*
+	 * Any bits set to 0 in the INT map register send their respective
+	 * interrupts to the INT1 pin, whereas bits set to 1 send their respective
+	 * interrupts to the INT2 pin. The intio shall convert this accordingly.
+	 */
+	int_map = FIELD_GET(ADXL345_REG_INT_SOURCE_MSK,
+			st->intio ? st->int_map : ~st->int_map);
+
+	ret = regmap_write(st->regmap, ADXL345_REG_INT_MAP, int_map);
+	if (ret)
+		return ret;
+
+	return regmap_write(st->regmap, ADXL345_REG_INT_ENABLE, int_enable);
+}
+
 static int adxl345_read_raw(struct iio_dev *indio_dev,
 			    struct iio_chan_spec const *chan,
 			    int *val, int *val2, long mask)
@@ -132,6 +181,31 @@ static int adxl345_write_raw(struct iio_dev *indio_dev,
 	return -EINVAL;
 }
 
+static int adxl345_set_watermark(struct iio_dev *indio_dev, unsigned int value)
+{
+	struct adxl345_state *st = iio_priv(indio_dev);
+	unsigned int fifo_mask = 0x1F;
+	int ret;
+
+	if (value == 0) {
+		st->int_map &= ~ADXL345_INT_WATERMARK;
+		return 0;
+	}
+
+	if (value > ADXL345_FIFO_SIZE)
+		value = ADXL345_FIFO_SIZE;
+
+	ret = regmap_update_bits(st->regmap, ADXL345_REG_FIFO_CTL,
+				 fifo_mask, value);
+	if (ret)
+		return ret;
+
+	st->watermark = value;
+	st->int_map |= ADXL345_INT_WATERMARK;
+
+	return 0;
+}
+
 static int adxl345_write_raw_get_fmt(struct iio_dev *indio_dev,
 				     struct iio_chan_spec const *chan,
 				     long mask)
@@ -187,11 +261,220 @@ static const struct attribute_group adxl345_attrs_group = {
 	.attrs = adxl345_attrs,
 };
 
+static int adxl345_set_fifo(struct adxl345_state *st)
+{
+	u8 fifo_ctl;
+	int ret;
+
+	/* FIFO should only be configured while in standby mode */
+	ret = adxl345_set_measure_en(st, false);
+	if (ret < 0)
+		return ret;
+
+	fifo_ctl = ADXL345_FIFO_CTL_SAMPLES(st->watermark) |
+		ADXL345_FIFO_CTL_TRIGGER(st->intio) |
+		ADXL345_FIFO_CTL_MODE(st->fifo_mode);
+
+	ret = regmap_write(st->regmap, ADXL345_REG_FIFO_CTL, fifo_ctl);
+	if (ret < 0)
+		return ret;
+
+	return adxl345_set_measure_en(st, true);
+}
+
+/**
+ * adxl345_get_samples() - Read number of FIFO entries.
+ * @st: The initialized state instance of this driver.
+ *
+ * The sensor does not support treating any axis individually, or exclude them
+ * from measuring.
+ *
+ * Return: negative error, or value.
+ */
+static int adxl345_get_samples(struct adxl345_state *st)
+{
+	unsigned int regval = 0;
+	int ret;
+
+	ret = regmap_read(st->regmap, ADXL345_REG_FIFO_STATUS, &regval);
+	if (ret < 0)
+		return ret;
+
+	return FIELD_GET(ADXL345_REG_FIFO_STATUS_MSK, regval);
+}
+
+/**
+ * adxl345_fifo_transfer() - Read samples number of elements.
+ * @st: The instance of the state object of this sensor.
+ * @samples: The number of lines in the FIFO referred to as fifo_entry.
+ *
+ * It is recommended that a multiple-byte read of all registers be performed to
+ * prevent a change in data between reads of sequential registers. That is to
+ * read out the data registers X0, X1, Y0, Y1, Z0, Z1, i.e. 6 bytes at once.
+ *
+ * Return: 0 or error value.
+ */
+static int adxl345_fifo_transfer(struct adxl345_state *st, int samples)
+{
+	size_t count;
+	int i, ret = 0;
+
+	/* count is the 3x the fifo_buf element size, hence 6B */
+	count = sizeof(st->fifo_buf[0]) * ADXL345_DIRS;
+	for (i = 0; i < samples; i++) {
+		/* read 3x 2 byte elements from base address into next fifo_buf position */
+		ret = regmap_bulk_read(st->regmap, ADXL345_REG_XYZ_BASE,
+				st->fifo_buf + (i * count / 2), count);
+		if (ret < 0)
+			return ret;
+
+		/*
+		 * To ensure that the FIFO has completely popped, there must be at least 5
+		 * us between the end of reading the data registers, signified by the
+		 * transition to register 0x38 from 0x37 or the CS pin going high, and the
+		 * start of new reads of the FIFO or reading the FIFO_STATUS register. For
+		 * SPI operation at 1.5 MHz or lower, the register addressing portion of the
+		 * transmission is sufficient delay to ensure the FIFO has completely
+		 * popped. It is necessary for SPI operation greater than 1.5 MHz to
+		 * de-assert the CS pin to ensure a total of 5 us, which is at most 3.4 us
+		 * at 5 MHz operation.
+		 */
+		if (st->fifo_delay && (samples > 1))
+			udelay(3);
+	}
+	return ret;
+}
+
+/**
+ * adxl345_fifo_reset() - Empty the FIFO in error condition.
+ * @st: The instance to the state object of the sensor.
+ *
+ * Read all elements of the FIFO. Reading the interrupt source register
+ * resets the sensor.
+ */
+static void adxl345_fifo_reset(struct adxl345_state *st)
+{
+	int regval;
+	int samples;
+
+	adxl345_set_measure_en(st, false);
+
+	samples = adxl345_get_samples(st);
+	if (samples > 0)
+		adxl345_fifo_transfer(st, samples);
+
+	regmap_read(st->regmap, ADXL345_REG_INT_SOURCE, &regval);
+
+	adxl345_set_measure_en(st, true);
+}
+
+static int adxl345_buffer_postenable(struct iio_dev *indio_dev)
+{
+	struct adxl345_state *st = iio_priv(indio_dev);
+	int ret;
+
+	ret = adxl345_set_interrupts(st);
+	if (ret < 0)
+		return ret;
+
+	st->fifo_mode = ADXL345_FIFO_STREAM;
+	return adxl345_set_fifo(st);
+}
+
+static int adxl345_buffer_predisable(struct iio_dev *indio_dev)
+{
+	struct adxl345_state *st = iio_priv(indio_dev);
+	int ret;
+
+	st->fifo_mode = ADXL345_FIFO_BYPASS;
+	ret = adxl345_set_fifo(st);
+	if (ret < 0)
+		return ret;
+
+	st->int_map = 0x00;
+	return adxl345_set_interrupts(st);
+}
+
+static const struct iio_buffer_setup_ops adxl345_buffer_ops = {
+	.postenable = adxl345_buffer_postenable,
+	.predisable = adxl345_buffer_predisable,
+};
+
+static int adxl345_get_status(struct adxl345_state *st)
+{
+	int ret;
+	unsigned int regval;
+
+	ret = regmap_read(st->regmap, ADXL345_REG_INT_SOURCE, &regval);
+	if (ret < 0)
+		return ret;
+
+	return FIELD_GET(ADXL345_REG_INT_SOURCE_MSK, regval);
+}
+
+static int adxl345_fifo_push(struct iio_dev *indio_dev,
+				  int samples)
+{
+	struct adxl345_state *st = iio_priv(indio_dev);
+	int i, ret;
+
+	if (samples <= 0)
+		return -EINVAL;
+
+	ret = adxl345_fifo_transfer(st, samples);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < ADXL345_DIRS * samples; i += ADXL345_DIRS)
+		iio_push_to_buffers(indio_dev, &st->fifo_buf[i]);
+
+	return 0;
+}
+
+/**
+ * adxl345_irq_handler() - Handle irqs of the ADXL345.
+ * @irq: The irq being handled.
+ * @p: The struct iio_device pointer for the device.
+ *
+ * Return: The interrupt was handled.
+ */
+static irqreturn_t adxl345_irq_handler(int irq, void *p)
+{
+	struct iio_dev *indio_dev = p;
+	struct adxl345_state *st = iio_priv(indio_dev);
+	int int_stat;
+	int samples;
+
+	int_stat = adxl345_get_status(st);
+	if (int_stat <= 0)
+		return IRQ_NONE;
+
+	if (int_stat & ADXL345_INT_OVERRUN)
+		goto err;
+
+	if (int_stat & ADXL345_INT_WATERMARK) {
+		samples = adxl345_get_samples(st);
+		if (samples < 0)
+			goto err;
+
+		if (adxl345_fifo_push(indio_dev, samples) < 0)
+			goto err;
+
+	}
+	return IRQ_HANDLED;
+
+err:
+	adxl345_fifo_reset(st);
+
+	return IRQ_HANDLED;
+}
+
 static const struct iio_info adxl345_info = {
 	.attrs		= &adxl345_attrs_group,
 	.read_raw	= adxl345_read_raw,
 	.write_raw	= adxl345_write_raw,
 	.write_raw_get_fmt	= adxl345_write_raw_get_fmt,
+	.hwfifo_set_watermark = adxl345_set_watermark,
 };
 
 /**
@@ -222,6 +505,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
 					 ADXL345_DATA_FORMAT_JUSTIFY |
 					 ADXL345_DATA_FORMAT_FULL_RES |
 					 ADXL345_DATA_FORMAT_SELF_TEST);
+	u8 fifo_ctl;
 	int ret;
 
 	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
@@ -242,6 +526,7 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = adxl345_channels;
 	indio_dev->num_channels = ARRAY_SIZE(adxl345_channels);
+	indio_dev->available_scan_masks = adxl345_scan_masks;
 
 	if (setup) {
 		/* Perform optional initial bus specific configuration */
@@ -292,6 +577,25 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap,
 			st->intio = ADXL345_INT_NONE;
 	}
 
+	if (st->intio != ADXL345_INT_NONE) {
+		/* FIFO_STREAM mode is going to be activated later */
+		ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, &adxl345_buffer_ops);
+		if (ret)
+			return ret;
+
+		ret = devm_request_threaded_irq(dev, st->irq, NULL, &adxl345_irq_handler,
+				IRQF_SHARED | IRQF_ONESHOT,
+				indio_dev->name, indio_dev);
+		if (ret)
+			return ret;
+	} else {
+		/* FIFO_BYPASS mode */
+		fifo_ctl = ADXL345_FIFO_CTL_MODE(ADXL345_FIFO_BYPASS);
+		ret = regmap_write(st->regmap, ADXL345_REG_FIFO_CTL, fifo_ctl);
+		if (ret < 0)
+			return ret;
+	}
+
 	return devm_iio_device_register(dev, indio_dev);
 }
 EXPORT_SYMBOL_NS_GPL(adxl345_core_probe, IIO_ADXL345);
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 2/7] iio: accel: adxl345: complete the list of defines
  2024-12-11 23:06 ` [PATCH v6 2/7] iio: accel: adxl345: complete the list of defines Lothar Rubusch
@ 2024-12-12  8:07   ` Krzysztof Kozlowski
  2024-12-12  9:37     ` Lothar Rubusch
  0 siblings, 1 reply; 17+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-12  8:07 UTC (permalink / raw)
  To: Lothar Rubusch
  Cc: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt,
	devicetree, linux-iio, linux-kernel, eraretuya

On Wed, Dec 11, 2024 at 11:06:43PM +0000, Lothar Rubusch wrote:
> Extend the list of constants. Keep them the header file for readability.
> The defines allow the implementation of events like watermark, single
> tap, double tap, freefall, etc.

We don't store constants just to store constants, so this commit does
not have reason to be separate. We store constants/defines only to
implement the driver. Merge these with the users... unless you want to
say there are no users of this at all, but then make it clear: move the
patch to the end.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 3/7] dt-bindings: iio: accel: adxl345: add interrupt-names
  2024-12-11 23:06 ` [PATCH v6 3/7] dt-bindings: iio: accel: adxl345: add interrupt-names Lothar Rubusch
@ 2024-12-12  8:08   ` Krzysztof Kozlowski
  2024-12-14 11:56     ` Jonathan Cameron
  2024-12-14 11:59   ` Jonathan Cameron
  1 sibling, 1 reply; 17+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-12  8:08 UTC (permalink / raw)
  To: Lothar Rubusch
  Cc: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt,
	devicetree, linux-iio, linux-kernel, eraretuya

On Wed, Dec 11, 2024 at 11:06:44PM +0000, Lothar Rubusch wrote:
> Add interrupt-names INT1 and INT2 for the two interrupt lines of the
> sensor. Only one line will be connected for incoming events. The driver
> needs to be configured accordingly. If no interrupt line is set up, the
> sensor will fall back to FIFO bypass mode and still measure, but no
> interrupt based events are possible.

There was interrupt before and it was required, so I do not understand
last statement. You describe case which is impossible.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 4/7] dt-bindings: iio: accel: adxl345: make interrupts not a required property
  2024-12-11 23:06 ` [PATCH v6 4/7] dt-bindings: iio: accel: adxl345: make interrupts not a required property Lothar Rubusch
@ 2024-12-12  8:11   ` Krzysztof Kozlowski
  2024-12-13  8:06     ` Lothar Rubusch
  0 siblings, 1 reply; 17+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-12  8:11 UTC (permalink / raw)
  To: Lothar Rubusch
  Cc: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt,
	devicetree, linux-iio, linux-kernel, eraretuya

On Wed, Dec 11, 2024 at 11:06:45PM +0000, Lothar Rubusch wrote:
> Remove interrupts from the list of required properties. The ADXL345
> provides two interrupt lines. Anyway, the interrupts are an option, to
> be used for additional event features. The driver can measure without
> interrupts. Hence, interrupts should never have been required for the
> ADXL345. Thus having interrupts required can be considered to be a
> mistake.

Partially this explains my question on previous patch, so consider
reordering them.

And with combined knowledge, your driver now depends on interrupt names
to setup interrupts. "interrupts" property alone is not sufficient, so
you should encode it in the binding and explain in rationale why this is
required (it is a change in ABI).

https://elixir.bootlin.com/linux/v6.8-rc3/source/Documentation/devicetree/bindings/example-schema.yaml#L193

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 2/7] iio: accel: adxl345: complete the list of defines
  2024-12-12  8:07   ` Krzysztof Kozlowski
@ 2024-12-12  9:37     ` Lothar Rubusch
  2024-12-14 11:49       ` Jonathan Cameron
  0 siblings, 1 reply; 17+ messages in thread
From: Lothar Rubusch @ 2024-12-12  9:37 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt,
	devicetree, linux-iio, linux-kernel, eraretuya

Hi  Krzysztof,
Thank you so much for reviewing.

On Thu, Dec 12, 2024 at 9:07 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On Wed, Dec 11, 2024 at 11:06:43PM +0000, Lothar Rubusch wrote:
> > Extend the list of constants. Keep them the header file for readability.
> > The defines allow the implementation of events like watermark, single
> > tap, double tap, freefall, etc.
>
> We don't store constants just to store constants, so this commit does
> not have reason to be separate. We store constants/defines only to
> implement the driver. Merge these with the users... unless you want to
> say there are no users of this at all, but then make it clear: move the
> patch to the end.
>

I see your point.

The defines are needed for the current introduction of the FIFO usage,
connected with the watermark feature. Some of it is related to
upcoming features, such as mentioned in the comment (tap events,
freefall, powersafe, selftest, etc).

This patch series now on FIFO/watermark are just the first step to get
a solid reviewed common base. Further features are upcoming. I did not
split up the constants. All the specified registers will be needed to
allow for their configuration and setup. I understand it's no organig
growth by immediate need, as I understand, but giving IMHO a bit
flexibility then in implementing what is the next feature, since all
registers are already defined.

Pls, let me know, if you prefer me to only introduce immediately
needed constants for a current specific feature?
Best,
L

> Best regards,
> Krzysztof
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 4/7] dt-bindings: iio: accel: adxl345: make interrupts not a required property
  2024-12-12  8:11   ` Krzysztof Kozlowski
@ 2024-12-13  8:06     ` Lothar Rubusch
  2024-12-13  8:49       ` Krzysztof Kozlowski
  0 siblings, 1 reply; 17+ messages in thread
From: Lothar Rubusch @ 2024-12-13  8:06 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt,
	devicetree, linux-iio, linux-kernel, eraretuya

On Thu, Dec 12, 2024 at 9:11 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On Wed, Dec 11, 2024 at 11:06:45PM +0000, Lothar Rubusch wrote:
> > Remove interrupts from the list of required properties. The ADXL345
> > provides two interrupt lines. Anyway, the interrupts are an option, to
> > be used for additional event features. The driver can measure without
> > interrupts. Hence, interrupts should never have been required for the
> > ADXL345. Thus having interrupts required can be considered to be a
> > mistake.
>
> Partially this explains my question on previous patch, so consider
> reordering them.
>

I understand.

> And with combined knowledge, your driver now depends on interrupt names
> to setup interrupts. "interrupts" property alone is not sufficient, so
> you should encode it in the binding and explain in rationale why this is
> required (it is a change in ABI).
>
> https://elixir.bootlin.com/linux/v6.8-rc3/source/Documentation/devicetree/bindings/example-schema.yaml#L193
>

The accelerometer does not need interrupts connected/configured for
basic functionality. Interrupt declaration allows for additional
features. Then there are two possible interrupt lines, only one is
connected. Thus, either only one INT out of two, or none needs to be
configured in the DT depending on the hardware setup. This also needs
to be configured then in the sensor, which INT line to use for
signalling. Thus we need the information if INT1 or INT2 was setup, if
any.

Hence, configuring an "interrupts" property only makes sense, if also
a "interrupt-names" is configured, and vice versa. None of them are
required for basic accelerometer functionality.

Thank you so much for providing me the link to the annotated
example-schema. I'll try then to set vice versa dependency of
interrupts and interrupt-names and hope.. I'm sure you'll let me know
right away if I'm doing something wrong.

Seriously, thanks the link is really helpful!
Best,
L

> Best regards,
> Krzysztof
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 4/7] dt-bindings: iio: accel: adxl345: make interrupts not a required property
  2024-12-13  8:06     ` Lothar Rubusch
@ 2024-12-13  8:49       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 17+ messages in thread
From: Krzysztof Kozlowski @ 2024-12-13  8:49 UTC (permalink / raw)
  To: Lothar Rubusch
  Cc: lars, Michael.Hennerich, jic23, robh, krzk+dt, conor+dt,
	devicetree, linux-iio, linux-kernel, eraretuya

On Fri, Dec 13, 2024 at 09:06:39AM +0100, Lothar Rubusch wrote:
> On Thu, Dec 12, 2024 at 9:11 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >
> > On Wed, Dec 11, 2024 at 11:06:45PM +0000, Lothar Rubusch wrote:
> > > Remove interrupts from the list of required properties. The ADXL345
> > > provides two interrupt lines. Anyway, the interrupts are an option, to
> > > be used for additional event features. The driver can measure without
> > > interrupts. Hence, interrupts should never have been required for the
> > > ADXL345. Thus having interrupts required can be considered to be a
> > > mistake.
> >
> > Partially this explains my question on previous patch, so consider
> > reordering them.
> >
> 
> I understand.
> 
> > And with combined knowledge, your driver now depends on interrupt names
> > to setup interrupts. "interrupts" property alone is not sufficient, so
> > you should encode it in the binding and explain in rationale why this is
> > required (it is a change in ABI).
> >
> > https://elixir.bootlin.com/linux/v6.8-rc3/source/Documentation/devicetree/bindings/example-schema.yaml#L193
> >
> 
> The accelerometer does not need interrupts connected/configured for
> basic functionality. Interrupt declaration allows for additional
> features. Then there are two possible interrupt lines, only one is
> connected. Thus, either only one INT out of two, or none needs to be
> configured in the DT depending on the hardware setup. This also needs
> to be configured then in the sensor, which INT line to use for
> signalling. Thus we need the information if INT1 or INT2 was setup, if
> any.

I meant, explain in the commit msg.

> 
> Hence, configuring an "interrupts" property only makes sense, if also
> a "interrupt-names" is configured, and vice versa. None of them are
> required for basic accelerometer functionality.

I know, I already stated this. But almost every question should have its
answer in the commit msg.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 2/7] iio: accel: adxl345: complete the list of defines
  2024-12-12  9:37     ` Lothar Rubusch
@ 2024-12-14 11:49       ` Jonathan Cameron
  0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2024-12-14 11:49 UTC (permalink / raw)
  To: Lothar Rubusch
  Cc: Krzysztof Kozlowski, lars, Michael.Hennerich, robh, krzk+dt,
	conor+dt, devicetree, linux-iio, linux-kernel, eraretuya

On Thu, 12 Dec 2024 10:37:55 +0100
Lothar Rubusch <l.rubusch@gmail.com> wrote:

> Hi  Krzysztof,
> Thank you so much for reviewing.
> 
> On Thu, Dec 12, 2024 at 9:07 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
> >
> > On Wed, Dec 11, 2024 at 11:06:43PM +0000, Lothar Rubusch wrote:  
> > > Extend the list of constants. Keep them the header file for readability.
> > > The defines allow the implementation of events like watermark, single
> > > tap, double tap, freefall, etc.  
> >
> > We don't store constants just to store constants, so this commit does
> > not have reason to be separate. We store constants/defines only to
> > implement the driver. Merge these with the users... unless you want to
> > say there are no users of this at all, but then make it clear: move the
> > patch to the end.
> >  
> 
> I see your point.
> 
> The defines are needed for the current introduction of the FIFO usage,
> connected with the watermark feature. Some of it is related to
> upcoming features, such as mentioned in the comment (tap events,
> freefall, powersafe, selftest, etc).
> 
> This patch series now on FIFO/watermark are just the first step to get
> a solid reviewed common base. Further features are upcoming. I did not
> split up the constants. All the specified registers will be needed to
> allow for their configuration and setup. I understand it's no organig
> growth by immediate need, as I understand, but giving IMHO a bit
> flexibility then in implementing what is the next feature, since all
> registers are already defined.
> 
> Pls, let me know, if you prefer me to only introduce immediately
> needed constants for a current specific feature?

That would be the normal way to do it in a series that is adding those
features.

There are cases where we do blanket includes of all registers etc in 
one patch but they tend to be autogenerated from another source (so
annoying to split up) rather than introduced alongside features.

Also tends to be more common for first posting of a driver rather than
adding new features when the author of the driver decided to do a subset
(so follow the local style).

Jonathan

> Best,
> L
> 
> > Best regards,
> > Krzysztof
> >  


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 3/7] dt-bindings: iio: accel: adxl345: add interrupt-names
  2024-12-12  8:08   ` Krzysztof Kozlowski
@ 2024-12-14 11:56     ` Jonathan Cameron
  0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2024-12-14 11:56 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Lothar Rubusch, lars, Michael.Hennerich, robh, krzk+dt, conor+dt,
	devicetree, linux-iio, linux-kernel, eraretuya

On Thu, 12 Dec 2024 09:08:22 +0100
Krzysztof Kozlowski <krzk@kernel.org> wrote:

> On Wed, Dec 11, 2024 at 11:06:44PM +0000, Lothar Rubusch wrote:
> > Add interrupt-names INT1 and INT2 for the two interrupt lines of the
> > sensor. Only one line will be connected for incoming events. The driver
> > needs to be configured accordingly.
This is all driver info.  This patch description just needs to say something
like:
"
There are two interrupt lines that may be connected. As the device can
route each type of interrupt to one or other of those lines, interrupt-names
is necessary for two reasons.

- One interrupt line is connected, the device has to be configured to send
  interrupts to that line.
- Two interrupt lines connected.  The device can route all interrupts to 
  one line or elect to split them up.

If no interrupt lines are connected, device functionality may be restricted.
"

Note as below, the required interrupts entry should be removed in a precursor
patch.

> If no interrupt line is set up, the
> > sensor will fall back to FIFO bypass mode and still measure, but no
> > interrupt based events are possible.  
> 
> There was interrupt before and it was required, so I do not understand
> last statement. You describe case which is impossible.

Binding was wrong. Interrupt isn't required for quite a bit of the functionality.

I'd like to see an earlier patch removing that required entry and explaining
why rather than jumping into adding the new interrupt-names part without
resolving that.  Its a relaxation of constraints so probably no need to backport
that patch.

Jonathan


> 
> Best regards,
> Krzysztof
> 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v6 3/7] dt-bindings: iio: accel: adxl345: add interrupt-names
  2024-12-11 23:06 ` [PATCH v6 3/7] dt-bindings: iio: accel: adxl345: add interrupt-names Lothar Rubusch
  2024-12-12  8:08   ` Krzysztof Kozlowski
@ 2024-12-14 11:59   ` Jonathan Cameron
  1 sibling, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2024-12-14 11:59 UTC (permalink / raw)
  To: Lothar Rubusch
  Cc: lars, Michael.Hennerich, robh, krzk+dt, conor+dt, devicetree,
	linux-iio, linux-kernel, eraretuya

On Wed, 11 Dec 2024 23:06:44 +0000
Lothar Rubusch <l.rubusch@gmail.com> wrote:

> Add interrupt-names INT1 and INT2 for the two interrupt lines of the
> sensor. Only one line will be connected for incoming events. The driver
> needs to be configured accordingly. If no interrupt line is set up, the
> sensor will fall back to FIFO bypass mode and still measure, but no
> interrupt based events are possible.
> 
> Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
Given discussion in mostly here rather than next version...

> ---
>  .../devicetree/bindings/iio/accel/adi,adxl345.yaml          | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
> index 280ed479e..0fe878473 100644
> --- a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
> +++ b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
> @@ -37,6 +37,10 @@ properties:
>    interrupts:
>      maxItems: 1
>  
> +  interrupt-names:
> +    items:
> +      - enum: [INT1, INT2]

Can we add a default for INT1 only?
That would the incorporate a single provided interrupt and 'probably'
not break any existing DT that is out there.

> +
>  required:
>    - compatible
>    - reg
> @@ -61,6 +65,7 @@ examples:
>              reg = <0x2a>;
>              interrupt-parent = <&gpio0>;
>              interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
> +            interrupt-names = "INT1";
>          };
>      };
>    - |
> @@ -79,5 +84,6 @@ examples:
>              spi-cpha;
>              interrupt-parent = <&gpio0>;
>              interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
> +            interrupt-names = "INT2";
>          };
>      };


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2024-12-14 11:59 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-11 23:06 [PATCH v6 0/7] iio: accel: adxl345: add FIFO operating with IRQ triggered watermark events Lothar Rubusch
2024-12-11 23:06 ` [PATCH v6 1/7] iio: accel: adxl345: add function to switch measuring mode Lothar Rubusch
2024-12-11 23:06 ` [PATCH v6 2/7] iio: accel: adxl345: complete the list of defines Lothar Rubusch
2024-12-12  8:07   ` Krzysztof Kozlowski
2024-12-12  9:37     ` Lothar Rubusch
2024-12-14 11:49       ` Jonathan Cameron
2024-12-11 23:06 ` [PATCH v6 3/7] dt-bindings: iio: accel: adxl345: add interrupt-names Lothar Rubusch
2024-12-12  8:08   ` Krzysztof Kozlowski
2024-12-14 11:56     ` Jonathan Cameron
2024-12-14 11:59   ` Jonathan Cameron
2024-12-11 23:06 ` [PATCH v6 4/7] dt-bindings: iio: accel: adxl345: make interrupts not a required property Lothar Rubusch
2024-12-12  8:11   ` Krzysztof Kozlowski
2024-12-13  8:06     ` Lothar Rubusch
2024-12-13  8:49       ` Krzysztof Kozlowski
2024-12-11 23:06 ` [PATCH v6 5/7] iio: accel: adxl345: introduce interrupt handling Lothar Rubusch
2024-12-11 23:06 ` [PATCH v6 6/7] iio: accel: adxl345: initialize FIFO delay value for SPI Lothar Rubusch
2024-12-11 23:06 ` [PATCH v6 7/7] iio: accel: adxl345: add FIFO with watermark events Lothar Rubusch

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 NNTP newsgroup(s).