devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging
@ 2023-09-29 17:23 David Lechner
  2023-09-29 17:23 ` [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210 David Lechner
                   ` (28 more replies)
  0 siblings, 29 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner, Apelete Seketeli

From: David Lechner <david@lechnology.com>

v3 changes:

* Added description of A0/A1 lines in DT bindings.
* Added power supply regulators to DT bindings.
* Dropped "staging: iio: Documentation: document IIO resolver AD2S1210
  sysfs attributes" (these attributes are being removed instead).
* Dropped applied patches:
  * "staging: iio: resolver: ad2s1210: fix ad2s1210_show_fault"
  * "iio: adc: MCP3564: fix the static checker warning"
* Split "staging: iio: resolver: ad2s1210: fix probe" into multiple patches.
* Moved sorting imports to separate patch.
* Renamed fclkin to clkin_hz.
* Added __be16 sample field to state struct for reading raw samples.
* Split out new function ad2s1210_single_conversion() from
  ad2s1210_read_raw().
* Split out new ad2s1210_get_hysteresis() and ad2s1210_set_hysteresis()
  functions.
* Fixed multi-line comment style.
* Added notes about soft reset not resetting config registers.
* Made use of FIELD_PREP() macro.
* Added more explanation to regmap commit message.
* Removed datasheet names from channel specs.
* Replaced "staging: iio: resolver: ad2s1210: rename fexcit attribute"
  with "staging: iio: resolver: ad2s1210: convert fexcit to channel
  attribute".
* Replaced "staging: iio: resolver: ad2s1210: add phase_lock_range
  attributes" with "staging: iio: resolver: ad2s1210: add phase lock
  range support"
* Added additional patches to convert custom device attributes to event
  attributes.
* Added patch to add channel label attributes.

v2 changes:
* Address initial device tree patch feedback
* Drop "iio: sysfs: add IIO_DEVICE_ATTR_NAMED_RW macro" (related cleanups
  also dropped for now, will address in a future series if needed)
* Apply improvements as a series of patches to the staging driver. It is
  not quite ready for the move out of staging patch yet.

This series has been tested on actual hardware using a EVAL-AD2S1210 evaluation
board. (Note: not all device tree features have been implemented in the driver
since the eval board doesn't support them out of the box. We plan to add them
later if needed.)

Most of the questions about dealing with faults from the v2 cover letter
have been addressed. There is still the question about what to do with
the current `fault` attribute (it is the only custom device attribute
remaining from the original staging driver). It was suggested to split it
out into multiple attributes in a subdirectory. Since we now have events
for all of the faults, I'm wondering if this is something that is still needed.
In the current implementation, it is possible to start listening to events,
clear the faults and then read a sample to trigger events for any current
faults so we have a way to get current faults already.

There is also the matter of clearing faults. Writing the excitation
frequency has a side-effect of clearing the faults, so we could use
that as the reset. Or we could change the current fault attribute to
write-only and rename it. Or is there a better way that I have overlooked?

Once this last issue is addressed, I think this driver will be ready
for consideration for moving out of staging.
---
David Lechner (27):
      dt-bindings: iio: resolver: add devicetree bindings for ad2s1210
      staging: iio: resolver: ad2s1210: fix use before initialization
      staging: iio: resolver: ad2s1210: remove call to spi_setup()
      staging: iio: resolver: ad2s1210: check return of ad2s1210_initial()
      staging: iio: resolver: ad2s1210: remove spi_set_drvdata()
      staging: iio: resolver: ad2s1210: sort imports
      staging: iio: resolver: ad2s1210: always use 16-bit value for raw read
      staging: iio: resolver: ad2s1210: implement IIO_CHAN_INFO_SCALE
      staging: iio: resolver: ad2s1210: use devicetree to get CLKIN rate
      staging: iio: resolver: ad2s1210: use regmap for config registers
      staging: iio: resolver: ad2s1210: add debugfs reg access
      staging: iio: resolver: ad2s1210: remove config attribute
      staging: iio: resolver: ad2s1210: rework gpios
      staging: iio: resolver: ad2s1210: implement hysteresis as channel attr
      staging: iio: resolver: ad2s1210: refactor setting excitation frequency
      staging: iio: resolver: ad2s1210: read excitation frequency from control register
      staging: iio: resolver: ad2s1210: convert fexcit to channel attribute
      staging: iio: resolver: ad2s1210: convert resolution to devicetree property
      staging: iio: resolver: ad2s1210: add phase lock range support
      staging: iio: resolver: ad2s1210: add triggered buffer support
      staging: iio: resolver: ad2s1210: convert LOT threshold attrs to event attrs
      staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
      staging: iio: resolver: ad2s1210: convert DOS overrange threshold to event attr
      staging: iio: resolver: ad2s1210: convert DOS mismatch threshold to event attr
      staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs
      staging: iio: resolver: ad2s1210: implement fault events
      staging: iio: resolver: ad2s1210: add label attribute support

 .../bindings/iio/resolver/adi,ad2s1210.yaml        |  177 +++
 .../Documentation/sysfs-bus-iio-resolver-ad2s1210  |   27 +
 drivers/staging/iio/resolver/Kconfig               |    1 +
 drivers/staging/iio/resolver/ad2s1210.c            | 1583 +++++++++++++++-----
 4 files changed, 1391 insertions(+), 397 deletions(-)
---
base-commit: 5e99f692d4e32e3250ab18d511894ca797407aec
change-id: 20230925-ad2s1210-mainline-2791ef75e386


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

* [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:34   ` Jonathan Cameron
                     ` (2 more replies)
  2023-09-29 17:23 ` [PATCH v3 02/27] staging: iio: resolver: ad2s1210: fix use before initialization David Lechner
                   ` (27 subsequent siblings)
  28 siblings, 3 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner, Apelete Seketeli

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This adds new DeviceTree bindings for the Analog Devices, Inc. AD2S1210
resolver-to-digital converter.

Co-developed-by: Apelete Seketeli <aseketeli@baylibre.com>
Signed-off-by: Apelete Seketeli <aseketeli@baylibre.com>
Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* Expanded top-level description of A0/A1 lines.
* Added required voltage -supply properties. (I did not pick up Rob's
  Reviewed-by since I wasn't sure if this was trivial enough.)

v2 changes:
* Add Co-developed-by:
* Remove extraneous quotes on strings
* Remove extraneous pipe on some multi-line descriptions

 .../bindings/iio/resolver/adi,ad2s1210.yaml        | 177 +++++++++++++++++++++
 1 file changed, 177 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/resolver/adi,ad2s1210.yaml b/Documentation/devicetree/bindings/iio/resolver/adi,ad2s1210.yaml
new file mode 100644
index 000000000000..8980b3cd8337
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/resolver/adi,ad2s1210.yaml
@@ -0,0 +1,177 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/resolver/adi,ad2s1210.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices AD2S1210 Resolver-to-Digital Converter
+
+maintainers:
+  - Michael Hennerich <michael.hennerich@analog.com>
+
+description: |
+  The AD2S1210 is a complete 10-bit to 16-bit resolution tracking
+  resolver-to-digital converter, integrating an on-board programmable
+  sinusoidal oscillator that provides sine wave excitation for
+  resolvers.
+
+  The AD2S1210 allows the user to read the angular position or the
+  angular velocity data directly from the parallel outputs or through
+  the serial interface.
+
+  The mode of operation of the communication channel (parallel or serial) is
+  selected by the A0 and A1 input pins. In normal mode, data is latched by
+  toggling the SAMPLE line and can then be read directly. In configuration mode,
+  data is read or written using a register access scheme (address byte with
+  read/write flag and data byte).
+
+    A1  A0  Result
+     0   0  Normal mode - position output
+     0   1  Normal mode - velocity output
+     1   0  Reserved
+     1   1  Configuration mode
+
+  In normal mode, the resolution of the digital output is selected using
+  the RES0 and RES1 input pins. In configuration mode, the resolution is
+  selected by setting the RES0 and RES1 bits in the control register.
+
+  RES1  RES0  Resolution (Bits)
+     0     0  10
+     0     1  12
+     1     0  14
+     1     1  16
+
+  Note on SPI connections: The CS line on the AD2S1210 should hard-wired to
+  logic low and the WR/FSYNC line on the AD2S1210 should be connected to the
+  SPI CSn output of the SPI controller.
+
+  Datasheet:
+  https://www.analog.com/media/en/technical-documentation/data-sheets/ad2s1210.pdf
+
+properties:
+  compatible:
+    const: adi,ad2s1210
+
+  reg:
+    maxItems: 1
+
+  spi-max-frequency:
+    maximum: 25000000
+
+  spi-cpha: true
+
+  avdd-supply:
+    description:
+      A 4.75 to 5.25 V regulator that powers the Analog Supply Voltage (AVDD)
+      pin.
+
+  dvdd-supply:
+    description:
+      A 4.75 to 5.25 V regulator that powers the Digital Supply Voltage (DVDD)
+      pin.
+
+  vdrive-supply:
+    description:
+      A 2.3 to 5.25 V regulator that powers the Logic Power Supply Input
+      (VDrive) pin.
+
+  clocks:
+    maxItems: 1
+    description: External oscillator clock (CLKIN).
+
+  reset-gpios:
+    description:
+      GPIO connected to the /RESET pin. As the line needs to be low for the
+      reset to be active, it should be configured as GPIO_ACTIVE_LOW.
+    maxItems: 1
+
+  sample-gpios:
+    description:
+      GPIO connected to the /SAMPLE pin. As the line needs to be low to trigger
+      a sample, it should be configured as GPIO_ACTIVE_LOW.
+    maxItems: 1
+
+  mode-gpios:
+    description:
+      GPIO lines connected to the A0 and A1 pins. These pins select the data
+      transfer mode.
+    minItems: 2
+    maxItems: 2
+
+  resolution-gpios:
+    description:
+      GPIO lines connected to the RES0 and RES1 pins. These pins select the
+      resolution of the digital output. If omitted, it is assumed that the
+      RES0 and RES1 pins are hard-wired to match the assigned-resolution-bits
+      property.
+    minItems: 2
+    maxItems: 2
+
+  fault-gpios:
+    description:
+      GPIO lines connected to the LOT and DOS pins. These pins combined indicate
+      the type of fault present, if any. As these pins a pulled low to indicate
+      a fault condition, they should be configured as GPIO_ACTIVE_LOW.
+    minItems: 2
+    maxItems: 2
+
+  adi,fixed-mode:
+    description:
+      This is used to indicate the selected mode if A0 and A1 are hard-wired
+      instead of connected to GPIOS (i.e. mode-gpios is omitted).
+    $ref: /schemas/types.yaml#/definitions/string
+    enum: [config, velocity, position]
+
+  assigned-resolution-bits:
+    description:
+      Resolution of the digital output required by the application. This
+      determines the precision of the angle and/or the maximum speed that can
+      be measured. If resolution-gpios is omitted, it is assumed that RES0 and
+      RES1 are hard-wired to match this value.
+    enum: [10, 12, 14, 16]
+
+required:
+  - compatible
+  - reg
+  - spi-cpha
+  - avdd-supply
+  - dvdd-supply
+  - vdrive-supply
+  - clocks
+  - sample-gpios
+  - assigned-resolution-bits
+
+oneOf:
+  - required:
+      - mode-gpios
+  - required:
+      - adi,fixed-mode
+
+allOf:
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        resolver@0 {
+            compatible = "adi,ad2s1210";
+            reg = <0>;
+            spi-max-frequency = <20000000>;
+            spi-cpha;
+            avdd-supply = <&avdd_regulator>;
+            dvdd-supply = <&dvdd_regulator>;
+            vdrive-supply = <&vdrive_regulator>;
+            clocks = <&ext_osc>;
+            sample-gpios = <&gpio0 90 GPIO_ACTIVE_LOW>;
+            mode-gpios = <&gpio0 86 0>, <&gpio0 87 0>;
+            resolution-gpios = <&gpio0 88 0>, <&gpio0 89 0>;
+            assigned-resolution-bits = <16>;
+        };
+    };

-- 
2.42.0


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

* [PATCH v3 02/27] staging: iio: resolver: ad2s1210: fix use before initialization
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
  2023-09-29 17:23 ` [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210 David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:28   ` Jonathan Cameron
  2023-10-02  8:07   ` Dan Carpenter
  2023-09-29 17:23 ` [PATCH v3 03/27] staging: iio: resolver: ad2s1210: remove call to spi_setup() David Lechner
                   ` (26 subsequent siblings)
  28 siblings, 2 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This fixes a use before initialization in ad2s1210_probe(). The
ad2s1210_setup_gpios() function uses st->sdev but it was being called
before this field was initialized.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* This is a new patch split out from "staging: iio: resolver: ad2s1210:
 fix probe"

 drivers/staging/iio/resolver/ad2s1210.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index f695ca0547e4..3f08b59f4e19 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -658,9 +658,6 @@ static int ad2s1210_probe(struct spi_device *spi)
 	if (!indio_dev)
 		return -ENOMEM;
 	st = iio_priv(indio_dev);
-	ret = ad2s1210_setup_gpios(st);
-	if (ret < 0)
-		return ret;
 
 	spi_set_drvdata(spi, indio_dev);
 
@@ -671,6 +668,10 @@ static int ad2s1210_probe(struct spi_device *spi)
 	st->resolution = 12;
 	st->fexcit = AD2S1210_DEF_EXCIT;
 
+	ret = ad2s1210_setup_gpios(st);
+	if (ret < 0)
+		return ret;
+
 	indio_dev->info = &ad2s1210_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = ad2s1210_channels;

-- 
2.42.0


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

* [PATCH v3 03/27] staging: iio: resolver: ad2s1210: remove call to spi_setup()
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
  2023-09-29 17:23 ` [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210 David Lechner
  2023-09-29 17:23 ` [PATCH v3 02/27] staging: iio: resolver: ad2s1210: fix use before initialization David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:35   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 04/27] staging: iio: resolver: ad2s1210: check return of ad2s1210_initial() David Lechner
                   ` (25 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This removes the call to spi_setup() in the ad2s1210 driver.

Setting MODE_3 was incorrect. It should be MODE_1 but we can let the
device tree select this and avoid the need to call spi_setup().

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* This is a new patch split out from "staging: iio: resolver: ad2s1210:
 fix probe"

 drivers/staging/iio/resolver/ad2s1210.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 3f08b59f4e19..8fde08887f7f 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -683,8 +683,6 @@ static int ad2s1210_probe(struct spi_device *spi)
 		return ret;
 
 	st->fclkin = spi->max_speed_hz;
-	spi->mode = SPI_MODE_3;
-	spi_setup(spi);
 	ad2s1210_initial(st);
 
 	return 0;

-- 
2.42.0


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

* [PATCH v3 04/27] staging: iio: resolver: ad2s1210: check return of ad2s1210_initial()
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (2 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 03/27] staging: iio: resolver: ad2s1210: remove call to spi_setup() David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:37   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 05/27] staging: iio: resolver: ad2s1210: remove spi_set_drvdata() David Lechner
                   ` (24 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This adds a check to the return value of ad2s1210_initial() since it
can fail. The call is also moved before devm_iio_device_register() so
that we don't have to unregister the device if it fails.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* This is a new patch split out from "staging: iio: resolver: ad2s1210:
 fix probe"

 drivers/staging/iio/resolver/ad2s1210.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 8fde08887f7f..b5e071d7c5fd 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -672,6 +672,10 @@ static int ad2s1210_probe(struct spi_device *spi)
 	if (ret < 0)
 		return ret;
 
+	ret = ad2s1210_initial(st);
+	if (ret < 0)
+		return ret;
+
 	indio_dev->info = &ad2s1210_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = ad2s1210_channels;
@@ -683,7 +687,6 @@ static int ad2s1210_probe(struct spi_device *spi)
 		return ret;
 
 	st->fclkin = spi->max_speed_hz;
-	ad2s1210_initial(st);
 
 	return 0;
 }

-- 
2.42.0


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

* [PATCH v3 05/27] staging: iio: resolver: ad2s1210: remove spi_set_drvdata()
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (3 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 04/27] staging: iio: resolver: ad2s1210: check return of ad2s1210_initial() David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:38   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 06/27] staging: iio: resolver: ad2s1210: sort imports David Lechner
                   ` (23 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

Since we never call spi_get_drvdata(), we can remove spi_set_drvdata().

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* This is a new patch split out from "staging: iio: resolver: ad2s1210:
 fix probe"

 drivers/staging/iio/resolver/ad2s1210.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index b5e071d7c5fd..28015322f562 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -659,8 +659,6 @@ static int ad2s1210_probe(struct spi_device *spi)
 		return -ENOMEM;
 	st = iio_priv(indio_dev);
 
-	spi_set_drvdata(spi, indio_dev);
-
 	mutex_init(&st->lock);
 	st->sdev = spi;
 	st->hysteresis = true;

-- 
2.42.0


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

* [PATCH v3 06/27] staging: iio: resolver: ad2s1210: sort imports
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (4 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 05/27] staging: iio: resolver: ad2s1210: remove spi_set_drvdata() David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:39   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 07/27] staging: iio: resolver: ad2s1210: always use 16-bit value for raw read David Lechner
                   ` (22 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

There are quite a few imports and we will be adding more so it will
make it easier to read if they are sorted.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* This is a new patch split out from "staging: iio: resolver: ad2s1210:
 use devicetree to get fclkin"

 drivers/staging/iio/resolver/ad2s1210.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 28015322f562..832f86bf15e5 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -4,16 +4,16 @@
  *
  * Copyright (c) 2010-2010 Analog Devices Inc.
  */
-#include <linux/types.h>
-#include <linux/mutex.h>
+#include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
-#include <linux/spi/spi.h>
 #include <linux/slab.h>
+#include <linux/spi/spi.h>
 #include <linux/sysfs.h>
-#include <linux/delay.h>
-#include <linux/gpio/consumer.h>
-#include <linux/module.h>
+#include <linux/types.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>

-- 
2.42.0


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

* [PATCH v3 07/27] staging: iio: resolver: ad2s1210: always use 16-bit value for raw read
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (5 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 06/27] staging: iio: resolver: ad2s1210: sort imports David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:41   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 08/27] staging: iio: resolver: ad2s1210: implement IIO_CHAN_INFO_SCALE David Lechner
                   ` (21 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This removes the special handling for resolutions lower than 16 bits.
This will allow us to use a fixed scale independent of the resolution.

A new sample field is added to store the raw data instead of reusing
the config mode rx buffer so that we don't have to do a cast or worry
about unaligned access.

Also, for the record, according to the datasheet, the logic for the
special handling based on hysteresis that was removed was incorrect.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* Added __be16 sample field to state struct and use instead of rx buffer.

 drivers/staging/iio/resolver/ad2s1210.c | 24 ++++++++----------------
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 832f86bf15e5..f9774dff2df4 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -95,7 +95,11 @@ struct ad2s1210_state {
 	bool hysteresis;
 	u8 resolution;
 	enum ad2s1210_mode mode;
-	u8 rx[2] __aligned(IIO_DMA_MINALIGN);
+	/** For reading raw sample value via SPI. */
+	__be16 sample __aligned(IIO_DMA_MINALIGN);
+	/** SPI transmit buffer. */
+	u8 rx[2];
+	/** SPI receive buffer. */
 	u8 tx[2];
 };
 
@@ -464,10 +468,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
 			     long m)
 {
 	struct ad2s1210_state *st = iio_priv(indio_dev);
-	u16 negative;
 	int ret = 0;
-	u16 pos;
-	s16 vel;
 
 	mutex_lock(&st->lock);
 	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0);
@@ -487,26 +488,17 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
 	}
 	if (ret < 0)
 		goto error_ret;
-	ret = spi_read(st->sdev, st->rx, 2);
+	ret = spi_read(st->sdev, &st->sample, 2);
 	if (ret < 0)
 		goto error_ret;
 
 	switch (chan->type) {
 	case IIO_ANGL:
-		pos = be16_to_cpup((__be16 *)st->rx);
-		if (st->hysteresis)
-			pos >>= 16 - st->resolution;
-		*val = pos;
+		*val = be16_to_cpu(st->sample);
 		ret = IIO_VAL_INT;
 		break;
 	case IIO_ANGL_VEL:
-		vel = be16_to_cpup((__be16 *)st->rx);
-		vel >>= 16 - st->resolution;
-		if (vel & 0x8000) {
-			negative = (0xffff >> st->resolution) << st->resolution;
-			vel |= negative;
-		}
-		*val = vel;
+		*val = (s16)be16_to_cpu(st->sample);
 		ret = IIO_VAL_INT;
 		break;
 	default:

-- 
2.42.0


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

* [PATCH v3 08/27] staging: iio: resolver: ad2s1210: implement IIO_CHAN_INFO_SCALE
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (6 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 07/27] staging: iio: resolver: ad2s1210: always use 16-bit value for raw read David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:43   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 09/27] staging: iio: resolver: ad2s1210: use devicetree to get CLKIN rate David Lechner
                   ` (20 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This adds an implementation of IIO_CHAN_INFO_SCALE to the ad2s1210
resolver driver. This allows userspace to get the scale factor for the
raw values.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* Split ad2s1210_read_raw() into two functions to reduce complexity.
* Use early return instead of break in switch statements.

 drivers/staging/iio/resolver/ad2s1210.c | 53 ++++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index f9774dff2df4..a710598a64f0 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -461,13 +461,10 @@ static ssize_t ad2s1210_store_reg(struct device *dev,
 	return ret < 0 ? ret : len;
 }
 
-static int ad2s1210_read_raw(struct iio_dev *indio_dev,
-			     struct iio_chan_spec const *chan,
-			     int *val,
-			     int *val2,
-			     long m)
+static int ad2s1210_single_conversion(struct ad2s1210_state *st,
+				      struct iio_chan_spec const *chan,
+				      int *val)
 {
-	struct ad2s1210_state *st = iio_priv(indio_dev);
 	int ret = 0;
 
 	mutex_lock(&st->lock);
@@ -514,6 +511,44 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
 	return ret;
 }
 
+static const int ad2s1210_velocity_scale[] = {
+	17089132, /* 8.192MHz / (2*pi * 2500 / 2^15) */
+	42722830, /* 8.192MHz / (2*pi * 1000 / 2^15) */
+	85445659, /* 8.192MHz / (2*pi * 500 / 2^15) */
+	341782638, /* 8.192MHz / (2*pi * 125 / 2^15) */
+};
+
+static int ad2s1210_read_raw(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     int *val,
+			     int *val2,
+			     long mask)
+{
+	struct ad2s1210_state *st = iio_priv(indio_dev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		return ad2s1210_single_conversion(st, chan, val);
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_ANGL:
+			/* approx 0.3 arc min converted to radians */
+			*val = 0;
+			*val2 = 95874;
+			return IIO_VAL_INT_PLUS_NANO;
+		case IIO_ANGL_VEL:
+			*val = st->fclkin;
+			*val2 = ad2s1210_velocity_scale[st->resolution];
+			return IIO_VAL_FRACTIONAL;
+		default:
+			return -EINVAL;
+		}
+
+	default:
+		return -EINVAL;
+	}
+}
+
 static IIO_DEVICE_ATTR(fclkin, 0644,
 		       ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0);
 static IIO_DEVICE_ATTR(fexcit, 0644,
@@ -552,12 +587,14 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 		.type = IIO_ANGL,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+				      BIT(IIO_CHAN_INFO_SCALE),
 	}, {
 		.type = IIO_ANGL_VEL,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+				      BIT(IIO_CHAN_INFO_SCALE),
 	}
 };
 

-- 
2.42.0


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

* [PATCH v3 09/27] staging: iio: resolver: ad2s1210: use devicetree to get CLKIN rate
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (7 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 08/27] staging: iio: resolver: ad2s1210: implement IIO_CHAN_INFO_SCALE David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:44   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 10/27] staging: iio: resolver: ad2s1210: use regmap for config registers David Lechner
                   ` (19 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This removes the fclkin sysfs attribute and replaces it with getting
the CLKIN clock rate using the clk subsystem (i.e. from the devicetree).

CLKIN comes from an external oscillator that is connected directly to
the AD2S1210 chip, so users of the sysfs attributes should not need to
be concerned with this.

The fclkin field (the datasheet name) is renamed to clkin_hz to be more
obvious that it is a frequency in Hz.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* Don't sort imports in this patch.
* Renamed fexcit to clkin_hz.
* Fixed ad2s1210_setup_clocks() being called in an earlier patch.

 drivers/staging/iio/resolver/Kconfig    |  1 +
 drivers/staging/iio/resolver/ad2s1210.c | 81 ++++++++++++---------------------
 2 files changed, 30 insertions(+), 52 deletions(-)

diff --git a/drivers/staging/iio/resolver/Kconfig b/drivers/staging/iio/resolver/Kconfig
index 6d1e2622e0b0..bebb35822c9e 100644
--- a/drivers/staging/iio/resolver/Kconfig
+++ b/drivers/staging/iio/resolver/Kconfig
@@ -7,6 +7,7 @@ menu "Resolver to digital converters"
 config AD2S1210
 	tristate "Analog Devices ad2s1210 driver"
 	depends on SPI
+	depends on COMMON_CLK
 	depends on GPIOLIB || COMPILE_TEST
 	help
 	  Say yes here to build support for Analog Devices spi resolver
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index a710598a64f0..c8723b6f3a3b 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -3,7 +3,9 @@
  * ad2s1210.c support for the ADI Resolver to Digital Converters: AD2S1210
  *
  * Copyright (c) 2010-2010 Analog Devices Inc.
+ * Copyright (c) 2023 BayLibre, SAS
  */
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/gpio/consumer.h>
@@ -90,7 +92,8 @@ struct ad2s1210_state {
 	struct mutex lock;
 	struct spi_device *sdev;
 	struct gpio_desc *gpios[5];
-	unsigned int fclkin;
+	/** The external oscillator frequency in Hz. */
+	unsigned long clkin_hz;
 	unsigned int fexcit;
 	bool hysteresis;
 	u8 resolution;
@@ -165,7 +168,7 @@ int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st)
 	int ret;
 	unsigned char fcw;
 
-	fcw = (unsigned char)(st->fexcit * (1 << 15) / st->fclkin);
+	fcw = (unsigned char)(st->fexcit * (1 << 15) / st->clkin_hz);
 	if (fcw < AD2S1210_MIN_FCW || fcw > AD2S1210_MAX_FCW) {
 		dev_err(&st->sdev->dev, "ad2s1210: FCW out of range\n");
 		return -ERANGE;
@@ -201,45 +204,6 @@ static inline int ad2s1210_soft_reset(struct ad2s1210_state *st)
 	return ad2s1210_config_write(st, 0x0);
 }
 
-static ssize_t ad2s1210_show_fclkin(struct device *dev,
-				    struct device_attribute *attr,
-				    char *buf)
-{
-	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-
-	return sprintf(buf, "%u\n", st->fclkin);
-}
-
-static ssize_t ad2s1210_store_fclkin(struct device *dev,
-				     struct device_attribute *attr,
-				     const char *buf,
-				     size_t len)
-{
-	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-	unsigned int fclkin;
-	int ret;
-
-	ret = kstrtouint(buf, 10, &fclkin);
-	if (ret)
-		return ret;
-	if (fclkin < AD2S1210_MIN_CLKIN || fclkin > AD2S1210_MAX_CLKIN) {
-		dev_err(dev, "ad2s1210: fclkin out of range\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(&st->lock);
-	st->fclkin = fclkin;
-
-	ret = ad2s1210_update_frequency_control_word(st);
-	if (ret < 0)
-		goto error_ret;
-	ret = ad2s1210_soft_reset(st);
-error_ret:
-	mutex_unlock(&st->lock);
-
-	return ret < 0 ? ret : len;
-}
-
 static ssize_t ad2s1210_show_fexcit(struct device *dev,
 				    struct device_attribute *attr,
 				    char *buf)
@@ -537,7 +501,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
 			*val2 = 95874;
 			return IIO_VAL_INT_PLUS_NANO;
 		case IIO_ANGL_VEL:
-			*val = st->fclkin;
+			*val = st->clkin_hz;
 			*val2 = ad2s1210_velocity_scale[st->resolution];
 			return IIO_VAL_FRACTIONAL;
 		default:
@@ -549,8 +513,6 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
 	}
 }
 
-static IIO_DEVICE_ATTR(fclkin, 0644,
-		       ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0);
 static IIO_DEVICE_ATTR(fexcit, 0644,
 		       ad2s1210_show_fexcit,	ad2s1210_store_fexcit, 0);
 static IIO_DEVICE_ATTR(control, 0644,
@@ -599,7 +561,6 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 };
 
 static struct attribute *ad2s1210_attributes[] = {
-	&iio_dev_attr_fclkin.dev_attr.attr,
 	&iio_dev_attr_fexcit.dev_attr.attr,
 	&iio_dev_attr_control.dev_attr.attr,
 	&iio_dev_attr_bits.dev_attr.attr,
@@ -657,6 +618,24 @@ static const struct iio_info ad2s1210_info = {
 	.attrs = &ad2s1210_attribute_group,
 };
 
+static int ad2s1210_setup_clocks(struct ad2s1210_state *st)
+{
+	struct device *dev = &st->sdev->dev;
+	struct clk *clk;
+
+	clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(clk))
+		return dev_err_probe(dev, PTR_ERR(clk), "failed to get clock\n");
+
+	st->clkin_hz = clk_get_rate(clk);
+	if (st->clkin_hz < AD2S1210_MIN_CLKIN || st->clkin_hz > AD2S1210_MAX_CLKIN)
+		return dev_err_probe(dev, -EINVAL,
+				     "clock frequency out of range: %lu\n",
+				     st->clkin_hz);
+
+	return 0;
+}
+
 static int ad2s1210_setup_gpios(struct ad2s1210_state *st)
 {
 	struct spi_device *spi = st->sdev;
@@ -695,6 +674,10 @@ static int ad2s1210_probe(struct spi_device *spi)
 	st->resolution = 12;
 	st->fexcit = AD2S1210_DEF_EXCIT;
 
+	ret = ad2s1210_setup_clocks(st);
+	if (ret < 0)
+		return ret;
+
 	ret = ad2s1210_setup_gpios(st);
 	if (ret < 0)
 		return ret;
@@ -709,13 +692,7 @@ static int ad2s1210_probe(struct spi_device *spi)
 	indio_dev->num_channels = ARRAY_SIZE(ad2s1210_channels);
 	indio_dev->name = spi_get_device_id(spi)->name;
 
-	ret = devm_iio_device_register(&spi->dev, indio_dev);
-	if (ret)
-		return ret;
-
-	st->fclkin = spi->max_speed_hz;
-
-	return 0;
+	return devm_iio_device_register(&spi->dev, indio_dev);
 }
 
 static const struct of_device_id ad2s1210_of_match[] = {

-- 
2.42.0


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

* [PATCH v3 10/27] staging: iio: resolver: ad2s1210: use regmap for config registers
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (8 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 09/27] staging: iio: resolver: ad2s1210: use devicetree to get CLKIN rate David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:51   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 11/27] staging: iio: resolver: ad2s1210: add debugfs reg access David Lechner
                   ` (18 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This makes use of the regmap API to read and write the configuration
registers. This simplifies code quite a bit and makes it safer
(previously, it was easy to write a bad value to the config registers
which causes the chip to lock up and need to be reset).

This chip has multiple modes of operation. In normal mode, we do not use
regmap since there is no addressing - data is just bitshifted out during
the SPI read. In config mode, we use regmap since it requires writing
the address (with read/write flag) before reading and writing.

We don't use the lock provided by the regmap because we need to also
synchronize with the normal mode SPI reads and with the various GPIOs.

There is also a quirk when reading registers (other than the fault
register). If the address/data bit is set in the value read, then it
indicates there is a configuration parity error and the data is not
valid. Previously, this was checked in a few places, but not
consistently. Now, we always check it in the regmap read function.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* Expanded description in commit message.
* Fixed multiline comment style.
* Replaced use of AD2S1210_DEF_CONTROL with FIELD_PREP().
* Removed unrelated `if (reg < 0)` change.

 drivers/staging/iio/resolver/ad2s1210.c | 259 +++++++++++++++++++-------------
 1 file changed, 155 insertions(+), 104 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index c8723b6f3a3b..0663a51d04ad 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -5,6 +5,8 @@
  * Copyright (c) 2010-2010 Analog Devices Inc.
  * Copyright (c) 2023 BayLibre, SAS
  */
+#include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/device.h>
@@ -12,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
@@ -22,21 +25,17 @@
 
 #define DRV_NAME "ad2s1210"
 
-#define AD2S1210_DEF_CONTROL		0x7E
-
-#define AD2S1210_MSB_IS_HIGH		0x80
-#define AD2S1210_MSB_IS_LOW		0x7F
-#define AD2S1210_PHASE_LOCK_RANGE_44	0x20
-#define AD2S1210_ENABLE_HYSTERESIS	0x10
-#define AD2S1210_SET_ENRES1		0x08
-#define AD2S1210_SET_ENRES0		0x04
-#define AD2S1210_SET_RES1		0x02
-#define AD2S1210_SET_RES0		0x01
-
-#define AD2S1210_SET_RESOLUTION		(AD2S1210_SET_RES1 | AD2S1210_SET_RES0)
-
-#define AD2S1210_REG_POSITION		0x80
-#define AD2S1210_REG_VELOCITY		0x82
+/* control register flags */
+#define AD2S1210_ADDRESS_DATA		BIT(7)
+#define AD2S1210_PHASE_LOCK_RANGE_44	BIT(5)
+#define AD2S1210_ENABLE_HYSTERESIS	BIT(4)
+#define AD2S1210_SET_ENRES		GENMASK(3, 2)
+#define AD2S1210_SET_RES		GENMASK(1, 0)
+
+#define AD2S1210_REG_POSITION_MSB	0x80
+#define AD2S1210_REG_POSITION_LSB	0x81
+#define AD2S1210_REG_VELOCITY_MSB	0x82
+#define AD2S1210_REG_VELOCITY_LSB	0x83
 #define AD2S1210_REG_LOS_THRD		0x88
 #define AD2S1210_REG_DOS_OVR_THRD	0x89
 #define AD2S1210_REG_DOS_MIS_THRD	0x8A
@@ -92,6 +91,8 @@ struct ad2s1210_state {
 	struct mutex lock;
 	struct spi_device *sdev;
 	struct gpio_desc *gpios[5];
+	/** Used to access config registers. */
+	struct regmap *regmap;
 	/** The external oscillator frequency in Hz. */
 	unsigned long clkin_hz;
 	unsigned int fexcit;
@@ -120,24 +121,51 @@ static inline void ad2s1210_set_mode(enum ad2s1210_mode mode,
 	st->mode = mode;
 }
 
-/* write 1 bytes (address or data) to the chip */
-static int ad2s1210_config_write(struct ad2s1210_state *st, u8 data)
+/*
+ * Writes the given data to the given register address.
+ *
+ * If the mode is configurable, the device will first be placed in
+ * configuration mode.
+ */
+static int ad2s1210_regmap_reg_write(void *context, unsigned int reg,
+				     unsigned int val)
 {
-	int ret;
+	struct ad2s1210_state *st = context;
+	struct spi_transfer xfers[] = {
+		{
+			.len = 1,
+			.rx_buf = &st->rx[0],
+			.tx_buf = &st->tx[0],
+			.cs_change = 1,
+		}, {
+			.len = 1,
+			.rx_buf = &st->rx[1],
+			.tx_buf = &st->tx[1],
+		},
+	};
+
+	/* values can only be 7 bits, the MSB indicates an address */
+	if (val & ~0x7F)
+		return -EINVAL;
+
+	st->tx[0] = reg;
+	st->tx[1] = val;
 
 	ad2s1210_set_mode(MOD_CONFIG, st);
-	st->tx[0] = data;
-	ret = spi_write(st->sdev, st->tx, 1);
-	if (ret < 0)
-		return ret;
 
-	return 0;
+	return spi_sync_transfer(st->sdev, xfers, ARRAY_SIZE(xfers));
 }
 
-/* read value from one of the registers */
-static int ad2s1210_config_read(struct ad2s1210_state *st,
-				unsigned char address)
+/*
+ * Reads value from one of the registers.
+ *
+ * If the mode is configurable, the device will first be placed in
+ * configuration mode.
+ */
+static int ad2s1210_regmap_reg_read(void *context, unsigned int reg,
+				    unsigned int *val)
 {
+	struct ad2s1210_state *st = context;
 	struct spi_transfer xfers[] = {
 		{
 			.len = 1,
@@ -150,22 +178,36 @@ static int ad2s1210_config_read(struct ad2s1210_state *st,
 			.tx_buf = &st->tx[1],
 		},
 	};
-	int ret = 0;
+	int ret;
 
 	ad2s1210_set_mode(MOD_CONFIG, st);
-	st->tx[0] = address | AD2S1210_MSB_IS_HIGH;
+	st->tx[0] = reg;
+	/*
+	 * Must be valid register address here otherwise this could write data.
+	 * It doesn't matter which one.
+	 */
 	st->tx[1] = AD2S1210_REG_FAULT;
-	ret = spi_sync_transfer(st->sdev, xfers, 2);
+
+	ret = spi_sync_transfer(st->sdev, xfers, ARRAY_SIZE(xfers));
 	if (ret < 0)
 		return ret;
 
-	return st->rx[1];
+	/*
+	 * If the D7 bit is set on any read/write register, it indicates a
+	 * parity error. The fault register is read-only and the D7 bit means
+	 * something else there.
+	 */
+	if (reg != AD2S1210_REG_FAULT && st->rx[1] & AD2S1210_ADDRESS_DATA)
+		return -EBADMSG;
+
+	*val = st->rx[1];
+
+	return 0;
 }
 
 static inline
 int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st)
 {
-	int ret;
 	unsigned char fcw;
 
 	fcw = (unsigned char)(st->fexcit * (1 << 15) / st->clkin_hz);
@@ -174,11 +216,7 @@ int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st)
 		return -ERANGE;
 	}
 
-	ret = ad2s1210_config_write(st, AD2S1210_REG_EXCIT_FREQ);
-	if (ret < 0)
-		return ret;
-
-	return ad2s1210_config_write(st, fcw);
+	return regmap_write(st->regmap, AD2S1210_REG_EXCIT_FREQ, fcw);
 }
 
 static const int ad2s1210_res_pins[4][2] = {
@@ -195,13 +233,7 @@ static inline void ad2s1210_set_resolution_pin(struct ad2s1210_state *st)
 
 static inline int ad2s1210_soft_reset(struct ad2s1210_state *st)
 {
-	int ret;
-
-	ret = ad2s1210_config_write(st, AD2S1210_REG_SOFT_RESET);
-	if (ret < 0)
-		return ret;
-
-	return ad2s1210_config_write(st, 0x0);
+	return regmap_write(st->regmap, AD2S1210_REG_SOFT_RESET, 0);
 }
 
 static ssize_t ad2s1210_show_fexcit(struct device *dev,
@@ -246,12 +278,13 @@ static ssize_t ad2s1210_show_control(struct device *dev,
 				     char *buf)
 {
 	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
+	unsigned int value;
 	int ret;
 
 	mutex_lock(&st->lock);
-	ret = ad2s1210_config_read(st, AD2S1210_REG_CONTROL);
+	ret = regmap_read(st->regmap, AD2S1210_REG_CONTROL, &value);
 	mutex_unlock(&st->lock);
-	return ret < 0 ? ret : sprintf(buf, "0x%x\n", ret);
+	return ret < 0 ? ret : sprintf(buf, "0x%x\n", value);
 }
 
 static ssize_t ad2s1210_store_control(struct device *dev,
@@ -268,25 +301,13 @@ static ssize_t ad2s1210_store_control(struct device *dev,
 		return -EINVAL;
 
 	mutex_lock(&st->lock);
-	ret = ad2s1210_config_write(st, AD2S1210_REG_CONTROL);
-	if (ret < 0)
-		goto error_ret;
-	data = udata & AD2S1210_MSB_IS_LOW;
-	ret = ad2s1210_config_write(st, data);
+	data = udata & ~AD2S1210_ADDRESS_DATA;
+	ret = regmap_write(st->regmap, AD2S1210_REG_CONTROL, data);
 	if (ret < 0)
 		goto error_ret;
 
-	ret = ad2s1210_config_read(st, AD2S1210_REG_CONTROL);
-	if (ret < 0)
-		goto error_ret;
-	if (ret & AD2S1210_MSB_IS_HIGH) {
-		ret = -EIO;
-		dev_err(dev,
-			"ad2s1210: write control register fail\n");
-		goto error_ret;
-	}
 	st->resolution =
-		ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION];
+		ad2s1210_resolution_value[data & AD2S1210_SET_RES];
 	ad2s1210_set_resolution_pin(st);
 	ret = len;
 	st->hysteresis = !!(data & AD2S1210_ENABLE_HYSTERESIS);
@@ -319,30 +340,17 @@ static ssize_t ad2s1210_store_resolution(struct device *dev,
 		dev_err(dev, "ad2s1210: resolution out of range\n");
 		return -EINVAL;
 	}
+
+	data = (udata - 10) >> 1;
+
 	mutex_lock(&st->lock);
-	ret = ad2s1210_config_read(st, AD2S1210_REG_CONTROL);
-	if (ret < 0)
-		goto error_ret;
-	data = ret;
-	data &= ~AD2S1210_SET_RESOLUTION;
-	data |= (udata - 10) >> 1;
-	ret = ad2s1210_config_write(st, AD2S1210_REG_CONTROL);
-	if (ret < 0)
-		goto error_ret;
-	ret = ad2s1210_config_write(st, data & AD2S1210_MSB_IS_LOW);
-	if (ret < 0)
-		goto error_ret;
-	ret = ad2s1210_config_read(st, AD2S1210_REG_CONTROL);
+	ret = regmap_update_bits(st->regmap, AD2S1210_REG_CONTROL,
+				 AD2S1210_SET_RES, data);
 	if (ret < 0)
 		goto error_ret;
-	data = ret;
-	if (data & AD2S1210_MSB_IS_HIGH) {
-		ret = -EIO;
-		dev_err(dev, "ad2s1210: setting resolution fail\n");
-		goto error_ret;
-	}
+
 	st->resolution =
-		ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION];
+		ad2s1210_resolution_value[data & AD2S1210_SET_RES];
 	ad2s1210_set_resolution_pin(st);
 	ret = len;
 error_ret:
@@ -355,13 +363,14 @@ static ssize_t ad2s1210_show_fault(struct device *dev,
 				   struct device_attribute *attr, char *buf)
 {
 	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
+	unsigned int value;
 	int ret;
 
 	mutex_lock(&st->lock);
-	ret = ad2s1210_config_read(st, AD2S1210_REG_FAULT);
+	ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, &value);
 	mutex_unlock(&st->lock);
 
-	return ret < 0 ? ret : sprintf(buf, "0x%02x\n", ret);
+	return ret < 0 ? ret : sprintf(buf, "0x%02x\n", value);
 }
 
 static ssize_t ad2s1210_clear_fault(struct device *dev,
@@ -370,6 +379,7 @@ static ssize_t ad2s1210_clear_fault(struct device *dev,
 				    size_t len)
 {
 	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
+	unsigned int value;
 	int ret;
 
 	mutex_lock(&st->lock);
@@ -377,7 +387,7 @@ static ssize_t ad2s1210_clear_fault(struct device *dev,
 	/* delay (2 * tck + 20) nano seconds */
 	udelay(1);
 	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1);
-	ret = ad2s1210_config_read(st, AD2S1210_REG_FAULT);
+	ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, &value);
 	if (ret < 0)
 		goto error_ret;
 	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0);
@@ -394,13 +404,14 @@ static ssize_t ad2s1210_show_reg(struct device *dev,
 {
 	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
 	struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
+	unsigned int value;
 	int ret;
 
 	mutex_lock(&st->lock);
-	ret = ad2s1210_config_read(st, iattr->address);
+	ret = regmap_read(st->regmap, iattr->address, &value);
 	mutex_unlock(&st->lock);
 
-	return ret < 0 ? ret : sprintf(buf, "%d\n", ret);
+	return ret < 0 ? ret : sprintf(buf, "%d\n", value);
 }
 
 static ssize_t ad2s1210_store_reg(struct device *dev,
@@ -415,12 +426,9 @@ static ssize_t ad2s1210_store_reg(struct device *dev,
 	ret = kstrtou8(buf, 10, &data);
 	if (ret)
 		return -EINVAL;
+
 	mutex_lock(&st->lock);
-	ret = ad2s1210_config_write(st, iattr->address);
-	if (ret < 0)
-		goto error_ret;
-	ret = ad2s1210_config_write(st, data & AD2S1210_MSB_IS_LOW);
-error_ret:
+	ret = regmap_write(st->regmap, iattr->address, data);
 	mutex_unlock(&st->lock);
 	return ret < 0 ? ret : len;
 }
@@ -587,22 +595,15 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
 	mutex_lock(&st->lock);
 	ad2s1210_set_resolution_pin(st);
 
-	ret = ad2s1210_config_write(st, AD2S1210_REG_CONTROL);
-	if (ret < 0)
-		goto error_ret;
-	data = AD2S1210_DEF_CONTROL & ~(AD2S1210_SET_RESOLUTION);
-	data |= (st->resolution - 10) >> 1;
-	ret = ad2s1210_config_write(st, data);
-	if (ret < 0)
-		goto error_ret;
-	ret = ad2s1210_config_read(st, AD2S1210_REG_CONTROL);
-	if (ret < 0)
-		goto error_ret;
+	/* Use default config register value plus resolution from devicetree. */
+	data = FIELD_PREP(AD2S1210_PHASE_LOCK_RANGE_44, 1);
+	data |= FIELD_PREP(AD2S1210_ENABLE_HYSTERESIS, 1);
+	data |= FIELD_PREP(AD2S1210_SET_ENRES, 0x3);
+	data |= FIELD_PREP(AD2S1210_SET_RES, (st->resolution - 10) >> 1);
 
-	if (ret & AD2S1210_MSB_IS_HIGH) {
-		ret = -EIO;
+	ret = regmap_write(st->regmap, AD2S1210_REG_CONTROL, data);
+	if (ret < 0)
 		goto error_ret;
-	}
 
 	ret = ad2s1210_update_frequency_control_word(st);
 	if (ret < 0)
@@ -656,6 +657,52 @@ static int ad2s1210_setup_gpios(struct ad2s1210_state *st)
 	return 0;
 }
 
+static const struct regmap_range ad2s1210_regmap_readable_ranges[] = {
+	regmap_reg_range(AD2S1210_REG_POSITION_MSB, AD2S1210_REG_VELOCITY_LSB),
+	regmap_reg_range(AD2S1210_REG_LOS_THRD, AD2S1210_REG_LOT_LOW_THRD),
+	regmap_reg_range(AD2S1210_REG_EXCIT_FREQ, AD2S1210_REG_CONTROL),
+	regmap_reg_range(AD2S1210_REG_FAULT, AD2S1210_REG_FAULT),
+};
+
+static const struct regmap_access_table ad2s1210_regmap_rd_table = {
+	.yes_ranges = ad2s1210_regmap_readable_ranges,
+	.n_yes_ranges = ARRAY_SIZE(ad2s1210_regmap_readable_ranges),
+};
+
+static const struct regmap_range ad2s1210_regmap_writeable_ranges[] = {
+	regmap_reg_range(AD2S1210_REG_LOS_THRD, AD2S1210_REG_LOT_LOW_THRD),
+	regmap_reg_range(AD2S1210_REG_EXCIT_FREQ, AD2S1210_REG_CONTROL),
+	regmap_reg_range(AD2S1210_REG_SOFT_RESET, AD2S1210_REG_SOFT_RESET),
+	regmap_reg_range(AD2S1210_REG_FAULT, AD2S1210_REG_FAULT),
+};
+
+static const struct regmap_access_table ad2s1210_regmap_wr_table = {
+	.yes_ranges = ad2s1210_regmap_writeable_ranges,
+	.n_yes_ranges = ARRAY_SIZE(ad2s1210_regmap_writeable_ranges),
+};
+
+static int ad2s1210_setup_regmap(struct ad2s1210_state *st)
+{
+	struct device *dev = &st->sdev->dev;
+	const struct regmap_config config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+		.disable_locking = true,
+		.reg_read = ad2s1210_regmap_reg_read,
+		.reg_write = ad2s1210_regmap_reg_write,
+		.rd_table = &ad2s1210_regmap_rd_table,
+		.wr_table = &ad2s1210_regmap_wr_table,
+		.can_sleep = true,
+	};
+
+	st->regmap = devm_regmap_init(dev, NULL, st, &config);
+	if (IS_ERR(st->regmap))
+		return dev_err_probe(dev, PTR_ERR(st->regmap),
+				     "failed to allocate register map\n");
+
+	return 0;
+}
+
 static int ad2s1210_probe(struct spi_device *spi)
 {
 	struct iio_dev *indio_dev;
@@ -682,6 +729,10 @@ static int ad2s1210_probe(struct spi_device *spi)
 	if (ret < 0)
 		return ret;
 
+	ret = ad2s1210_setup_regmap(st);
+	if (ret < 0)
+		return ret;
+
 	ret = ad2s1210_initial(st);
 	if (ret < 0)
 		return ret;

-- 
2.42.0


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

* [PATCH v3 11/27] staging: iio: resolver: ad2s1210: add debugfs reg access
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (9 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 10/27] staging: iio: resolver: ad2s1210: use regmap for config registers David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:52   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 12/27] staging: iio: resolver: ad2s1210: remove config attribute David Lechner
                   ` (17 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This add an implementation of debugfs_reg_access for the AD2S1210
driver.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes: None

 drivers/staging/iio/resolver/ad2s1210.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 0663a51d04ad..31415fbb6384 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -614,9 +614,29 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
 	return ret;
 }
 
+static int ad2s1210_debugfs_reg_access(struct iio_dev *indio_dev,
+				       unsigned int reg, unsigned int writeval,
+				       unsigned int *readval)
+{
+	struct ad2s1210_state *st = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&st->lock);
+
+	if (readval)
+		ret = regmap_read(st->regmap, reg, readval);
+	else
+		ret = regmap_write(st->regmap, reg, writeval);
+
+	mutex_unlock(&st->lock);
+
+	return ret;
+}
+
 static const struct iio_info ad2s1210_info = {
 	.read_raw = ad2s1210_read_raw,
 	.attrs = &ad2s1210_attribute_group,
+	.debugfs_reg_access = &ad2s1210_debugfs_reg_access,
 };
 
 static int ad2s1210_setup_clocks(struct ad2s1210_state *st)

-- 
2.42.0


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

* [PATCH v3 12/27] staging: iio: resolver: ad2s1210: remove config attribute
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (10 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 11/27] staging: iio: resolver: ad2s1210: add debugfs reg access David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:53   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 13/27] staging: iio: resolver: ad2s1210: rework gpios David Lechner
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This removes the config register sysfs attribute.

Writing to the config register directly can be dangerous and userspace
should not need to have to know the register layout. This register
can still be accessed though debugfs if needed.

We can add new attributes to set specific flags in the config register
in the future if needed (e.g. `enable_hysterisis` and
`phase_lock_range`).

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes: None

 drivers/staging/iio/resolver/ad2s1210.c | 47 ---------------------------------
 1 file changed, 47 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 31415fbb6384..2b9377447f6a 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -273,50 +273,6 @@ static ssize_t ad2s1210_store_fexcit(struct device *dev,
 	return ret < 0 ? ret : len;
 }
 
-static ssize_t ad2s1210_show_control(struct device *dev,
-				     struct device_attribute *attr,
-				     char *buf)
-{
-	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-	unsigned int value;
-	int ret;
-
-	mutex_lock(&st->lock);
-	ret = regmap_read(st->regmap, AD2S1210_REG_CONTROL, &value);
-	mutex_unlock(&st->lock);
-	return ret < 0 ? ret : sprintf(buf, "0x%x\n", value);
-}
-
-static ssize_t ad2s1210_store_control(struct device *dev,
-				      struct device_attribute *attr,
-				      const char *buf, size_t len)
-{
-	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-	unsigned char udata;
-	unsigned char data;
-	int ret;
-
-	ret = kstrtou8(buf, 16, &udata);
-	if (ret)
-		return -EINVAL;
-
-	mutex_lock(&st->lock);
-	data = udata & ~AD2S1210_ADDRESS_DATA;
-	ret = regmap_write(st->regmap, AD2S1210_REG_CONTROL, data);
-	if (ret < 0)
-		goto error_ret;
-
-	st->resolution =
-		ad2s1210_resolution_value[data & AD2S1210_SET_RES];
-	ad2s1210_set_resolution_pin(st);
-	ret = len;
-	st->hysteresis = !!(data & AD2S1210_ENABLE_HYSTERESIS);
-
-error_ret:
-	mutex_unlock(&st->lock);
-	return ret;
-}
-
 static ssize_t ad2s1210_show_resolution(struct device *dev,
 					struct device_attribute *attr,
 					char *buf)
@@ -523,8 +479,6 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
 
 static IIO_DEVICE_ATTR(fexcit, 0644,
 		       ad2s1210_show_fexcit,	ad2s1210_store_fexcit, 0);
-static IIO_DEVICE_ATTR(control, 0644,
-		       ad2s1210_show_control, ad2s1210_store_control, 0);
 static IIO_DEVICE_ATTR(bits, 0644,
 		       ad2s1210_show_resolution, ad2s1210_store_resolution, 0);
 static IIO_DEVICE_ATTR(fault, 0644,
@@ -570,7 +524,6 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 
 static struct attribute *ad2s1210_attributes[] = {
 	&iio_dev_attr_fexcit.dev_attr.attr,
-	&iio_dev_attr_control.dev_attr.attr,
 	&iio_dev_attr_bits.dev_attr.attr,
 	&iio_dev_attr_fault.dev_attr.attr,
 	&iio_dev_attr_los_thrd.dev_attr.attr,

-- 
2.42.0


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

* [PATCH v3 13/27] staging: iio: resolver: ad2s1210: rework gpios
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (11 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 12/27] staging: iio: resolver: ad2s1210: remove config attribute David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 14:55   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 14/27] staging: iio: resolver: ad2s1210: implement hysteresis as channel attr David Lechner
                   ` (15 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

- Remove "adi," prefix from gpio names.
- Sample gpio is now expected to be active low.
- Convert A0 and A1 gpios to "mode-gpios" gpio array.
- Convert RES0 and RES1 gpios to "resolution-gpios" gpio array.
- Remove extraneous lookup tables.
- Remove unused mode field from state struct.
- Swap argument order of ad2s1210_set_mode() while we are touching this.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* Fixed multiline comment style.

 drivers/staging/iio/resolver/ad2s1210.c | 164 +++++++++++++++++---------------
 1 file changed, 85 insertions(+), 79 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 2b9377447f6a..0ec3598b600a 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -58,39 +58,21 @@
 #define AD2S1210_DEF_EXCIT	10000
 
 enum ad2s1210_mode {
-	MOD_POS = 0,
-	MOD_VEL,
-	MOD_CONFIG,
-	MOD_RESERVED,
+	MOD_POS = 0b00,
+	MOD_VEL = 0b01,
+	MOD_RESERVED = 0b10,
+	MOD_CONFIG = 0b11,
 };
 
-enum ad2s1210_gpios {
-	AD2S1210_SAMPLE,
-	AD2S1210_A0,
-	AD2S1210_A1,
-	AD2S1210_RES0,
-	AD2S1210_RES1,
-};
-
-struct ad2s1210_gpio {
-	const char *name;
-	unsigned long flags;
-};
-
-static const struct ad2s1210_gpio gpios[] = {
-	[AD2S1210_SAMPLE] = { .name = "adi,sample", .flags = GPIOD_OUT_LOW },
-	[AD2S1210_A0] = { .name = "adi,a0", .flags = GPIOD_OUT_LOW },
-	[AD2S1210_A1] = { .name = "adi,a1", .flags = GPIOD_OUT_LOW },
-	[AD2S1210_RES0] = { .name = "adi,res0", .flags = GPIOD_OUT_LOW },
-	[AD2S1210_RES1] = { .name = "adi,res1", .flags = GPIOD_OUT_LOW },
-};
-
-static const unsigned int ad2s1210_resolution_value[] = { 10, 12, 14, 16 };
-
 struct ad2s1210_state {
 	struct mutex lock;
 	struct spi_device *sdev;
-	struct gpio_desc *gpios[5];
+	/** GPIO pin connected to SAMPLE line. */
+	struct gpio_desc *sample_gpio;
+	/** GPIO pins connected to A0 and A1 lines. */
+	struct gpio_descs *mode_gpios;
+	/** GPIO pins connected to RES0 and RES1 lines. */
+	struct gpio_descs *resolution_gpios;
 	/** Used to access config registers. */
 	struct regmap *regmap;
 	/** The external oscillator frequency in Hz. */
@@ -98,7 +80,6 @@ struct ad2s1210_state {
 	unsigned int fexcit;
 	bool hysteresis;
 	u8 resolution;
-	enum ad2s1210_mode mode;
 	/** For reading raw sample value via SPI. */
 	__be16 sample __aligned(IIO_DMA_MINALIGN);
 	/** SPI transmit buffer. */
@@ -107,18 +88,15 @@ struct ad2s1210_state {
 	u8 tx[2];
 };
 
-static const int ad2s1210_mode_vals[4][2] = {
-	[MOD_POS] = { 0, 0 },
-	[MOD_VEL] = { 0, 1 },
-	[MOD_CONFIG] = { 1, 1 },
-};
-
-static inline void ad2s1210_set_mode(enum ad2s1210_mode mode,
-				     struct ad2s1210_state *st)
+static int ad2s1210_set_mode(struct ad2s1210_state *st, enum ad2s1210_mode mode)
 {
-	gpiod_set_value(st->gpios[AD2S1210_A0], ad2s1210_mode_vals[mode][0]);
-	gpiod_set_value(st->gpios[AD2S1210_A1], ad2s1210_mode_vals[mode][1]);
-	st->mode = mode;
+	struct gpio_descs *gpios = st->mode_gpios;
+	DECLARE_BITMAP(bitmap, 2);
+
+	bitmap[0] = mode;
+
+	return gpiod_set_array_value(gpios->ndescs, gpios->desc, gpios->info,
+				     bitmap);
 }
 
 /*
@@ -143,6 +121,7 @@ static int ad2s1210_regmap_reg_write(void *context, unsigned int reg,
 			.tx_buf = &st->tx[1],
 		},
 	};
+	int ret;
 
 	/* values can only be 7 bits, the MSB indicates an address */
 	if (val & ~0x7F)
@@ -151,7 +130,9 @@ static int ad2s1210_regmap_reg_write(void *context, unsigned int reg,
 	st->tx[0] = reg;
 	st->tx[1] = val;
 
-	ad2s1210_set_mode(MOD_CONFIG, st);
+	ret = ad2s1210_set_mode(st, MOD_CONFIG);
+	if (ret < 0)
+		return ret;
 
 	return spi_sync_transfer(st->sdev, xfers, ARRAY_SIZE(xfers));
 }
@@ -180,7 +161,10 @@ static int ad2s1210_regmap_reg_read(void *context, unsigned int reg,
 	};
 	int ret;
 
-	ad2s1210_set_mode(MOD_CONFIG, st);
+	ret = ad2s1210_set_mode(st, MOD_CONFIG);
+	if (ret < 0)
+		return ret;
+
 	st->tx[0] = reg;
 	/*
 	 * Must be valid register address here otherwise this could write data.
@@ -219,16 +203,16 @@ int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st)
 	return regmap_write(st->regmap, AD2S1210_REG_EXCIT_FREQ, fcw);
 }
 
-static const int ad2s1210_res_pins[4][2] = {
-	{ 0, 0 }, {0, 1}, {1, 0}, {1, 1}
-};
-
-static inline void ad2s1210_set_resolution_pin(struct ad2s1210_state *st)
+static int ad2s1210_set_resolution_gpios(struct ad2s1210_state *st,
+					 u8 resolution)
 {
-	gpiod_set_value(st->gpios[AD2S1210_RES0],
-			ad2s1210_res_pins[(st->resolution - 10) / 2][0]);
-	gpiod_set_value(st->gpios[AD2S1210_RES1],
-			ad2s1210_res_pins[(st->resolution - 10) / 2][1]);
+	struct gpio_descs *gpios = st->resolution_gpios;
+	DECLARE_BITMAP(bitmap, 2);
+
+	bitmap[0] = (resolution - 10) >> 1;
+
+	return gpiod_set_array_value(gpios->ndescs, gpios->desc, gpios->info,
+				     bitmap);
 }
 
 static inline int ad2s1210_soft_reset(struct ad2s1210_state *st)
@@ -305,10 +289,13 @@ static ssize_t ad2s1210_store_resolution(struct device *dev,
 	if (ret < 0)
 		goto error_ret;
 
-	st->resolution =
-		ad2s1210_resolution_value[data & AD2S1210_SET_RES];
-	ad2s1210_set_resolution_pin(st);
+	ret = ad2s1210_set_resolution_gpios(st, udata);
+	if (ret < 0)
+		goto error_ret;
+
+	st->resolution = udata;
 	ret = len;
+
 error_ret:
 	mutex_unlock(&st->lock);
 	return ret;
@@ -339,15 +326,19 @@ static ssize_t ad2s1210_clear_fault(struct device *dev,
 	int ret;
 
 	mutex_lock(&st->lock);
-	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0);
+
+	gpiod_set_value(st->sample_gpio, 1);
 	/* delay (2 * tck + 20) nano seconds */
 	udelay(1);
-	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1);
+	gpiod_set_value(st->sample_gpio, 0);
+
 	ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, &value);
 	if (ret < 0)
 		goto error_ret;
-	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0);
-	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1);
+
+	gpiod_set_value(st->sample_gpio, 1);
+	gpiod_set_value(st->sample_gpio, 0);
+
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -393,19 +384,19 @@ static int ad2s1210_single_conversion(struct ad2s1210_state *st,
 				      struct iio_chan_spec const *chan,
 				      int *val)
 {
-	int ret = 0;
+	int ret;
 
 	mutex_lock(&st->lock);
-	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0);
+	gpiod_set_value(st->sample_gpio, 1);
 	/* delay (6 * tck + 20) nano seconds */
 	udelay(1);
 
 	switch (chan->type) {
 	case IIO_ANGL:
-		ad2s1210_set_mode(MOD_POS, st);
+		ret = ad2s1210_set_mode(st, MOD_POS);
 		break;
 	case IIO_ANGL_VEL:
-		ad2s1210_set_mode(MOD_VEL, st);
+		ret = ad2s1210_set_mode(st, MOD_VEL);
 		break;
 	default:
 		ret = -EINVAL;
@@ -432,7 +423,7 @@ static int ad2s1210_single_conversion(struct ad2s1210_state *st,
 	}
 
 error_ret:
-	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1);
+	gpiod_set_value(st->sample_gpio, 0);
 	/* delay (2 * tck + 20) nano seconds */
 	udelay(1);
 	mutex_unlock(&st->lock);
@@ -546,7 +537,9 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
 	int ret;
 
 	mutex_lock(&st->lock);
-	ad2s1210_set_resolution_pin(st);
+	ret = ad2s1210_set_resolution_gpios(st, st->resolution);
+	if (ret < 0)
+		return ret;
 
 	/* Use default config register value plus resolution from devicetree. */
 	data = FIELD_PREP(AD2S1210_PHASE_LOCK_RANGE_44, 1);
@@ -612,20 +605,34 @@ static int ad2s1210_setup_clocks(struct ad2s1210_state *st)
 
 static int ad2s1210_setup_gpios(struct ad2s1210_state *st)
 {
-	struct spi_device *spi = st->sdev;
-	int i, ret;
-
-	for (i = 0; i < ARRAY_SIZE(gpios); i++) {
-		st->gpios[i] = devm_gpiod_get(&spi->dev, gpios[i].name,
-					      gpios[i].flags);
-		if (IS_ERR(st->gpios[i])) {
-			ret = PTR_ERR(st->gpios[i]);
-			dev_err(&spi->dev,
-				"ad2s1210: failed to request %s GPIO: %d\n",
-				gpios[i].name, ret);
-			return ret;
-		}
-	}
+	struct device *dev = &st->sdev->dev;
+
+	/* should not be sampling on startup */
+	st->sample_gpio = devm_gpiod_get(dev, "sample", GPIOD_OUT_LOW);
+	if (IS_ERR(st->sample_gpio))
+		return dev_err_probe(dev, PTR_ERR(st->sample_gpio),
+				     "failed to request sample GPIO\n");
+
+	/* both pins high means that we start in config mode */
+	st->mode_gpios = devm_gpiod_get_array(dev, "mode", GPIOD_OUT_HIGH);
+	if (IS_ERR(st->mode_gpios))
+		return dev_err_probe(dev, PTR_ERR(st->mode_gpios),
+				     "failed to request mode GPIOs\n");
+
+	if (st->mode_gpios->ndescs != 2)
+		return dev_err_probe(dev, -EINVAL,
+				     "requires exactly 2 mode-gpios\n");
+
+	/* both pins high means that we start with 16-bit resolution */
+	st->resolution_gpios = devm_gpiod_get_array(dev, "resolution",
+						    GPIOD_OUT_HIGH);
+	if (IS_ERR(st->resolution_gpios))
+		return dev_err_probe(dev, PTR_ERR(st->resolution_gpios),
+				     "failed to request resolution GPIOs\n");
+
+	if (st->resolution_gpios->ndescs != 2)
+		return dev_err_probe(dev, -EINVAL,
+				     "requires exactly 2 resolution-gpios\n");
 
 	return 0;
 }
@@ -690,7 +697,6 @@ static int ad2s1210_probe(struct spi_device *spi)
 	mutex_init(&st->lock);
 	st->sdev = spi;
 	st->hysteresis = true;
-	st->mode = MOD_CONFIG;
 	st->resolution = 12;
 	st->fexcit = AD2S1210_DEF_EXCIT;
 

-- 
2.42.0


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

* [PATCH v3 14/27] staging: iio: resolver: ad2s1210: implement hysteresis as channel attr
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (12 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 13/27] staging: iio: resolver: ad2s1210: rework gpios David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-29 17:53   ` David Lechner
  2023-09-30 15:03   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 15/27] staging: iio: resolver: ad2s1210: refactor setting excitation frequency David Lechner
                   ` (14 subsequent siblings)
  28 siblings, 2 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

The AD2S1210 resolver has a hysteresis feature that can be used to
prevent flicker in the LSB of the position register. This can be either
enabled or disabled. Disabling hysteresis is useful for increasing
precision by oversampling.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* Refactored into more functions to reduce complexity of switch statements.
* Use early return instead of break in switch statements.

 drivers/staging/iio/resolver/ad2s1210.c | 86 +++++++++++++++++++++++++++++++--
 1 file changed, 83 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 0ec3598b600a..a82cb124a12f 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -78,7 +78,6 @@ struct ad2s1210_state {
 	/** The external oscillator frequency in Hz. */
 	unsigned long clkin_hz;
 	unsigned int fexcit;
-	bool hysteresis;
 	u8 resolution;
 	/** For reading raw sample value via SPI. */
 	__be16 sample __aligned(IIO_DMA_MINALIGN);
@@ -430,6 +429,35 @@ static int ad2s1210_single_conversion(struct ad2s1210_state *st,
 	return ret;
 }
 
+static int ad2s1210_get_hysteresis(struct ad2s1210_state *st, int *val)
+{
+	int ret;
+
+	mutex_lock(&st->lock);
+	ret = regmap_test_bits(st->regmap, AD2S1210_REG_CONTROL,
+			       AD2S1210_ENABLE_HYSTERESIS);
+	mutex_unlock(&st->lock);
+
+	if (ret < 0)
+		return ret;
+
+	*val = !!ret;
+	return IIO_VAL_INT;
+}
+
+static int ad2s1210_set_hysteresis(struct ad2s1210_state *st, int val)
+{
+	int ret;
+
+	mutex_lock(&st->lock);
+	ret = regmap_update_bits(st->regmap, AD2S1210_REG_CONTROL,
+				 AD2S1210_ENABLE_HYSTERESIS,
+				 val ? AD2S1210_ENABLE_HYSTERESIS : 0);
+	mutex_unlock(&st->lock);
+
+	return ret;
+}
+
 static const int ad2s1210_velocity_scale[] = {
 	17089132, /* 8.192MHz / (2*pi * 2500 / 2^15) */
 	42722830, /* 8.192MHz / (2*pi * 1000 / 2^15) */
@@ -462,7 +490,55 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
 		default:
 			return -EINVAL;
 		}
+	case IIO_CHAN_INFO_HYSTERESIS:
+		switch (chan->type) {
+		case IIO_ANGL:
+			return ad2s1210_get_hysteresis(st, val);
+		default:
+			return -EINVAL;
+		}
+	default:
+		return -EINVAL;
+	}
+}
+
+static int ad2s1210_read_avail(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       const int **vals, int *type,
+			       int *length, long mask)
+{
+	static const int hysteresis_available[] = { 0, 1 };
+
+	switch (mask) {
+	case IIO_CHAN_INFO_HYSTERESIS:
+		switch (chan->type) {
+		case IIO_ANGL:
+			*vals = hysteresis_available;
+			*type = IIO_VAL_INT;
+			*length = ARRAY_SIZE(hysteresis_available);
+			return IIO_AVAIL_LIST;
+		default:
+			return -EINVAL;
+		}
+	default:
+		return -EINVAL;
+	}
+}
 
+static int ad2s1210_write_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int val, int val2, long mask)
+{
+	struct ad2s1210_state *st = iio_priv(indio_dev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_HYSTERESIS:
+		switch (chan->type) {
+		case IIO_ANGL:
+			return ad2s1210_set_hysteresis(st, val);
+		default:
+			return -EINVAL;
+		}
 	default:
 		return -EINVAL;
 	}
@@ -503,7 +579,10 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 		.indexed = 1,
 		.channel = 0,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
-				      BIT(IIO_CHAN_INFO_SCALE),
+				      BIT(IIO_CHAN_INFO_SCALE) |
+				      BIT(IIO_CHAN_INFO_HYSTERESIS),
+		.info_mask_separate_available =
+					BIT(IIO_CHAN_INFO_HYSTERESIS),
 	}, {
 		.type = IIO_ANGL_VEL,
 		.indexed = 1,
@@ -581,6 +660,8 @@ static int ad2s1210_debugfs_reg_access(struct iio_dev *indio_dev,
 
 static const struct iio_info ad2s1210_info = {
 	.read_raw = ad2s1210_read_raw,
+	.read_avail = ad2s1210_read_avail,
+	.write_raw = ad2s1210_write_raw,
 	.attrs = &ad2s1210_attribute_group,
 	.debugfs_reg_access = &ad2s1210_debugfs_reg_access,
 };
@@ -696,7 +777,6 @@ static int ad2s1210_probe(struct spi_device *spi)
 
 	mutex_init(&st->lock);
 	st->sdev = spi;
-	st->hysteresis = true;
 	st->resolution = 12;
 	st->fexcit = AD2S1210_DEF_EXCIT;
 

-- 
2.42.0


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

* [PATCH v3 15/27] staging: iio: resolver: ad2s1210: refactor setting excitation frequency
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (13 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 14/27] staging: iio: resolver: ad2s1210: implement hysteresis as channel attr David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 15:06   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 16/27] staging: iio: resolver: ad2s1210: read excitation frequency from control register David Lechner
                   ` (13 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This combines the ad2s1210_update_frequency_control_word() and
ad2s1210_soft_reset() functions into a single function since they
both have to be called together. (The software reset does not reset
any configuration registers, it only updates the excitation output
and resets the tracking loop.)

Also clean up a few things while touching this:
- move AD2S1210_DEF_EXCIT macro with similar macros
- remove unnecessary dev_err() calls

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* Expanded comment on soft reset register write.
* Fixed multiline comment style.

 drivers/staging/iio/resolver/ad2s1210.c | 66 +++++++++++++++++----------------
 1 file changed, 34 insertions(+), 32 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index a82cb124a12f..28ab877e1bc0 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -51,12 +51,11 @@
 #define AD2S1210_MIN_CLKIN	6144000
 #define AD2S1210_MAX_CLKIN	10240000
 #define AD2S1210_MIN_EXCIT	2000
+#define AD2S1210_DEF_EXCIT	10000
 #define AD2S1210_MAX_EXCIT	20000
 #define AD2S1210_MIN_FCW	0x4
 #define AD2S1210_MAX_FCW	0x50
 
-#define AD2S1210_DEF_EXCIT	10000
-
 enum ad2s1210_mode {
 	MOD_POS = 0b00,
 	MOD_VEL = 0b01,
@@ -188,18 +187,32 @@ static int ad2s1210_regmap_reg_read(void *context, unsigned int reg,
 	return 0;
 }
 
-static inline
-int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st)
+/*
+ * Sets the excitation frequency and performs software reset.
+ *
+ * Must be called with lock held.
+ */
+static int ad2s1210_reinit_excitation_frequency(struct ad2s1210_state *st,
+						u16 fexcit)
 {
-	unsigned char fcw;
+	int ret;
+	u8 fcw;
 
-	fcw = (unsigned char)(st->fexcit * (1 << 15) / st->clkin_hz);
-	if (fcw < AD2S1210_MIN_FCW || fcw > AD2S1210_MAX_FCW) {
-		dev_err(&st->sdev->dev, "ad2s1210: FCW out of range\n");
+	fcw = fexcit * (1 << 15) / st->clkin_hz;
+	if (fcw < AD2S1210_MIN_FCW || fcw > AD2S1210_MAX_FCW)
 		return -ERANGE;
-	}
 
-	return regmap_write(st->regmap, AD2S1210_REG_EXCIT_FREQ, fcw);
+	ret = regmap_write(st->regmap, AD2S1210_REG_EXCIT_FREQ, fcw);
+	if (ret < 0)
+		return ret;
+
+	st->fexcit = fexcit;
+
+	/*
+	 * Software reset reinitializes the excitation frequency output.
+	 * It does not reset any of the configuration registers.
+	 */
+	return regmap_write(st->regmap, AD2S1210_REG_SOFT_RESET, 0);
 }
 
 static int ad2s1210_set_resolution_gpios(struct ad2s1210_state *st,
@@ -214,11 +227,6 @@ static int ad2s1210_set_resolution_gpios(struct ad2s1210_state *st,
 				     bitmap);
 }
 
-static inline int ad2s1210_soft_reset(struct ad2s1210_state *st)
-{
-	return regmap_write(st->regmap, AD2S1210_REG_SOFT_RESET, 0);
-}
-
 static ssize_t ad2s1210_show_fexcit(struct device *dev,
 				    struct device_attribute *attr,
 				    char *buf)
@@ -233,27 +241,24 @@ static ssize_t ad2s1210_store_fexcit(struct device *dev,
 				     const char *buf, size_t len)
 {
 	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-	unsigned int fexcit;
+	u16 fexcit;
 	int ret;
 
-	ret = kstrtouint(buf, 10, &fexcit);
-	if (ret < 0)
-		return ret;
-	if (fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT) {
-		dev_err(dev,
-			"ad2s1210: excitation frequency out of range\n");
+	ret = kstrtou16(buf, 10, &fexcit);
+	if (ret < 0 || fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT)
 		return -EINVAL;
-	}
+
 	mutex_lock(&st->lock);
-	st->fexcit = fexcit;
-	ret = ad2s1210_update_frequency_control_word(st);
+	ret = ad2s1210_reinit_excitation_frequency(st, fexcit);
 	if (ret < 0)
 		goto error_ret;
-	ret = ad2s1210_soft_reset(st);
+
+	ret = len;
+
 error_ret:
 	mutex_unlock(&st->lock);
 
-	return ret < 0 ? ret : len;
+	return ret;
 }
 
 static ssize_t ad2s1210_show_resolution(struct device *dev,
@@ -630,10 +635,8 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
 	if (ret < 0)
 		goto error_ret;
 
-	ret = ad2s1210_update_frequency_control_word(st);
-	if (ret < 0)
-		goto error_ret;
-	ret = ad2s1210_soft_reset(st);
+	ret = ad2s1210_reinit_excitation_frequency(st, AD2S1210_DEF_EXCIT);
+
 error_ret:
 	mutex_unlock(&st->lock);
 	return ret;
@@ -778,7 +781,6 @@ static int ad2s1210_probe(struct spi_device *spi)
 	mutex_init(&st->lock);
 	st->sdev = spi;
 	st->resolution = 12;
-	st->fexcit = AD2S1210_DEF_EXCIT;
 
 	ret = ad2s1210_setup_clocks(st);
 	if (ret < 0)

-- 
2.42.0


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

* [PATCH v3 16/27] staging: iio: resolver: ad2s1210: read excitation frequency from control register
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (14 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 15/27] staging: iio: resolver: ad2s1210: refactor setting excitation frequency David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 15:08   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 17/27] staging: iio: resolver: ad2s1210: convert fexcit to channel attribute David Lechner
                   ` (12 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This modifies the ad2s1210_show_fexcit() function to read the excitation
frequency from the control register. This way we don't have to keep
track of the value and don't risk returning a stale value.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes: None

 drivers/staging/iio/resolver/ad2s1210.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 28ab877e1bc0..b15d71b17266 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -76,7 +76,6 @@ struct ad2s1210_state {
 	struct regmap *regmap;
 	/** The external oscillator frequency in Hz. */
 	unsigned long clkin_hz;
-	unsigned int fexcit;
 	u8 resolution;
 	/** For reading raw sample value via SPI. */
 	__be16 sample __aligned(IIO_DMA_MINALIGN);
@@ -206,8 +205,6 @@ static int ad2s1210_reinit_excitation_frequency(struct ad2s1210_state *st,
 	if (ret < 0)
 		return ret;
 
-	st->fexcit = fexcit;
-
 	/*
 	 * Software reset reinitializes the excitation frequency output.
 	 * It does not reset any of the configuration registers.
@@ -232,8 +229,22 @@ static ssize_t ad2s1210_show_fexcit(struct device *dev,
 				    char *buf)
 {
 	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
+	unsigned int value;
+	u16 fexcit;
+	int ret;
 
-	return sprintf(buf, "%u\n", st->fexcit);
+	mutex_lock(&st->lock);
+	ret = regmap_read(st->regmap, AD2S1210_REG_EXCIT_FREQ, &value);
+	if (ret < 0)
+		goto error_ret;
+
+	fexcit = value * st->clkin_hz / (1 << 15);
+
+	ret = sprintf(buf, "%u\n", fexcit);
+
+error_ret:
+	mutex_unlock(&st->lock);
+	return ret;
 }
 
 static ssize_t ad2s1210_store_fexcit(struct device *dev,

-- 
2.42.0


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

* [PATCH v3 17/27] staging: iio: resolver: ad2s1210: convert fexcit to channel attribute
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (15 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 16/27] staging: iio: resolver: ad2s1210: read excitation frequency from control register David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 15:12   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 18/27] staging: iio: resolver: ad2s1210: convert resolution to devicetree property David Lechner
                   ` (11 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

The ad2s1210 driver has a device-specific attribute `fexcit` for setting
the frequency of the excitation output. This converts it to a channel in
order to use standard IIO ABI.

The excitation frequency is an analog output that generates a sine wave.
Only the frequency is configurable. According to the datasheet, the
specified range of the excitation frequency is from 2 kHz to 20 kHz and
can be set in increments of 250 Hz.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* This is a new patch in v3 instead of "iio: resolver: ad2s1210: rename fexcit
  attribute"

 drivers/staging/iio/resolver/ad2s1210.c | 122 ++++++++++++++++++--------------
 1 file changed, 70 insertions(+), 52 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index b15d71b17266..6accb9e3db46 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -224,54 +224,6 @@ static int ad2s1210_set_resolution_gpios(struct ad2s1210_state *st,
 				     bitmap);
 }
 
-static ssize_t ad2s1210_show_fexcit(struct device *dev,
-				    struct device_attribute *attr,
-				    char *buf)
-{
-	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-	unsigned int value;
-	u16 fexcit;
-	int ret;
-
-	mutex_lock(&st->lock);
-	ret = regmap_read(st->regmap, AD2S1210_REG_EXCIT_FREQ, &value);
-	if (ret < 0)
-		goto error_ret;
-
-	fexcit = value * st->clkin_hz / (1 << 15);
-
-	ret = sprintf(buf, "%u\n", fexcit);
-
-error_ret:
-	mutex_unlock(&st->lock);
-	return ret;
-}
-
-static ssize_t ad2s1210_store_fexcit(struct device *dev,
-				     struct device_attribute *attr,
-				     const char *buf, size_t len)
-{
-	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-	u16 fexcit;
-	int ret;
-
-	ret = kstrtou16(buf, 10, &fexcit);
-	if (ret < 0 || fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT)
-		return -EINVAL;
-
-	mutex_lock(&st->lock);
-	ret = ad2s1210_reinit_excitation_frequency(st, fexcit);
-	if (ret < 0)
-		goto error_ret;
-
-	ret = len;
-
-error_ret:
-	mutex_unlock(&st->lock);
-
-	return ret;
-}
-
 static ssize_t ad2s1210_show_resolution(struct device *dev,
 					struct device_attribute *attr,
 					char *buf)
@@ -474,6 +426,38 @@ static int ad2s1210_set_hysteresis(struct ad2s1210_state *st, int val)
 	return ret;
 }
 
+static int ad2s1210_get_excitation_frequency(struct ad2s1210_state *st, int *val)
+{
+	unsigned int reg_val;
+	int ret;
+
+	mutex_lock(&st->lock);
+	ret = regmap_read(st->regmap, AD2S1210_REG_EXCIT_FREQ, &reg_val);
+	if (ret < 0)
+		goto error_ret;
+
+	*val = reg_val * st->clkin_hz / (1 << 15);
+	ret = IIO_VAL_INT;
+
+error_ret:
+	mutex_unlock(&st->lock);
+	return ret;
+}
+
+static int ad2s1210_set_excitation_frequency(struct ad2s1210_state *st, int val)
+{
+	int ret;
+
+	if (val < AD2S1210_MIN_EXCIT || val > AD2S1210_MAX_EXCIT)
+		return -EINVAL;
+
+	mutex_lock(&st->lock);
+	ret = ad2s1210_reinit_excitation_frequency(st, val);
+	mutex_unlock(&st->lock);
+
+	return ret;
+}
+
 static const int ad2s1210_velocity_scale[] = {
 	17089132, /* 8.192MHz / (2*pi * 2500 / 2^15) */
 	42722830, /* 8.192MHz / (2*pi * 1000 / 2^15) */
@@ -506,6 +490,13 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
 		default:
 			return -EINVAL;
 		}
+	case IIO_CHAN_INFO_FREQUENCY:
+		switch (chan->type) {
+		case IIO_ALTVOLTAGE:
+			return ad2s1210_get_excitation_frequency(st, val);
+		default:
+			return -EINVAL;
+		}
 	case IIO_CHAN_INFO_HYSTERESIS:
 		switch (chan->type) {
 		case IIO_ANGL:
@@ -523,9 +514,23 @@ static int ad2s1210_read_avail(struct iio_dev *indio_dev,
 			       const int **vals, int *type,
 			       int *length, long mask)
 {
+	static const int excitation_frequency_available[] = {
+		AD2S1210_MIN_EXCIT,
+		250, /* step */
+		AD2S1210_MAX_EXCIT,
+	};
 	static const int hysteresis_available[] = { 0, 1 };
 
 	switch (mask) {
+	case IIO_CHAN_INFO_FREQUENCY:
+		switch (chan->type) {
+		case IIO_ALTVOLTAGE:
+			*type = IIO_VAL_INT;
+			*vals = excitation_frequency_available;
+			return IIO_AVAIL_RANGE;
+		default:
+			return -EINVAL;
+		}
 	case IIO_CHAN_INFO_HYSTERESIS:
 		switch (chan->type) {
 		case IIO_ANGL:
@@ -548,6 +553,13 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
 	struct ad2s1210_state *st = iio_priv(indio_dev);
 
 	switch (mask) {
+	case IIO_CHAN_INFO_FREQUENCY:
+		switch (chan->type) {
+		case IIO_ALTVOLTAGE:
+			return ad2s1210_set_excitation_frequency(st, val);
+		default:
+			return -EINVAL;
+		}
 	case IIO_CHAN_INFO_HYSTERESIS:
 		switch (chan->type) {
 		case IIO_ANGL:
@@ -560,8 +572,6 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
 	}
 }
 
-static IIO_DEVICE_ATTR(fexcit, 0644,
-		       ad2s1210_show_fexcit,	ad2s1210_store_fexcit, 0);
 static IIO_DEVICE_ATTR(bits, 0644,
 		       ad2s1210_show_resolution, ad2s1210_store_resolution, 0);
 static IIO_DEVICE_ATTR(fault, 0644,
@@ -605,11 +615,19 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 		.channel = 0,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 				      BIT(IIO_CHAN_INFO_SCALE),
-	}
+	}, {
+		/* excitation frequency output */
+		.type = IIO_ALTVOLTAGE,
+		.indexed = 1,
+		.channel = 0,
+		.output = 1,
+		.scan_index = -1,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_FREQUENCY),
+		.info_mask_separate_available = BIT(IIO_CHAN_INFO_FREQUENCY),
+	},
 };
 
 static struct attribute *ad2s1210_attributes[] = {
-	&iio_dev_attr_fexcit.dev_attr.attr,
 	&iio_dev_attr_bits.dev_attr.attr,
 	&iio_dev_attr_fault.dev_attr.attr,
 	&iio_dev_attr_los_thrd.dev_attr.attr,

-- 
2.42.0


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

* [PATCH v3 18/27] staging: iio: resolver: ad2s1210: convert resolution to devicetree property
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (16 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 17/27] staging: iio: resolver: ad2s1210: convert fexcit to channel attribute David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 15:15   ` Jonathan Cameron
  2023-09-29 17:23 ` [PATCH v3 19/27] staging: iio: resolver: ad2s1210: add phase lock range support David Lechner
                   ` (10 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

Selecting the resolution was implemented as the `bits` sysfs attribute.
However, the selection of the resolution depends on how the hardware
is wired and the specific application, so this is rather a job for
devicetree to describe.

A new devicetree property `adi,resolution` to specify the resolution
required for each chip is added and the `bits` sysfs attribute is
removed.

Since the resolution is now supplied by a devicetree property, the
resolution-gpios are now optional and we can allow for the case where
the resolution pins on the AD2S1210 are hard-wired instead of requiring
them to be connected to gpios.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* Fixed multiline comment style.

 drivers/staging/iio/resolver/ad2s1210.c | 136 ++++++++++++++------------------
 1 file changed, 61 insertions(+), 75 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 6accb9e3db46..a0a426d0af19 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -63,6 +63,13 @@ enum ad2s1210_mode {
 	MOD_CONFIG = 0b11,
 };
 
+enum ad2s1210_resolution {
+	AD2S1210_RES_10 = 0b00,
+	AD2S1210_RES_12 = 0b01,
+	AD2S1210_RES_14 = 0b10,
+	AD2S1210_RES_16 = 0b11,
+};
+
 struct ad2s1210_state {
 	struct mutex lock;
 	struct spi_device *sdev;
@@ -70,13 +77,12 @@ struct ad2s1210_state {
 	struct gpio_desc *sample_gpio;
 	/** GPIO pins connected to A0 and A1 lines. */
 	struct gpio_descs *mode_gpios;
-	/** GPIO pins connected to RES0 and RES1 lines. */
-	struct gpio_descs *resolution_gpios;
 	/** Used to access config registers. */
 	struct regmap *regmap;
 	/** The external oscillator frequency in Hz. */
 	unsigned long clkin_hz;
-	u8 resolution;
+	/** The selected resolution */
+	enum ad2s1210_resolution resolution;
 	/** For reading raw sample value via SPI. */
 	__be16 sample __aligned(IIO_DMA_MINALIGN);
 	/** SPI transmit buffer. */
@@ -212,62 +218,6 @@ static int ad2s1210_reinit_excitation_frequency(struct ad2s1210_state *st,
 	return regmap_write(st->regmap, AD2S1210_REG_SOFT_RESET, 0);
 }
 
-static int ad2s1210_set_resolution_gpios(struct ad2s1210_state *st,
-					 u8 resolution)
-{
-	struct gpio_descs *gpios = st->resolution_gpios;
-	DECLARE_BITMAP(bitmap, 2);
-
-	bitmap[0] = (resolution - 10) >> 1;
-
-	return gpiod_set_array_value(gpios->ndescs, gpios->desc, gpios->info,
-				     bitmap);
-}
-
-static ssize_t ad2s1210_show_resolution(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
-{
-	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-
-	return sprintf(buf, "%d\n", st->resolution);
-}
-
-static ssize_t ad2s1210_store_resolution(struct device *dev,
-					 struct device_attribute *attr,
-					 const char *buf, size_t len)
-{
-	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-	unsigned char data;
-	unsigned char udata;
-	int ret;
-
-	ret = kstrtou8(buf, 10, &udata);
-	if (ret || udata < 10 || udata > 16) {
-		dev_err(dev, "ad2s1210: resolution out of range\n");
-		return -EINVAL;
-	}
-
-	data = (udata - 10) >> 1;
-
-	mutex_lock(&st->lock);
-	ret = regmap_update_bits(st->regmap, AD2S1210_REG_CONTROL,
-				 AD2S1210_SET_RES, data);
-	if (ret < 0)
-		goto error_ret;
-
-	ret = ad2s1210_set_resolution_gpios(st, udata);
-	if (ret < 0)
-		goto error_ret;
-
-	st->resolution = udata;
-	ret = len;
-
-error_ret:
-	mutex_unlock(&st->lock);
-	return ret;
-}
-
 /* read the fault register since last sample */
 static ssize_t ad2s1210_show_fault(struct device *dev,
 				   struct device_attribute *attr, char *buf)
@@ -572,8 +522,6 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
 	}
 }
 
-static IIO_DEVICE_ATTR(bits, 0644,
-		       ad2s1210_show_resolution, ad2s1210_store_resolution, 0);
 static IIO_DEVICE_ATTR(fault, 0644,
 		       ad2s1210_show_fault, ad2s1210_clear_fault, 0);
 
@@ -628,7 +576,6 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 };
 
 static struct attribute *ad2s1210_attributes[] = {
-	&iio_dev_attr_bits.dev_attr.attr,
 	&iio_dev_attr_fault.dev_attr.attr,
 	&iio_dev_attr_los_thrd.dev_attr.attr,
 	&iio_dev_attr_dos_ovr_thrd.dev_attr.attr,
@@ -650,15 +597,12 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
 	int ret;
 
 	mutex_lock(&st->lock);
-	ret = ad2s1210_set_resolution_gpios(st, st->resolution);
-	if (ret < 0)
-		return ret;
 
 	/* Use default config register value plus resolution from devicetree. */
 	data = FIELD_PREP(AD2S1210_PHASE_LOCK_RANGE_44, 1);
 	data |= FIELD_PREP(AD2S1210_ENABLE_HYSTERESIS, 1);
 	data |= FIELD_PREP(AD2S1210_SET_ENRES, 0x3);
-	data |= FIELD_PREP(AD2S1210_SET_RES, (st->resolution - 10) >> 1);
+	data |= FIELD_PREP(AD2S1210_SET_RES, st->resolution);
 
 	ret = regmap_write(st->regmap, AD2S1210_REG_CONTROL, data);
 	if (ret < 0)
@@ -698,6 +642,26 @@ static const struct iio_info ad2s1210_info = {
 	.debugfs_reg_access = &ad2s1210_debugfs_reg_access,
 };
 
+static int ad2s1210_setup_properties(struct ad2s1210_state *st)
+{
+	struct device *dev = &st->sdev->dev;
+	u32 val;
+	int ret;
+
+	ret = device_property_read_u32(dev, "assigned-resolution-bits", &val);
+	if (ret < 0)
+		return dev_err_probe(dev, ret,
+			"failed to read assigned-resolution-bits property\n");
+
+	if (val < 10 || val > 16)
+		return dev_err_probe(dev, -EINVAL,
+				     "resolution out of range: %u\n", val);
+
+	st->resolution = (val - 10) >> 1;
+
+	return 0;
+}
+
 static int ad2s1210_setup_clocks(struct ad2s1210_state *st)
 {
 	struct device *dev = &st->sdev->dev;
@@ -719,6 +683,9 @@ static int ad2s1210_setup_clocks(struct ad2s1210_state *st)
 static int ad2s1210_setup_gpios(struct ad2s1210_state *st)
 {
 	struct device *dev = &st->sdev->dev;
+	struct gpio_descs *resolution_gpios;
+	DECLARE_BITMAP(bitmap, 2);
+	int ret;
 
 	/* should not be sampling on startup */
 	st->sample_gpio = devm_gpiod_get(dev, "sample", GPIOD_OUT_LOW);
@@ -736,16 +703,32 @@ static int ad2s1210_setup_gpios(struct ad2s1210_state *st)
 		return dev_err_probe(dev, -EINVAL,
 				     "requires exactly 2 mode-gpios\n");
 
-	/* both pins high means that we start with 16-bit resolution */
-	st->resolution_gpios = devm_gpiod_get_array(dev, "resolution",
-						    GPIOD_OUT_HIGH);
-	if (IS_ERR(st->resolution_gpios))
-		return dev_err_probe(dev, PTR_ERR(st->resolution_gpios),
+	/*
+	 * If resolution gpios are provided, they get set to the required
+	 * resolution, otherwise it is assumed the RES0 and RES1 pins are
+	 * hard-wired to match the resolution indicated in the devicetree.
+	 */
+	resolution_gpios = devm_gpiod_get_array_optional(dev, "resolution",
+							 GPIOD_ASIS);
+	if (IS_ERR(resolution_gpios))
+		return dev_err_probe(dev, PTR_ERR(resolution_gpios),
 				     "failed to request resolution GPIOs\n");
 
-	if (st->resolution_gpios->ndescs != 2)
-		return dev_err_probe(dev, -EINVAL,
-				     "requires exactly 2 resolution-gpios\n");
+	if (resolution_gpios) {
+		if (resolution_gpios->ndescs != 2)
+			return dev_err_probe(dev, -EINVAL,
+				      "requires exactly 2 resolution-gpios\n");
+
+		bitmap[0] = st->resolution;
+
+		ret = gpiod_set_array_value(resolution_gpios->ndescs,
+					    resolution_gpios->desc,
+					    resolution_gpios->info,
+					    bitmap);
+		if (ret < 0)
+			return dev_err_probe(dev, ret,
+					     "failed to set resolution gpios\n");
+	}
 
 	return 0;
 }
@@ -809,7 +792,10 @@ static int ad2s1210_probe(struct spi_device *spi)
 
 	mutex_init(&st->lock);
 	st->sdev = spi;
-	st->resolution = 12;
+
+	ret = ad2s1210_setup_properties(st);
+	if (ret < 0)
+		return ret;
 
 	ret = ad2s1210_setup_clocks(st);
 	if (ret < 0)

-- 
2.42.0


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

* [PATCH v3 19/27] staging: iio: resolver: ad2s1210: add phase lock range support
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (17 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 18/27] staging: iio: resolver: ad2s1210: convert resolution to devicetree property David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 15:18   ` Jonathan Cameron
  2023-10-03  8:03   ` kernel test robot
  2023-09-29 17:23 ` [PATCH v3 20/27] staging: iio: resolver: ad2s1210: add triggered buffer support David Lechner
                   ` (9 subsequent siblings)
  28 siblings, 2 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

The AD2S1210 chip has a phase lock range feature that allows selecting
the allowable phase difference between the excitation output and the
sine and cosine inputs. This can be set to either 44 degrees (default)
or 360 degrees.

This patch adds a new phase channel with a threshold event that can be
used to configure the phase lock range. Actually emitting the event
will be added in a subsequent patch.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* This is a new patch to replace "staging: iio: resolver: ad2s1210: add
 phase_lock_range attributes"

 drivers/staging/iio/resolver/ad2s1210.c | 125 ++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index a0a426d0af19..bafc134eed97 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -56,6 +56,13 @@
 #define AD2S1210_MIN_FCW	0x4
 #define AD2S1210_MAX_FCW	0x50
 
+/* 44 degrees ~= 0.767945 radians */
+#define PHASE_44_DEG_TO_RAD_INT 0
+#define PHASE_44_DEG_TO_RAD_MICRO 767945
+/* 360 degrees ~= 6.283185 radians */
+#define PHASE_360_DEG_TO_RAD_INT 6
+#define PHASE_360_DEG_TO_RAD_MICRO 283185
+
 enum ad2s1210_mode {
 	MOD_POS = 0b00,
 	MOD_VEL = 0b01,
@@ -376,6 +383,54 @@ static int ad2s1210_set_hysteresis(struct ad2s1210_state *st, int val)
 	return ret;
 }
 
+static int ad2s1210_get_phase_lock_range(struct ad2s1210_state *st,
+					 int *val, int *val2)
+{
+	int ret;
+
+	mutex_lock(&st->lock);
+	ret = regmap_test_bits(st->regmap, AD2S1210_REG_CONTROL,
+			       AD2S1210_PHASE_LOCK_RANGE_44);
+	mutex_unlock(&st->lock);
+
+	if (ret < 0)
+		return ret;
+
+	if (ret) {
+		/* 44 degrees as radians */
+		*val = PHASE_44_DEG_TO_RAD_INT;
+		*val2 = PHASE_44_DEG_TO_RAD_MICRO;
+	} else {
+		/* 360 degrees as radians */
+		*val = PHASE_360_DEG_TO_RAD_INT;
+		*val2 = PHASE_360_DEG_TO_RAD_MICRO;
+	}
+
+	return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int ad2s1210_set_phase_lock_range(struct ad2s1210_state *st,
+					 int val, int val2)
+{
+	int deg, ret;
+
+	/* convert radians to degrees - only two allowable values */
+	if (val == PHASE_44_DEG_TO_RAD_INT && val2 == PHASE_44_DEG_TO_RAD_MICRO)
+		deg = 44;
+	else if (val == PHASE_360_DEG_TO_RAD_INT &&
+		 val2 == PHASE_360_DEG_TO_RAD_MICRO)
+		deg = 360;
+	else
+		return -EINVAL;
+
+	mutex_lock(&st->lock);
+	ret = regmap_update_bits(st->regmap, AD2S1210_REG_CONTROL,
+				 AD2S1210_PHASE_LOCK_RANGE_44,
+				 deg == 44 ? AD2S1210_PHASE_LOCK_RANGE_44 : 0);
+	mutex_unlock(&st->lock);
+	return ret;
+}
+
 static int ad2s1210_get_excitation_frequency(struct ad2s1210_state *st, int *val)
 {
 	unsigned int reg_val;
@@ -547,6 +602,16 @@ static IIO_DEVICE_ATTR(lot_low_thrd, 0644,
 		       ad2s1210_show_reg, ad2s1210_store_reg,
 		       AD2S1210_REG_LOT_LOW_THRD);
 
+static const struct iio_event_spec ad2s1210_phase_event_spec[] = {
+	{
+		/* Phase error fault. */
+		.type = IIO_EV_TYPE_MAG,
+		.dir = IIO_EV_DIR_NONE,
+		/* Phase lock range. */
+		.mask_separate = BIT(IIO_EV_INFO_VALUE),
+	},
+};
+
 static const struct iio_chan_spec ad2s1210_channels[] = {
 	{
 		.type = IIO_ANGL,
@@ -563,6 +628,14 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 		.channel = 0,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 				      BIT(IIO_CHAN_INFO_SCALE),
+	}, {
+		/* used to configure phase lock range and get phase lock error */
+		.type = IIO_PHASE,
+		.indexed = 1,
+		.channel = 0,
+		.scan_index = -1,
+		.event_spec = ad2s1210_phase_event_spec,
+		.num_event_specs = ARRAY_SIZE(ad2s1210_phase_event_spec),
 	}, {
 		/* excitation frequency output */
 		.type = IIO_ALTVOLTAGE,
@@ -591,6 +664,21 @@ static const struct attribute_group ad2s1210_attribute_group = {
 	.attrs = ad2s1210_attributes,
 };
 
+IIO_CONST_ATTR(in_phase0_mag_value_available,
+	       __stringify(PHASE_44_DEG_TO_RAD_INT) "."
+	       __stringify(PHASE_44_DEG_TO_RAD_MICRO) " "
+	       __stringify(PHASE_360_DEG_TO_RAD_INT) "."
+	       __stringify(PHASE_360_DEG_TO_RAD_MICRO));
+
+static struct attribute *ad2s1210_event_attributes[] = {
+	&iio_const_attr_in_phase0_mag_value_available.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad2s1210_event_attribute_group = {
+	.attrs = ad2s1210_event_attributes,
+};
+
 static int ad2s1210_initial(struct ad2s1210_state *st)
 {
 	unsigned char data;
@@ -615,6 +703,40 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
 	return ret;
 }
 
+static int ad2s1210_read_event_value(struct iio_dev *indio_dev,
+				     const struct iio_chan_spec *chan,
+				     enum iio_event_type type,
+				     enum iio_event_direction dir,
+				     enum iio_event_info info,
+				     int *val, int *val2)
+{
+	struct ad2s1210_state *st = iio_priv(indio_dev);
+
+	switch (chan->type) {
+	case IIO_PHASE:
+		return ad2s1210_get_phase_lock_range(st, val, val2);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int ad2s1210_write_event_value(struct iio_dev *indio_dev,
+				      const struct iio_chan_spec *chan,
+				      enum iio_event_type type,
+				      enum iio_event_direction dir,
+				      enum iio_event_info info,
+				      int val, int val2)
+{
+	struct ad2s1210_state *st = iio_priv(indio_dev);
+
+	switch (chan->type) {
+	case IIO_PHASE:
+		return ad2s1210_set_phase_lock_range(st, val, val2);
+	default:
+		return -EINVAL;
+	}
+}
+
 static int ad2s1210_debugfs_reg_access(struct iio_dev *indio_dev,
 				       unsigned int reg, unsigned int writeval,
 				       unsigned int *readval)
@@ -635,10 +757,13 @@ static int ad2s1210_debugfs_reg_access(struct iio_dev *indio_dev,
 }
 
 static const struct iio_info ad2s1210_info = {
+	.event_attrs = &ad2s1210_event_attribute_group,
 	.read_raw = ad2s1210_read_raw,
 	.read_avail = ad2s1210_read_avail,
 	.write_raw = ad2s1210_write_raw,
 	.attrs = &ad2s1210_attribute_group,
+	.read_event_value = ad2s1210_read_event_value,
+	.write_event_value = ad2s1210_write_event_value,
 	.debugfs_reg_access = &ad2s1210_debugfs_reg_access,
 };
 

-- 
2.42.0


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

* [PATCH v3 20/27] staging: iio: resolver: ad2s1210: add triggered buffer support
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (18 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 19/27] staging: iio: resolver: ad2s1210: add phase lock range support David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-29 17:23 ` [PATCH v3 21/27] staging: iio: resolver: ad2s1210: convert LOT threshold attrs to event attrs David Lechner
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

This adds support for triggered buffers to the AD2S1210 resolver driver.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes:
* Dropped setting datasheet_name of channels.

 drivers/staging/iio/resolver/ad2s1210.c | 83 ++++++++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index bafc134eed97..c0bc9eac18e8 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -20,8 +20,11 @@
 #include <linux/sysfs.h>
 #include <linux/types.h>
 
+#include <linux/iio/buffer.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
 
 #define DRV_NAME "ad2s1210"
 
@@ -92,6 +95,12 @@ struct ad2s1210_state {
 	enum ad2s1210_resolution resolution;
 	/** For reading raw sample value via SPI. */
 	__be16 sample __aligned(IIO_DMA_MINALIGN);
+	/** Scan buffer */
+	struct {
+		__be16 chan[2];
+		/* Ensure timestamp is naturally aligned. */
+		s64 timestamp __aligned(8);
+	} scan;
 	/** SPI transmit buffer. */
 	u8 rx[2];
 	/** SPI receive buffer. */
@@ -617,6 +626,13 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 		.type = IIO_ANGL,
 		.indexed = 1,
 		.channel = 0,
+		.scan_index = 0,
+		.scan_type = {
+			.sign = 'u',
+			.realbits = 16,
+			.storagebits = 16,
+			.endianness = IIO_BE,
+		},
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 				      BIT(IIO_CHAN_INFO_SCALE) |
 				      BIT(IIO_CHAN_INFO_HYSTERESIS),
@@ -626,9 +642,18 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 		.type = IIO_ANGL_VEL,
 		.indexed = 1,
 		.channel = 0,
+		.scan_index = 1,
+		.scan_type = {
+			.sign = 's',
+			.realbits = 16,
+			.storagebits = 16,
+			.endianness = IIO_BE,
+		},
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 				      BIT(IIO_CHAN_INFO_SCALE),
-	}, {
+	},
+	IIO_CHAN_SOFT_TIMESTAMP(2),
+	{
 		/* used to configure phase lock range and get phase lock error */
 		.type = IIO_PHASE,
 		.indexed = 1,
@@ -756,6 +781,55 @@ static int ad2s1210_debugfs_reg_access(struct iio_dev *indio_dev,
 	return ret;
 }
 
+static irqreturn_t ad2s1210_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct ad2s1210_state *st = iio_priv(indio_dev);
+	size_t chan = 0;
+	int ret;
+
+	mutex_lock(&st->lock);
+
+	memset(&st->scan, 0, sizeof(st->scan));
+	gpiod_set_value(st->sample_gpio, 1);
+
+	if (test_bit(0, indio_dev->active_scan_mask)) {
+		ret = ad2s1210_set_mode(st, MOD_POS);
+		if (ret < 0)
+			goto error_ret;
+
+		/* REVIST: we can read 3 bytes here and also get fault flags */
+		ret = spi_read(st->sdev, st->rx, 2);
+		if (ret < 0)
+			goto error_ret;
+
+		memcpy(&st->scan.chan[chan++], st->rx, 2);
+	}
+
+	if (test_bit(1, indio_dev->active_scan_mask)) {
+		ret = ad2s1210_set_mode(st, MOD_VEL);
+		if (ret < 0)
+			goto error_ret;
+
+		/* REVIST: we can read 3 bytes here and also get fault flags */
+		ret = spi_read(st->sdev, st->rx, 2);
+		if (ret < 0)
+			goto error_ret;
+
+		memcpy(&st->scan.chan[chan++], st->rx, 2);
+	}
+
+	iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, pf->timestamp);
+
+error_ret:
+	gpiod_set_value(st->sample_gpio, 0);
+	mutex_unlock(&st->lock);
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
 static const struct iio_info ad2s1210_info = {
 	.event_attrs = &ad2s1210_event_attribute_group,
 	.read_raw = ad2s1210_read_raw,
@@ -944,6 +1018,13 @@ static int ad2s1210_probe(struct spi_device *spi)
 	indio_dev->num_channels = ARRAY_SIZE(ad2s1210_channels);
 	indio_dev->name = spi_get_device_id(spi)->name;
 
+	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
+					      &iio_pollfunc_store_time,
+					      &ad2s1210_trigger_handler, NULL);
+	if (ret < 0)
+		return dev_err_probe(&spi->dev, ret,
+				     "iio triggered buffer setup failed\n");
+
 	return devm_iio_device_register(&spi->dev, indio_dev);
 }
 

-- 
2.42.0


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

* [PATCH v3 21/27] staging: iio: resolver: ad2s1210: convert LOT threshold attrs to event attrs
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (19 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 20/27] staging: iio: resolver: ad2s1210: add triggered buffer support David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 15:29   ` Jonathan Cameron
  2023-10-03 11:11   ` kernel test robot
  2023-09-29 17:23 ` [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr David Lechner
                   ` (7 subsequent siblings)
  28 siblings, 2 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

The AD2S1210 monitors the internal error signal (difference between
estimated angle and measured angle) to determine a loss of position
tracking (LOT) condition. When the error value exceeds a threshold, a
fault is triggered. This threshold is user-configurable.

This patch converts the custom lot_high_thrd and lot_low_thrd attributes
in the ad2s1210 driver to standard event attributes. This will allow
tooling to be able to expose these in a generic way.

Since the low threshold determines the hysteresis, it requires some
special handling to expose the difference between the high and low
register values as the hysteresis instead of exposing the low register
value directly.

The attributes also return the values in radians now as required by the
ABI.

Actually emitting the fault event will be done in a later patch.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes: This is a new patch in v3

 drivers/staging/iio/resolver/ad2s1210.c | 191 ++++++++++++++++++++++++++++++--
 1 file changed, 183 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index c0bc9eac18e8..5cc8106800d6 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -440,6 +440,123 @@ static int ad2s1210_set_phase_lock_range(struct ad2s1210_state *st,
 	return ret;
 }
 
+/* map resolution to microradians/LSB for LOT registers */
+static const int ad2s1210_lot_threshold_urad_per_lsb[] = {
+	6184, /* 10-bit: ~0.35 deg/LSB, 45 deg max */
+	2473, /* 12-bit: ~0.14 deg/LSB, 18 deg max */
+	1237, /* 14-bit: ~0.07 deg/LSB, 9 deg max */
+	1237, /* 16-bit: same as 14-bit */
+};
+
+static int ad2s1210_get_lot_high_threshold(struct ad2s1210_state *st,
+					   int *val, int *val2)
+{
+	unsigned int reg_val;
+	int ret;
+
+	mutex_lock(&st->lock);
+	ret = regmap_read(st->regmap, AD2S1210_REG_LOT_HIGH_THRD, &reg_val);
+	mutex_unlock(&st->lock);
+
+	if (ret < 0)
+		return ret;
+
+	*val = 0;
+	*val2 = reg_val * ad2s1210_lot_threshold_urad_per_lsb[st->resolution];
+	return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int ad2s1210_set_lot_high_threshold(struct ad2s1210_state *st,
+					   int val, int val2)
+{
+	unsigned int high_reg_val, low_reg_val, hysteresis;
+	int ret;
+
+	/* all valid values are between 0 and pi/4 radians */
+	if (val != 0)
+		return -EINVAL;
+
+	mutex_lock(&st->lock);
+	/*
+	 * We need to read both high and low registers first so we can preserve
+	 * the hysteresis.
+	 */
+	ret = regmap_read(st->regmap, AD2S1210_REG_LOT_HIGH_THRD, &high_reg_val);
+	if (ret < 0)
+		goto error_ret;
+
+	ret = regmap_read(st->regmap, AD2S1210_REG_LOT_LOW_THRD, &low_reg_val);
+	if (ret < 0)
+		goto error_ret;
+
+	hysteresis = high_reg_val - low_reg_val;
+	high_reg_val = val2 / ad2s1210_lot_threshold_urad_per_lsb[st->resolution];
+	low_reg_val = high_reg_val - hysteresis;
+
+	ret = regmap_write(st->regmap, AD2S1210_REG_LOT_HIGH_THRD, high_reg_val);
+	if (ret < 0)
+		goto error_ret;
+
+	ret = regmap_write(st->regmap, AD2S1210_REG_LOT_LOW_THRD, low_reg_val);
+
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret;
+}
+
+static int ad2s1210_get_lot_low_threshold(struct ad2s1210_state *st,
+					  int *val, int *val2)
+{
+	unsigned int high_reg_val, low_reg_val;
+	int ret;
+
+	mutex_lock(&st->lock);
+	ret = regmap_read(st->regmap, AD2S1210_REG_LOT_HIGH_THRD, &high_reg_val);
+	if (ret < 0)
+		goto error_ret;
+
+	ret = regmap_read(st->regmap, AD2S1210_REG_LOT_LOW_THRD, &low_reg_val);
+
+error_ret:
+	mutex_unlock(&st->lock);
+
+	if (ret < 0)
+		return ret;
+
+	/* sysfs value is hysteresis rather than actual low value */
+	*val = 0;
+	*val2 = (high_reg_val - low_reg_val) *
+		ad2s1210_lot_threshold_urad_per_lsb[st->resolution];
+	return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int ad2s1210_set_lot_low_threshold(struct ad2s1210_state *st,
+					  int val, int val2)
+{
+	unsigned int reg_val, hysteresis;
+	int ret;
+
+	/* all valid values are between 0 and pi/4 radians */
+	if (val != 0)
+		return -EINVAL;
+
+	hysteresis = val2 / ad2s1210_lot_threshold_urad_per_lsb[st->resolution];
+
+	mutex_lock(&st->lock);
+	ret = regmap_read(st->regmap, AD2S1210_REG_LOT_HIGH_THRD, &reg_val);
+	if (ret < 0)
+		goto error_ret;
+
+	ret = regmap_write(st->regmap, AD2S1210_REG_LOT_LOW_THRD,
+			   reg_val - hysteresis);
+
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret;
+}
+
 static int ad2s1210_get_excitation_frequency(struct ad2s1210_state *st, int *val)
 {
 	unsigned int reg_val;
@@ -604,12 +721,19 @@ static IIO_DEVICE_ATTR(dos_rst_max_thrd, 0644,
 static IIO_DEVICE_ATTR(dos_rst_min_thrd, 0644,
 		       ad2s1210_show_reg, ad2s1210_store_reg,
 		       AD2S1210_REG_DOS_RST_MIN_THRD);
-static IIO_DEVICE_ATTR(lot_high_thrd, 0644,
-		       ad2s1210_show_reg, ad2s1210_store_reg,
-		       AD2S1210_REG_LOT_HIGH_THRD);
-static IIO_DEVICE_ATTR(lot_low_thrd, 0644,
-		       ad2s1210_show_reg, ad2s1210_store_reg,
-		       AD2S1210_REG_LOT_LOW_THRD);
+
+static const struct iio_event_spec ad2s1210_position_event_spec[] = {
+	{
+		/* Tracking error exceeds LOT threshold fault. */
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_RISING,
+		.mask_separate =
+			/* Loss of tracking high threshold. */
+			BIT(IIO_EV_INFO_VALUE) |
+			/* Loss of tracking low threshold. */
+			BIT(IIO_EV_INFO_HYSTERESIS),
+	},
+};
 
 static const struct iio_event_spec ad2s1210_phase_event_spec[] = {
 	{
@@ -653,6 +777,15 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 				      BIT(IIO_CHAN_INFO_SCALE),
 	},
 	IIO_CHAN_SOFT_TIMESTAMP(2),
+	{
+		/* used to configure LOT thresholds and get tracking error */
+		.type = IIO_ANGL,
+		.indexed = 1,
+		.channel = 1,
+		.scan_index = -1,
+		.event_spec = ad2s1210_position_event_spec,
+		.num_event_specs = ARRAY_SIZE(ad2s1210_position_event_spec),
+	},
 	{
 		/* used to configure phase lock range and get phase lock error */
 		.type = IIO_PHASE,
@@ -680,8 +813,6 @@ static struct attribute *ad2s1210_attributes[] = {
 	&iio_dev_attr_dos_mis_thrd.dev_attr.attr,
 	&iio_dev_attr_dos_rst_max_thrd.dev_attr.attr,
 	&iio_dev_attr_dos_rst_min_thrd.dev_attr.attr,
-	&iio_dev_attr_lot_high_thrd.dev_attr.attr,
-	&iio_dev_attr_lot_low_thrd.dev_attr.attr,
 	NULL,
 };
 
@@ -689,14 +820,40 @@ static const struct attribute_group ad2s1210_attribute_group = {
 	.attrs = ad2s1210_attributes,
 };
 
+static ssize_t
+in_angl1_thresh_rising_value_available_show(struct device *dev,
+					    struct device_attribute *attr,
+					    char *buf)
+{
+	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
+	int step = ad2s1210_lot_threshold_urad_per_lsb[st->resolution];
+
+	return sysfs_emit(buf, "[0 0.%06d 0.%06d]\n", step, step * 0x7F);
+}
+
+static ssize_t
+in_angl1_thresh_rising_hysteresis_available_show(struct device *dev,
+						 struct device_attribute *attr,
+						 char *buf)
+{
+	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
+	int step = ad2s1210_lot_threshold_urad_per_lsb[st->resolution];
+
+	return sysfs_emit(buf, "[0 0.%06d 0.%06d]\n", step, step * 0x7F);
+}
+
 IIO_CONST_ATTR(in_phase0_mag_value_available,
 	       __stringify(PHASE_44_DEG_TO_RAD_INT) "."
 	       __stringify(PHASE_44_DEG_TO_RAD_MICRO) " "
 	       __stringify(PHASE_360_DEG_TO_RAD_INT) "."
 	       __stringify(PHASE_360_DEG_TO_RAD_MICRO));
+IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_value_available, 0);
+IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_hysteresis_available, 0);
 
 static struct attribute *ad2s1210_event_attributes[] = {
 	&iio_const_attr_in_phase0_mag_value_available.dev_attr.attr,
+	&iio_dev_attr_in_angl1_thresh_rising_value_available.dev_attr.attr,
+	&iio_dev_attr_in_angl1_thresh_rising_hysteresis_available.dev_attr.attr,
 	NULL,
 };
 
@@ -738,6 +895,15 @@ static int ad2s1210_read_event_value(struct iio_dev *indio_dev,
 	struct ad2s1210_state *st = iio_priv(indio_dev);
 
 	switch (chan->type) {
+	case IIO_ANGL:
+		switch (info) {
+		case IIO_EV_INFO_VALUE:
+			return ad2s1210_get_lot_high_threshold(st, val, val2);
+		case IIO_EV_INFO_HYSTERESIS:
+			return ad2s1210_get_lot_low_threshold(st, val, val2);
+		default:
+			return -EINVAL;
+		}
 	case IIO_PHASE:
 		return ad2s1210_get_phase_lock_range(st, val, val2);
 	default:
@@ -755,6 +921,15 @@ static int ad2s1210_write_event_value(struct iio_dev *indio_dev,
 	struct ad2s1210_state *st = iio_priv(indio_dev);
 
 	switch (chan->type) {
+	case IIO_ANGL:
+		switch (info) {
+		case IIO_EV_INFO_VALUE:
+			return ad2s1210_set_lot_high_threshold(st, val, val2);
+		case IIO_EV_INFO_HYSTERESIS:
+			return ad2s1210_set_lot_low_threshold(st, val, val2);
+		default:
+			return -EINVAL;
+		}
 	case IIO_PHASE:
 		return ad2s1210_set_phase_lock_range(st, val, val2);
 	default:

-- 
2.42.0


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

* [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (20 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 21/27] staging: iio: resolver: ad2s1210: convert LOT threshold attrs to event attrs David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 15:32   ` Jonathan Cameron
                     ` (2 more replies)
  2023-09-29 17:23 ` [PATCH v3 23/27] staging: iio: resolver: ad2s1210: convert DOS overrange " David Lechner
                   ` (6 subsequent siblings)
  28 siblings, 3 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

The AD2S1210 has a programmable threshold for the loss of signal (LOS)
fault. This fault is triggered when either the sine or cosine input
falls below the threshold voltage.

This patch converts the custom device LOS threshold attribute to an
event falling edge threshold attribute on a new monitor signal channel.
The monitor signal is an internal signal that combines the amplitudes
of the sine and cosine inputs as well as the current angle and position
output. This signal is used to detect faults in the input signals.

The attribute now uses millivolts instead of the raw register value in
accordance with the IIO ABI.

Emitting the event will be implemented in a later patch.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes: This is a new patch in v3

 drivers/staging/iio/resolver/ad2s1210.c | 75 +++++++++++++++++++++++++++++++--
 1 file changed, 71 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 5cc8106800d6..7abbc184c351 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -66,6 +66,11 @@
 #define PHASE_360_DEG_TO_RAD_INT 6
 #define PHASE_360_DEG_TO_RAD_MICRO 283185
 
+/* Threshold voltage registers have 1 LSB == 38 mV */
+#define THRESHOLD_MILLIVOLT_PER_LSB 38
+/* max voltage for threshold registers is 0x7F * 38 mV */
+#define THRESHOLD_RANGE_STR "[0 38 4826]"
+
 enum ad2s1210_mode {
 	MOD_POS = 0b00,
 	MOD_VEL = 0b01,
@@ -448,6 +453,38 @@ static const int ad2s1210_lot_threshold_urad_per_lsb[] = {
 	1237, /* 16-bit: same as 14-bit */
 };
 
+static int ad2s1210_get_voltage_threshold(struct ad2s1210_state *st,
+					  unsigned int reg, int *val)
+{
+	unsigned int reg_val;
+	int ret;
+
+	mutex_lock(&st->lock);
+	ret = regmap_read(st->regmap, reg, &reg_val);
+	mutex_unlock(&st->lock);
+
+	if (ret < 0)
+		return ret;
+
+	*val = reg_val * THRESHOLD_MILLIVOLT_PER_LSB;
+	return IIO_VAL_INT;
+}
+
+static int ad2s1210_set_voltage_threshold(struct ad2s1210_state *st,
+					  unsigned int reg, int val)
+{
+	unsigned int reg_val;
+	int ret;
+
+	reg_val = val / THRESHOLD_MILLIVOLT_PER_LSB;
+
+	mutex_lock(&st->lock);
+	ret = regmap_write(st->regmap, reg, reg_val);
+	mutex_unlock(&st->lock);
+
+	return ret;
+}
+
 static int ad2s1210_get_lot_high_threshold(struct ad2s1210_state *st,
 					   int *val, int *val2)
 {
@@ -706,9 +743,6 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
 static IIO_DEVICE_ATTR(fault, 0644,
 		       ad2s1210_show_fault, ad2s1210_clear_fault, 0);
 
-static IIO_DEVICE_ATTR(los_thrd, 0644,
-		       ad2s1210_show_reg, ad2s1210_store_reg,
-		       AD2S1210_REG_LOS_THRD);
 static IIO_DEVICE_ATTR(dos_ovr_thrd, 0644,
 		       ad2s1210_show_reg, ad2s1210_store_reg,
 		       AD2S1210_REG_DOS_OVR_THRD);
@@ -745,6 +779,16 @@ static const struct iio_event_spec ad2s1210_phase_event_spec[] = {
 	},
 };
 
+static const struct iio_event_spec ad2s1210_monitor_signal_event_spec[] = {
+	{
+		/* Sine/cosine below LOS threshold fault. */
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_FALLING,
+		/* Loss of signal threshold. */
+		.mask_separate = BIT(IIO_EV_INFO_VALUE),
+	},
+};
+
 static const struct iio_chan_spec ad2s1210_channels[] = {
 	{
 		.type = IIO_ANGL,
@@ -803,12 +847,19 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 		.scan_index = -1,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_FREQUENCY),
 		.info_mask_separate_available = BIT(IIO_CHAN_INFO_FREQUENCY),
+	}, {
+		/* monitor signal */
+		.type = IIO_ALTVOLTAGE,
+		.indexed = 1,
+		.channel = 0,
+		.scan_index = -1,
+		.event_spec = ad2s1210_monitor_signal_event_spec,
+		.num_event_specs = ARRAY_SIZE(ad2s1210_monitor_signal_event_spec),
 	},
 };
 
 static struct attribute *ad2s1210_attributes[] = {
 	&iio_dev_attr_fault.dev_attr.attr,
-	&iio_dev_attr_los_thrd.dev_attr.attr,
 	&iio_dev_attr_dos_ovr_thrd.dev_attr.attr,
 	&iio_dev_attr_dos_mis_thrd.dev_attr.attr,
 	&iio_dev_attr_dos_rst_max_thrd.dev_attr.attr,
@@ -847,11 +898,13 @@ IIO_CONST_ATTR(in_phase0_mag_value_available,
 	       __stringify(PHASE_44_DEG_TO_RAD_MICRO) " "
 	       __stringify(PHASE_360_DEG_TO_RAD_INT) "."
 	       __stringify(PHASE_360_DEG_TO_RAD_MICRO));
+IIO_CONST_ATTR(in_altvoltage0_thresh_falling_value_available, THRESHOLD_RANGE_STR);
 IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_value_available, 0);
 IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_hysteresis_available, 0);
 
 static struct attribute *ad2s1210_event_attributes[] = {
 	&iio_const_attr_in_phase0_mag_value_available.dev_attr.attr,
+	&iio_const_attr_in_altvoltage0_thresh_falling_value_available.dev_attr.attr,
 	&iio_dev_attr_in_angl1_thresh_rising_value_available.dev_attr.attr,
 	&iio_dev_attr_in_angl1_thresh_rising_hysteresis_available.dev_attr.attr,
 	NULL,
@@ -904,6 +957,13 @@ static int ad2s1210_read_event_value(struct iio_dev *indio_dev,
 		default:
 			return -EINVAL;
 		}
+	case IIO_ALTVOLTAGE:
+		if (chan->output)
+			return -EINVAL;
+		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_FALLING)
+			return ad2s1210_get_voltage_threshold(st,
+						AD2S1210_REG_LOS_THRD, val);
+		return -EINVAL;
 	case IIO_PHASE:
 		return ad2s1210_get_phase_lock_range(st, val, val2);
 	default:
@@ -930,6 +990,13 @@ static int ad2s1210_write_event_value(struct iio_dev *indio_dev,
 		default:
 			return -EINVAL;
 		}
+	case IIO_ALTVOLTAGE:
+		if (chan->output)
+			return -EINVAL;
+		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_FALLING)
+			return ad2s1210_set_voltage_threshold(st,
+						AD2S1210_REG_LOS_THRD, val);
+		return -EINVAL;
 	case IIO_PHASE:
 		return ad2s1210_set_phase_lock_range(st, val, val2);
 	default:

-- 
2.42.0


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

* [PATCH v3 23/27] staging: iio: resolver: ad2s1210: convert DOS overrange threshold to event attr
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (21 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 15:33   ` Jonathan Cameron
  2023-10-03 17:21   ` kernel test robot
  2023-09-29 17:23 ` [PATCH v3 24/27] staging: iio: resolver: ad2s1210: convert DOS mismatch " David Lechner
                   ` (5 subsequent siblings)
  28 siblings, 2 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

The AD2S1210 has a programmable threshold for the degradation of signal
(DOS) overrange fault. This fault is triggered when either the sine or
cosine input rises the threshold voltage.

This patch converts the custom device DOS overrange threshold attribute
to an event rising edge threshold attribute on the monitor signal
channel.

The attribute now uses millivolts instead of the raw register value in
accordance with the IIO ABI.

Emitting the event will be implemented in a later patch.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes: This is a new patch in v3

 drivers/staging/iio/resolver/ad2s1210.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 7abbc184c351..66def9f1dd1b 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -743,9 +743,6 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
 static IIO_DEVICE_ATTR(fault, 0644,
 		       ad2s1210_show_fault, ad2s1210_clear_fault, 0);
 
-static IIO_DEVICE_ATTR(dos_ovr_thrd, 0644,
-		       ad2s1210_show_reg, ad2s1210_store_reg,
-		       AD2S1210_REG_DOS_OVR_THRD);
 static IIO_DEVICE_ATTR(dos_mis_thrd, 0644,
 		       ad2s1210_show_reg, ad2s1210_store_reg,
 		       AD2S1210_REG_DOS_MIS_THRD);
@@ -787,6 +784,13 @@ static const struct iio_event_spec ad2s1210_monitor_signal_event_spec[] = {
 		/* Loss of signal threshold. */
 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
 	},
+	{
+		/* Sine/cosine DOS overrange fault.*/
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_RISING,
+		/* Degredation of signal overrange threshold. */
+		.mask_separate = BIT(IIO_EV_INFO_VALUE),
+	},
 };
 
 static const struct iio_chan_spec ad2s1210_channels[] = {
@@ -860,7 +864,6 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 
 static struct attribute *ad2s1210_attributes[] = {
 	&iio_dev_attr_fault.dev_attr.attr,
-	&iio_dev_attr_dos_ovr_thrd.dev_attr.attr,
 	&iio_dev_attr_dos_mis_thrd.dev_attr.attr,
 	&iio_dev_attr_dos_rst_max_thrd.dev_attr.attr,
 	&iio_dev_attr_dos_rst_min_thrd.dev_attr.attr,
@@ -899,12 +902,14 @@ IIO_CONST_ATTR(in_phase0_mag_value_available,
 	       __stringify(PHASE_360_DEG_TO_RAD_INT) "."
 	       __stringify(PHASE_360_DEG_TO_RAD_MICRO));
 IIO_CONST_ATTR(in_altvoltage0_thresh_falling_value_available, THRESHOLD_RANGE_STR);
+IIO_CONST_ATTR(in_altvoltage0_thresh_rising_value_available, THRESHOLD_RANGE_STR);
 IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_value_available, 0);
 IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_hysteresis_available, 0);
 
 static struct attribute *ad2s1210_event_attributes[] = {
 	&iio_const_attr_in_phase0_mag_value_available.dev_attr.attr,
 	&iio_const_attr_in_altvoltage0_thresh_falling_value_available.dev_attr.attr,
+	&iio_const_attr_in_altvoltage0_thresh_rising_value_available.dev_attr.attr,
 	&iio_dev_attr_in_angl1_thresh_rising_value_available.dev_attr.attr,
 	&iio_dev_attr_in_angl1_thresh_rising_hysteresis_available.dev_attr.attr,
 	NULL,
@@ -963,6 +968,9 @@ static int ad2s1210_read_event_value(struct iio_dev *indio_dev,
 		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_FALLING)
 			return ad2s1210_get_voltage_threshold(st,
 						AD2S1210_REG_LOS_THRD, val);
+		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_RISING)
+			return ad2s1210_get_voltage_threshold(st,
+						AD2S1210_REG_DOS_OVR_THRD, val);
 		return -EINVAL;
 	case IIO_PHASE:
 		return ad2s1210_get_phase_lock_range(st, val, val2);
@@ -996,6 +1004,9 @@ static int ad2s1210_write_event_value(struct iio_dev *indio_dev,
 		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_FALLING)
 			return ad2s1210_set_voltage_threshold(st,
 						AD2S1210_REG_LOS_THRD, val);
+		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_RISING)
+			return ad2s1210_set_voltage_threshold(st,
+						AD2S1210_REG_DOS_OVR_THRD, val);
 		return -EINVAL;
 	case IIO_PHASE:
 		return ad2s1210_set_phase_lock_range(st, val, val2);

-- 
2.42.0


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

* [PATCH v3 24/27] staging: iio: resolver: ad2s1210: convert DOS mismatch threshold to event attr
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (22 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 23/27] staging: iio: resolver: ad2s1210: convert DOS overrange " David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-10-03 20:08   ` kernel test robot
  2023-09-29 17:23 ` [PATCH v3 25/27] staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs David Lechner
                   ` (4 subsequent siblings)
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

The AD2S1210 has a programmable threshold for the degradation of signal
(DOS) mismatch fault. This fault is triggered when the difference in
voltage between the sine and cosine inputs exceeds the threshold. In
other words, when the magnitude of sine and cosine inputs are equal,
the AC component of the monitor signal is zero and when the magnitudes
of the sine and cosine inputs are not equal, the AC component of the
monitor signal is the difference between the sine and cosine inputs.
So the fault occurs when the magnitude of the AC component of the
monitor signal exceeds the DOS mismatch threshold voltage.

This patch converts the custom device DOS mismatch threshold attribute
to an event magnitude attribute on the monitor signal channel.

The attribute now uses millivolts instead of the raw register value in
accordance with the IIO ABI.

Emitting the event will be implemented in a later patch.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes: This is a new patch in v3

 drivers/staging/iio/resolver/ad2s1210.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 66def9f1dd1b..aa14edbe8a77 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -743,9 +743,6 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
 static IIO_DEVICE_ATTR(fault, 0644,
 		       ad2s1210_show_fault, ad2s1210_clear_fault, 0);
 
-static IIO_DEVICE_ATTR(dos_mis_thrd, 0644,
-		       ad2s1210_show_reg, ad2s1210_store_reg,
-		       AD2S1210_REG_DOS_MIS_THRD);
 static IIO_DEVICE_ATTR(dos_rst_max_thrd, 0644,
 		       ad2s1210_show_reg, ad2s1210_store_reg,
 		       AD2S1210_REG_DOS_RST_MAX_THRD);
@@ -791,6 +788,12 @@ static const struct iio_event_spec ad2s1210_monitor_signal_event_spec[] = {
 		/* Degredation of signal overrange threshold. */
 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
 	},
+	{
+		/* Sine/cosine DOS mismatch fault.*/
+		.type = IIO_EV_TYPE_MAG,
+		.dir = IIO_EV_DIR_NONE,
+		.mask_separate = BIT(IIO_EV_INFO_VALUE),
+	},
 };
 
 static const struct iio_chan_spec ad2s1210_channels[] = {
@@ -864,7 +867,6 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 
 static struct attribute *ad2s1210_attributes[] = {
 	&iio_dev_attr_fault.dev_attr.attr,
-	&iio_dev_attr_dos_mis_thrd.dev_attr.attr,
 	&iio_dev_attr_dos_rst_max_thrd.dev_attr.attr,
 	&iio_dev_attr_dos_rst_min_thrd.dev_attr.attr,
 	NULL,
@@ -903,6 +905,7 @@ IIO_CONST_ATTR(in_phase0_mag_value_available,
 	       __stringify(PHASE_360_DEG_TO_RAD_MICRO));
 IIO_CONST_ATTR(in_altvoltage0_thresh_falling_value_available, THRESHOLD_RANGE_STR);
 IIO_CONST_ATTR(in_altvoltage0_thresh_rising_value_available, THRESHOLD_RANGE_STR);
+IIO_CONST_ATTR(in_altvoltage0_mag_value_available, THRESHOLD_RANGE_STR);
 IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_value_available, 0);
 IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_hysteresis_available, 0);
 
@@ -910,6 +913,7 @@ static struct attribute *ad2s1210_event_attributes[] = {
 	&iio_const_attr_in_phase0_mag_value_available.dev_attr.attr,
 	&iio_const_attr_in_altvoltage0_thresh_falling_value_available.dev_attr.attr,
 	&iio_const_attr_in_altvoltage0_thresh_rising_value_available.dev_attr.attr,
+	&iio_const_attr_in_altvoltage0_mag_value_available.dev_attr.attr,
 	&iio_dev_attr_in_angl1_thresh_rising_value_available.dev_attr.attr,
 	&iio_dev_attr_in_angl1_thresh_rising_hysteresis_available.dev_attr.attr,
 	NULL,
@@ -971,6 +975,9 @@ static int ad2s1210_read_event_value(struct iio_dev *indio_dev,
 		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_RISING)
 			return ad2s1210_get_voltage_threshold(st,
 						AD2S1210_REG_DOS_OVR_THRD, val);
+		if (type == IIO_EV_TYPE_MAG)
+			return ad2s1210_get_voltage_threshold(st,
+						AD2S1210_REG_DOS_MIS_THRD, val);
 		return -EINVAL;
 	case IIO_PHASE:
 		return ad2s1210_get_phase_lock_range(st, val, val2);
@@ -1007,6 +1014,9 @@ static int ad2s1210_write_event_value(struct iio_dev *indio_dev,
 		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_RISING)
 			return ad2s1210_set_voltage_threshold(st,
 						AD2S1210_REG_DOS_OVR_THRD, val);
+		if (type == IIO_EV_TYPE_MAG)
+			return ad2s1210_set_voltage_threshold(st,
+						AD2S1210_REG_DOS_MIS_THRD, val);
 		return -EINVAL;
 	case IIO_PHASE:
 		return ad2s1210_set_phase_lock_range(st, val, val2);

-- 
2.42.0


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

* [PATCH v3 25/27] staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (23 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 24/27] staging: iio: resolver: ad2s1210: convert DOS mismatch " David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30 15:47   ` Jonathan Cameron
  2023-10-03 23:23   ` kernel test robot
  2023-09-29 17:23 ` [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events David Lechner
                   ` (3 subsequent siblings)
  28 siblings, 2 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

The AD2S1210 has a programmable threshold for the degradation of signal
(DOS) mismatch fault. This fault is triggered when the difference in
amplitude between the sine and cosine inputs exceeds the threshold.

The DOS reset min/max registers on the chip provide initial values
for internal tracking of the min/max of the monitor signal after the
fault register is cleared.

This patch converts the custom device DOS reset min/max threshold
attributes custom event attributes on the monitor signal channel.

The attributes now use millivolts instead of the raw register value in
accordance with the IIO ABI.

Emitting the event will be implemented in a later patch.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes: This is a new patch in v3

 .../Documentation/sysfs-bus-iio-resolver-ad2s1210  | 27 ++++++
 drivers/staging/iio/resolver/ad2s1210.c            | 99 ++++++++++++----------
 2 files changed, 82 insertions(+), 44 deletions(-)

diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-resolver-ad2s1210 b/drivers/staging/iio/Documentation/sysfs-bus-iio-resolver-ad2s1210
new file mode 100644
index 000000000000..ea75881b0c77
--- /dev/null
+++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-resolver-ad2s1210
@@ -0,0 +1,27 @@
+What:		/sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_max
+KernelVersion:  6.7
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Reading returns the current Degradation of Signal Reset Maximum
+		Threshold value in millivolts. Writing sets the value.
+
+What:		/sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_max_available
+KernelVersion:  6.7
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Reading returns the allowable voltage range for
+		in_altvoltage0-altvoltage1_thresh_rising_reset_max.
+
+What:		/sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_min
+KernelVersion:  6.7
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Reading returns the current Degradation of Signal Reset Minimum
+		Threshold value in millivolts. Writing sets the value.
+
+What:		/sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_min_available
+KernelVersion:  6.7
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Reading returns the allowable voltage range for
+		in_altvoltage0-altvoltage1_thresh_rising_reset_min.
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index aa14edbe8a77..e1c95ec73545 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -283,41 +283,6 @@ static ssize_t ad2s1210_clear_fault(struct device *dev,
 	return ret < 0 ? ret : len;
 }
 
-static ssize_t ad2s1210_show_reg(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-	struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
-	unsigned int value;
-	int ret;
-
-	mutex_lock(&st->lock);
-	ret = regmap_read(st->regmap, iattr->address, &value);
-	mutex_unlock(&st->lock);
-
-	return ret < 0 ? ret : sprintf(buf, "%d\n", value);
-}
-
-static ssize_t ad2s1210_store_reg(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf, size_t len)
-{
-	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-	unsigned char data;
-	int ret;
-	struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
-
-	ret = kstrtou8(buf, 10, &data);
-	if (ret)
-		return -EINVAL;
-
-	mutex_lock(&st->lock);
-	ret = regmap_write(st->regmap, iattr->address, data);
-	mutex_unlock(&st->lock);
-	return ret < 0 ? ret : len;
-}
-
 static int ad2s1210_single_conversion(struct ad2s1210_state *st,
 				      struct iio_chan_spec const *chan,
 				      int *val)
@@ -743,13 +708,6 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
 static IIO_DEVICE_ATTR(fault, 0644,
 		       ad2s1210_show_fault, ad2s1210_clear_fault, 0);
 
-static IIO_DEVICE_ATTR(dos_rst_max_thrd, 0644,
-		       ad2s1210_show_reg, ad2s1210_store_reg,
-		       AD2S1210_REG_DOS_RST_MAX_THRD);
-static IIO_DEVICE_ATTR(dos_rst_min_thrd, 0644,
-		       ad2s1210_show_reg, ad2s1210_store_reg,
-		       AD2S1210_REG_DOS_RST_MIN_THRD);
-
 static const struct iio_event_spec ad2s1210_position_event_spec[] = {
 	{
 		/* Tracking error exceeds LOT threshold fault. */
@@ -867,8 +825,6 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 
 static struct attribute *ad2s1210_attributes[] = {
 	&iio_dev_attr_fault.dev_attr.attr,
-	&iio_dev_attr_dos_rst_max_thrd.dev_attr.attr,
-	&iio_dev_attr_dos_rst_min_thrd.dev_attr.attr,
 	NULL,
 };
 
@@ -876,6 +832,49 @@ static const struct attribute_group ad2s1210_attribute_group = {
 	.attrs = ad2s1210_attributes,
 };
 
+static ssize_t event_attr_voltage_reg_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
+	struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
+	unsigned int value;
+	int ret;
+
+	mutex_lock(&st->lock);
+	ret = regmap_read(st->regmap, iattr->address, &value);
+	mutex_unlock(&st->lock);
+
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n", value * THRESHOLD_MILLIVOLT_PER_LSB);
+}
+
+static ssize_t event_attr_voltage_reg_store(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf, size_t len)
+{
+	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
+	struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
+	u16 data;
+	int ret;
+
+	ret = kstrtou16(buf, 10, &data);
+	if (ret)
+		return -EINVAL;
+
+	mutex_lock(&st->lock);
+	ret = regmap_write(st->regmap, iattr->address,
+			   data / THRESHOLD_MILLIVOLT_PER_LSB);
+	mutex_unlock(&st->lock);
+
+	if (ret < 0)
+		return ret;
+
+	return len;
+}
+
 static ssize_t
 in_angl1_thresh_rising_value_available_show(struct device *dev,
 					    struct device_attribute *attr,
@@ -906,6 +905,14 @@ IIO_CONST_ATTR(in_phase0_mag_value_available,
 IIO_CONST_ATTR(in_altvoltage0_thresh_falling_value_available, THRESHOLD_RANGE_STR);
 IIO_CONST_ATTR(in_altvoltage0_thresh_rising_value_available, THRESHOLD_RANGE_STR);
 IIO_CONST_ATTR(in_altvoltage0_mag_value_available, THRESHOLD_RANGE_STR);
+IIO_DEVICE_ATTR(in_altvoltage0_mag_reset_max, 0644,
+		event_attr_voltage_reg_show, event_attr_voltage_reg_store,
+		AD2S1210_REG_DOS_RST_MAX_THRD);
+IIO_CONST_ATTR(in_altvoltage0_mag_reset_max_available, THRESHOLD_RANGE_STR);
+IIO_DEVICE_ATTR(in_altvoltage0_mag_reset_min, 0644,
+		event_attr_voltage_reg_show, event_attr_voltage_reg_store,
+		AD2S1210_REG_DOS_RST_MIN_THRD);
+IIO_CONST_ATTR(in_altvoltage0_mag_reset_min_available, THRESHOLD_RANGE_STR);
 IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_value_available, 0);
 IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_hysteresis_available, 0);
 
@@ -914,6 +921,10 @@ static struct attribute *ad2s1210_event_attributes[] = {
 	&iio_const_attr_in_altvoltage0_thresh_falling_value_available.dev_attr.attr,
 	&iio_const_attr_in_altvoltage0_thresh_rising_value_available.dev_attr.attr,
 	&iio_const_attr_in_altvoltage0_mag_value_available.dev_attr.attr,
+	&iio_dev_attr_in_altvoltage0_mag_reset_max.dev_attr.attr,
+	&iio_const_attr_in_altvoltage0_mag_reset_max_available.dev_attr.attr,
+	&iio_dev_attr_in_altvoltage0_mag_reset_min.dev_attr.attr,
+	&iio_const_attr_in_altvoltage0_mag_reset_min_available.dev_attr.attr,
 	&iio_dev_attr_in_angl1_thresh_rising_value_available.dev_attr.attr,
 	&iio_dev_attr_in_angl1_thresh_rising_hysteresis_available.dev_attr.attr,
 	NULL,

-- 
2.42.0


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

* [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (24 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 25/27] staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-30  3:55   ` kernel test robot
                     ` (2 more replies)
  2023-09-29 17:23 ` [PATCH v3 27/27] staging: iio: resolver: ad2s1210: add label attribute support David Lechner
                   ` (2 subsequent siblings)
  28 siblings, 3 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

When reading the position and velocity on the AD2S1210, there is also a
3rd byte following the two data bytes that contains the fault flag bits.
This patch adds support for reading this byte and generating events when
faults occur.

The faults are mapped to various channels and event types in order to
have a unique event for each fault.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes: This is a new patch in v3

 drivers/staging/iio/resolver/ad2s1210.c | 175 +++++++++++++++++++++++++++++---
 1 file changed, 161 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index e1c95ec73545..dc3cc3ab855e 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -21,6 +21,7 @@
 #include <linux/types.h>
 
 #include <linux/iio/buffer.h>
+#include <linux/iio/events.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/trigger_consumer.h>
@@ -35,6 +36,16 @@
 #define AD2S1210_SET_ENRES		GENMASK(3, 2)
 #define AD2S1210_SET_RES		GENMASK(1, 0)
 
+/* fault register flags */
+#define AD2S1210_FAULT_CLIP		BIT(7)
+#define AD2S1210_FAULT_LOS		BIT(6)
+#define AD2S1210_FAULT_DOS_OVR		BIT(5)
+#define AD2S1210_FAULT_DOS_MIS		BIT(4)
+#define AD2S1210_FAULT_LOT		BIT(3)
+#define AD2S1210_FAULT_VELOCITY		BIT(2)
+#define AD2S1210_FAULT_PHASE		BIT(1)
+#define AD2S1210_FAULT_CONFIG_PARITY	BIT(0)
+
 #define AD2S1210_REG_POSITION_MSB	0x80
 #define AD2S1210_REG_POSITION_LSB	0x81
 #define AD2S1210_REG_VELOCITY_MSB	0x82
@@ -71,6 +82,8 @@
 /* max voltage for threshold registers is 0x7F * 38 mV */
 #define THRESHOLD_RANGE_STR "[0 38 4826]"
 
+#define FAULT_ONESHOT(bit, new, old) (new & bit && !(old & bit))
+
 enum ad2s1210_mode {
 	MOD_POS = 0b00,
 	MOD_VEL = 0b01,
@@ -98,8 +111,13 @@ struct ad2s1210_state {
 	unsigned long clkin_hz;
 	/** The selected resolution */
 	enum ad2s1210_resolution resolution;
+	/** Copy of fault register from the previous read. */
+	u8 prev_fault_flags;
 	/** For reading raw sample value via SPI. */
-	__be16 sample __aligned(IIO_DMA_MINALIGN);
+	struct {
+		__be16 raw;
+		u8 fault;
+	} sample __aligned(IIO_DMA_MINALIGN);;
 	/** Scan buffer */
 	struct {
 		__be16 chan[2];
@@ -158,7 +176,15 @@ static int ad2s1210_regmap_reg_write(void *context, unsigned int reg,
 	if (ret < 0)
 		return ret;
 
-	return spi_sync_transfer(st->sdev, xfers, ARRAY_SIZE(xfers));
+	ret = spi_sync_transfer(st->sdev, xfers, ARRAY_SIZE(xfers));
+	if (ret < 0)
+		return ret;
+
+	/* soft reset also clears the fault register */
+	if (reg == AD2S1210_REG_SOFT_RESET)
+		st->prev_fault_flags = 0;
+
+	return 0;
 }
 
 /*
@@ -200,6 +226,10 @@ static int ad2s1210_regmap_reg_read(void *context, unsigned int reg,
 	if (ret < 0)
 		return ret;
 
+	/* reading the fault register also clears it */
+	if (reg == AD2S1210_REG_FAULT)
+		st->prev_fault_flags = 0;
+
 	/*
 	 * If the D7 bit is set on any read/write register, it indicates a
 	 * parity error. The fault register is read-only and the D7 bit means
@@ -283,14 +313,92 @@ static ssize_t ad2s1210_clear_fault(struct device *dev,
 	return ret < 0 ? ret : len;
 }
 
-static int ad2s1210_single_conversion(struct ad2s1210_state *st,
+static void ad2s1210_push_events(struct iio_dev *indio_dev,
+				 u8 flags, s64 timestamp)
+{
+	struct ad2s1210_state *st = iio_priv(indio_dev);
+
+	/* Sine/cosine inputs clipped */
+	if (FAULT_ONESHOT(AD2S1210_FAULT_CLIP, flags, st->prev_fault_flags))
+		iio_push_event(indio_dev,
+			       IIO_MOD_EVENT_CODE(IIO_ALTVOLTAGE, 1,
+			       			  IIO_MOD_X_OR_Y,
+						  IIO_EV_TYPE_MAG,
+						  IIO_EV_DIR_NONE),
+			       timestamp);
+
+	/* Sine/cosine inputs below LOS threshold */
+	if (FAULT_ONESHOT(AD2S1210_FAULT_LOS, flags, st->prev_fault_flags))
+		iio_push_event(indio_dev,
+			       IIO_UNMOD_EVENT_CODE(IIO_ALTVOLTAGE, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
+
+	/* Sine/cosine inputs exceed DOS overrange threshold */
+	if (FAULT_ONESHOT(AD2S1210_FAULT_DOS_OVR, flags, st->prev_fault_flags))
+		iio_push_event(indio_dev,
+			       IIO_UNMOD_EVENT_CODE(IIO_ALTVOLTAGE, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
+
+	/* Sine/cosine inputs exceed DOS mismatch threshold */
+	if (FAULT_ONESHOT(AD2S1210_FAULT_DOS_MIS, flags, st->prev_fault_flags))
+		iio_push_event(indio_dev,
+			       IIO_UNMOD_EVENT_CODE(IIO_ALTVOLTAGE, 0,
+						    IIO_EV_TYPE_MAG,
+						    IIO_EV_DIR_NONE),
+			       timestamp);
+
+	/* Tracking error exceeds LOT threshold */
+	if (FAULT_ONESHOT(AD2S1210_FAULT_LOT, flags, st->prev_fault_flags))
+		iio_push_event(indio_dev,
+			       IIO_UNMOD_EVENT_CODE(IIO_ANGL, 1,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
+
+	/* Velocity exceeds maximum tracking rate */
+	if (FAULT_ONESHOT(AD2S1210_FAULT_VELOCITY, flags, st->prev_fault_flags))
+		iio_push_event(indio_dev,
+			       IIO_UNMOD_EVENT_CODE(IIO_ANGL_VEL, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
+
+	/* Phase error exceeds phase lock range */
+	if (FAULT_ONESHOT(AD2S1210_FAULT_PHASE, flags, st->prev_fault_flags))
+		iio_push_event(indio_dev,
+			       IIO_UNMOD_EVENT_CODE(IIO_PHASE, 0,
+						    IIO_EV_TYPE_MAG,
+						    IIO_EV_DIR_NONE),
+			       timestamp);
+
+	/* Configuration parity error */
+	if (FAULT_ONESHOT(AD2S1210_FAULT_CONFIG_PARITY, flags,
+			  st->prev_fault_flags))
+		/*
+		 * Userspace should also get notified of this via error return
+		 * when trying to write to any attribute that writes a register.
+		 */
+		dev_err_ratelimited(&indio_dev->dev,
+				    "Configuration parity error\n");
+
+	st->prev_fault_flags = flags;
+}
+
+static int ad2s1210_single_conversion(struct iio_dev *indio_dev,
 				      struct iio_chan_spec const *chan,
 				      int *val)
 {
+	struct ad2s1210_state *st = iio_priv(indio_dev);
+	s64 timestamp;
 	int ret;
 
 	mutex_lock(&st->lock);
 	gpiod_set_value(st->sample_gpio, 1);
+	timestamp = iio_get_time_ns(indio_dev);
 	/* delay (6 * tck + 20) nano seconds */
 	udelay(1);
 
@@ -307,17 +415,17 @@ static int ad2s1210_single_conversion(struct ad2s1210_state *st,
 	}
 	if (ret < 0)
 		goto error_ret;
-	ret = spi_read(st->sdev, &st->sample, 2);
+	ret = spi_read(st->sdev, &st->sample, 3);
 	if (ret < 0)
 		goto error_ret;
 
 	switch (chan->type) {
 	case IIO_ANGL:
-		*val = be16_to_cpu(st->sample);
+		*val = be16_to_cpu(st->sample.raw);
 		ret = IIO_VAL_INT;
 		break;
 	case IIO_ANGL_VEL:
-		*val = (s16)be16_to_cpu(st->sample);
+		*val = (s16)be16_to_cpu(st->sample.raw);
 		ret = IIO_VAL_INT;
 		break;
 	default:
@@ -325,6 +433,8 @@ static int ad2s1210_single_conversion(struct ad2s1210_state *st,
 		break;
 	}
 
+	ad2s1210_push_events(indio_dev, st->rx[2], timestamp);
+
 error_ret:
 	gpiod_set_value(st->sample_gpio, 0);
 	/* delay (2 * tck + 20) nano seconds */
@@ -608,7 +718,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
-		return ad2s1210_single_conversion(st, chan, val);
+		return ad2s1210_single_conversion(indio_dev, chan, val);
 	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_ANGL:
@@ -721,6 +831,14 @@ static const struct iio_event_spec ad2s1210_position_event_spec[] = {
 	},
 };
 
+static const struct iio_event_spec ad2s1210_velocity_event_spec[] = {
+	{
+		/* Velocity exceeds maximum tracking rate fault. */
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_RISING,
+	},
+};
+
 static const struct iio_event_spec ad2s1210_phase_event_spec[] = {
 	{
 		/* Phase error fault. */
@@ -754,6 +872,14 @@ static const struct iio_event_spec ad2s1210_monitor_signal_event_spec[] = {
 	},
 };
 
+static const struct iio_event_spec ad2s1210_sin_cos_event_spec[] = {
+	{
+		/* Sine/cosine clipping fault. */
+		.type = IIO_EV_TYPE_MAG,
+		.dir = IIO_EV_DIR_NONE,
+	},
+};
+
 static const struct iio_chan_spec ad2s1210_channels[] = {
 	{
 		.type = IIO_ANGL,
@@ -784,6 +910,8 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 		},
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 				      BIT(IIO_CHAN_INFO_SCALE),
+		.event_spec = ad2s1210_velocity_event_spec,
+		.num_event_specs = ARRAY_SIZE(ad2s1210_velocity_event_spec),
 	},
 	IIO_CHAN_SOFT_TIMESTAMP(2),
 	{
@@ -820,6 +948,26 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
 		.scan_index = -1,
 		.event_spec = ad2s1210_monitor_signal_event_spec,
 		.num_event_specs = ARRAY_SIZE(ad2s1210_monitor_signal_event_spec),
+	}, {
+		/* sine input */
+		.type = IIO_ALTVOLTAGE,
+		.indexed = 1,
+		.channel = 1,
+		.modified = 1,
+		.channel2 = IIO_MOD_Y,
+		.scan_index = -1,
+		.event_spec = ad2s1210_sin_cos_event_spec,
+		.num_event_specs = ARRAY_SIZE(ad2s1210_sin_cos_event_spec),
+	}, {
+		/* cosine input */
+		.type = IIO_ALTVOLTAGE,
+		.indexed = 1,
+		.channel = 1,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.scan_index = -1,
+		.event_spec = ad2s1210_sin_cos_event_spec,
+		.num_event_specs = ARRAY_SIZE(ad2s1210_sin_cos_event_spec),
 	},
 };
 
@@ -936,7 +1084,7 @@ static const struct attribute_group ad2s1210_event_attribute_group = {
 
 static int ad2s1210_initial(struct ad2s1210_state *st)
 {
-	unsigned char data;
+	unsigned int data;
 	int ret;
 
 	mutex_lock(&st->lock);
@@ -1073,12 +1221,11 @@ static irqreturn_t ad2s1210_trigger_handler(int irq, void *p)
 		if (ret < 0)
 			goto error_ret;
 
-		/* REVIST: we can read 3 bytes here and also get fault flags */
-		ret = spi_read(st->sdev, st->rx, 2);
+		ret = spi_read(st->sdev, &st->sample, 3);
 		if (ret < 0)
 			goto error_ret;
 
-		memcpy(&st->scan.chan[chan++], st->rx, 2);
+		memcpy(&st->scan.chan[chan++], &st->sample.raw, 2);
 	}
 
 	if (test_bit(1, indio_dev->active_scan_mask)) {
@@ -1086,14 +1233,14 @@ static irqreturn_t ad2s1210_trigger_handler(int irq, void *p)
 		if (ret < 0)
 			goto error_ret;
 
-		/* REVIST: we can read 3 bytes here and also get fault flags */
-		ret = spi_read(st->sdev, st->rx, 2);
+		ret = spi_read(st->sdev, &st->sample, 3);
 		if (ret < 0)
 			goto error_ret;
 
-		memcpy(&st->scan.chan[chan++], st->rx, 2);
+		memcpy(&st->scan.chan[chan++], &st->sample.raw, 2);
 	}
 
+	ad2s1210_push_events(indio_dev, st->sample.fault, pf->timestamp);
 	iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, pf->timestamp);
 
 error_ret:

-- 
2.42.0


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

* [PATCH v3 27/27] staging: iio: resolver: ad2s1210: add label attribute support
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (25 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events David Lechner
@ 2023-09-29 17:23 ` David Lechner
  2023-09-29 17:49 ` [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
  2023-09-29 22:02 ` David Lechner
  28 siblings, 0 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:23 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, David Lechner

From: David Lechner <david@lechnology.com>

From: David Lechner <dlechner@baylibre.com>

The ad2s1210 resolver driver has quite a few channels, mostly for
internal signals for event support. This makes it difficult to know
which channel is which. This patch adds a label attribute to the
channels to make it easier to identify them.

Signed-off-by: David Lechner <dlechner@baylibre.com>
---

v3 changes: This is a new patch in v3

 drivers/staging/iio/resolver/ad2s1210.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index dc3cc3ab855e..a187fa07d315 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -1106,6 +1106,34 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
 	return ret;
 }
 
+static int ad2s1210_read_label(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       char *label)
+{
+	if (chan->type == IIO_ANGL) {
+		if (chan->channel == 0)
+			return sprintf(label, "position\n");
+		if (chan->channel == 1)
+			return sprintf(label, "tracking error\n");
+	}
+	if (chan->type == IIO_ANGL_VEL)
+		return sprintf(label, "velocity\n");
+	if (chan->type == IIO_PHASE)
+		return sprintf(label, "synthetic reference\n");
+	if (chan->type == IIO_ALTVOLTAGE) {
+		if (chan->output)
+			return sprintf(label, "excitation\n");
+		if (chan->channel == 0)
+			return sprintf(label, "monitor signal\n");
+		if (chan->channel == 1 && chan->channel2 == IIO_MOD_X)
+			return sprintf(label, "cosine\n");
+		if (chan->channel == 1 && chan->channel2 == IIO_MOD_Y)
+			return sprintf(label, "sine\n");
+	}
+
+	return -EINVAL;
+}
+
 static int ad2s1210_read_event_value(struct iio_dev *indio_dev,
 				     const struct iio_chan_spec *chan,
 				     enum iio_event_type type,
@@ -1256,6 +1284,7 @@ static const struct iio_info ad2s1210_info = {
 	.read_raw = ad2s1210_read_raw,
 	.read_avail = ad2s1210_read_avail,
 	.write_raw = ad2s1210_write_raw,
+	.read_label = ad2s1210_read_label,
 	.attrs = &ad2s1210_attribute_group,
 	.read_event_value = ad2s1210_read_event_value,
 	.write_event_value = ad2s1210_write_event_value,

-- 
2.42.0


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

* Re: [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (26 preceding siblings ...)
  2023-09-29 17:23 ` [PATCH v3 27/27] staging: iio: resolver: ad2s1210: add label attribute support David Lechner
@ 2023-09-29 17:49 ` David Lechner
  2023-09-30 14:26   ` Jonathan Cameron
  2023-09-29 22:02 ` David Lechner
  28 siblings, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:49 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, Apelete Seketeli

On Fri, Sep 29, 2023 at 12:25 PM David Lechner <dlechner@baylibre.com> wrote:
>
> From: David Lechner <david@lechnology.com>
>

Ugh, an automated tool picked up my personal email on this for some
reason. This extra From: line can be dropped from any patches that get
picked up on this round. I will make sure to double-check next time.

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

* Re: [PATCH v3 14/27] staging: iio: resolver: ad2s1210: implement hysteresis as channel attr
  2023-09-29 17:23 ` [PATCH v3 14/27] staging: iio: resolver: ad2s1210: implement hysteresis as channel attr David Lechner
@ 2023-09-29 17:53   ` David Lechner
  2023-09-30 15:00     ` Jonathan Cameron
  2023-09-30 15:03   ` Jonathan Cameron
  1 sibling, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-09-29 17:53 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel

On Fri, Sep 29, 2023 at 12:25 PM David Lechner <dlechner@baylibre.com> wrote:
>
> The AD2S1210 resolver has a hysteresis feature that can be used to
> prevent flicker in the LSB of the position register. This can be either
> enabled or disabled. Disabling hysteresis is useful for increasing
> precision by oversampling.
>
> Signed-off-by: David Lechner <dlechner@baylibre.com>
> ---

...

> +static int ad2s1210_read_avail(struct iio_dev *indio_dev,
> +                              struct iio_chan_spec const *chan,
> +                              const int **vals, int *type,
> +                              int *length, long mask)
> +{
> +       static const int hysteresis_available[] = { 0, 1 };

This is basically an enable/disable. Should the 1 value be changed to the
appropriate radians value since this is hysteresis on the position
(angle) channel?

> +
> +       switch (mask) {
> +       case IIO_CHAN_INFO_HYSTERESIS:
> +               switch (chan->type) {
> +               case IIO_ANGL:
> +                       *vals = hysteresis_available;
> +                       *type = IIO_VAL_INT;
> +                       *length = ARRAY_SIZE(hysteresis_available);
> +                       return IIO_AVAIL_LIST;
> +               default:
> +                       return -EINVAL;
> +               }
> +       default:
> +               return -EINVAL;
> +       }
> +}
>

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

* Re: [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging
  2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
                   ` (27 preceding siblings ...)
  2023-09-29 17:49 ` [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
@ 2023-09-29 22:02 ` David Lechner
  28 siblings, 0 replies; 88+ messages in thread
From: David Lechner @ 2023-09-29 22:02 UTC (permalink / raw)
  To: linux-iio, devicetree, linux-staging
  Cc: David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, Apelete Seketeli

On 9/29/23 12:23 PM, David Lechner wrote:
> From: David Lechner <david@lechnology.com>
> 
> v3 changes:
> 
> * Added description of A0/A1 lines in DT bindings.
> * Added power supply regulators to DT bindings.
> * Dropped "staging: iio: Documentation: document IIO resolver AD2S1210
>    sysfs attributes" (these attributes are being removed instead).
> * Dropped applied patches:
>    * "staging: iio: resolver: ad2s1210: fix ad2s1210_show_fault"
>    * "iio: adc: MCP3564: fix the static checker warning"
> * Split "staging: iio: resolver: ad2s1210: fix probe" into multiple patches.
> * Moved sorting imports to separate patch.
> * Renamed fclkin to clkin_hz.
> * Added __be16 sample field to state struct for reading raw samples.
> * Split out new function ad2s1210_single_conversion() from
>    ad2s1210_read_raw().
> * Split out new ad2s1210_get_hysteresis() and ad2s1210_set_hysteresis()
>    functions.
> * Fixed multi-line comment style.
> * Added notes about soft reset not resetting config registers.
> * Made use of FIELD_PREP() macro.
> * Added more explanation to regmap commit message.
> * Removed datasheet names from channel specs.
> * Replaced "staging: iio: resolver: ad2s1210: rename fexcit attribute"
>    with "staging: iio: resolver: ad2s1210: convert fexcit to channel
>    attribute".
> * Replaced "staging: iio: resolver: ad2s1210: add phase_lock_range
>    attributes" with "staging: iio: resolver: ad2s1210: add phase lock
>    range support"
> * Added additional patches to convert custom device attributes to event
>    attributes.
> * Added patch to add channel label attributes.
> 
> v2 changes:
> * Address initial device tree patch feedback
> * Drop "iio: sysfs: add IIO_DEVICE_ATTR_NAMED_RW macro" (related cleanups
>    also dropped for now, will address in a future series if needed)
> * Apply improvements as a series of patches to the staging driver. It is
>    not quite ready for the move out of staging patch yet.
> 
> This series has been tested on actual hardware using a EVAL-AD2S1210 evaluation
> board. (Note: not all device tree features have been implemented in the driver
> since the eval board doesn't support them out of the box. We plan to add them
> later if needed.)
> 
> Most of the questions about dealing with faults from the v2 cover letter
> have been addressed. There is still the question about what to do with
> the current `fault` attribute (it is the only custom device attribute
> remaining from the original staging driver). It was suggested to split it
> out into multiple attributes in a subdirectory. Since we now have events
> for all of the faults, I'm wondering if this is something that is still needed.
> In the current implementation, it is possible to start listening to events,
> clear the faults and then read a sample to trigger events for any current
> faults so we have a way to get current faults already.
> 
> There is also the matter of clearing faults. Writing the excitation
> frequency has a side-effect of clearing the faults, so we could use
> that as the reset. Or we could change the current fault attribute to
> write-only and rename it. Or is there a better way that I have overlooked?
> 
> Once this last issue is addressed, I think this driver will be ready
> for consideration for moving out of staging.
> ---
> David Lechner (27):
>        dt-bindings: iio: resolver: add devicetree bindings for ad2s1210
>        staging: iio: resolver: ad2s1210: fix use before initialization
>        staging: iio: resolver: ad2s1210: remove call to spi_setup()
>        staging: iio: resolver: ad2s1210: check return of ad2s1210_initial()
>        staging: iio: resolver: ad2s1210: remove spi_set_drvdata()
>        staging: iio: resolver: ad2s1210: sort imports
>        staging: iio: resolver: ad2s1210: always use 16-bit value for raw read
>        staging: iio: resolver: ad2s1210: implement IIO_CHAN_INFO_SCALE
>        staging: iio: resolver: ad2s1210: use devicetree to get CLKIN rate
>        staging: iio: resolver: ad2s1210: use regmap for config registers
>        staging: iio: resolver: ad2s1210: add debugfs reg access
>        staging: iio: resolver: ad2s1210: remove config attribute
>        staging: iio: resolver: ad2s1210: rework gpios
>        staging: iio: resolver: ad2s1210: implement hysteresis as channel attr
>        staging: iio: resolver: ad2s1210: refactor setting excitation frequency
>        staging: iio: resolver: ad2s1210: read excitation frequency from control register
>        staging: iio: resolver: ad2s1210: convert fexcit to channel attribute
>        staging: iio: resolver: ad2s1210: convert resolution to devicetree property
>        staging: iio: resolver: ad2s1210: add phase lock range support
>        staging: iio: resolver: ad2s1210: add triggered buffer support
>        staging: iio: resolver: ad2s1210: convert LOT threshold attrs to event attrs
>        staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
>        staging: iio: resolver: ad2s1210: convert DOS overrange threshold to event attr
>        staging: iio: resolver: ad2s1210: convert DOS mismatch threshold to event attr
>        staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs
>        staging: iio: resolver: ad2s1210: implement fault events
>        staging: iio: resolver: ad2s1210: add label attribute support
> 
>   .../bindings/iio/resolver/adi,ad2s1210.yaml        |  177 +++
>   .../Documentation/sysfs-bus-iio-resolver-ad2s1210  |   27 +
>   drivers/staging/iio/resolver/Kconfig               |    1 +
>   drivers/staging/iio/resolver/ad2s1210.c            | 1583 +++++++++++++++-----
>   4 files changed, 1391 insertions(+), 397 deletions(-)
> ---
> base-commit: 5e99f692d4e32e3250ab18d511894ca797407aec
> change-id: 20230925-ad2s1210-mainline-2791ef75e386
> 

In the end, this is what sysfs looks like:


root@analog:~# tree /sys/bus/iio/devices/iio\:device1/
/sys/bus/iio/devices/iio:device1/
├── buffer
│   ├── data_available
│   ├── direction
│   ├── enable
│   ├── length
│   └── watermark
├── buffer0
│   ├── data_available
│   ├── direction
│   ├── enable
│   ├── in_angl0_en
│   ├── in_angl0_index
│   ├── in_angl0_type
│   ├── in_anglvel0_en
│   ├── in_anglvel0_index
│   ├── in_anglvel0_type
│   ├── in_timestamp_en
│   ├── in_timestamp_index
│   ├── in_timestamp_type
│   ├── length
│   └── watermark
├── current_timestamp_clock
├── dev
├── events
│   ├── in_altvoltage0_mag_reset_max
│   ├── in_altvoltage0_mag_reset_max_available
│   ├── in_altvoltage0_mag_reset_min
│   ├── in_altvoltage0_mag_reset_min_available
│   ├── in_altvoltage0_mag_value
│   ├── in_altvoltage0_mag_value_available
│   ├── in_altvoltage0_thresh_falling_value
│   ├── in_altvoltage0_thresh_falling_value_available
│   ├── in_altvoltage0_thresh_rising_value
│   ├── in_altvoltage0_thresh_rising_value_available
│   ├── in_angl1_thresh_rising_hysteresis
│   ├── in_angl1_thresh_rising_hysteresis_available
│   ├── in_angl1_thresh_rising_value
│   ├── in_angl1_thresh_rising_value_available
│   ├── in_phase0_mag_value
│   └── in_phase0_mag_value_available
├── fault
├── in_altvoltage0_label
├── in_altvoltage1_x_label
├── in_altvoltage1_y_label
├── in_angl0_hysteresis
├── in_angl0_hysteresis_available
├── in_angl0_label
├── in_angl0_raw
├── in_angl0_scale
├── in_angl1_label
├── in_anglvel0_label
├── in_anglvel0_raw
├── in_anglvel0_scale
├── in_phase0_label
├── name
├── of_node -> ../../../../../../../../firmware/devicetree/base/axi/spi@e0006000/ad2s1210@0
├── out_altvoltage0_frequency
├── out_altvoltage0_frequency_available
├── out_altvoltage0_label
├── power
│   ├── autosuspend_delay_ms
│   ├── control
│   ├── runtime_active_time
│   ├── runtime_status
│   └── runtime_suspended_time
├── scan_elements
│   ├── in_angl0_en
│   ├── in_angl0_index
│   ├── in_angl0_type
│   ├── in_anglvel0_en
│   ├── in_anglvel0_index
│   ├── in_anglvel0_type
│   ├── in_timestamp_en
│   ├── in_timestamp_index
│   └── in_timestamp_type
├── subsystem -> ../../../../../../../../bus/iio
├── trigger
│   └── current_trigger
├── uevent
└── waiting_for_supplier

8 directories, 72 files

And this is what the output of iio_info looks like:
(note: iio_info does not currently support events so those
attributes are not visible here)

         iio:device1: ad2s1210 (buffer capable)
                 9 channels found:
                         angl0:  (input, index: 0, format: be:U16/16>>0)
                         5 channel-specific attributes found:
                                 attr  0: hysteresis value: 1
                                 attr  1: hysteresis_available value: 0 1
                                 attr  2: label value: position
                                 attr  3: raw value: 12578
                                 attr  4: scale value: 0.000095874
                         anglvel0:  (input, index: 1, format: be:S16/16>>0)
                         3 channel-specific attributes found:
                                 attr  0: label value: velocity
                                 attr  1: raw value: 5
                                 attr  2: scale value: 0.023968449
                         timestamp:  (input, index: 2, format: le:S64/64>>0)
                         phase0:  (input)
                         1 channel-specific attributes found:
                                 attr  0: label value: synthetic reference
                         altvoltage0:  (output)
                         3 channel-specific attributes found:
                                 attr  0: frequency value: 10000
                                 attr  1: frequency_available value: [2000 250 20000]
                                 attr  2: label value: excitation
                         angl1:  (input)
                         1 channel-specific attributes found:
                                 attr  0: label value: tracking error
                         altvoltage1_y:  (input)
                         1 channel-specific attributes found:
                                 attr  0: label value: sine
                         altvoltage0:  (input)
                         1 channel-specific attributes found:
                                 attr  0: label value: monitor signal
                         altvoltage1_x:  (input)
                         1 channel-specific attributes found:
                                 attr  0: label value: cosine
                 3 device-specific attributes found:
                                 attr  0: current_timestamp_clock value: realtime
                                 attr  1: fault value: 0x00
                                 attr  2: waiting_for_supplier value: 0
                 2 buffer-specific attributes found:
                                 attr  0: data_available value: 0
                                 attr  1: direction value: in
                 1 debug attributes found:
                                 debug attr  0: direct_reg_access ERROR: Input/output error (5)
                 Current trigger: trigger0(test)


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

* Re: [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events
  2023-09-29 17:23 ` [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events David Lechner
@ 2023-09-30  3:55   ` kernel test robot
  2023-09-30 16:00   ` Jonathan Cameron
  2023-10-03 10:53   ` Dan Carpenter
  2 siblings, 0 replies; 88+ messages in thread
From: kernel test robot @ 2023-09-30  3:55 UTC (permalink / raw)
  To: David Lechner, linux-iio, devicetree, linux-staging
  Cc: oe-kbuild-all, David Lechner, Jonathan Cameron, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

Hi David,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 5e99f692d4e32e3250ab18d511894ca797407aec]

url:    https://github.com/intel-lab-lkp/linux/commits/David-Lechner/dt-bindings-iio-resolver-add-devicetree-bindings-for-ad2s1210/20230930-014031
base:   5e99f692d4e32e3250ab18d511894ca797407aec
patch link:    https://lore.kernel.org/r/20230929-ad2s1210-mainline-v3-26-fa4364281745%40baylibre.com
patch subject: [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events
config: i386-randconfig-003-20230930 (https://download.01.org/0day-ci/archive/20230930/202309301112.XWUnLqJ3-lkp@intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230930/202309301112.XWUnLqJ3-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202309301112.XWUnLqJ3-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/staging/iio/resolver/ad2s1210.c:1452:34: warning: 'ad2s1210_of_match' defined but not used [-Wunused-const-variable=]
    1452 | static const struct of_device_id ad2s1210_of_match[] = {
         |                                  ^~~~~~~~~~~~~~~~~
   drivers/staging/iio/resolver/ad2s1210.c: In function 'ad2s1210_read_raw':
>> drivers/staging/iio/resolver/ad2s1210.c:436:40: warning: array subscript 2 is above array bounds of 'u8[2]' {aka 'unsigned char[2]'} [-Warray-bounds]
     436 |  ad2s1210_push_events(indio_dev, st->rx[2], timestamp);
         |                                  ~~~~~~^~~


vim +436 drivers/staging/iio/resolver/ad2s1210.c

   390	
   391	static int ad2s1210_single_conversion(struct iio_dev *indio_dev,
   392					      struct iio_chan_spec const *chan,
   393					      int *val)
   394	{
   395		struct ad2s1210_state *st = iio_priv(indio_dev);
   396		s64 timestamp;
   397		int ret;
   398	
   399		mutex_lock(&st->lock);
   400		gpiod_set_value(st->sample_gpio, 1);
   401		timestamp = iio_get_time_ns(indio_dev);
   402		/* delay (6 * tck + 20) nano seconds */
   403		udelay(1);
   404	
   405		switch (chan->type) {
   406		case IIO_ANGL:
   407			ret = ad2s1210_set_mode(st, MOD_POS);
   408			break;
   409		case IIO_ANGL_VEL:
   410			ret = ad2s1210_set_mode(st, MOD_VEL);
   411			break;
   412		default:
   413			ret = -EINVAL;
   414			break;
   415		}
   416		if (ret < 0)
   417			goto error_ret;
   418		ret = spi_read(st->sdev, &st->sample, 3);
   419		if (ret < 0)
   420			goto error_ret;
   421	
   422		switch (chan->type) {
   423		case IIO_ANGL:
   424			*val = be16_to_cpu(st->sample.raw);
   425			ret = IIO_VAL_INT;
   426			break;
   427		case IIO_ANGL_VEL:
   428			*val = (s16)be16_to_cpu(st->sample.raw);
   429			ret = IIO_VAL_INT;
   430			break;
   431		default:
   432			ret = -EINVAL;
   433			break;
   434		}
   435	
 > 436		ad2s1210_push_events(indio_dev, st->rx[2], timestamp);
   437	
   438	error_ret:
   439		gpiod_set_value(st->sample_gpio, 0);
   440		/* delay (2 * tck + 20) nano seconds */
   441		udelay(1);
   442		mutex_unlock(&st->lock);
   443		return ret;
   444	}
   445	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging
  2023-09-29 17:49 ` [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
@ 2023-09-30 14:26   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:26 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel,
	Apelete Seketeli

On Fri, 29 Sep 2023 12:49:42 -0500
David Lechner <dlechner@baylibre.com> wrote:

> On Fri, Sep 29, 2023 at 12:25 PM David Lechner <dlechner@baylibre.com> wrote:
> >
> > From: David Lechner <david@lechnology.com>
> >  
> 
> Ugh, an automated tool picked up my personal email on this for some
> reason. This extra From: line can be dropped from any patches that get
> picked up on this round. I will make sure to double-check next time.

Seems b4 picks up the second, correct From anyway which is handy ;)

Jonathan

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

* Re: [PATCH v3 02/27] staging: iio: resolver: ad2s1210: fix use before initialization
  2023-09-29 17:23 ` [PATCH v3 02/27] staging: iio: resolver: ad2s1210: fix use before initialization David Lechner
@ 2023-09-30 14:28   ` Jonathan Cameron
  2023-10-02  8:07   ` Dan Carpenter
  1 sibling, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:28 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:07 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This fixes a use before initialization in ad2s1210_probe(). The
> ad2s1210_setup_gpios() function uses st->sdev but it was being called
> before this field was initialized.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
Applied to the togreg banch of iio.git and pushed out as testing for 0-day to
poke at it.

I didn't pull this out as a fix to upstream quicker because it would
make a mess of the rest of applying the rest of the series.

Maybe we want to consider backporting some of these at somepoint.

Jonathan

> ---
> 
> v3 changes:
> * This is a new patch split out from "staging: iio: resolver: ad2s1210:
>  fix probe"
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index f695ca0547e4..3f08b59f4e19 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -658,9 +658,6 @@ static int ad2s1210_probe(struct spi_device *spi)
>  	if (!indio_dev)
>  		return -ENOMEM;
>  	st = iio_priv(indio_dev);
> -	ret = ad2s1210_setup_gpios(st);
> -	if (ret < 0)
> -		return ret;
>  
>  	spi_set_drvdata(spi, indio_dev);
>  
> @@ -671,6 +668,10 @@ static int ad2s1210_probe(struct spi_device *spi)
>  	st->resolution = 12;
>  	st->fexcit = AD2S1210_DEF_EXCIT;
>  
> +	ret = ad2s1210_setup_gpios(st);
> +	if (ret < 0)
> +		return ret;
> +
>  	indio_dev->info = &ad2s1210_info;
>  	indio_dev->modes = INDIO_DIRECT_MODE;
>  	indio_dev->channels = ad2s1210_channels;
> 


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

* Re: [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210
  2023-09-29 17:23 ` [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210 David Lechner
@ 2023-09-30 14:34   ` Jonathan Cameron
  2023-10-04 10:41     ` Hennerich, Michael
  2023-10-02  8:02   ` Dan Carpenter
  2023-10-02 15:18   ` Rob Herring
  2 siblings, 1 reply; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:34 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel,
	Apelete Seketeli

On Fri, 29 Sep 2023 12:23:06 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This adds new DeviceTree bindings for the Analog Devices, Inc. AD2S1210
> resolver-to-digital converter.
> 
> Co-developed-by: Apelete Seketeli <aseketeli@baylibre.com>
> Signed-off-by: Apelete Seketeli <aseketeli@baylibre.com>
> Signed-off-by: David Lechner <dlechner@baylibre.com>

Michael, ideally I'd like your ack on this given it volunteers you as
maintainer. If I don't hear I'm fine with leaving Michael listed
because he's in MAINTAINERS anyway covering these bindings via
a wild card entry:

ANALOG DEVICES INC IIO DRIVERS
M:	Lars-Peter Clausen <lars@metafoo.de>
M:	Michael Hennerich <Michael.Hennerich@analog.com>
...
F:	Documentation/devicetree/bindings/iio/*/adi,*

So any queries should hit Michael anyway.

LGTM but I'll also want the dt binding maintainers input before picking this
up.

Jonathan

> ---
> 
> v3 changes:
> * Expanded top-level description of A0/A1 lines.
> * Added required voltage -supply properties. (I did not pick up Rob's
>   Reviewed-by since I wasn't sure if this was trivial enough.)
> 
> v2 changes:
> * Add Co-developed-by:
> * Remove extraneous quotes on strings
> * Remove extraneous pipe on some multi-line descriptions
> 
>  .../bindings/iio/resolver/adi,ad2s1210.yaml        | 177 +++++++++++++++++++++
>  1 file changed, 177 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/iio/resolver/adi,ad2s1210.yaml b/Documentation/devicetree/bindings/iio/resolver/adi,ad2s1210.yaml
> new file mode 100644
> index 000000000000..8980b3cd8337
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/resolver/adi,ad2s1210.yaml
> @@ -0,0 +1,177 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iio/resolver/adi,ad2s1210.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices AD2S1210 Resolver-to-Digital Converter
> +
> +maintainers:
> +  - Michael Hennerich <michael.hennerich@analog.com>
> +
> +description: |
> +  The AD2S1210 is a complete 10-bit to 16-bit resolution tracking
> +  resolver-to-digital converter, integrating an on-board programmable
> +  sinusoidal oscillator that provides sine wave excitation for
> +  resolvers.
> +
> +  The AD2S1210 allows the user to read the angular position or the
> +  angular velocity data directly from the parallel outputs or through
> +  the serial interface.
> +
> +  The mode of operation of the communication channel (parallel or serial) is
> +  selected by the A0 and A1 input pins. In normal mode, data is latched by
> +  toggling the SAMPLE line and can then be read directly. In configuration mode,
> +  data is read or written using a register access scheme (address byte with
> +  read/write flag and data byte).
> +
> +    A1  A0  Result
> +     0   0  Normal mode - position output
> +     0   1  Normal mode - velocity output
> +     1   0  Reserved
> +     1   1  Configuration mode
> +
> +  In normal mode, the resolution of the digital output is selected using
> +  the RES0 and RES1 input pins. In configuration mode, the resolution is
> +  selected by setting the RES0 and RES1 bits in the control register.
> +
> +  RES1  RES0  Resolution (Bits)
> +     0     0  10
> +     0     1  12
> +     1     0  14
> +     1     1  16
> +
> +  Note on SPI connections: The CS line on the AD2S1210 should hard-wired to
> +  logic low and the WR/FSYNC line on the AD2S1210 should be connected to the
> +  SPI CSn output of the SPI controller.
> +
> +  Datasheet:
> +  https://www.analog.com/media/en/technical-documentation/data-sheets/ad2s1210.pdf
> +
> +properties:
> +  compatible:
> +    const: adi,ad2s1210
> +
> +  reg:
> +    maxItems: 1
> +
> +  spi-max-frequency:
> +    maximum: 25000000
> +
> +  spi-cpha: true
> +
> +  avdd-supply:
> +    description:
> +      A 4.75 to 5.25 V regulator that powers the Analog Supply Voltage (AVDD)
> +      pin.
> +
> +  dvdd-supply:
> +    description:
> +      A 4.75 to 5.25 V regulator that powers the Digital Supply Voltage (DVDD)
> +      pin.
> +
> +  vdrive-supply:
> +    description:
> +      A 2.3 to 5.25 V regulator that powers the Logic Power Supply Input
> +      (VDrive) pin.
> +
> +  clocks:
> +    maxItems: 1
> +    description: External oscillator clock (CLKIN).
> +
> +  reset-gpios:
> +    description:
> +      GPIO connected to the /RESET pin. As the line needs to be low for the
> +      reset to be active, it should be configured as GPIO_ACTIVE_LOW.
> +    maxItems: 1
> +
> +  sample-gpios:
> +    description:
> +      GPIO connected to the /SAMPLE pin. As the line needs to be low to trigger
> +      a sample, it should be configured as GPIO_ACTIVE_LOW.
> +    maxItems: 1
> +
> +  mode-gpios:
> +    description:
> +      GPIO lines connected to the A0 and A1 pins. These pins select the data
> +      transfer mode.
> +    minItems: 2
> +    maxItems: 2
> +
> +  resolution-gpios:
> +    description:
> +      GPIO lines connected to the RES0 and RES1 pins. These pins select the
> +      resolution of the digital output. If omitted, it is assumed that the
> +      RES0 and RES1 pins are hard-wired to match the assigned-resolution-bits
> +      property.
> +    minItems: 2
> +    maxItems: 2
> +
> +  fault-gpios:
> +    description:
> +      GPIO lines connected to the LOT and DOS pins. These pins combined indicate
> +      the type of fault present, if any. As these pins a pulled low to indicate
> +      a fault condition, they should be configured as GPIO_ACTIVE_LOW.
> +    minItems: 2
> +    maxItems: 2
> +
> +  adi,fixed-mode:
> +    description:
> +      This is used to indicate the selected mode if A0 and A1 are hard-wired
> +      instead of connected to GPIOS (i.e. mode-gpios is omitted).
> +    $ref: /schemas/types.yaml#/definitions/string
> +    enum: [config, velocity, position]
> +
> +  assigned-resolution-bits:
> +    description:
> +      Resolution of the digital output required by the application. This
> +      determines the precision of the angle and/or the maximum speed that can
> +      be measured. If resolution-gpios is omitted, it is assumed that RES0 and
> +      RES1 are hard-wired to match this value.
> +    enum: [10, 12, 14, 16]
> +
> +required:
> +  - compatible
> +  - reg
> +  - spi-cpha
> +  - avdd-supply
> +  - dvdd-supply
> +  - vdrive-supply
> +  - clocks
> +  - sample-gpios
> +  - assigned-resolution-bits
> +
> +oneOf:
> +  - required:
> +      - mode-gpios
> +  - required:
> +      - adi,fixed-mode
> +
> +allOf:
> +  - $ref: /schemas/spi/spi-peripheral-props.yaml#
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    spi {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        resolver@0 {
> +            compatible = "adi,ad2s1210";
> +            reg = <0>;
> +            spi-max-frequency = <20000000>;
> +            spi-cpha;
> +            avdd-supply = <&avdd_regulator>;
> +            dvdd-supply = <&dvdd_regulator>;
> +            vdrive-supply = <&vdrive_regulator>;
> +            clocks = <&ext_osc>;
> +            sample-gpios = <&gpio0 90 GPIO_ACTIVE_LOW>;
> +            mode-gpios = <&gpio0 86 0>, <&gpio0 87 0>;
> +            resolution-gpios = <&gpio0 88 0>, <&gpio0 89 0>;
> +            assigned-resolution-bits = <16>;
> +        };
> +    };
> 


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

* Re: [PATCH v3 03/27] staging: iio: resolver: ad2s1210: remove call to spi_setup()
  2023-09-29 17:23 ` [PATCH v3 03/27] staging: iio: resolver: ad2s1210: remove call to spi_setup() David Lechner
@ 2023-09-30 14:35   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:35 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:08 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This removes the call to spi_setup() in the ad2s1210 driver.
> 
> Setting MODE_3 was incorrect. It should be MODE_1 but we can let the
> device tree select this and avoid the need to call spi_setup().
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>

Applied and pushed out as testing for all the normal reasons.

Thanks,

Jonathan

> ---
> 
> v3 changes:
> * This is a new patch split out from "staging: iio: resolver: ad2s1210:
>  fix probe"
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index 3f08b59f4e19..8fde08887f7f 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -683,8 +683,6 @@ static int ad2s1210_probe(struct spi_device *spi)
>  		return ret;
>  
>  	st->fclkin = spi->max_speed_hz;
> -	spi->mode = SPI_MODE_3;
> -	spi_setup(spi);
>  	ad2s1210_initial(st);
>  
>  	return 0;
> 


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

* Re: [PATCH v3 04/27] staging: iio: resolver: ad2s1210: check return of ad2s1210_initial()
  2023-09-29 17:23 ` [PATCH v3 04/27] staging: iio: resolver: ad2s1210: check return of ad2s1210_initial() David Lechner
@ 2023-09-30 14:37   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:37 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:09 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This adds a check to the return value of ad2s1210_initial() since it
> can fail. The call is also moved before devm_iio_device_register() so
> that we don't have to unregister the device if it fails.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
Applied

> ---
> 
> v3 changes:
> * This is a new patch split out from "staging: iio: resolver: ad2s1210:
>  fix probe"
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index 8fde08887f7f..b5e071d7c5fd 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -672,6 +672,10 @@ static int ad2s1210_probe(struct spi_device *spi)
>  	if (ret < 0)
>  		return ret;
>  
> +	ret = ad2s1210_initial(st);
> +	if (ret < 0)
> +		return ret;
> +
>  	indio_dev->info = &ad2s1210_info;
>  	indio_dev->modes = INDIO_DIRECT_MODE;
>  	indio_dev->channels = ad2s1210_channels;
> @@ -683,7 +687,6 @@ static int ad2s1210_probe(struct spi_device *spi)
>  		return ret;
>  
>  	st->fclkin = spi->max_speed_hz;
> -	ad2s1210_initial(st);
>  
>  	return 0;
>  }
> 


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

* Re: [PATCH v3 05/27] staging: iio: resolver: ad2s1210: remove spi_set_drvdata()
  2023-09-29 17:23 ` [PATCH v3 05/27] staging: iio: resolver: ad2s1210: remove spi_set_drvdata() David Lechner
@ 2023-09-30 14:38   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:38 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:10 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> Since we never call spi_get_drvdata(), we can remove spi_set_drvdata().
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
Applied.

> ---
> 
> v3 changes:
> * This is a new patch split out from "staging: iio: resolver: ad2s1210:
>  fix probe"
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index b5e071d7c5fd..28015322f562 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -659,8 +659,6 @@ static int ad2s1210_probe(struct spi_device *spi)
>  		return -ENOMEM;
>  	st = iio_priv(indio_dev);
>  
> -	spi_set_drvdata(spi, indio_dev);
> -
>  	mutex_init(&st->lock);
>  	st->sdev = spi;
>  	st->hysteresis = true;
> 


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

* Re: [PATCH v3 06/27] staging: iio: resolver: ad2s1210: sort imports
  2023-09-29 17:23 ` [PATCH v3 06/27] staging: iio: resolver: ad2s1210: sort imports David Lechner
@ 2023-09-30 14:39   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:39 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:11 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> There are quite a few imports and we will be adding more so it will
> make it easier to read if they are sorted.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
Applied

> ---
> 
> v3 changes:
> * This is a new patch split out from "staging: iio: resolver: ad2s1210:
>  use devicetree to get fclkin"
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index 28015322f562..832f86bf15e5 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -4,16 +4,16 @@
>   *
>   * Copyright (c) 2010-2010 Analog Devices Inc.
>   */
> -#include <linux/types.h>
> -#include <linux/mutex.h>
> +#include <linux/delay.h>
>  #include <linux/device.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
>  #include <linux/of.h>
> -#include <linux/spi/spi.h>
>  #include <linux/slab.h>
> +#include <linux/spi/spi.h>
>  #include <linux/sysfs.h>
> -#include <linux/delay.h>
> -#include <linux/gpio/consumer.h>
> -#include <linux/module.h>
> +#include <linux/types.h>
>  
>  #include <linux/iio/iio.h>
>  #include <linux/iio/sysfs.h>
> 


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

* Re: [PATCH v3 07/27] staging: iio: resolver: ad2s1210: always use 16-bit value for raw read
  2023-09-29 17:23 ` [PATCH v3 07/27] staging: iio: resolver: ad2s1210: always use 16-bit value for raw read David Lechner
@ 2023-09-30 14:41   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:41 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:12 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This removes the special handling for resolutions lower than 16 bits.
> This will allow us to use a fixed scale independent of the resolution.
> 
> A new sample field is added to store the raw data instead of reusing
> the config mode rx buffer so that we don't have to do a cast or worry
> about unaligned access.
> 
> Also, for the record, according to the datasheet, the logic for the
> special handling based on hysteresis that was removed was incorrect.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
LGTM

Applied.

Thanks,

Jonathan

> ---
> 
> v3 changes:
> * Added __be16 sample field to state struct and use instead of rx buffer.
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 24 ++++++++----------------
>  1 file changed, 8 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index 832f86bf15e5..f9774dff2df4 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -95,7 +95,11 @@ struct ad2s1210_state {
>  	bool hysteresis;
>  	u8 resolution;
>  	enum ad2s1210_mode mode;
> -	u8 rx[2] __aligned(IIO_DMA_MINALIGN);
> +	/** For reading raw sample value via SPI. */
> +	__be16 sample __aligned(IIO_DMA_MINALIGN);
> +	/** SPI transmit buffer. */
> +	u8 rx[2];
> +	/** SPI receive buffer. */
>  	u8 tx[2];
>  };
>  
> @@ -464,10 +468,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
>  			     long m)
>  {
>  	struct ad2s1210_state *st = iio_priv(indio_dev);
> -	u16 negative;
>  	int ret = 0;
> -	u16 pos;
> -	s16 vel;
>  
>  	mutex_lock(&st->lock);
>  	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0);
> @@ -487,26 +488,17 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
>  	}
>  	if (ret < 0)
>  		goto error_ret;
> -	ret = spi_read(st->sdev, st->rx, 2);
> +	ret = spi_read(st->sdev, &st->sample, 2);
>  	if (ret < 0)
>  		goto error_ret;
>  
>  	switch (chan->type) {
>  	case IIO_ANGL:
> -		pos = be16_to_cpup((__be16 *)st->rx);
> -		if (st->hysteresis)
> -			pos >>= 16 - st->resolution;
> -		*val = pos;
> +		*val = be16_to_cpu(st->sample);
>  		ret = IIO_VAL_INT;
>  		break;
>  	case IIO_ANGL_VEL:
> -		vel = be16_to_cpup((__be16 *)st->rx);
> -		vel >>= 16 - st->resolution;
> -		if (vel & 0x8000) {
> -			negative = (0xffff >> st->resolution) << st->resolution;
> -			vel |= negative;
> -		}
> -		*val = vel;
> +		*val = (s16)be16_to_cpu(st->sample);
>  		ret = IIO_VAL_INT;
>  		break;
>  	default:
> 


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

* Re: [PATCH v3 08/27] staging: iio: resolver: ad2s1210: implement IIO_CHAN_INFO_SCALE
  2023-09-29 17:23 ` [PATCH v3 08/27] staging: iio: resolver: ad2s1210: implement IIO_CHAN_INFO_SCALE David Lechner
@ 2023-09-30 14:43   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:43 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:13 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This adds an implementation of IIO_CHAN_INFO_SCALE to the ad2s1210
> resolver driver. This allows userspace to get the scale factor for the
> raw values.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
Applied

Thanks,

> ---
> 
> v3 changes:
> * Split ad2s1210_read_raw() into two functions to reduce complexity.
> * Use early return instead of break in switch statements.
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 53 ++++++++++++++++++++++++++++-----
>  1 file changed, 45 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index f9774dff2df4..a710598a64f0 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -461,13 +461,10 @@ static ssize_t ad2s1210_store_reg(struct device *dev,
>  	return ret < 0 ? ret : len;
>  }
>  
> -static int ad2s1210_read_raw(struct iio_dev *indio_dev,
> -			     struct iio_chan_spec const *chan,
> -			     int *val,
> -			     int *val2,
> -			     long m)
> +static int ad2s1210_single_conversion(struct ad2s1210_state *st,
> +				      struct iio_chan_spec const *chan,
> +				      int *val)
>  {
> -	struct ad2s1210_state *st = iio_priv(indio_dev);
>  	int ret = 0;
>  
>  	mutex_lock(&st->lock);
> @@ -514,6 +511,44 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
>  	return ret;
>  }
>  
> +static const int ad2s1210_velocity_scale[] = {
> +	17089132, /* 8.192MHz / (2*pi * 2500 / 2^15) */
> +	42722830, /* 8.192MHz / (2*pi * 1000 / 2^15) */
> +	85445659, /* 8.192MHz / (2*pi * 500 / 2^15) */
> +	341782638, /* 8.192MHz / (2*pi * 125 / 2^15) */
> +};
> +
> +static int ad2s1210_read_raw(struct iio_dev *indio_dev,
> +			     struct iio_chan_spec const *chan,
> +			     int *val,
> +			     int *val2,
> +			     long mask)
> +{
> +	struct ad2s1210_state *st = iio_priv(indio_dev);
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:
> +		return ad2s1210_single_conversion(st, chan, val);
> +	case IIO_CHAN_INFO_SCALE:
> +		switch (chan->type) {
> +		case IIO_ANGL:
> +			/* approx 0.3 arc min converted to radians */
> +			*val = 0;
> +			*val2 = 95874;
> +			return IIO_VAL_INT_PLUS_NANO;
> +		case IIO_ANGL_VEL:
> +			*val = st->fclkin;
> +			*val2 = ad2s1210_velocity_scale[st->resolution];
> +			return IIO_VAL_FRACTIONAL;
> +		default:
> +			return -EINVAL;
> +		}
> +
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>  static IIO_DEVICE_ATTR(fclkin, 0644,
>  		       ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0);
>  static IIO_DEVICE_ATTR(fexcit, 0644,
> @@ -552,12 +587,14 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
>  		.type = IIO_ANGL,
>  		.indexed = 1,
>  		.channel = 0,
> -		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
>  	}, {
>  		.type = IIO_ANGL_VEL,
>  		.indexed = 1,
>  		.channel = 0,
> -		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
>  	}
>  };
>  
> 


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

* Re: [PATCH v3 09/27] staging: iio: resolver: ad2s1210: use devicetree to get CLKIN rate
  2023-09-29 17:23 ` [PATCH v3 09/27] staging: iio: resolver: ad2s1210: use devicetree to get CLKIN rate David Lechner
@ 2023-09-30 14:44   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:44 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:14 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This removes the fclkin sysfs attribute and replaces it with getting
> the CLKIN clock rate using the clk subsystem (i.e. from the devicetree).
> 
> CLKIN comes from an external oscillator that is connected directly to
> the AD2S1210 chip, so users of the sysfs attributes should not need to
> be concerned with this.
> 
> The fclkin field (the datasheet name) is renamed to clkin_hz to be more
> obvious that it is a frequency in Hz.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
LGTM

Applied

J
> ---
> 
> v3 changes:
> * Don't sort imports in this patch.
> * Renamed fexcit to clkin_hz.
> * Fixed ad2s1210_setup_clocks() being called in an earlier patch.
> 
>  drivers/staging/iio/resolver/Kconfig    |  1 +
>  drivers/staging/iio/resolver/ad2s1210.c | 81 ++++++++++++---------------------
>  2 files changed, 30 insertions(+), 52 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/Kconfig b/drivers/staging/iio/resolver/Kconfig
> index 6d1e2622e0b0..bebb35822c9e 100644
> --- a/drivers/staging/iio/resolver/Kconfig
> +++ b/drivers/staging/iio/resolver/Kconfig
> @@ -7,6 +7,7 @@ menu "Resolver to digital converters"
>  config AD2S1210
>  	tristate "Analog Devices ad2s1210 driver"
>  	depends on SPI
> +	depends on COMMON_CLK
>  	depends on GPIOLIB || COMPILE_TEST
>  	help
>  	  Say yes here to build support for Analog Devices spi resolver
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index a710598a64f0..c8723b6f3a3b 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -3,7 +3,9 @@
>   * ad2s1210.c support for the ADI Resolver to Digital Converters: AD2S1210
>   *
>   * Copyright (c) 2010-2010 Analog Devices Inc.
> + * Copyright (c) 2023 BayLibre, SAS
>   */
> +#include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
>  #include <linux/gpio/consumer.h>
> @@ -90,7 +92,8 @@ struct ad2s1210_state {
>  	struct mutex lock;
>  	struct spi_device *sdev;
>  	struct gpio_desc *gpios[5];
> -	unsigned int fclkin;
> +	/** The external oscillator frequency in Hz. */
> +	unsigned long clkin_hz;
>  	unsigned int fexcit;
>  	bool hysteresis;
>  	u8 resolution;
> @@ -165,7 +168,7 @@ int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st)
>  	int ret;
>  	unsigned char fcw;
>  
> -	fcw = (unsigned char)(st->fexcit * (1 << 15) / st->fclkin);
> +	fcw = (unsigned char)(st->fexcit * (1 << 15) / st->clkin_hz);
>  	if (fcw < AD2S1210_MIN_FCW || fcw > AD2S1210_MAX_FCW) {
>  		dev_err(&st->sdev->dev, "ad2s1210: FCW out of range\n");
>  		return -ERANGE;
> @@ -201,45 +204,6 @@ static inline int ad2s1210_soft_reset(struct ad2s1210_state *st)
>  	return ad2s1210_config_write(st, 0x0);
>  }
>  
> -static ssize_t ad2s1210_show_fclkin(struct device *dev,
> -				    struct device_attribute *attr,
> -				    char *buf)
> -{
> -	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> -
> -	return sprintf(buf, "%u\n", st->fclkin);
> -}
> -
> -static ssize_t ad2s1210_store_fclkin(struct device *dev,
> -				     struct device_attribute *attr,
> -				     const char *buf,
> -				     size_t len)
> -{
> -	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> -	unsigned int fclkin;
> -	int ret;
> -
> -	ret = kstrtouint(buf, 10, &fclkin);
> -	if (ret)
> -		return ret;
> -	if (fclkin < AD2S1210_MIN_CLKIN || fclkin > AD2S1210_MAX_CLKIN) {
> -		dev_err(dev, "ad2s1210: fclkin out of range\n");
> -		return -EINVAL;
> -	}
> -
> -	mutex_lock(&st->lock);
> -	st->fclkin = fclkin;
> -
> -	ret = ad2s1210_update_frequency_control_word(st);
> -	if (ret < 0)
> -		goto error_ret;
> -	ret = ad2s1210_soft_reset(st);
> -error_ret:
> -	mutex_unlock(&st->lock);
> -
> -	return ret < 0 ? ret : len;
> -}
> -
>  static ssize_t ad2s1210_show_fexcit(struct device *dev,
>  				    struct device_attribute *attr,
>  				    char *buf)
> @@ -537,7 +501,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
>  			*val2 = 95874;
>  			return IIO_VAL_INT_PLUS_NANO;
>  		case IIO_ANGL_VEL:
> -			*val = st->fclkin;
> +			*val = st->clkin_hz;
>  			*val2 = ad2s1210_velocity_scale[st->resolution];
>  			return IIO_VAL_FRACTIONAL;
>  		default:
> @@ -549,8 +513,6 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
>  	}
>  }
>  
> -static IIO_DEVICE_ATTR(fclkin, 0644,
> -		       ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0);
>  static IIO_DEVICE_ATTR(fexcit, 0644,
>  		       ad2s1210_show_fexcit,	ad2s1210_store_fexcit, 0);
>  static IIO_DEVICE_ATTR(control, 0644,
> @@ -599,7 +561,6 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
>  };
>  
>  static struct attribute *ad2s1210_attributes[] = {
> -	&iio_dev_attr_fclkin.dev_attr.attr,
>  	&iio_dev_attr_fexcit.dev_attr.attr,
>  	&iio_dev_attr_control.dev_attr.attr,
>  	&iio_dev_attr_bits.dev_attr.attr,
> @@ -657,6 +618,24 @@ static const struct iio_info ad2s1210_info = {
>  	.attrs = &ad2s1210_attribute_group,
>  };
>  
> +static int ad2s1210_setup_clocks(struct ad2s1210_state *st)
> +{
> +	struct device *dev = &st->sdev->dev;
> +	struct clk *clk;
> +
> +	clk = devm_clk_get_enabled(dev, NULL);
> +	if (IS_ERR(clk))
> +		return dev_err_probe(dev, PTR_ERR(clk), "failed to get clock\n");
> +
> +	st->clkin_hz = clk_get_rate(clk);
> +	if (st->clkin_hz < AD2S1210_MIN_CLKIN || st->clkin_hz > AD2S1210_MAX_CLKIN)
> +		return dev_err_probe(dev, -EINVAL,
> +				     "clock frequency out of range: %lu\n",
> +				     st->clkin_hz);
> +
> +	return 0;
> +}
> +
>  static int ad2s1210_setup_gpios(struct ad2s1210_state *st)
>  {
>  	struct spi_device *spi = st->sdev;
> @@ -695,6 +674,10 @@ static int ad2s1210_probe(struct spi_device *spi)
>  	st->resolution = 12;
>  	st->fexcit = AD2S1210_DEF_EXCIT;
>  
> +	ret = ad2s1210_setup_clocks(st);
> +	if (ret < 0)
> +		return ret;
> +
>  	ret = ad2s1210_setup_gpios(st);
>  	if (ret < 0)
>  		return ret;
> @@ -709,13 +692,7 @@ static int ad2s1210_probe(struct spi_device *spi)
>  	indio_dev->num_channels = ARRAY_SIZE(ad2s1210_channels);
>  	indio_dev->name = spi_get_device_id(spi)->name;
>  
> -	ret = devm_iio_device_register(&spi->dev, indio_dev);
> -	if (ret)
> -		return ret;
> -
> -	st->fclkin = spi->max_speed_hz;
> -
> -	return 0;
> +	return devm_iio_device_register(&spi->dev, indio_dev);
>  }
>  
>  static const struct of_device_id ad2s1210_of_match[] = {
> 


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

* Re: [PATCH v3 10/27] staging: iio: resolver: ad2s1210: use regmap for config registers
  2023-09-29 17:23 ` [PATCH v3 10/27] staging: iio: resolver: ad2s1210: use regmap for config registers David Lechner
@ 2023-09-30 14:51   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:51 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:15 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This makes use of the regmap API to read and write the configuration
> registers. This simplifies code quite a bit and makes it safer
> (previously, it was easy to write a bad value to the config registers
> which causes the chip to lock up and need to be reset).
> 
> This chip has multiple modes of operation. In normal mode, we do not use
> regmap since there is no addressing - data is just bitshifted out during
> the SPI read. In config mode, we use regmap since it requires writing
> the address (with read/write flag) before reading and writing.
> 
> We don't use the lock provided by the regmap because we need to also
> synchronize with the normal mode SPI reads and with the various GPIOs.
> 
> There is also a quirk when reading registers (other than the fault
> register). If the address/data bit is set in the value read, then it
> indicates there is a configuration parity error and the data is not
> valid. Previously, this was checked in a few places, but not
> consistently. Now, we always check it in the regmap read function.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>

This was a complex change, so I'm partly relying on the fact it clearly
works after the change to be sure it is correct ;)

Anyhow, code is much cleaner and probably right, so applied to the
togreg branch of iio.git and pushed out as testing for all the normal
reasons.

Thanks,

Jonathan



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

* Re: [PATCH v3 11/27] staging: iio: resolver: ad2s1210: add debugfs reg access
  2023-09-29 17:23 ` [PATCH v3 11/27] staging: iio: resolver: ad2s1210: add debugfs reg access David Lechner
@ 2023-09-30 14:52   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:52 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:16 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This add an implementation of debugfs_reg_access for the AD2S1210
> driver.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>

I never really care if a driver implements this or not.
However, if you find it useful that's fine, so applied.

Thanks,

Jonathan

> ---
> 
> v3 changes: None
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index 0663a51d04ad..31415fbb6384 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -614,9 +614,29 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
>  	return ret;
>  }
>  
> +static int ad2s1210_debugfs_reg_access(struct iio_dev *indio_dev,
> +				       unsigned int reg, unsigned int writeval,
> +				       unsigned int *readval)
> +{
> +	struct ad2s1210_state *st = iio_priv(indio_dev);
> +	int ret;
> +
> +	mutex_lock(&st->lock);
> +
> +	if (readval)
> +		ret = regmap_read(st->regmap, reg, readval);
> +	else
> +		ret = regmap_write(st->regmap, reg, writeval);
> +
> +	mutex_unlock(&st->lock);
> +
> +	return ret;
> +}
> +
>  static const struct iio_info ad2s1210_info = {
>  	.read_raw = ad2s1210_read_raw,
>  	.attrs = &ad2s1210_attribute_group,
> +	.debugfs_reg_access = &ad2s1210_debugfs_reg_access,
>  };
>  
>  static int ad2s1210_setup_clocks(struct ad2s1210_state *st)
> 


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

* Re: [PATCH v3 12/27] staging: iio: resolver: ad2s1210: remove config attribute
  2023-09-29 17:23 ` [PATCH v3 12/27] staging: iio: resolver: ad2s1210: remove config attribute David Lechner
@ 2023-09-30 14:53   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:53 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:17 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This removes the config register sysfs attribute.
> 
> Writing to the config register directly can be dangerous and userspace
> should not need to have to know the register layout. This register
> can still be accessed though debugfs if needed.
> 
> We can add new attributes to set specific flags in the config register
> in the future if needed (e.g. `enable_hysterisis` and
> `phase_lock_range`).
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
Applied.


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

* Re: [PATCH v3 13/27] staging: iio: resolver: ad2s1210: rework gpios
  2023-09-29 17:23 ` [PATCH v3 13/27] staging: iio: resolver: ad2s1210: rework gpios David Lechner
@ 2023-09-30 14:55   ` Jonathan Cameron
  2023-10-05 13:38     ` Jonathan Cameron
  0 siblings, 1 reply; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 14:55 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:18 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> - Remove "adi," prefix from gpio names.
> - Sample gpio is now expected to be active low.
> - Convert A0 and A1 gpios to "mode-gpios" gpio array.
> - Convert RES0 and RES1 gpios to "resolution-gpios" gpio array.
> - Remove extraneous lookup tables.
> - Remove unused mode field from state struct.
> - Swap argument order of ad2s1210_set_mode() while we are touching this.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
Applied,

Thanks,
Jonathan

> ---
> 
> v3 changes:
> * Fixed multiline comment style.
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 164 +++++++++++++++++---------------
>  1 file changed, 85 insertions(+), 79 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index 2b9377447f6a..0ec3598b600a 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -58,39 +58,21 @@
>  #define AD2S1210_DEF_EXCIT	10000
>  
>  enum ad2s1210_mode {
> -	MOD_POS = 0,
> -	MOD_VEL,
> -	MOD_CONFIG,
> -	MOD_RESERVED,
> +	MOD_POS = 0b00,
> +	MOD_VEL = 0b01,
> +	MOD_RESERVED = 0b10,
> +	MOD_CONFIG = 0b11,
>  };
>  
> -enum ad2s1210_gpios {
> -	AD2S1210_SAMPLE,
> -	AD2S1210_A0,
> -	AD2S1210_A1,
> -	AD2S1210_RES0,
> -	AD2S1210_RES1,
> -};
> -
> -struct ad2s1210_gpio {
> -	const char *name;
> -	unsigned long flags;
> -};
> -
> -static const struct ad2s1210_gpio gpios[] = {
> -	[AD2S1210_SAMPLE] = { .name = "adi,sample", .flags = GPIOD_OUT_LOW },
> -	[AD2S1210_A0] = { .name = "adi,a0", .flags = GPIOD_OUT_LOW },
> -	[AD2S1210_A1] = { .name = "adi,a1", .flags = GPIOD_OUT_LOW },
> -	[AD2S1210_RES0] = { .name = "adi,res0", .flags = GPIOD_OUT_LOW },
> -	[AD2S1210_RES1] = { .name = "adi,res1", .flags = GPIOD_OUT_LOW },
> -};
> -
> -static const unsigned int ad2s1210_resolution_value[] = { 10, 12, 14, 16 };
> -
>  struct ad2s1210_state {
>  	struct mutex lock;
>  	struct spi_device *sdev;
> -	struct gpio_desc *gpios[5];
> +	/** GPIO pin connected to SAMPLE line. */
> +	struct gpio_desc *sample_gpio;
> +	/** GPIO pins connected to A0 and A1 lines. */
> +	struct gpio_descs *mode_gpios;
> +	/** GPIO pins connected to RES0 and RES1 lines. */
> +	struct gpio_descs *resolution_gpios;
>  	/** Used to access config registers. */
>  	struct regmap *regmap;
>  	/** The external oscillator frequency in Hz. */
> @@ -98,7 +80,6 @@ struct ad2s1210_state {
>  	unsigned int fexcit;
>  	bool hysteresis;
>  	u8 resolution;
> -	enum ad2s1210_mode mode;
>  	/** For reading raw sample value via SPI. */
>  	__be16 sample __aligned(IIO_DMA_MINALIGN);
>  	/** SPI transmit buffer. */
> @@ -107,18 +88,15 @@ struct ad2s1210_state {
>  	u8 tx[2];
>  };
>  
> -static const int ad2s1210_mode_vals[4][2] = {
> -	[MOD_POS] = { 0, 0 },
> -	[MOD_VEL] = { 0, 1 },
> -	[MOD_CONFIG] = { 1, 1 },
> -};
> -
> -static inline void ad2s1210_set_mode(enum ad2s1210_mode mode,
> -				     struct ad2s1210_state *st)
> +static int ad2s1210_set_mode(struct ad2s1210_state *st, enum ad2s1210_mode mode)
>  {
> -	gpiod_set_value(st->gpios[AD2S1210_A0], ad2s1210_mode_vals[mode][0]);
> -	gpiod_set_value(st->gpios[AD2S1210_A1], ad2s1210_mode_vals[mode][1]);
> -	st->mode = mode;
> +	struct gpio_descs *gpios = st->mode_gpios;
> +	DECLARE_BITMAP(bitmap, 2);
> +
> +	bitmap[0] = mode;
> +
> +	return gpiod_set_array_value(gpios->ndescs, gpios->desc, gpios->info,
> +				     bitmap);
>  }
>  
>  /*
> @@ -143,6 +121,7 @@ static int ad2s1210_regmap_reg_write(void *context, unsigned int reg,
>  			.tx_buf = &st->tx[1],
>  		},
>  	};
> +	int ret;
>  
>  	/* values can only be 7 bits, the MSB indicates an address */
>  	if (val & ~0x7F)
> @@ -151,7 +130,9 @@ static int ad2s1210_regmap_reg_write(void *context, unsigned int reg,
>  	st->tx[0] = reg;
>  	st->tx[1] = val;
>  
> -	ad2s1210_set_mode(MOD_CONFIG, st);
> +	ret = ad2s1210_set_mode(st, MOD_CONFIG);
> +	if (ret < 0)
> +		return ret;
>  
>  	return spi_sync_transfer(st->sdev, xfers, ARRAY_SIZE(xfers));
>  }
> @@ -180,7 +161,10 @@ static int ad2s1210_regmap_reg_read(void *context, unsigned int reg,
>  	};
>  	int ret;
>  
> -	ad2s1210_set_mode(MOD_CONFIG, st);
> +	ret = ad2s1210_set_mode(st, MOD_CONFIG);
> +	if (ret < 0)
> +		return ret;
> +
>  	st->tx[0] = reg;
>  	/*
>  	 * Must be valid register address here otherwise this could write data.
> @@ -219,16 +203,16 @@ int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st)
>  	return regmap_write(st->regmap, AD2S1210_REG_EXCIT_FREQ, fcw);
>  }
>  
> -static const int ad2s1210_res_pins[4][2] = {
> -	{ 0, 0 }, {0, 1}, {1, 0}, {1, 1}
> -};
> -
> -static inline void ad2s1210_set_resolution_pin(struct ad2s1210_state *st)
> +static int ad2s1210_set_resolution_gpios(struct ad2s1210_state *st,
> +					 u8 resolution)
>  {
> -	gpiod_set_value(st->gpios[AD2S1210_RES0],
> -			ad2s1210_res_pins[(st->resolution - 10) / 2][0]);
> -	gpiod_set_value(st->gpios[AD2S1210_RES1],
> -			ad2s1210_res_pins[(st->resolution - 10) / 2][1]);
> +	struct gpio_descs *gpios = st->resolution_gpios;
> +	DECLARE_BITMAP(bitmap, 2);
> +
> +	bitmap[0] = (resolution - 10) >> 1;
> +
> +	return gpiod_set_array_value(gpios->ndescs, gpios->desc, gpios->info,
> +				     bitmap);
>  }
>  
>  static inline int ad2s1210_soft_reset(struct ad2s1210_state *st)
> @@ -305,10 +289,13 @@ static ssize_t ad2s1210_store_resolution(struct device *dev,
>  	if (ret < 0)
>  		goto error_ret;
>  
> -	st->resolution =
> -		ad2s1210_resolution_value[data & AD2S1210_SET_RES];
> -	ad2s1210_set_resolution_pin(st);
> +	ret = ad2s1210_set_resolution_gpios(st, udata);
> +	if (ret < 0)
> +		goto error_ret;
> +
> +	st->resolution = udata;
>  	ret = len;
> +
>  error_ret:
>  	mutex_unlock(&st->lock);
>  	return ret;
> @@ -339,15 +326,19 @@ static ssize_t ad2s1210_clear_fault(struct device *dev,
>  	int ret;
>  
>  	mutex_lock(&st->lock);
> -	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0);
> +
> +	gpiod_set_value(st->sample_gpio, 1);
>  	/* delay (2 * tck + 20) nano seconds */
>  	udelay(1);
> -	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1);
> +	gpiod_set_value(st->sample_gpio, 0);
> +
>  	ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, &value);
>  	if (ret < 0)
>  		goto error_ret;
> -	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0);
> -	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1);
> +
> +	gpiod_set_value(st->sample_gpio, 1);
> +	gpiod_set_value(st->sample_gpio, 0);
> +
>  error_ret:
>  	mutex_unlock(&st->lock);
>  
> @@ -393,19 +384,19 @@ static int ad2s1210_single_conversion(struct ad2s1210_state *st,
>  				      struct iio_chan_spec const *chan,
>  				      int *val)
>  {
> -	int ret = 0;
> +	int ret;
>  
>  	mutex_lock(&st->lock);
> -	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0);
> +	gpiod_set_value(st->sample_gpio, 1);
>  	/* delay (6 * tck + 20) nano seconds */
>  	udelay(1);
>  
>  	switch (chan->type) {
>  	case IIO_ANGL:
> -		ad2s1210_set_mode(MOD_POS, st);
> +		ret = ad2s1210_set_mode(st, MOD_POS);
>  		break;
>  	case IIO_ANGL_VEL:
> -		ad2s1210_set_mode(MOD_VEL, st);
> +		ret = ad2s1210_set_mode(st, MOD_VEL);
>  		break;
>  	default:
>  		ret = -EINVAL;
> @@ -432,7 +423,7 @@ static int ad2s1210_single_conversion(struct ad2s1210_state *st,
>  	}
>  
>  error_ret:
> -	gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1);
> +	gpiod_set_value(st->sample_gpio, 0);
>  	/* delay (2 * tck + 20) nano seconds */
>  	udelay(1);
>  	mutex_unlock(&st->lock);
> @@ -546,7 +537,9 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
>  	int ret;
>  
>  	mutex_lock(&st->lock);
> -	ad2s1210_set_resolution_pin(st);
> +	ret = ad2s1210_set_resolution_gpios(st, st->resolution);
> +	if (ret < 0)
> +		return ret;
>  
>  	/* Use default config register value plus resolution from devicetree. */
>  	data = FIELD_PREP(AD2S1210_PHASE_LOCK_RANGE_44, 1);
> @@ -612,20 +605,34 @@ static int ad2s1210_setup_clocks(struct ad2s1210_state *st)
>  
>  static int ad2s1210_setup_gpios(struct ad2s1210_state *st)
>  {
> -	struct spi_device *spi = st->sdev;
> -	int i, ret;
> -
> -	for (i = 0; i < ARRAY_SIZE(gpios); i++) {
> -		st->gpios[i] = devm_gpiod_get(&spi->dev, gpios[i].name,
> -					      gpios[i].flags);
> -		if (IS_ERR(st->gpios[i])) {
> -			ret = PTR_ERR(st->gpios[i]);
> -			dev_err(&spi->dev,
> -				"ad2s1210: failed to request %s GPIO: %d\n",
> -				gpios[i].name, ret);
> -			return ret;
> -		}
> -	}
> +	struct device *dev = &st->sdev->dev;
> +
> +	/* should not be sampling on startup */
> +	st->sample_gpio = devm_gpiod_get(dev, "sample", GPIOD_OUT_LOW);
> +	if (IS_ERR(st->sample_gpio))
> +		return dev_err_probe(dev, PTR_ERR(st->sample_gpio),
> +				     "failed to request sample GPIO\n");
> +
> +	/* both pins high means that we start in config mode */
> +	st->mode_gpios = devm_gpiod_get_array(dev, "mode", GPIOD_OUT_HIGH);
> +	if (IS_ERR(st->mode_gpios))
> +		return dev_err_probe(dev, PTR_ERR(st->mode_gpios),
> +				     "failed to request mode GPIOs\n");
> +
> +	if (st->mode_gpios->ndescs != 2)
> +		return dev_err_probe(dev, -EINVAL,
> +				     "requires exactly 2 mode-gpios\n");
> +
> +	/* both pins high means that we start with 16-bit resolution */
> +	st->resolution_gpios = devm_gpiod_get_array(dev, "resolution",
> +						    GPIOD_OUT_HIGH);
> +	if (IS_ERR(st->resolution_gpios))
> +		return dev_err_probe(dev, PTR_ERR(st->resolution_gpios),
> +				     "failed to request resolution GPIOs\n");
> +
> +	if (st->resolution_gpios->ndescs != 2)
> +		return dev_err_probe(dev, -EINVAL,
> +				     "requires exactly 2 resolution-gpios\n");
>  
>  	return 0;
>  }
> @@ -690,7 +697,6 @@ static int ad2s1210_probe(struct spi_device *spi)
>  	mutex_init(&st->lock);
>  	st->sdev = spi;
>  	st->hysteresis = true;
> -	st->mode = MOD_CONFIG;
>  	st->resolution = 12;
>  	st->fexcit = AD2S1210_DEF_EXCIT;
>  
> 


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

* Re: [PATCH v3 14/27] staging: iio: resolver: ad2s1210: implement hysteresis as channel attr
  2023-09-29 17:53   ` David Lechner
@ 2023-09-30 15:00     ` Jonathan Cameron
  2023-09-30 21:23       ` David Lechner
  0 siblings, 1 reply; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:00 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:53:00 -0500
David Lechner <dlechner@baylibre.com> wrote:

> On Fri, Sep 29, 2023 at 12:25 PM David Lechner <dlechner@baylibre.com> wrote:
> >
> > The AD2S1210 resolver has a hysteresis feature that can be used to
> > prevent flicker in the LSB of the position register. This can be either
> > enabled or disabled. Disabling hysteresis is useful for increasing
> > precision by oversampling.
> >
> > Signed-off-by: David Lechner <dlechner@baylibre.com>
> > ---  
> 
> ...
> 
> > +static int ad2s1210_read_avail(struct iio_dev *indio_dev,
> > +                              struct iio_chan_spec const *chan,
> > +                              const int **vals, int *type,
> > +                              int *length, long mask)
> > +{
> > +       static const int hysteresis_available[] = { 0, 1 };  
> 
> This is basically an enable/disable. Should the 1 value be changed to the
> appropriate radians value since this is hysteresis on the position
> (angle) channel?

Good point. However it should be in the _raw units. The text is
slightly more explicit on this for
the variant of hysteresis applied to threshold events as it's
added or substracted from a threshold (and thresholds are in
_raw readings unless only _processed is available).

Does that make 0, 1 correct as we are talking about LSB only?

Jonathan


> 
> > +
> > +       switch (mask) {
> > +       case IIO_CHAN_INFO_HYSTERESIS:
> > +               switch (chan->type) {
> > +               case IIO_ANGL:
> > +                       *vals = hysteresis_available;
> > +                       *type = IIO_VAL_INT;
> > +                       *length = ARRAY_SIZE(hysteresis_available);
> > +                       return IIO_AVAIL_LIST;
> > +               default:
> > +                       return -EINVAL;
> > +               }
> > +       default:
> > +               return -EINVAL;
> > +       }
> > +}
> >  


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

* Re: [PATCH v3 14/27] staging: iio: resolver: ad2s1210: implement hysteresis as channel attr
  2023-09-29 17:23 ` [PATCH v3 14/27] staging: iio: resolver: ad2s1210: implement hysteresis as channel attr David Lechner
  2023-09-29 17:53   ` David Lechner
@ 2023-09-30 15:03   ` Jonathan Cameron
  1 sibling, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:03 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:19 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> The AD2S1210 resolver has a hysteresis feature that can be used to
> prevent flicker in the LSB of the position register. This can be either
> enabled or disabled. Disabling hysteresis is useful for increasing
> precision by oversampling.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
One trivial thing inline.

Thanks,

Jonathan

> ---
> 
> v3 changes:
> * Refactored into more functions to reduce complexity of switch statements.
> * Use early return instead of break in switch statements.
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 86 +++++++++++++++++++++++++++++++--
>  1 file changed, 83 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index 0ec3598b600a..a82cb124a12f 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -78,7 +78,6 @@ struct ad2s1210_state {
>  	/** The external oscillator frequency in Hz. */
>  	unsigned long clkin_hz;
>  	unsigned int fexcit;
> -	bool hysteresis;
>  	u8 resolution;
>  	/** For reading raw sample value via SPI. */
>  	__be16 sample __aligned(IIO_DMA_MINALIGN);
> @@ -430,6 +429,35 @@ static int ad2s1210_single_conversion(struct ad2s1210_state *st,
>  	return ret;
>  }
>  
> +static int ad2s1210_get_hysteresis(struct ad2s1210_state *st, int *val)
> +{
> +	int ret;
> +
> +	mutex_lock(&st->lock);
> +	ret = regmap_test_bits(st->regmap, AD2S1210_REG_CONTROL,
> +			       AD2S1210_ENABLE_HYSTERESIS);
> +	mutex_unlock(&st->lock);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	*val = !!ret;

regmap_test_bits() is documented as returning 1 or 0 anyway.
So this !! isn't necessary..

> +	return IIO_VAL_INT;
> +}
> +
> +static int ad2s1210_set_hysteresis(struct ad2s1210_state *st, int val)
> +{
> +	int ret;
> +
> +	mutex_lock(&st->lock);
> +	ret = regmap_update_bits(st->regmap, AD2S1210_REG_CONTROL,
> +				 AD2S1210_ENABLE_HYSTERESIS,
> +				 val ? AD2S1210_ENABLE_HYSTERESIS : 0);
> +	mutex_unlock(&st->lock);
> +
> +	return ret;
> +}
> +
>  static const int ad2s1210_velocity_scale[] = {
>  	17089132, /* 8.192MHz / (2*pi * 2500 / 2^15) */
>  	42722830, /* 8.192MHz / (2*pi * 1000 / 2^15) */
> @@ -462,7 +490,55 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
>  		default:
>  			return -EINVAL;
>  		}
> +	case IIO_CHAN_INFO_HYSTERESIS:
> +		switch (chan->type) {
> +		case IIO_ANGL:
> +			return ad2s1210_get_hysteresis(st, val);
> +		default:
> +			return -EINVAL;
> +		}
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int ad2s1210_read_avail(struct iio_dev *indio_dev,
> +			       struct iio_chan_spec const *chan,
> +			       const int **vals, int *type,
> +			       int *length, long mask)
> +{
> +	static const int hysteresis_available[] = { 0, 1 };
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_HYSTERESIS:
> +		switch (chan->type) {
> +		case IIO_ANGL:
> +			*vals = hysteresis_available;
> +			*type = IIO_VAL_INT;
> +			*length = ARRAY_SIZE(hysteresis_available);
> +			return IIO_AVAIL_LIST;
> +		default:
> +			return -EINVAL;
> +		}
> +	default:
> +		return -EINVAL;
> +	}
> +}
>  
> +static int ad2s1210_write_raw(struct iio_dev *indio_dev,
> +			      struct iio_chan_spec const *chan,
> +			      int val, int val2, long mask)
> +{
> +	struct ad2s1210_state *st = iio_priv(indio_dev);
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_HYSTERESIS:
> +		switch (chan->type) {
> +		case IIO_ANGL:
> +			return ad2s1210_set_hysteresis(st, val);
> +		default:
> +			return -EINVAL;
> +		}
>  	default:
>  		return -EINVAL;
>  	}
> @@ -503,7 +579,10 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
>  		.indexed = 1,
>  		.channel = 0,
>  		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> -				      BIT(IIO_CHAN_INFO_SCALE),
> +				      BIT(IIO_CHAN_INFO_SCALE) |
> +				      BIT(IIO_CHAN_INFO_HYSTERESIS),
> +		.info_mask_separate_available =
> +					BIT(IIO_CHAN_INFO_HYSTERESIS),
>  	}, {
>  		.type = IIO_ANGL_VEL,
>  		.indexed = 1,
> @@ -581,6 +660,8 @@ static int ad2s1210_debugfs_reg_access(struct iio_dev *indio_dev,
>  
>  static const struct iio_info ad2s1210_info = {
>  	.read_raw = ad2s1210_read_raw,
> +	.read_avail = ad2s1210_read_avail,
> +	.write_raw = ad2s1210_write_raw,
>  	.attrs = &ad2s1210_attribute_group,
>  	.debugfs_reg_access = &ad2s1210_debugfs_reg_access,
>  };
> @@ -696,7 +777,6 @@ static int ad2s1210_probe(struct spi_device *spi)
>  
>  	mutex_init(&st->lock);
>  	st->sdev = spi;
> -	st->hysteresis = true;
>  	st->resolution = 12;
>  	st->fexcit = AD2S1210_DEF_EXCIT;
>  
> 


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

* Re: [PATCH v3 15/27] staging: iio: resolver: ad2s1210: refactor setting excitation frequency
  2023-09-29 17:23 ` [PATCH v3 15/27] staging: iio: resolver: ad2s1210: refactor setting excitation frequency David Lechner
@ 2023-09-30 15:06   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:06 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:20 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This combines the ad2s1210_update_frequency_control_word() and
> ad2s1210_soft_reset() functions into a single function since they
> both have to be called together. (The software reset does not reset
> any configuration registers, it only updates the excitation output
> and resets the tracking loop.)
> 
> Also clean up a few things while touching this:
> - move AD2S1210_DEF_EXCIT macro with similar macros
> - remove unnecessary dev_err() calls
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
I'm sure it'll will stop me at some point but I'll keep trying to apply
patches even though I skipped previous one on basis the fewer I see
again, the less terrifying my inbox looks :)

So applied this one and pushed out as testing. Bit of fuzz as you'd expect.

Thanks,

Jonathan

> ---
> 
> v3 changes:
> * Expanded comment on soft reset register write.
> * Fixed multiline comment style.
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 66 +++++++++++++++++----------------
>  1 file changed, 34 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index a82cb124a12f..28ab877e1bc0 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -51,12 +51,11 @@
>  #define AD2S1210_MIN_CLKIN	6144000
>  #define AD2S1210_MAX_CLKIN	10240000
>  #define AD2S1210_MIN_EXCIT	2000
> +#define AD2S1210_DEF_EXCIT	10000
>  #define AD2S1210_MAX_EXCIT	20000
>  #define AD2S1210_MIN_FCW	0x4
>  #define AD2S1210_MAX_FCW	0x50
>  
> -#define AD2S1210_DEF_EXCIT	10000
> -
>  enum ad2s1210_mode {
>  	MOD_POS = 0b00,
>  	MOD_VEL = 0b01,
> @@ -188,18 +187,32 @@ static int ad2s1210_regmap_reg_read(void *context, unsigned int reg,
>  	return 0;
>  }
>  
> -static inline
> -int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st)
> +/*
> + * Sets the excitation frequency and performs software reset.
> + *
> + * Must be called with lock held.
> + */
> +static int ad2s1210_reinit_excitation_frequency(struct ad2s1210_state *st,
> +						u16 fexcit)
>  {
> -	unsigned char fcw;
> +	int ret;
> +	u8 fcw;
>  
> -	fcw = (unsigned char)(st->fexcit * (1 << 15) / st->clkin_hz);
> -	if (fcw < AD2S1210_MIN_FCW || fcw > AD2S1210_MAX_FCW) {
> -		dev_err(&st->sdev->dev, "ad2s1210: FCW out of range\n");
> +	fcw = fexcit * (1 << 15) / st->clkin_hz;
> +	if (fcw < AD2S1210_MIN_FCW || fcw > AD2S1210_MAX_FCW)
>  		return -ERANGE;
> -	}
>  
> -	return regmap_write(st->regmap, AD2S1210_REG_EXCIT_FREQ, fcw);
> +	ret = regmap_write(st->regmap, AD2S1210_REG_EXCIT_FREQ, fcw);
> +	if (ret < 0)
> +		return ret;
> +
> +	st->fexcit = fexcit;
> +
> +	/*
> +	 * Software reset reinitializes the excitation frequency output.
> +	 * It does not reset any of the configuration registers.
> +	 */
> +	return regmap_write(st->regmap, AD2S1210_REG_SOFT_RESET, 0);
>  }
>  
>  static int ad2s1210_set_resolution_gpios(struct ad2s1210_state *st,
> @@ -214,11 +227,6 @@ static int ad2s1210_set_resolution_gpios(struct ad2s1210_state *st,
>  				     bitmap);
>  }
>  
> -static inline int ad2s1210_soft_reset(struct ad2s1210_state *st)
> -{
> -	return regmap_write(st->regmap, AD2S1210_REG_SOFT_RESET, 0);
> -}
> -
>  static ssize_t ad2s1210_show_fexcit(struct device *dev,
>  				    struct device_attribute *attr,
>  				    char *buf)
> @@ -233,27 +241,24 @@ static ssize_t ad2s1210_store_fexcit(struct device *dev,
>  				     const char *buf, size_t len)
>  {
>  	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> -	unsigned int fexcit;
> +	u16 fexcit;
>  	int ret;
>  
> -	ret = kstrtouint(buf, 10, &fexcit);
> -	if (ret < 0)
> -		return ret;
> -	if (fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT) {
> -		dev_err(dev,
> -			"ad2s1210: excitation frequency out of range\n");
> +	ret = kstrtou16(buf, 10, &fexcit);
> +	if (ret < 0 || fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT)
>  		return -EINVAL;
> -	}
> +
>  	mutex_lock(&st->lock);
> -	st->fexcit = fexcit;
> -	ret = ad2s1210_update_frequency_control_word(st);
> +	ret = ad2s1210_reinit_excitation_frequency(st, fexcit);
>  	if (ret < 0)
>  		goto error_ret;
> -	ret = ad2s1210_soft_reset(st);
> +
> +	ret = len;
> +
>  error_ret:
>  	mutex_unlock(&st->lock);
>  
> -	return ret < 0 ? ret : len;
> +	return ret;
>  }
>  
>  static ssize_t ad2s1210_show_resolution(struct device *dev,
> @@ -630,10 +635,8 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
>  	if (ret < 0)
>  		goto error_ret;
>  
> -	ret = ad2s1210_update_frequency_control_word(st);
> -	if (ret < 0)
> -		goto error_ret;
> -	ret = ad2s1210_soft_reset(st);
> +	ret = ad2s1210_reinit_excitation_frequency(st, AD2S1210_DEF_EXCIT);
> +
>  error_ret:
>  	mutex_unlock(&st->lock);
>  	return ret;
> @@ -778,7 +781,6 @@ static int ad2s1210_probe(struct spi_device *spi)
>  	mutex_init(&st->lock);
>  	st->sdev = spi;
>  	st->resolution = 12;
> -	st->fexcit = AD2S1210_DEF_EXCIT;
>  
>  	ret = ad2s1210_setup_clocks(st);
>  	if (ret < 0)
> 


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

* Re: [PATCH v3 16/27] staging: iio: resolver: ad2s1210: read excitation frequency from control register
  2023-09-29 17:23 ` [PATCH v3 16/27] staging: iio: resolver: ad2s1210: read excitation frequency from control register David Lechner
@ 2023-09-30 15:08   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:08 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:21 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This modifies the ad2s1210_show_fexcit() function to read the excitation
> frequency from the control register. This way we don't have to keep
> track of the value and don't risk returning a stale value.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
Applied.

A bit more fuzz with this one as context was different for the first hunk.

Jonathan

> ---
> 
> v3 changes: None
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 19 +++++++++++++++----
>  1 file changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index 28ab877e1bc0..b15d71b17266 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -76,7 +76,6 @@ struct ad2s1210_state {
>  	struct regmap *regmap;
>  	/** The external oscillator frequency in Hz. */
>  	unsigned long clkin_hz;
> -	unsigned int fexcit;
>  	u8 resolution;
>  	/** For reading raw sample value via SPI. */
>  	__be16 sample __aligned(IIO_DMA_MINALIGN);
> @@ -206,8 +205,6 @@ static int ad2s1210_reinit_excitation_frequency(struct ad2s1210_state *st,
>  	if (ret < 0)
>  		return ret;
>  
> -	st->fexcit = fexcit;
> -
>  	/*
>  	 * Software reset reinitializes the excitation frequency output.
>  	 * It does not reset any of the configuration registers.
> @@ -232,8 +229,22 @@ static ssize_t ad2s1210_show_fexcit(struct device *dev,
>  				    char *buf)
>  {
>  	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> +	unsigned int value;
> +	u16 fexcit;
> +	int ret;
>  
> -	return sprintf(buf, "%u\n", st->fexcit);
> +	mutex_lock(&st->lock);
> +	ret = regmap_read(st->regmap, AD2S1210_REG_EXCIT_FREQ, &value);
> +	if (ret < 0)
> +		goto error_ret;
> +
> +	fexcit = value * st->clkin_hz / (1 << 15);
> +
> +	ret = sprintf(buf, "%u\n", fexcit);
> +
> +error_ret:
> +	mutex_unlock(&st->lock);
> +	return ret;
>  }
>  
>  static ssize_t ad2s1210_store_fexcit(struct device *dev,
> 


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

* Re: [PATCH v3 17/27] staging: iio: resolver: ad2s1210: convert fexcit to channel attribute
  2023-09-29 17:23 ` [PATCH v3 17/27] staging: iio: resolver: ad2s1210: convert fexcit to channel attribute David Lechner
@ 2023-09-30 15:12   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:12 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:22 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> The ad2s1210 driver has a device-specific attribute `fexcit` for setting
> the frequency of the excitation output. This converts it to a channel in
> order to use standard IIO ABI.
> 
> The excitation frequency is an analog output that generates a sine wave.
> Only the frequency is configurable. According to the datasheet, the
> specified range of the excitation frequency is from 2 kHz to 20 kHz and
> can be set in increments of 250 Hz.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
And this is the point where things got non trivial given I skipped
the hysterisis patch.

This looks good to me though, so will pick it up once questions on that
earlier patch are resolved.

Thanks,

Jonathan

> ---
> 
> v3 changes:
> * This is a new patch in v3 instead of "iio: resolver: ad2s1210: rename fexcit
>   attribute"
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 122 ++++++++++++++++++--------------
>  1 file changed, 70 insertions(+), 52 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index b15d71b17266..6accb9e3db46 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -224,54 +224,6 @@ static int ad2s1210_set_resolution_gpios(struct ad2s1210_state *st,
>  				     bitmap);
>  }
>  
> -static ssize_t ad2s1210_show_fexcit(struct device *dev,
> -				    struct device_attribute *attr,
> -				    char *buf)
> -{
> -	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> -	unsigned int value;
> -	u16 fexcit;
> -	int ret;
> -
> -	mutex_lock(&st->lock);
> -	ret = regmap_read(st->regmap, AD2S1210_REG_EXCIT_FREQ, &value);
> -	if (ret < 0)
> -		goto error_ret;
> -
> -	fexcit = value * st->clkin_hz / (1 << 15);
> -
> -	ret = sprintf(buf, "%u\n", fexcit);
> -
> -error_ret:
> -	mutex_unlock(&st->lock);
> -	return ret;
> -}
> -
> -static ssize_t ad2s1210_store_fexcit(struct device *dev,
> -				     struct device_attribute *attr,
> -				     const char *buf, size_t len)
> -{
> -	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> -	u16 fexcit;
> -	int ret;
> -
> -	ret = kstrtou16(buf, 10, &fexcit);
> -	if (ret < 0 || fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT)
> -		return -EINVAL;
> -
> -	mutex_lock(&st->lock);
> -	ret = ad2s1210_reinit_excitation_frequency(st, fexcit);
> -	if (ret < 0)
> -		goto error_ret;
> -
> -	ret = len;
> -
> -error_ret:
> -	mutex_unlock(&st->lock);
> -
> -	return ret;
> -}
> -
>  static ssize_t ad2s1210_show_resolution(struct device *dev,
>  					struct device_attribute *attr,
>  					char *buf)
> @@ -474,6 +426,38 @@ static int ad2s1210_set_hysteresis(struct ad2s1210_state *st, int val)
>  	return ret;
>  }
>  
> +static int ad2s1210_get_excitation_frequency(struct ad2s1210_state *st, int *val)
> +{
> +	unsigned int reg_val;
> +	int ret;
> +
> +	mutex_lock(&st->lock);
> +	ret = regmap_read(st->regmap, AD2S1210_REG_EXCIT_FREQ, &reg_val);
> +	if (ret < 0)
> +		goto error_ret;
> +
> +	*val = reg_val * st->clkin_hz / (1 << 15);
> +	ret = IIO_VAL_INT;
> +
> +error_ret:
> +	mutex_unlock(&st->lock);
> +	return ret;
> +}
> +
> +static int ad2s1210_set_excitation_frequency(struct ad2s1210_state *st, int val)
> +{
> +	int ret;
> +
> +	if (val < AD2S1210_MIN_EXCIT || val > AD2S1210_MAX_EXCIT)
> +		return -EINVAL;
> +
> +	mutex_lock(&st->lock);
> +	ret = ad2s1210_reinit_excitation_frequency(st, val);
> +	mutex_unlock(&st->lock);
> +
> +	return ret;
> +}
> +
>  static const int ad2s1210_velocity_scale[] = {
>  	17089132, /* 8.192MHz / (2*pi * 2500 / 2^15) */
>  	42722830, /* 8.192MHz / (2*pi * 1000 / 2^15) */
> @@ -506,6 +490,13 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
>  		default:
>  			return -EINVAL;
>  		}
> +	case IIO_CHAN_INFO_FREQUENCY:
> +		switch (chan->type) {
> +		case IIO_ALTVOLTAGE:
> +			return ad2s1210_get_excitation_frequency(st, val);
> +		default:
> +			return -EINVAL;
> +		}
>  	case IIO_CHAN_INFO_HYSTERESIS:
>  		switch (chan->type) {
>  		case IIO_ANGL:
> @@ -523,9 +514,23 @@ static int ad2s1210_read_avail(struct iio_dev *indio_dev,
>  			       const int **vals, int *type,
>  			       int *length, long mask)
>  {
> +	static const int excitation_frequency_available[] = {
> +		AD2S1210_MIN_EXCIT,
> +		250, /* step */
> +		AD2S1210_MAX_EXCIT,
> +	};
>  	static const int hysteresis_available[] = { 0, 1 };
>  
>  	switch (mask) {
> +	case IIO_CHAN_INFO_FREQUENCY:
> +		switch (chan->type) {
> +		case IIO_ALTVOLTAGE:
> +			*type = IIO_VAL_INT;
> +			*vals = excitation_frequency_available;
> +			return IIO_AVAIL_RANGE;
> +		default:
> +			return -EINVAL;
> +		}
>  	case IIO_CHAN_INFO_HYSTERESIS:
>  		switch (chan->type) {
>  		case IIO_ANGL:
> @@ -548,6 +553,13 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
>  	struct ad2s1210_state *st = iio_priv(indio_dev);
>  
>  	switch (mask) {
> +	case IIO_CHAN_INFO_FREQUENCY:
> +		switch (chan->type) {
> +		case IIO_ALTVOLTAGE:
> +			return ad2s1210_set_excitation_frequency(st, val);
> +		default:
> +			return -EINVAL;
> +		}
>  	case IIO_CHAN_INFO_HYSTERESIS:
>  		switch (chan->type) {
>  		case IIO_ANGL:
> @@ -560,8 +572,6 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
>  	}
>  }
>  
> -static IIO_DEVICE_ATTR(fexcit, 0644,
> -		       ad2s1210_show_fexcit,	ad2s1210_store_fexcit, 0);
>  static IIO_DEVICE_ATTR(bits, 0644,
>  		       ad2s1210_show_resolution, ad2s1210_store_resolution, 0);
>  static IIO_DEVICE_ATTR(fault, 0644,
> @@ -605,11 +615,19 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
>  		.channel = 0,
>  		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
>  				      BIT(IIO_CHAN_INFO_SCALE),
> -	}
> +	}, {
> +		/* excitation frequency output */
> +		.type = IIO_ALTVOLTAGE,
> +		.indexed = 1,
> +		.channel = 0,
> +		.output = 1,
> +		.scan_index = -1,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_FREQUENCY),
> +		.info_mask_separate_available = BIT(IIO_CHAN_INFO_FREQUENCY),
> +	},
>  };
>  
>  static struct attribute *ad2s1210_attributes[] = {
> -	&iio_dev_attr_fexcit.dev_attr.attr,
>  	&iio_dev_attr_bits.dev_attr.attr,
>  	&iio_dev_attr_fault.dev_attr.attr,
>  	&iio_dev_attr_los_thrd.dev_attr.attr,
> 


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

* Re: [PATCH v3 18/27] staging: iio: resolver: ad2s1210: convert resolution to devicetree property
  2023-09-29 17:23 ` [PATCH v3 18/27] staging: iio: resolver: ad2s1210: convert resolution to devicetree property David Lechner
@ 2023-09-30 15:15   ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:15 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:23 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> Selecting the resolution was implemented as the `bits` sysfs attribute.
> However, the selection of the resolution depends on how the hardware
> is wired and the specific application, so this is rather a job for
> devicetree to describe.
> 
> A new devicetree property `adi,resolution` to specify the resolution
> required for each chip is added and the `bits` sysfs attribute is
> removed.

Description need updating to reflect property having a different name.

Otherwise this LGTM
> 
> Since the resolution is now supplied by a devicetree property, the
> resolution-gpios are now optional and we can allow for the case where
> the resolution pins on the AD2S1210 are hard-wired instead of requiring
> them to be connected to gpios.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
...

>  
> +static int ad2s1210_setup_properties(struct ad2s1210_state *st)
> +{
> +	struct device *dev = &st->sdev->dev;
> +	u32 val;
> +	int ret;
> +
> +	ret = device_property_read_u32(dev, "assigned-resolution-bits", &val);
Doesn't match patch description of what this is called.

> +	if (ret < 0)
> +		return dev_err_probe(dev, ret,
> +			"failed to read assigned-resolution-bits property\n");
> +
> +	if (val < 10 || val > 16)
> +		return dev_err_probe(dev, -EINVAL,
> +				     "resolution out of range: %u\n", val);
> +
> +	st->resolution = (val - 10) >> 1;
> +
> +	return 0;
> +}
> +


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

* Re: [PATCH v3 19/27] staging: iio: resolver: ad2s1210: add phase lock range support
  2023-09-29 17:23 ` [PATCH v3 19/27] staging: iio: resolver: ad2s1210: add phase lock range support David Lechner
@ 2023-09-30 15:18   ` Jonathan Cameron
  2023-10-03  8:03   ` kernel test robot
  1 sibling, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:18 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:24 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> The AD2S1210 chip has a phase lock range feature that allows selecting
> the allowable phase difference between the excitation output and the
> sine and cosine inputs. This can be set to either 44 degrees (default)
> or 360 degrees.
> 
> This patch adds a new phase channel with a threshold event that can be
> used to configure the phase lock range. Actually emitting the event
> will be added in a subsequent patch.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
> ---
Looks good to me.


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

* Re: [PATCH v3 21/27] staging: iio: resolver: ad2s1210: convert LOT threshold attrs to event attrs
  2023-09-29 17:23 ` [PATCH v3 21/27] staging: iio: resolver: ad2s1210: convert LOT threshold attrs to event attrs David Lechner
@ 2023-09-30 15:29   ` Jonathan Cameron
  2023-10-03 11:11   ` kernel test robot
  1 sibling, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:29 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:26 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> The AD2S1210 monitors the internal error signal (difference between
> estimated angle and measured angle) to determine a loss of position
> tracking (LOT) condition. When the error value exceeds a threshold, a
> fault is triggered. This threshold is user-configurable.
> 
> This patch converts the custom lot_high_thrd and lot_low_thrd attributes
> in the ad2s1210 driver to standard event attributes. This will allow
> tooling to be able to expose these in a generic way.
> 
> Since the low threshold determines the hysteresis, it requires some
> special handling to expose the difference between the high and low
> register values as the hysteresis instead of exposing the low register
> value directly.
> 
> The attributes also return the values in radians now as required by the
> ABI.
> 
> Actually emitting the fault event will be done in a later patch.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
> ---

A style comment inline. Otherwise this an any patches before it I skipped
commenting on look fine to me.


> +
> +static int ad2s1210_get_lot_low_threshold(struct ad2s1210_state *st,
> +					  int *val, int *val2)
> +{
> +	unsigned int high_reg_val, low_reg_val;
> +	int ret;
> +
> +	mutex_lock(&st->lock);
> +	ret = regmap_read(st->regmap, AD2S1210_REG_LOT_HIGH_THRD, &high_reg_val);
> +	if (ret < 0)
> +		goto error_ret;
> +
> +	ret = regmap_read(st->regmap, AD2S1210_REG_LOT_LOW_THRD, &low_reg_val);
> +
A separate error path is going to be easier to read.

	return IIO_VAL_INT_PLUS_MICRO;

error_ret:
	mutex_unlock(&st->lock);

	return ret;

Of make use of the new stuff in cleanup.h etc.  something like.

	scoped_guard(mutex)(&st->lock) {
		ret = regmap_read(st->regmap, ...)
		if (ret)
			return ret;

		ret = regmap_read(...)
		if (ret)
			return ret;
	}
	
	/* sysfs value is hysteresis rather than actual low value */

In general you could make could use o
guard(mutex)(&st->lock);
in the other functions where  you hold the lock to the end of the function.

Could do that as a follow on patch though and as that stuff is all
very new, I'm not going to mind if you don't want to use it at all and
just use the approach above.

> +error_ret:
> +	mutex_unlock(&st->lock);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	/* sysfs value is hysteresis rather than actual low value */
> +	*val = 0;
> +	*val2 = (high_reg_val - low_reg_val) *
> +		ad2s1210_lot_threshold_urad_per_lsb[st->resolution];
> +	return IIO_VAL_INT_PLUS_MICRO;
> +}
> +
> +static int ad2s1210_set_lot_low_threshold(struct ad2s1210_state *st,
> +					  int val, int val2)
> +{
> +	unsigned int reg_val, hysteresis;
> +	int ret;
> +
> +	/* all valid values are between 0 and pi/4 radians */
> +	if (val != 0)
> +		return -EINVAL;
> +
> +	hysteresis = val2 / ad2s1210_lot_threshold_urad_per_lsb[st->resolution];
> +
> +	mutex_lock(&st->lock);
> +	ret = regmap_read(st->regmap, AD2S1210_REG_LOT_HIGH_THRD, &reg_val);
> +	if (ret < 0)
> +		goto error_ret;
> +
> +	ret = regmap_write(st->regmap, AD2S1210_REG_LOT_LOW_THRD,
> +			   reg_val - hysteresis);
> +
> +error_ret:
> +	mutex_unlock(&st->lock);
> +
> +	return ret;
> +}
>


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

* Re: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
  2023-09-29 17:23 ` [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr David Lechner
@ 2023-09-30 15:32   ` Jonathan Cameron
  2023-10-04 11:01     ` Hennerich, Michael
  2023-09-30 15:42   ` Jonathan Cameron
  2023-10-03 14:21   ` kernel test robot
  2 siblings, 1 reply; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:32 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:27 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> The AD2S1210 has a programmable threshold for the loss of signal (LOS)
> fault. This fault is triggered when either the sine or cosine input
> falls below the threshold voltage.
> 
> This patch converts the custom device LOS threshold attribute to an
> event falling edge threshold attribute on a new monitor signal channel.
> The monitor signal is an internal signal that combines the amplitudes
> of the sine and cosine inputs as well as the current angle and position
> output. This signal is used to detect faults in the input signals.
> 
> The attribute now uses millivolts instead of the raw register value in
> accordance with the IIO ABI.
> 
> Emitting the event will be implemented in a later patch.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>

I think I'm fine with treating these internal signals like this, but
I would ideally like someone from Analog devices to take a look at how
these are being done and make sure our interpretations of the signals
make sense to them.  We are pushing the boundaries a little here (though
we have done similar before for fault events I think.)

Jonathan


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

* Re: [PATCH v3 23/27] staging: iio: resolver: ad2s1210: convert DOS overrange threshold to event attr
  2023-09-29 17:23 ` [PATCH v3 23/27] staging: iio: resolver: ad2s1210: convert DOS overrange " David Lechner
@ 2023-09-30 15:33   ` Jonathan Cameron
  2023-10-03 17:21   ` kernel test robot
  1 sibling, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:33 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:28 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> The AD2S1210 has a programmable threshold for the degradation of signal
> (DOS) overrange fault. This fault is triggered when either the sine or
> cosine input rises the threshold voltage.

rises above the threshold voltage.

> 
> This patch converts the custom device DOS overrange threshold attribute
> to an event rising edge threshold attribute on the monitor signal
> channel.
> 
> The attribute now uses millivolts instead of the raw register value in
> accordance with the IIO ABI.
> 
> Emitting the event will be implemented in a later patch.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>

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

* Re: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
  2023-09-29 17:23 ` [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr David Lechner
  2023-09-30 15:32   ` Jonathan Cameron
@ 2023-09-30 15:42   ` Jonathan Cameron
  2023-09-30 15:46     ` Jonathan Cameron
  2023-10-02 16:09     ` David Lechner
  2023-10-03 14:21   ` kernel test robot
  2 siblings, 2 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:42 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:27 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> The AD2S1210 has a programmable threshold for the loss of signal (LOS)
> fault. This fault is triggered when either the sine or cosine input
> falls below the threshold voltage.
> 
> This patch converts the custom device LOS threshold attribute to an
> event falling edge threshold attribute on a new monitor signal channel.
> The monitor signal is an internal signal that combines the amplitudes
> of the sine and cosine inputs as well as the current angle and position
> output. This signal is used to detect faults in the input signals.

Hmm. Looking forwards, I'm less sure that we should be shoving all these
error conditions onto one channel. Fundamentally we have
sine and cosine inputs. I think we should treat those as separate channels
and include a third differential channel between them.

So this one becomes a double event (you need to signal it on both
cosine and sine channels).  The DOS overange is similar.
The DOS mismatch is a threshold on the differential channel giving

events/in_altvoltage0_thresh_falling_value
events/in_altvoltage1_thresh_falling_value (these match)
events/in_altvoltage0_thresh_rising_value
events/in_altvoltage1_thresh_rising_value (matches previous which is fine)
events/in_altvoltage1-0_mag_rising_value

Does that work here?  Avoids smashing different types of signals together.
We could even do the LOT as differential between two angle channels
(tracking one and measured one) but meh that's getting complex.

Note this will rely on channel labels to make the above make any sense at all.

Jonathan


> 
> The attribute now uses millivolts instead of the raw register value in
> accordance with the IIO ABI.
> 
> Emitting the event will be implemented in a later patch.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
> ---
> 
> v3 changes: This is a new patch in v3
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 75 +++++++++++++++++++++++++++++++--
>  1 file changed, 71 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index 5cc8106800d6..7abbc184c351 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -66,6 +66,11 @@
>  #define PHASE_360_DEG_TO_RAD_INT 6
>  #define PHASE_360_DEG_TO_RAD_MICRO 283185
>  
> +/* Threshold voltage registers have 1 LSB == 38 mV */
> +#define THRESHOLD_MILLIVOLT_PER_LSB 38
> +/* max voltage for threshold registers is 0x7F * 38 mV */
> +#define THRESHOLD_RANGE_STR "[0 38 4826]"
> +
>  enum ad2s1210_mode {
>  	MOD_POS = 0b00,
>  	MOD_VEL = 0b01,
> @@ -448,6 +453,38 @@ static const int ad2s1210_lot_threshold_urad_per_lsb[] = {
>  	1237, /* 16-bit: same as 14-bit */
>  };
>  
> +static int ad2s1210_get_voltage_threshold(struct ad2s1210_state *st,
> +					  unsigned int reg, int *val)
> +{
> +	unsigned int reg_val;
> +	int ret;
> +
> +	mutex_lock(&st->lock);
> +	ret = regmap_read(st->regmap, reg, &reg_val);
> +	mutex_unlock(&st->lock);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	*val = reg_val * THRESHOLD_MILLIVOLT_PER_LSB;
> +	return IIO_VAL_INT;
> +}
> +
> +static int ad2s1210_set_voltage_threshold(struct ad2s1210_state *st,
> +					  unsigned int reg, int val)
> +{
> +	unsigned int reg_val;
> +	int ret;
> +
> +	reg_val = val / THRESHOLD_MILLIVOLT_PER_LSB;
> +
> +	mutex_lock(&st->lock);
> +	ret = regmap_write(st->regmap, reg, reg_val);
> +	mutex_unlock(&st->lock);
> +
> +	return ret;
> +}
> +
>  static int ad2s1210_get_lot_high_threshold(struct ad2s1210_state *st,
>  					   int *val, int *val2)
>  {
> @@ -706,9 +743,6 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
>  static IIO_DEVICE_ATTR(fault, 0644,
>  		       ad2s1210_show_fault, ad2s1210_clear_fault, 0);
>  
> -static IIO_DEVICE_ATTR(los_thrd, 0644,
> -		       ad2s1210_show_reg, ad2s1210_store_reg,
> -		       AD2S1210_REG_LOS_THRD);
>  static IIO_DEVICE_ATTR(dos_ovr_thrd, 0644,
>  		       ad2s1210_show_reg, ad2s1210_store_reg,
>  		       AD2S1210_REG_DOS_OVR_THRD);
> @@ -745,6 +779,16 @@ static const struct iio_event_spec ad2s1210_phase_event_spec[] = {
>  	},
>  };
>  
> +static const struct iio_event_spec ad2s1210_monitor_signal_event_spec[] = {
> +	{
> +		/* Sine/cosine below LOS threshold fault. */
> +		.type = IIO_EV_TYPE_THRESH,
> +		.dir = IIO_EV_DIR_FALLING,
> +		/* Loss of signal threshold. */
> +		.mask_separate = BIT(IIO_EV_INFO_VALUE),
> +	},
> +};
> +
>  static const struct iio_chan_spec ad2s1210_channels[] = {
>  	{
>  		.type = IIO_ANGL,
> @@ -803,12 +847,19 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
>  		.scan_index = -1,
>  		.info_mask_separate = BIT(IIO_CHAN_INFO_FREQUENCY),
>  		.info_mask_separate_available = BIT(IIO_CHAN_INFO_FREQUENCY),
> +	}, {
> +		/* monitor signal */
> +		.type = IIO_ALTVOLTAGE,
> +		.indexed = 1,
> +		.channel = 0,
> +		.scan_index = -1,
> +		.event_spec = ad2s1210_monitor_signal_event_spec,
> +		.num_event_specs = ARRAY_SIZE(ad2s1210_monitor_signal_event_spec),
>  	},
>  };
>  
>  static struct attribute *ad2s1210_attributes[] = {
>  	&iio_dev_attr_fault.dev_attr.attr,
> -	&iio_dev_attr_los_thrd.dev_attr.attr,
>  	&iio_dev_attr_dos_ovr_thrd.dev_attr.attr,
>  	&iio_dev_attr_dos_mis_thrd.dev_attr.attr,
>  	&iio_dev_attr_dos_rst_max_thrd.dev_attr.attr,
> @@ -847,11 +898,13 @@ IIO_CONST_ATTR(in_phase0_mag_value_available,
>  	       __stringify(PHASE_44_DEG_TO_RAD_MICRO) " "
>  	       __stringify(PHASE_360_DEG_TO_RAD_INT) "."
>  	       __stringify(PHASE_360_DEG_TO_RAD_MICRO));
> +IIO_CONST_ATTR(in_altvoltage0_thresh_falling_value_available, THRESHOLD_RANGE_STR);
>  IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_value_available, 0);
>  IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_hysteresis_available, 0);
>  
>  static struct attribute *ad2s1210_event_attributes[] = {
>  	&iio_const_attr_in_phase0_mag_value_available.dev_attr.attr,
> +	&iio_const_attr_in_altvoltage0_thresh_falling_value_available.dev_attr.attr,
>  	&iio_dev_attr_in_angl1_thresh_rising_value_available.dev_attr.attr,
>  	&iio_dev_attr_in_angl1_thresh_rising_hysteresis_available.dev_attr.attr,
>  	NULL,
> @@ -904,6 +957,13 @@ static int ad2s1210_read_event_value(struct iio_dev *indio_dev,
>  		default:
>  			return -EINVAL;
>  		}
> +	case IIO_ALTVOLTAGE:
> +		if (chan->output)
> +			return -EINVAL;
> +		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_FALLING)
> +			return ad2s1210_get_voltage_threshold(st,
> +						AD2S1210_REG_LOS_THRD, val);
> +		return -EINVAL;
>  	case IIO_PHASE:
>  		return ad2s1210_get_phase_lock_range(st, val, val2);
>  	default:
> @@ -930,6 +990,13 @@ static int ad2s1210_write_event_value(struct iio_dev *indio_dev,
>  		default:
>  			return -EINVAL;
>  		}
> +	case IIO_ALTVOLTAGE:
> +		if (chan->output)
> +			return -EINVAL;
> +		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_FALLING)
> +			return ad2s1210_set_voltage_threshold(st,
> +						AD2S1210_REG_LOS_THRD, val);
> +		return -EINVAL;
>  	case IIO_PHASE:
>  		return ad2s1210_set_phase_lock_range(st, val, val2);
>  	default:
> 


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

* Re: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
  2023-09-30 15:42   ` Jonathan Cameron
@ 2023-09-30 15:46     ` Jonathan Cameron
  2023-10-02 16:09     ` David Lechner
  1 sibling, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:46 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Sat, 30 Sep 2023 16:42:51 +0100
Jonathan Cameron <jic23@kernel.org> wrote:

> On Fri, 29 Sep 2023 12:23:27 -0500
> David Lechner <dlechner@baylibre.com> wrote:
> 
> > From: David Lechner <david@lechnology.com>
> > 
> > From: David Lechner <dlechner@baylibre.com>
> > 
> > The AD2S1210 has a programmable threshold for the loss of signal (LOS)
> > fault. This fault is triggered when either the sine or cosine input
> > falls below the threshold voltage.
> > 
> > This patch converts the custom device LOS threshold attribute to an
> > event falling edge threshold attribute on a new monitor signal channel.
> > The monitor signal is an internal signal that combines the amplitudes
> > of the sine and cosine inputs as well as the current angle and position
> > output. This signal is used to detect faults in the input signals.  
> 
> Hmm. Looking forwards, I'm less sure that we should be shoving all these
> error conditions onto one channel. Fundamentally we have
> sine and cosine inputs. I think we should treat those as separate channels
> and include a third differential channel between them.
> 
> So this one becomes a double event (you need to signal it on both
> cosine and sine channels).  The DOS overange is similar.
> The DOS mismatch is a threshold on the differential channel giving
> 
> events/in_altvoltage0_thresh_falling_value
> events/in_altvoltage1_thresh_falling_value (these match)
> events/in_altvoltage0_thresh_rising_value
> events/in_altvoltage1_thresh_rising_value (matches previous which is fine)
> events/in_altvoltage1-0_mag_rising_value

Sorry, got the syntax wrong :( Should have checked the ABI docs.

events/in_altvoltage1-altvoltage0_mag_rising_value

> 
> Does that work here?  Avoids smashing different types of signals together.
> We could even do the LOT as differential between two angle channels
> (tracking one and measured one) but meh that's getting complex.
> 
> Note this will rely on channel labels to make the above make any sense at all.
> 
> Jonathan
> 
> 
> > 
> > The attribute now uses millivolts instead of the raw register value in
> > accordance with the IIO ABI.
> > 
> > Emitting the event will be implemented in a later patch.
> > 
> > Signed-off-by: David Lechner <dlechner@baylibre.com>
> > ---
> > 
> > v3 changes: This is a new patch in v3
> > 
> >  drivers/staging/iio/resolver/ad2s1210.c | 75 +++++++++++++++++++++++++++++++--
> >  1 file changed, 71 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> > index 5cc8106800d6..7abbc184c351 100644
> > --- a/drivers/staging/iio/resolver/ad2s1210.c
> > +++ b/drivers/staging/iio/resolver/ad2s1210.c
> > @@ -66,6 +66,11 @@
> >  #define PHASE_360_DEG_TO_RAD_INT 6
> >  #define PHASE_360_DEG_TO_RAD_MICRO 283185
> >  
> > +/* Threshold voltage registers have 1 LSB == 38 mV */
> > +#define THRESHOLD_MILLIVOLT_PER_LSB 38
> > +/* max voltage for threshold registers is 0x7F * 38 mV */
> > +#define THRESHOLD_RANGE_STR "[0 38 4826]"
> > +
> >  enum ad2s1210_mode {
> >  	MOD_POS = 0b00,
> >  	MOD_VEL = 0b01,
> > @@ -448,6 +453,38 @@ static const int ad2s1210_lot_threshold_urad_per_lsb[] = {
> >  	1237, /* 16-bit: same as 14-bit */
> >  };
> >  
> > +static int ad2s1210_get_voltage_threshold(struct ad2s1210_state *st,
> > +					  unsigned int reg, int *val)
> > +{
> > +	unsigned int reg_val;
> > +	int ret;
> > +
> > +	mutex_lock(&st->lock);
> > +	ret = regmap_read(st->regmap, reg, &reg_val);
> > +	mutex_unlock(&st->lock);
> > +
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	*val = reg_val * THRESHOLD_MILLIVOLT_PER_LSB;
> > +	return IIO_VAL_INT;
> > +}
> > +
> > +static int ad2s1210_set_voltage_threshold(struct ad2s1210_state *st,
> > +					  unsigned int reg, int val)
> > +{
> > +	unsigned int reg_val;
> > +	int ret;
> > +
> > +	reg_val = val / THRESHOLD_MILLIVOLT_PER_LSB;
> > +
> > +	mutex_lock(&st->lock);
> > +	ret = regmap_write(st->regmap, reg, reg_val);
> > +	mutex_unlock(&st->lock);
> > +
> > +	return ret;
> > +}
> > +
> >  static int ad2s1210_get_lot_high_threshold(struct ad2s1210_state *st,
> >  					   int *val, int *val2)
> >  {
> > @@ -706,9 +743,6 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
> >  static IIO_DEVICE_ATTR(fault, 0644,
> >  		       ad2s1210_show_fault, ad2s1210_clear_fault, 0);
> >  
> > -static IIO_DEVICE_ATTR(los_thrd, 0644,
> > -		       ad2s1210_show_reg, ad2s1210_store_reg,
> > -		       AD2S1210_REG_LOS_THRD);
> >  static IIO_DEVICE_ATTR(dos_ovr_thrd, 0644,
> >  		       ad2s1210_show_reg, ad2s1210_store_reg,
> >  		       AD2S1210_REG_DOS_OVR_THRD);
> > @@ -745,6 +779,16 @@ static const struct iio_event_spec ad2s1210_phase_event_spec[] = {
> >  	},
> >  };
> >  
> > +static const struct iio_event_spec ad2s1210_monitor_signal_event_spec[] = {
> > +	{
> > +		/* Sine/cosine below LOS threshold fault. */
> > +		.type = IIO_EV_TYPE_THRESH,
> > +		.dir = IIO_EV_DIR_FALLING,
> > +		/* Loss of signal threshold. */
> > +		.mask_separate = BIT(IIO_EV_INFO_VALUE),
> > +	},
> > +};
> > +
> >  static const struct iio_chan_spec ad2s1210_channels[] = {
> >  	{
> >  		.type = IIO_ANGL,
> > @@ -803,12 +847,19 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
> >  		.scan_index = -1,
> >  		.info_mask_separate = BIT(IIO_CHAN_INFO_FREQUENCY),
> >  		.info_mask_separate_available = BIT(IIO_CHAN_INFO_FREQUENCY),
> > +	}, {
> > +		/* monitor signal */
> > +		.type = IIO_ALTVOLTAGE,
> > +		.indexed = 1,
> > +		.channel = 0,
> > +		.scan_index = -1,
> > +		.event_spec = ad2s1210_monitor_signal_event_spec,
> > +		.num_event_specs = ARRAY_SIZE(ad2s1210_monitor_signal_event_spec),
> >  	},
> >  };
> >  
> >  static struct attribute *ad2s1210_attributes[] = {
> >  	&iio_dev_attr_fault.dev_attr.attr,
> > -	&iio_dev_attr_los_thrd.dev_attr.attr,
> >  	&iio_dev_attr_dos_ovr_thrd.dev_attr.attr,
> >  	&iio_dev_attr_dos_mis_thrd.dev_attr.attr,
> >  	&iio_dev_attr_dos_rst_max_thrd.dev_attr.attr,
> > @@ -847,11 +898,13 @@ IIO_CONST_ATTR(in_phase0_mag_value_available,
> >  	       __stringify(PHASE_44_DEG_TO_RAD_MICRO) " "
> >  	       __stringify(PHASE_360_DEG_TO_RAD_INT) "."
> >  	       __stringify(PHASE_360_DEG_TO_RAD_MICRO));
> > +IIO_CONST_ATTR(in_altvoltage0_thresh_falling_value_available, THRESHOLD_RANGE_STR);
> >  IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_value_available, 0);
> >  IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_hysteresis_available, 0);
> >  
> >  static struct attribute *ad2s1210_event_attributes[] = {
> >  	&iio_const_attr_in_phase0_mag_value_available.dev_attr.attr,
> > +	&iio_const_attr_in_altvoltage0_thresh_falling_value_available.dev_attr.attr,
> >  	&iio_dev_attr_in_angl1_thresh_rising_value_available.dev_attr.attr,
> >  	&iio_dev_attr_in_angl1_thresh_rising_hysteresis_available.dev_attr.attr,
> >  	NULL,
> > @@ -904,6 +957,13 @@ static int ad2s1210_read_event_value(struct iio_dev *indio_dev,
> >  		default:
> >  			return -EINVAL;
> >  		}
> > +	case IIO_ALTVOLTAGE:
> > +		if (chan->output)
> > +			return -EINVAL;
> > +		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_FALLING)
> > +			return ad2s1210_get_voltage_threshold(st,
> > +						AD2S1210_REG_LOS_THRD, val);
> > +		return -EINVAL;
> >  	case IIO_PHASE:
> >  		return ad2s1210_get_phase_lock_range(st, val, val2);
> >  	default:
> > @@ -930,6 +990,13 @@ static int ad2s1210_write_event_value(struct iio_dev *indio_dev,
> >  		default:
> >  			return -EINVAL;
> >  		}
> > +	case IIO_ALTVOLTAGE:
> > +		if (chan->output)
> > +			return -EINVAL;
> > +		if (type == IIO_EV_TYPE_THRESH && dir == IIO_EV_DIR_FALLING)
> > +			return ad2s1210_set_voltage_threshold(st,
> > +						AD2S1210_REG_LOS_THRD, val);
> > +		return -EINVAL;
> >  	case IIO_PHASE:
> >  		return ad2s1210_set_phase_lock_range(st, val, val2);
> >  	default:
> >   
> 


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

* Re: [PATCH v3 25/27] staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs
  2023-09-29 17:23 ` [PATCH v3 25/27] staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs David Lechner
@ 2023-09-30 15:47   ` Jonathan Cameron
  2023-10-02 17:06     ` David Lechner
  2023-10-03 23:23   ` kernel test robot
  1 sibling, 1 reply; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 15:47 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:30 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> The AD2S1210 has a programmable threshold for the degradation of signal
> (DOS) mismatch fault. This fault is triggered when the difference in
> amplitude between the sine and cosine inputs exceeds the threshold.
> 
> The DOS reset min/max registers on the chip provide initial values
> for internal tracking of the min/max of the monitor signal after the
> fault register is cleared.
> 
> This patch converts the custom device DOS reset min/max threshold
> attributes custom event attributes on the monitor signal channel.
> 
> The attributes now use millivolts instead of the raw register value in
> accordance with the IIO ABI.
> 
> Emitting the event will be implemented in a later patch.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
> ---
> 
> v3 changes: This is a new patch in v3
> 
>  .../Documentation/sysfs-bus-iio-resolver-ad2s1210  | 27 ++++++
>  drivers/staging/iio/resolver/ad2s1210.c            | 99 ++++++++++++----------
>  2 files changed, 82 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-resolver-ad2s1210 b/drivers/staging/iio/Documentation/sysfs-bus-iio-resolver-ad2s1210
> new file mode 100644
> index 000000000000..ea75881b0c77
> --- /dev/null
> +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-resolver-ad2s1210
> @@ -0,0 +1,27 @@
> +What:		/sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_max
Ah. So these are differential.  But the mismatch channel value isn't?  

I also got the format wrong for differential channels. Oops. Should
be the in_altvoltage0-altvoltage1 format for the previous suggestion
to change that channel type to differential.

This looks fine to me as new ABI.

Jonathan



> +KernelVersion:  6.7
> +Contact:	linux-iio@vger.kernel.org
> +Description:
> +		Reading returns the current Degradation of Signal Reset Maximum
> +		Threshold value in millivolts. Writing sets the value.
> +
> +What:		/sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_max_available
> +KernelVersion:  6.7
> +Contact:	linux-iio@vger.kernel.org
> +Description:
> +		Reading returns the allowable voltage range for
> +		in_altvoltage0-altvoltage1_thresh_rising_reset_max.
> +
> +What:		/sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_min
> +KernelVersion:  6.7
> +Contact:	linux-iio@vger.kernel.org
> +Description:
> +		Reading returns the current Degradation of Signal Reset Minimum
> +		Threshold value in millivolts. Writing sets the value.
> +
> +What:		/sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_min_available
> +KernelVersion:  6.7
> +Contact:	linux-iio@vger.kernel.org
> +Description:
> +		Reading returns the allowable voltage range for
> +		in_altvoltage0-altvoltage1_thresh_rising_reset_min.
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index aa14edbe8a77..e1c95ec73545 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -283,41 +283,6 @@ static ssize_t ad2s1210_clear_fault(struct device *dev,
>  	return ret < 0 ? ret : len;
>  }
>  
> -static ssize_t ad2s1210_show_reg(struct device *dev,
> -				 struct device_attribute *attr,
> -				 char *buf)
> -{
> -	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> -	struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
> -	unsigned int value;
> -	int ret;
> -
> -	mutex_lock(&st->lock);
> -	ret = regmap_read(st->regmap, iattr->address, &value);
> -	mutex_unlock(&st->lock);
> -
> -	return ret < 0 ? ret : sprintf(buf, "%d\n", value);
> -}
> -
> -static ssize_t ad2s1210_store_reg(struct device *dev,
> -				  struct device_attribute *attr,
> -				  const char *buf, size_t len)
> -{
> -	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> -	unsigned char data;
> -	int ret;
> -	struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
> -
> -	ret = kstrtou8(buf, 10, &data);
> -	if (ret)
> -		return -EINVAL;
> -
> -	mutex_lock(&st->lock);
> -	ret = regmap_write(st->regmap, iattr->address, data);
> -	mutex_unlock(&st->lock);
> -	return ret < 0 ? ret : len;
> -}
> -
>  static int ad2s1210_single_conversion(struct ad2s1210_state *st,
>  				      struct iio_chan_spec const *chan,
>  				      int *val)
> @@ -743,13 +708,6 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
>  static IIO_DEVICE_ATTR(fault, 0644,
>  		       ad2s1210_show_fault, ad2s1210_clear_fault, 0);
>  
> -static IIO_DEVICE_ATTR(dos_rst_max_thrd, 0644,
> -		       ad2s1210_show_reg, ad2s1210_store_reg,
> -		       AD2S1210_REG_DOS_RST_MAX_THRD);
> -static IIO_DEVICE_ATTR(dos_rst_min_thrd, 0644,
> -		       ad2s1210_show_reg, ad2s1210_store_reg,
> -		       AD2S1210_REG_DOS_RST_MIN_THRD);
> -
>  static const struct iio_event_spec ad2s1210_position_event_spec[] = {
>  	{
>  		/* Tracking error exceeds LOT threshold fault. */
> @@ -867,8 +825,6 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
>  
>  static struct attribute *ad2s1210_attributes[] = {
>  	&iio_dev_attr_fault.dev_attr.attr,
> -	&iio_dev_attr_dos_rst_max_thrd.dev_attr.attr,
> -	&iio_dev_attr_dos_rst_min_thrd.dev_attr.attr,
>  	NULL,
>  };
>  
> @@ -876,6 +832,49 @@ static const struct attribute_group ad2s1210_attribute_group = {
>  	.attrs = ad2s1210_attributes,
>  };
>  
> +static ssize_t event_attr_voltage_reg_show(struct device *dev,
> +					   struct device_attribute *attr,
> +					   char *buf)
> +{
> +	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> +	struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
> +	unsigned int value;
> +	int ret;
> +
> +	mutex_lock(&st->lock);
> +	ret = regmap_read(st->regmap, iattr->address, &value);
> +	mutex_unlock(&st->lock);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	return sprintf(buf, "%d\n", value * THRESHOLD_MILLIVOLT_PER_LSB);
> +}
> +
> +static ssize_t event_attr_voltage_reg_store(struct device *dev,
> +					    struct device_attribute *attr,
> +					    const char *buf, size_t len)
> +{
> +	struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> +	struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
> +	u16 data;
> +	int ret;
> +
> +	ret = kstrtou16(buf, 10, &data);
> +	if (ret)
> +		return -EINVAL;
> +
> +	mutex_lock(&st->lock);
> +	ret = regmap_write(st->regmap, iattr->address,
> +			   data / THRESHOLD_MILLIVOLT_PER_LSB);
> +	mutex_unlock(&st->lock);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	return len;
> +}
> +
>  static ssize_t
>  in_angl1_thresh_rising_value_available_show(struct device *dev,
>  					    struct device_attribute *attr,
> @@ -906,6 +905,14 @@ IIO_CONST_ATTR(in_phase0_mag_value_available,
>  IIO_CONST_ATTR(in_altvoltage0_thresh_falling_value_available, THRESHOLD_RANGE_STR);
>  IIO_CONST_ATTR(in_altvoltage0_thresh_rising_value_available, THRESHOLD_RANGE_STR);
>  IIO_CONST_ATTR(in_altvoltage0_mag_value_available, THRESHOLD_RANGE_STR);
> +IIO_DEVICE_ATTR(in_altvoltage0_mag_reset_max, 0644,
> +		event_attr_voltage_reg_show, event_attr_voltage_reg_store,
> +		AD2S1210_REG_DOS_RST_MAX_THRD);
> +IIO_CONST_ATTR(in_altvoltage0_mag_reset_max_available, THRESHOLD_RANGE_STR);
> +IIO_DEVICE_ATTR(in_altvoltage0_mag_reset_min, 0644,
> +		event_attr_voltage_reg_show, event_attr_voltage_reg_store,
> +		AD2S1210_REG_DOS_RST_MIN_THRD);
> +IIO_CONST_ATTR(in_altvoltage0_mag_reset_min_available, THRESHOLD_RANGE_STR);
>  IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_value_available, 0);
>  IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_hysteresis_available, 0);
>  
> @@ -914,6 +921,10 @@ static struct attribute *ad2s1210_event_attributes[] = {
>  	&iio_const_attr_in_altvoltage0_thresh_falling_value_available.dev_attr.attr,
>  	&iio_const_attr_in_altvoltage0_thresh_rising_value_available.dev_attr.attr,
>  	&iio_const_attr_in_altvoltage0_mag_value_available.dev_attr.attr,
> +	&iio_dev_attr_in_altvoltage0_mag_reset_max.dev_attr.attr,
> +	&iio_const_attr_in_altvoltage0_mag_reset_max_available.dev_attr.attr,
> +	&iio_dev_attr_in_altvoltage0_mag_reset_min.dev_attr.attr,
> +	&iio_const_attr_in_altvoltage0_mag_reset_min_available.dev_attr.attr,
>  	&iio_dev_attr_in_angl1_thresh_rising_value_available.dev_attr.attr,
>  	&iio_dev_attr_in_angl1_thresh_rising_hysteresis_available.dev_attr.attr,
>  	NULL,
> 


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

* Re: [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events
  2023-09-29 17:23 ` [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events David Lechner
  2023-09-30  3:55   ` kernel test robot
@ 2023-09-30 16:00   ` Jonathan Cameron
  2023-10-02 16:43     ` David Lechner
  2023-10-02 16:58     ` David Lechner
  2023-10-03 10:53   ` Dan Carpenter
  2 siblings, 2 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-09-30 16:00 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Fri, 29 Sep 2023 12:23:31 -0500
David Lechner <dlechner@baylibre.com> wrote:

> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> When reading the position and velocity on the AD2S1210, there is also a
> 3rd byte following the two data bytes that contains the fault flag bits.
> This patch adds support for reading this byte and generating events when
> faults occur.
> 
> The faults are mapped to various channels and event types in order to
> have a unique event for each fault.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>

Use of x and y modifiers is a little odd.  What was your reasoning?
Was it just that there was a X_OR_Y modifier?  If so, don't use that!
It seemed like a good idea at the time, but it's not nice to deal with
and requires a channel with that modifier to hang the controls off
+ make sure userspace expects that event code.

> ---
> 
> v3 changes: This is a new patch in v3
> 
>  drivers/staging/iio/resolver/ad2s1210.c | 175 +++++++++++++++++++++++++++++---
>  1 file changed, 161 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> index e1c95ec73545..dc3cc3ab855e 100644
> --- a/drivers/staging/iio/resolver/ad2s1210.c
> +++ b/drivers/staging/iio/resolver/ad2s1210.c
> @@ -21,6 +21,7 @@
>  #include <linux/types.h>
>  
>  #include <linux/iio/buffer.h>
> +#include <linux/iio/events.h>
>  #include <linux/iio/iio.h>
>  #include <linux/iio/sysfs.h>
>  #include <linux/iio/trigger_consumer.h>
> @@ -35,6 +36,16 @@
>  #define AD2S1210_SET_ENRES		GENMASK(3, 2)
>  #define AD2S1210_SET_RES		GENMASK(1, 0)
>  
> +/* fault register flags */
> +#define AD2S1210_FAULT_CLIP		BIT(7)
> +#define AD2S1210_FAULT_LOS		BIT(6)
> +#define AD2S1210_FAULT_DOS_OVR		BIT(5)
> +#define AD2S1210_FAULT_DOS_MIS		BIT(4)
> +#define AD2S1210_FAULT_LOT		BIT(3)
> +#define AD2S1210_FAULT_VELOCITY		BIT(2)
> +#define AD2S1210_FAULT_PHASE		BIT(1)
> +#define AD2S1210_FAULT_CONFIG_PARITY	BIT(0)
> +
>  #define AD2S1210_REG_POSITION_MSB	0x80
>  #define AD2S1210_REG_POSITION_LSB	0x81
>  #define AD2S1210_REG_VELOCITY_MSB	0x82
> @@ -71,6 +82,8 @@
>  /* max voltage for threshold registers is 0x7F * 38 mV */
>  #define THRESHOLD_RANGE_STR "[0 38 4826]"
>  
> +#define FAULT_ONESHOT(bit, new, old) (new & bit && !(old & bit))
> +
>  enum ad2s1210_mode {
>  	MOD_POS = 0b00,
>  	MOD_VEL = 0b01,
> @@ -98,8 +111,13 @@ struct ad2s1210_state {
>  	unsigned long clkin_hz;
>  	/** The selected resolution */
>  	enum ad2s1210_resolution resolution;
> +	/** Copy of fault register from the previous read. */
> +	u8 prev_fault_flags;
>  	/** For reading raw sample value via SPI. */
> -	__be16 sample __aligned(IIO_DMA_MINALIGN);
> +	struct {
> +		__be16 raw;
> +		u8 fault;
> +	} sample __aligned(IIO_DMA_MINALIGN);;
>  	/** Scan buffer */
>  	struct {
>  		__be16 chan[2];
> @@ -158,7 +176,15 @@ static int ad2s1210_regmap_reg_write(void *context, unsigned int reg,
>  	if (ret < 0)
>  		return ret;
>  
> -	return spi_sync_transfer(st->sdev, xfers, ARRAY_SIZE(xfers));
> +	ret = spi_sync_transfer(st->sdev, xfers, ARRAY_SIZE(xfers));
> +	if (ret < 0)
> +		return ret;
> +
> +	/* soft reset also clears the fault register */
> +	if (reg == AD2S1210_REG_SOFT_RESET)
> +		st->prev_fault_flags = 0;
> +
> +	return 0;
>  }
>  
>  /*
> @@ -200,6 +226,10 @@ static int ad2s1210_regmap_reg_read(void *context, unsigned int reg,
>  	if (ret < 0)
>  		return ret;
>  
> +	/* reading the fault register also clears it */
> +	if (reg == AD2S1210_REG_FAULT)
> +		st->prev_fault_flags = 0;
> +
>  	/*
>  	 * If the D7 bit is set on any read/write register, it indicates a
>  	 * parity error. The fault register is read-only and the D7 bit means
> @@ -283,14 +313,92 @@ static ssize_t ad2s1210_clear_fault(struct device *dev,
>  	return ret < 0 ? ret : len;
>  }
>  
> -static int ad2s1210_single_conversion(struct ad2s1210_state *st,
> +static void ad2s1210_push_events(struct iio_dev *indio_dev,
> +				 u8 flags, s64 timestamp)
> +{
> +	struct ad2s1210_state *st = iio_priv(indio_dev);
> +
> +	/* Sine/cosine inputs clipped */
> +	if (FAULT_ONESHOT(AD2S1210_FAULT_CLIP, flags, st->prev_fault_flags))
> +		iio_push_event(indio_dev,
> +			       IIO_MOD_EVENT_CODE(IIO_ALTVOLTAGE, 1,
> +			       			  IIO_MOD_X_OR_Y,
Hmm. So this is a weird corner I'd forgotten about and explains your
use of X and Y modifiers. 
Long ago this was added to support a similar case to the one you have,
but mixing and matching modifiers like this doesn't scale, so
I think we'd be better just signally events on both channels.
If nothing else, someone waiting for an event on a specific channel
isn't looking for this weird modifier.

When it was used before we added a channel for MOD_X_OR_Y so events
were enabled on that. It's horrible though so don't do that.

> +						  IIO_EV_TYPE_MAG,
> +						  IIO_EV_DIR_NONE),
> +			       timestamp);
> +
> +	/* Sine/cosine inputs below LOS threshold */
> +	if (FAULT_ONESHOT(AD2S1210_FAULT_LOS, flags, st->prev_fault_flags))
> +		iio_push_event(indio_dev,
> +			       IIO_UNMOD_EVENT_CODE(IIO_ALTVOLTAGE, 0,
> +						    IIO_EV_TYPE_THRESH,
> +						    IIO_EV_DIR_FALLING),
> +			       timestamp);
> +
> +	/* Sine/cosine inputs exceed DOS overrange threshold */
> +	if (FAULT_ONESHOT(AD2S1210_FAULT_DOS_OVR, flags, st->prev_fault_flags))
> +		iio_push_event(indio_dev,
> +			       IIO_UNMOD_EVENT_CODE(IIO_ALTVOLTAGE, 0,
> +						    IIO_EV_TYPE_THRESH,
> +						    IIO_EV_DIR_RISING),
> +			       timestamp);
> +
> +	/* Sine/cosine inputs exceed DOS mismatch threshold */
> +	if (FAULT_ONESHOT(AD2S1210_FAULT_DOS_MIS, flags, st->prev_fault_flags))
> +		iio_push_event(indio_dev,
> +			       IIO_UNMOD_EVENT_CODE(IIO_ALTVOLTAGE, 0,
> +						    IIO_EV_TYPE_MAG,
> +						    IIO_EV_DIR_NONE),
> +			       timestamp);
> +
> +	/* Tracking error exceeds LOT threshold */
> +	if (FAULT_ONESHOT(AD2S1210_FAULT_LOT, flags, st->prev_fault_flags))
> +		iio_push_event(indio_dev,
> +			       IIO_UNMOD_EVENT_CODE(IIO_ANGL, 1,
> +						    IIO_EV_TYPE_THRESH,
> +						    IIO_EV_DIR_RISING),
> +			       timestamp);
> +
> +	/* Velocity exceeds maximum tracking rate */
> +	if (FAULT_ONESHOT(AD2S1210_FAULT_VELOCITY, flags, st->prev_fault_flags))
> +		iio_push_event(indio_dev,
> +			       IIO_UNMOD_EVENT_CODE(IIO_ANGL_VEL, 0,
> +						    IIO_EV_TYPE_THRESH,
> +						    IIO_EV_DIR_RISING),
> +			       timestamp);
> +
> +	/* Phase error exceeds phase lock range */
> +	if (FAULT_ONESHOT(AD2S1210_FAULT_PHASE, flags, st->prev_fault_flags))
> +		iio_push_event(indio_dev,
> +			       IIO_UNMOD_EVENT_CODE(IIO_PHASE, 0,
> +						    IIO_EV_TYPE_MAG,
> +						    IIO_EV_DIR_NONE),
> +			       timestamp);
> +
> +	/* Configuration parity error */
> +	if (FAULT_ONESHOT(AD2S1210_FAULT_CONFIG_PARITY, flags,
> +			  st->prev_fault_flags))
> +		/*
> +		 * Userspace should also get notified of this via error return
> +		 * when trying to write to any attribute that writes a register.
> +		 */
> +		dev_err_ratelimited(&indio_dev->dev,
> +				    "Configuration parity error\n");
> +
> +	st->prev_fault_flags = flags;
> +}
> +
> +static int ad2s1210_single_conversion(struct iio_dev *indio_dev,
>  				      struct iio_chan_spec const *chan,
>  				      int *val)
>  {
> +	struct ad2s1210_state *st = iio_priv(indio_dev);
> +	s64 timestamp;
>  	int ret;
>  
>  	mutex_lock(&st->lock);
>  	gpiod_set_value(st->sample_gpio, 1);
> +	timestamp = iio_get_time_ns(indio_dev);
>  	/* delay (6 * tck + 20) nano seconds */
>  	udelay(1);
>  
> @@ -307,17 +415,17 @@ static int ad2s1210_single_conversion(struct ad2s1210_state *st,
>  	}
>  	if (ret < 0)
>  		goto error_ret;
> -	ret = spi_read(st->sdev, &st->sample, 2);
> +	ret = spi_read(st->sdev, &st->sample, 3);
>  	if (ret < 0)
>  		goto error_ret;
>  
>  	switch (chan->type) {
>  	case IIO_ANGL:
> -		*val = be16_to_cpu(st->sample);
> +		*val = be16_to_cpu(st->sample.raw);
>  		ret = IIO_VAL_INT;
>  		break;
>  	case IIO_ANGL_VEL:
> -		*val = (s16)be16_to_cpu(st->sample);
> +		*val = (s16)be16_to_cpu(st->sample.raw);
>  		ret = IIO_VAL_INT;
>  		break;
>  	default:
> @@ -325,6 +433,8 @@ static int ad2s1210_single_conversion(struct ad2s1210_state *st,
>  		break;
>  	}
>  
> +	ad2s1210_push_events(indio_dev, st->rx[2], timestamp);
> +
>  error_ret:
>  	gpiod_set_value(st->sample_gpio, 0);
>  	/* delay (2 * tck + 20) nano seconds */
> @@ -608,7 +718,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
>  
>  	switch (mask) {
>  	case IIO_CHAN_INFO_RAW:
> -		return ad2s1210_single_conversion(st, chan, val);
> +		return ad2s1210_single_conversion(indio_dev, chan, val);
>  	case IIO_CHAN_INFO_SCALE:
>  		switch (chan->type) {
>  		case IIO_ANGL:
> @@ -721,6 +831,14 @@ static const struct iio_event_spec ad2s1210_position_event_spec[] = {
>  	},
>  };
>  
> +static const struct iio_event_spec ad2s1210_velocity_event_spec[] = {
> +	{
> +		/* Velocity exceeds maximum tracking rate fault. */
> +		.type = IIO_EV_TYPE_THRESH,
> +		.dir = IIO_EV_DIR_RISING,
> +	},
> +};
> +
>  static const struct iio_event_spec ad2s1210_phase_event_spec[] = {
>  	{
>  		/* Phase error fault. */
> @@ -754,6 +872,14 @@ static const struct iio_event_spec ad2s1210_monitor_signal_event_spec[] = {
>  	},
>  };
>  
> +static const struct iio_event_spec ad2s1210_sin_cos_event_spec[] = {
> +	{
> +		/* Sine/cosine clipping fault. */
> +		.type = IIO_EV_TYPE_MAG,
> +		.dir = IIO_EV_DIR_NONE,
> +	},
> +};
> +
>  static const struct iio_chan_spec ad2s1210_channels[] = {
>  	{
>  		.type = IIO_ANGL,
> @@ -784,6 +910,8 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
>  		},
>  		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
>  				      BIT(IIO_CHAN_INFO_SCALE),
> +		.event_spec = ad2s1210_velocity_event_spec,
> +		.num_event_specs = ARRAY_SIZE(ad2s1210_velocity_event_spec),
>  	},
>  	IIO_CHAN_SOFT_TIMESTAMP(2),
>  	{
> @@ -820,6 +948,26 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
>  		.scan_index = -1,
>  		.event_spec = ad2s1210_monitor_signal_event_spec,
>  		.num_event_specs = ARRAY_SIZE(ad2s1210_monitor_signal_event_spec),
> +	}, {
> +		/* sine input */
> +		.type = IIO_ALTVOLTAGE,
> +		.indexed = 1,
> +		.channel = 1,
> +		.modified = 1,
> +		.channel2 = IIO_MOD_Y,
A bit odd and I'm not sure it's beneficial over just using an index
and a label for the channel. 

If a modifier is necessary then we could add a new one for this.
Another option might be to provide in_altvoltage0_phase 

or... can we map this to i (inphase) and q (quadrature) phases?
Sort of feels like we can, and those modifiers already exist.

Note though that if we do that, we'll need to modify the various
ABI docs etc to include the modifiers whenever it's about the sine
and cosine channels.

> +		.scan_index = -1,
> +		.event_spec = ad2s1210_sin_cos_event_spec,
> +		.num_event_specs = ARRAY_SIZE(ad2s1210_sin_cos_event_spec),
> +	}, {
> +		/* cosine input */
> +		.type = IIO_ALTVOLTAGE,
> +		.indexed = 1,
> +		.channel = 1,
> +		.modified = 1,
> +		.channel2 = IIO_MOD_X,
> +		.scan_index = -1,
> +		.event_spec = ad2s1210_sin_cos_event_spec,
> +		.num_event_specs = ARRAY_SIZE(ad2s1210_sin_cos_event_spec),
>  	},
>  };
>  
> @@ -936,7 +1084,7 @@ static const struct attribute_group ad2s1210_event_attribute_group = {
>  
>  static int ad2s1210_initial(struct ad2s1210_state *st)
>  {
> -	unsigned char data;
> +	unsigned int data;
>  	int ret;
>  
>  	mutex_lock(&st->lock);
> @@ -1073,12 +1221,11 @@ static irqreturn_t ad2s1210_trigger_handler(int irq, void *p)
>  		if (ret < 0)
>  			goto error_ret;
>  
> -		/* REVIST: we can read 3 bytes here and also get fault flags */
> -		ret = spi_read(st->sdev, st->rx, 2);
> +		ret = spi_read(st->sdev, &st->sample, 3);
>  		if (ret < 0)
>  			goto error_ret;
>  
> -		memcpy(&st->scan.chan[chan++], st->rx, 2);
> +		memcpy(&st->scan.chan[chan++], &st->sample.raw, 2);
>  	}
>  
>  	if (test_bit(1, indio_dev->active_scan_mask)) {
> @@ -1086,14 +1233,14 @@ static irqreturn_t ad2s1210_trigger_handler(int irq, void *p)
>  		if (ret < 0)
>  			goto error_ret;
>  
> -		/* REVIST: we can read 3 bytes here and also get fault flags */
> -		ret = spi_read(st->sdev, st->rx, 2);
> +		ret = spi_read(st->sdev, &st->sample, 3);
>  		if (ret < 0)
>  			goto error_ret;
>  
> -		memcpy(&st->scan.chan[chan++], st->rx, 2);
> +		memcpy(&st->scan.chan[chan++], &st->sample.raw, 2);
>  	}
>  
> +	ad2s1210_push_events(indio_dev, st->sample.fault, pf->timestamp);
>  	iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, pf->timestamp);
>  
>  error_ret:
> 


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

* Re: [PATCH v3 14/27] staging: iio: resolver: ad2s1210: implement hysteresis as channel attr
  2023-09-30 15:00     ` Jonathan Cameron
@ 2023-09-30 21:23       ` David Lechner
  0 siblings, 0 replies; 88+ messages in thread
From: David Lechner @ 2023-09-30 21:23 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Sat, Sep 30, 2023 at 10:00 AM Jonathan Cameron <jic23@kernel.org> wrote:
>
> On Fri, 29 Sep 2023 12:53:00 -0500
> David Lechner <dlechner@baylibre.com> wrote:
>
> > On Fri, Sep 29, 2023 at 12:25 PM David Lechner <dlechner@baylibre.com> wrote:
> > >
> > > The AD2S1210 resolver has a hysteresis feature that can be used to
> > > prevent flicker in the LSB of the position register. This can be either
> > > enabled or disabled. Disabling hysteresis is useful for increasing
> > > precision by oversampling.
> > >
> > > Signed-off-by: David Lechner <dlechner@baylibre.com>
> > > ---
> >
> > ...
> >
> > > +static int ad2s1210_read_avail(struct iio_dev *indio_dev,
> > > +                              struct iio_chan_spec const *chan,
> > > +                              const int **vals, int *type,
> > > +                              int *length, long mask)
> > > +{
> > > +       static const int hysteresis_available[] = { 0, 1 };
> >
> > This is basically an enable/disable. Should the 1 value be changed to the
> > appropriate radians value since this is hysteresis on the position
> > (angle) channel?
>
> Good point. However it should be in the _raw units. The text is
> slightly more explicit on this for
> the variant of hysteresis applied to threshold events as it's
> added or substracted from a threshold (and thresholds are in
> _raw readings unless only _processed is available).
>
> Does that make 0, 1 correct as we are talking about LSB only?
>

It is currently only correct (as a raw value) if the selected
resolution is 16-bit. So I will need to fix this so the value is `1 <<
(16 - resolution)`.

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

* Re: [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210
  2023-09-29 17:23 ` [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210 David Lechner
  2023-09-30 14:34   ` Jonathan Cameron
@ 2023-10-02  8:02   ` Dan Carpenter
  2023-10-02  9:03     ` Jonathan Cameron
  2023-10-02 15:18   ` Rob Herring
  2 siblings, 1 reply; 88+ messages in thread
From: Dan Carpenter @ 2023-10-02  8:02 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner,
	Jonathan Cameron, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Michael Hennerich, Nuno Sá, Axel Haslam, Philip Molloy,
	linux-kernel, Apelete Seketeli

On Fri, Sep 29, 2023 at 12:23:06PM -0500, David Lechner wrote:
> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 

Having two from headers kind of messes things up.  The second From is
included in the body of the commit message.

regards,
dan carpenter


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

* Re: [PATCH v3 02/27] staging: iio: resolver: ad2s1210: fix use before initialization
  2023-09-29 17:23 ` [PATCH v3 02/27] staging: iio: resolver: ad2s1210: fix use before initialization David Lechner
  2023-09-30 14:28   ` Jonathan Cameron
@ 2023-10-02  8:07   ` Dan Carpenter
  2023-10-02  9:17     ` Jonathan Cameron
  1 sibling, 1 reply; 88+ messages in thread
From: Dan Carpenter @ 2023-10-02  8:07 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner,
	Jonathan Cameron, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Michael Hennerich, Nuno Sá, Axel Haslam, Philip Molloy,
	linux-kernel

On Fri, Sep 29, 2023 at 12:23:07PM -0500, David Lechner wrote:
> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This fixes a use before initialization in ad2s1210_probe(). The
> ad2s1210_setup_gpios() function uses st->sdev but it was being called
> before this field was initialized.
> 
> Signed-off-by: David Lechner <dlechner@baylibre.com>
> ---
> 

Fixes: b19e9ad5e2cb ("staging:iio:resolver:ad2s1210 general driver cleanup.")

This would crash the driver right away, on probe.  It's amazing no one
filed a bug report even though the bug is 12 years old.

regards,
dan carpenter


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

* Re: [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210
  2023-10-02  8:02   ` Dan Carpenter
@ 2023-10-02  9:03     ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-10-02  9:03 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: David Lechner, linux-iio, devicetree, linux-staging,
	David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, Apelete Seketeli

On Mon, 2 Oct 2023 11:02:40 +0300
Dan Carpenter <dan.carpenter@linaro.org> wrote:

> On Fri, Sep 29, 2023 at 12:23:06PM -0500, David Lechner wrote:
> > From: David Lechner <david@lechnology.com>
> > 
> > From: David Lechner <dlechner@baylibre.com>
> >   
> 
> Having two from headers kind of messes things up.  The second From is
> included in the body of the commit message.
> 
> regards,
> dan carpenter

Strangely b4 + git am didn't do that.  I was assuming I'd need
to fix these by hand but didn't need to.  I thanked my lucky
stars for a few mins saved and didn't look into why ;)

e.g.
https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git/commit/?h=testing&id=b3689e14415a874630f0894d8c3ac7ea01603d57

BTW, David replied to the cover letter to call out this mess up.




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

* Re: [PATCH v3 02/27] staging: iio: resolver: ad2s1210: fix use before initialization
  2023-10-02  8:07   ` Dan Carpenter
@ 2023-10-02  9:17     ` Jonathan Cameron
  2023-10-06 14:48       ` Vincent Whitchurch
  0 siblings, 1 reply; 88+ messages in thread
From: Jonathan Cameron @ 2023-10-02  9:17 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: David Lechner, linux-iio, devicetree, linux-staging,
	David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Hennerich, Nuno Sá, Axel Haslam,
	Philip Molloy, linux-kernel, Vincent Whitchurch

On Mon, 2 Oct 2023 11:07:15 +0300
Dan Carpenter <dan.carpenter@linaro.org> wrote:

> On Fri, Sep 29, 2023 at 12:23:07PM -0500, David Lechner wrote:
> > From: David Lechner <david@lechnology.com>
> > 
> > From: David Lechner <dlechner@baylibre.com>
> > 
> > This fixes a use before initialization in ad2s1210_probe(). The
> > ad2s1210_setup_gpios() function uses st->sdev but it was being called
> > before this field was initialized.
> > 
> > Signed-off-by: David Lechner <dlechner@baylibre.com>
> > ---
> >   
> 
> Fixes: b19e9ad5e2cb ("staging:iio:resolver:ad2s1210 general driver cleanup.")
Thanks but nope, not that one.

At that point ad2s1210_setup_gpios, didn't use st->sdev.
I think this went wrong when the platform data was removed in 

I 'think' it was
Fixes: f356dc6ec26b ("staging: iio: ad2s1210: Switch to the gpio descriptor interface")



> 
> This would crash the driver right away, on probe.  It's amazing no one
> filed a bug report even though the bug is 12 years old.
Only 5 years :)

Welcome to the long tail of IIO Devices and the long term availability of the
hardware - this is still a production part.  Clearly no one was using the
upstream driver for 5 + years, but here comes David who is not only fixing
the bugs but cleaning it up.

Hmm. What happened to roadtest? I was hoping that would solve this sort
of issue by allowing simple testing of basic functionality... Hope it
is still headed for a new version / upstream!

Jonathan

> regards,
> dan carpenter





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

* Re: [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210
  2023-09-29 17:23 ` [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210 David Lechner
  2023-09-30 14:34   ` Jonathan Cameron
  2023-10-02  8:02   ` Dan Carpenter
@ 2023-10-02 15:18   ` Rob Herring
  2023-10-05 14:13     ` Jonathan Cameron
  2 siblings, 1 reply; 88+ messages in thread
From: Rob Herring @ 2023-10-02 15:18 UTC (permalink / raw)
  To: David Lechner
  Cc: Philip Molloy, linux-staging, Axel Haslam, Apelete Seketeli,
	Rob Herring, Conor Dooley, linux-iio, Michael Hennerich,
	Jonathan Cameron, linux-kernel, Nuno Sá, Krzysztof Kozlowski,
	devicetree, David Lechner


On Fri, 29 Sep 2023 12:23:06 -0500, David Lechner wrote:
> From: David Lechner <david@lechnology.com>
> 
> From: David Lechner <dlechner@baylibre.com>
> 
> This adds new DeviceTree bindings for the Analog Devices, Inc. AD2S1210
> resolver-to-digital converter.
> 
> Co-developed-by: Apelete Seketeli <aseketeli@baylibre.com>
> Signed-off-by: Apelete Seketeli <aseketeli@baylibre.com>
> Signed-off-by: David Lechner <dlechner@baylibre.com>
> ---
> 
> v3 changes:
> * Expanded top-level description of A0/A1 lines.
> * Added required voltage -supply properties. (I did not pick up Rob's
>   Reviewed-by since I wasn't sure if this was trivial enough.)
> 
> v2 changes:
> * Add Co-developed-by:
> * Remove extraneous quotes on strings
> * Remove extraneous pipe on some multi-line descriptions
> 
>  .../bindings/iio/resolver/adi,ad2s1210.yaml        | 177 +++++++++++++++++++++
>  1 file changed, 177 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>


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

* Re: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
  2023-09-30 15:42   ` Jonathan Cameron
  2023-09-30 15:46     ` Jonathan Cameron
@ 2023-10-02 16:09     ` David Lechner
  2023-10-05 14:37       ` Jonathan Cameron
  1 sibling, 1 reply; 88+ messages in thread
From: David Lechner @ 2023-10-02 16:09 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Sat, Sep 30, 2023 at 10:42 AM Jonathan Cameron <jic23@kernel.org> wrote:
>
> On Fri, 29 Sep 2023 12:23:27 -0500
> David Lechner <dlechner@baylibre.com> wrote:
>
> > From: David Lechner <david@lechnology.com>
> >
> > From: David Lechner <dlechner@baylibre.com>
> >
> > The AD2S1210 has a programmable threshold for the loss of signal (LOS)
> > fault. This fault is triggered when either the sine or cosine input
> > falls below the threshold voltage.
> >
> > This patch converts the custom device LOS threshold attribute to an
> > event falling edge threshold attribute on a new monitor signal channel.
> > The monitor signal is an internal signal that combines the amplitudes
> > of the sine and cosine inputs as well as the current angle and position
> > output. This signal is used to detect faults in the input signals.
>
> Hmm. Looking forwards, I'm less sure that we should be shoving all these
> error conditions onto one channel. Fundamentally we have
> sine and cosine inputs. I think we should treat those as separate channels
> and include a third differential channel between them.

At first, I did consider a differential channel as you suggested in
v2. However, the datasheet is quite clear that the LOS and DOS faults
(and only those faults) come from a signal it calls the "monitor
signal". This signal is defined as:

    Monitor = A1 * sin(theta)  * sin(phi) + A2 * cos(theta) * cos(phi)

where A1 * sin(theta) is the the sine input, A2 * cos(theta) is the
cosine input and phi is the position output. So mathematically
speaking, there is no signal that is the difference between the two
inputs. (See "Theory of Operation" section in the datasheet.)

But if we want to hide these internal details and don't care about a
strict definition of "differential", then what is suggested below
seems fine.

>
> So this one becomes a double event (you need to signal it on both
> cosine and sine channels).  The DOS overange is similar.
> The DOS mismatch is a threshold on the differential channel giving
>
> events/in_altvoltage0_thresh_falling_value
> events/in_altvoltage1_thresh_falling_value (these match)
> events/in_altvoltage0_thresh_rising_value
> events/in_altvoltage1_thresh_rising_value (matches previous which is fine)
> events/in_altvoltage1-altvoltage0_mag_rising_value
>
> Does that work here?  Avoids smashing different types of signals together.
> We could even do the LOT as differential between two angle channels
> (tracking one and measured one) but meh that's getting complex.>
> Note this will rely on channel labels to make the above make any sense at all.

I think this could be OK - I think what matters most is having some
documentation that maps the faults and registers on the chip to the
iio names. Where would the sine/cosine clipping fault fit in though? I
got a bit too creative and used X_OR_Y to differentiate it (see
discussion in "staging: iio: resolver: ad2s1210: implement fault
events"). Strictly speaking, it should probably be a type: threshold,
direction: either event on both the sine and cosine input channels
(another double event) since it occurs if either of the signal exceeds
the power or ground rail voltage. But we already have threshold rising
and threshold falling on these channels with a different meaning. I
guess it could call it magnitude instead of a threshold?

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

* Re: [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events
  2023-09-30 16:00   ` Jonathan Cameron
@ 2023-10-02 16:43     ` David Lechner
  2023-10-02 16:58     ` David Lechner
  1 sibling, 0 replies; 88+ messages in thread
From: David Lechner @ 2023-10-02 16:43 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Sat, Sep 30, 2023 at 11:00 AM Jonathan Cameron <jic23@kernel.org> wrote:
>
> On Fri, 29 Sep 2023 12:23:31 -0500
> David Lechner <dlechner@baylibre.com> wrote:
>
> > From: David Lechner <david@lechnology.com>
> >
> > From: David Lechner <dlechner@baylibre.com>
> >
> > When reading the position and velocity on the AD2S1210, there is also a
> > 3rd byte following the two data bytes that contains the fault flag bits.
> > This patch adds support for reading this byte and generating events when
> > faults occur.
> >
> > The faults are mapped to various channels and event types in order to
> > have a unique event for each fault.
> >
> > Signed-off-by: David Lechner <dlechner@baylibre.com>
>
> Use of x and y modifiers is a little odd.  What was your reasoning?
> Was it just that there was a X_OR_Y modifier?  If so, don't use that!
> It seemed like a good idea at the time, but it's not nice to deal with
> and requires a channel with that modifier to hang the controls off
> + make sure userspace expects that event code.
>

Yes, I was perhaps getting a bit too creative here (the two inputs
come from transformers mounted 90 degrees apart so measure X and Y
component of an angle). The only reason I did this was to take
advantage of the possibility of an "OR" event to avoid double events
for a single fault bit. We can just go with the double event on the
two different input channels as discussed in "[PATCH v3 22/27]
staging: iio: resolver: ad2s1210: convert LOS threshold to event
attr".

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

* Re: [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events
  2023-09-30 16:00   ` Jonathan Cameron
  2023-10-02 16:43     ` David Lechner
@ 2023-10-02 16:58     ` David Lechner
  2023-10-02 18:49       ` David Lechner
  2023-10-05 14:52       ` Jonathan Cameron
  1 sibling, 2 replies; 88+ messages in thread
From: David Lechner @ 2023-10-02 16:58 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Sat, Sep 30, 2023 at 11:00 AM Jonathan Cameron <jic23@kernel.org> wrote:
>
> On Fri, 29 Sep 2023 12:23:31 -0500
> David Lechner <dlechner@baylibre.com> wrote:
>
> > From: David Lechner <david@lechnology.com>
> >
> > From: David Lechner <dlechner@baylibre.com>
> >
> > When reading the position and velocity on the AD2S1210, there is also a
> > 3rd byte following the two data bytes that contains the fault flag bits.
> > This patch adds support for reading this byte and generating events when
> > faults occur.
> >
> > The faults are mapped to various channels and event types in order to
> > have a unique event for each fault.
> >
> > Signed-off-by: David Lechner <dlechner@baylibre.com>
>
> Use of x and y modifiers is a little odd.  What was your reasoning?
> Was it just that there was a X_OR_Y modifier?  If so, don't use that!
> It seemed like a good idea at the time, but it's not nice to deal with
> and requires a channel with that modifier to hang the controls off
> + make sure userspace expects that event code.


Regarding the point about "requires a channel with that modifier to
hang the controls off...". Although that comment was about modifiers,
does it also apply in general.

There are several fault events that don't have any configurable
parameters, namely _sine/cosine inputs clipping_ and _velocity exceeds
max tracking rate_. So there won't be any attributes that contain the
event specification for those (e.g. no `events/in_angl0_*`
attributes). It sounds like this would be a problem as well?

Should we consider a IIO_EV_INFO_LABEL so that we can have some sort
of attribute (namely `events/<dir>_<channel spec>_label`) so that
userspace can enumerate expected events for non-configurable events?

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

* Re: [PATCH v3 25/27] staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs
  2023-09-30 15:47   ` Jonathan Cameron
@ 2023-10-02 17:06     ` David Lechner
  0 siblings, 0 replies; 88+ messages in thread
From: David Lechner @ 2023-10-02 17:06 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Sat, Sep 30, 2023 at 10:47 AM Jonathan Cameron <jic23@kernel.org> wrote:
>
> On Fri, 29 Sep 2023 12:23:30 -0500
> David Lechner <dlechner@baylibre.com> wrote:
>
> > From: David Lechner <david@lechnology.com>
> >
> > From: David Lechner <dlechner@baylibre.com>
> >
> > The AD2S1210 has a programmable threshold for the degradation of signal
> > (DOS) mismatch fault. This fault is triggered when the difference in
> > amplitude between the sine and cosine inputs exceeds the threshold.
> >
> > The DOS reset min/max registers on the chip provide initial values
> > for internal tracking of the min/max of the monitor signal after the
> > fault register is cleared.
> >
> > This patch converts the custom device DOS reset min/max threshold
> > attributes custom event attributes on the monitor signal channel.
> >
> > The attributes now use millivolts instead of the raw register value in
> > accordance with the IIO ABI.
> >
> > Emitting the event will be implemented in a later patch.
> >
> > Signed-off-by: David Lechner <dlechner@baylibre.com>
> > ---
> >
> > v3 changes: This is a new patch in v3
> >
> >  .../Documentation/sysfs-bus-iio-resolver-ad2s1210  | 27 ++++++
> >  drivers/staging/iio/resolver/ad2s1210.c            | 99 ++++++++++++----------
> >  2 files changed, 82 insertions(+), 44 deletions(-)
> >
> > diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-resolver-ad2s1210 b/drivers/staging/iio/Documentation/sysfs-bus-iio-resolver-ad2s1210
> > new file mode 100644
> > index 000000000000..ea75881b0c77
> > --- /dev/null
> > +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-resolver-ad2s1210
> > @@ -0,0 +1,27 @@
> > +What:                /sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_max
> Ah. So these are differential.  But the mismatch channel value isn't?
>
> I also got the format wrong for differential channels. Oops. Should
> be the in_altvoltage0-altvoltage1 format for the previous suggestion
> to change that channel type to differential.
>
> This looks fine to me as new ABI.
>
> Jonathan
>

As discussed in
<https://lore.kernel.org/linux-iio/CAMknhBFKSqXvgOeRjGAOfURzndmxmCffdU6MUirEmfzKqwM_Kg@mail.gmail.com/>,
technically no they are not differential. I started to implement it
that way but changed my mind after understanding the datasheet more in
depth. It looks like I forgot to update the documentation in this
patch to match the final implementation that was submitted.

In any case, I will update the documentation to match the
implementation or vice versa depending on what we decide on for which
channel the events should be associated with.

>
>
> > +KernelVersion:  6.7
> > +Contact:     linux-iio@vger.kernel.org
> > +Description:
> > +             Reading returns the current Degradation of Signal Reset Maximum
> > +             Threshold value in millivolts. Writing sets the value.
> > +
> > +What:                /sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_max_available
> > +KernelVersion:  6.7
> > +Contact:     linux-iio@vger.kernel.org
> > +Description:
> > +             Reading returns the allowable voltage range for
> > +             in_altvoltage0-altvoltage1_thresh_rising_reset_max.
> > +
> > +What:                /sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_min
> > +KernelVersion:  6.7
> > +Contact:     linux-iio@vger.kernel.org
> > +Description:
> > +             Reading returns the current Degradation of Signal Reset Minimum
> > +             Threshold value in millivolts. Writing sets the value.
> > +
> > +What:                /sys/bus/iio/devices/iio:deviceX/events/in_altvoltage0-altvoltage1_thresh_rising_reset_min_available
> > +KernelVersion:  6.7
> > +Contact:     linux-iio@vger.kernel.org
> > +Description:
> > +             Reading returns the allowable voltage range for
> > +             in_altvoltage0-altvoltage1_thresh_rising_reset_min.
> > diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
> > index aa14edbe8a77..e1c95ec73545 100644
> > --- a/drivers/staging/iio/resolver/ad2s1210.c
> > +++ b/drivers/staging/iio/resolver/ad2s1210.c
> > @@ -283,41 +283,6 @@ static ssize_t ad2s1210_clear_fault(struct device *dev,
> >       return ret < 0 ? ret : len;
> >  }
> >
> > -static ssize_t ad2s1210_show_reg(struct device *dev,
> > -                              struct device_attribute *attr,
> > -                              char *buf)
> > -{
> > -     struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> > -     struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
> > -     unsigned int value;
> > -     int ret;
> > -
> > -     mutex_lock(&st->lock);
> > -     ret = regmap_read(st->regmap, iattr->address, &value);
> > -     mutex_unlock(&st->lock);
> > -
> > -     return ret < 0 ? ret : sprintf(buf, "%d\n", value);
> > -}
> > -
> > -static ssize_t ad2s1210_store_reg(struct device *dev,
> > -                               struct device_attribute *attr,
> > -                               const char *buf, size_t len)
> > -{
> > -     struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> > -     unsigned char data;
> > -     int ret;
> > -     struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
> > -
> > -     ret = kstrtou8(buf, 10, &data);
> > -     if (ret)
> > -             return -EINVAL;
> > -
> > -     mutex_lock(&st->lock);
> > -     ret = regmap_write(st->regmap, iattr->address, data);
> > -     mutex_unlock(&st->lock);
> > -     return ret < 0 ? ret : len;
> > -}
> > -
> >  static int ad2s1210_single_conversion(struct ad2s1210_state *st,
> >                                     struct iio_chan_spec const *chan,
> >                                     int *val)
> > @@ -743,13 +708,6 @@ static int ad2s1210_write_raw(struct iio_dev *indio_dev,
> >  static IIO_DEVICE_ATTR(fault, 0644,
> >                      ad2s1210_show_fault, ad2s1210_clear_fault, 0);
> >
> > -static IIO_DEVICE_ATTR(dos_rst_max_thrd, 0644,
> > -                    ad2s1210_show_reg, ad2s1210_store_reg,
> > -                    AD2S1210_REG_DOS_RST_MAX_THRD);
> > -static IIO_DEVICE_ATTR(dos_rst_min_thrd, 0644,
> > -                    ad2s1210_show_reg, ad2s1210_store_reg,
> > -                    AD2S1210_REG_DOS_RST_MIN_THRD);
> > -
> >  static const struct iio_event_spec ad2s1210_position_event_spec[] = {
> >       {
> >               /* Tracking error exceeds LOT threshold fault. */
> > @@ -867,8 +825,6 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
> >
> >  static struct attribute *ad2s1210_attributes[] = {
> >       &iio_dev_attr_fault.dev_attr.attr,
> > -     &iio_dev_attr_dos_rst_max_thrd.dev_attr.attr,
> > -     &iio_dev_attr_dos_rst_min_thrd.dev_attr.attr,
> >       NULL,
> >  };
> >
> > @@ -876,6 +832,49 @@ static const struct attribute_group ad2s1210_attribute_group = {
> >       .attrs = ad2s1210_attributes,
> >  };
> >
> > +static ssize_t event_attr_voltage_reg_show(struct device *dev,
> > +                                        struct device_attribute *attr,
> > +                                        char *buf)
> > +{
> > +     struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> > +     struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
> > +     unsigned int value;
> > +     int ret;
> > +
> > +     mutex_lock(&st->lock);
> > +     ret = regmap_read(st->regmap, iattr->address, &value);
> > +     mutex_unlock(&st->lock);
> > +
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     return sprintf(buf, "%d\n", value * THRESHOLD_MILLIVOLT_PER_LSB);
> > +}
> > +
> > +static ssize_t event_attr_voltage_reg_store(struct device *dev,
> > +                                         struct device_attribute *attr,
> > +                                         const char *buf, size_t len)
> > +{
> > +     struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
> > +     struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
> > +     u16 data;
> > +     int ret;
> > +
> > +     ret = kstrtou16(buf, 10, &data);
> > +     if (ret)
> > +             return -EINVAL;
> > +
> > +     mutex_lock(&st->lock);
> > +     ret = regmap_write(st->regmap, iattr->address,
> > +                        data / THRESHOLD_MILLIVOLT_PER_LSB);
> > +     mutex_unlock(&st->lock);
> > +
> > +     if (ret < 0)
> > +             return ret;
> > +
> > +     return len;
> > +}
> > +
> >  static ssize_t
> >  in_angl1_thresh_rising_value_available_show(struct device *dev,
> >                                           struct device_attribute *attr,
> > @@ -906,6 +905,14 @@ IIO_CONST_ATTR(in_phase0_mag_value_available,
> >  IIO_CONST_ATTR(in_altvoltage0_thresh_falling_value_available, THRESHOLD_RANGE_STR);
> >  IIO_CONST_ATTR(in_altvoltage0_thresh_rising_value_available, THRESHOLD_RANGE_STR);
> >  IIO_CONST_ATTR(in_altvoltage0_mag_value_available, THRESHOLD_RANGE_STR);
> > +IIO_DEVICE_ATTR(in_altvoltage0_mag_reset_max, 0644,
> > +             event_attr_voltage_reg_show, event_attr_voltage_reg_store,
> > +             AD2S1210_REG_DOS_RST_MAX_THRD);
> > +IIO_CONST_ATTR(in_altvoltage0_mag_reset_max_available, THRESHOLD_RANGE_STR);
> > +IIO_DEVICE_ATTR(in_altvoltage0_mag_reset_min, 0644,
> > +             event_attr_voltage_reg_show, event_attr_voltage_reg_store,
> > +             AD2S1210_REG_DOS_RST_MIN_THRD);
> > +IIO_CONST_ATTR(in_altvoltage0_mag_reset_min_available, THRESHOLD_RANGE_STR);
> >  IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_value_available, 0);
> >  IIO_DEVICE_ATTR_RO(in_angl1_thresh_rising_hysteresis_available, 0);

These attribute names don't match the documentation above. :-/

> >
> > @@ -914,6 +921,10 @@ static struct attribute *ad2s1210_event_attributes[] = {
> >       &iio_const_attr_in_altvoltage0_thresh_falling_value_available.dev_attr.attr,
> >       &iio_const_attr_in_altvoltage0_thresh_rising_value_available.dev_attr.attr,
> >       &iio_const_attr_in_altvoltage0_mag_value_available.dev_attr.attr,
> > +     &iio_dev_attr_in_altvoltage0_mag_reset_max.dev_attr.attr,
> > +     &iio_const_attr_in_altvoltage0_mag_reset_max_available.dev_attr.attr,
> > +     &iio_dev_attr_in_altvoltage0_mag_reset_min.dev_attr.attr,
> > +     &iio_const_attr_in_altvoltage0_mag_reset_min_available.dev_attr.attr,
> >       &iio_dev_attr_in_angl1_thresh_rising_value_available.dev_attr.attr,
> >       &iio_dev_attr_in_angl1_thresh_rising_hysteresis_available.dev_attr.attr,
> >       NULL,
> >
>

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

* Re: [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events
  2023-10-02 16:58     ` David Lechner
@ 2023-10-02 18:49       ` David Lechner
  2023-10-05 14:52       ` Jonathan Cameron
  1 sibling, 0 replies; 88+ messages in thread
From: David Lechner @ 2023-10-02 18:49 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Mon, Oct 2, 2023 at 11:58 AM David Lechner <dlechner@baylibre.com> wrote:
>
> On Sat, Sep 30, 2023 at 11:00 AM Jonathan Cameron <jic23@kernel.org> wrote:
> >
> > On Fri, 29 Sep 2023 12:23:31 -0500
> > David Lechner <dlechner@baylibre.com> wrote:
> >
> > > From: David Lechner <david@lechnology.com>
> > >
> > > From: David Lechner <dlechner@baylibre.com>
> > >
> > > When reading the position and velocity on the AD2S1210, there is also a
> > > 3rd byte following the two data bytes that contains the fault flag bits.
> > > This patch adds support for reading this byte and generating events when
> > > faults occur.
> > >
> > > The faults are mapped to various channels and event types in order to
> > > have a unique event for each fault.
> > >
> > > Signed-off-by: David Lechner <dlechner@baylibre.com>
> >
> > Use of x and y modifiers is a little odd.  What was your reasoning?
> > Was it just that there was a X_OR_Y modifier?  If so, don't use that!
> > It seemed like a good idea at the time, but it's not nice to deal with
> > and requires a channel with that modifier to hang the controls off
> > + make sure userspace expects that event code.
>
>
> Regarding the point about "requires a channel with that modifier to
> hang the controls off...". Although that comment was about modifiers,
> does it also apply in general.
>
> There are several fault events that don't have any configurable
> parameters, namely _sine/cosine inputs clipping_ and _velocity exceeds
> max tracking rate_. So there won't be any attributes that contain the
> event specification for those (e.g. no `events/in_angl0_*`
> attributes). It sounds like this would be a problem as well?
>
> Should we consider a IIO_EV_INFO_LABEL so that we can have some sort
> of attribute (namely `events/<dir>_<channel spec>_label`) so that
> userspace can enumerate expected events for non-configurable events?

Well, I didn't think that all the way through before I hit send.
IIO_EV_INFO_LABEL is clearly not the right way to implement a
`events/*_label` attribute, but however we consider going about it,
the point of adding such an attribute was the main idea.

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

* Re: [PATCH v3 19/27] staging: iio: resolver: ad2s1210: add phase lock range support
  2023-09-29 17:23 ` [PATCH v3 19/27] staging: iio: resolver: ad2s1210: add phase lock range support David Lechner
  2023-09-30 15:18   ` Jonathan Cameron
@ 2023-10-03  8:03   ` kernel test robot
  1 sibling, 0 replies; 88+ messages in thread
From: kernel test robot @ 2023-10-03  8:03 UTC (permalink / raw)
  To: David Lechner, linux-iio, devicetree, linux-staging
  Cc: oe-kbuild-all, David Lechner, Jonathan Cameron, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

Hi David,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 5e99f692d4e32e3250ab18d511894ca797407aec]

url:    https://github.com/intel-lab-lkp/linux/commits/David-Lechner/dt-bindings-iio-resolver-add-devicetree-bindings-for-ad2s1210/20230930-014031
base:   5e99f692d4e32e3250ab18d511894ca797407aec
patch link:    https://lore.kernel.org/r/20230929-ad2s1210-mainline-v3-19-fa4364281745%40baylibre.com
patch subject: [PATCH v3 19/27] staging: iio: resolver: ad2s1210: add phase lock range support
config: i386-randconfig-062-20231003 (https://download.01.org/0day-ci/archive/20231003/202310031533.yGtxQ3t0-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231003/202310031533.yGtxQ3t0-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202310031533.yGtxQ3t0-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/staging/iio/resolver/ad2s1210.c:667:1: sparse: sparse: symbol 'iio_const_attr_in_phase0_mag_value_available' was not declared. Should it be static?

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events
  2023-09-29 17:23 ` [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events David Lechner
  2023-09-30  3:55   ` kernel test robot
  2023-09-30 16:00   ` Jonathan Cameron
@ 2023-10-03 10:53   ` Dan Carpenter
  2 siblings, 0 replies; 88+ messages in thread
From: Dan Carpenter @ 2023-10-03 10:53 UTC (permalink / raw)
  To: oe-kbuild, David Lechner, linux-iio, devicetree, linux-staging
  Cc: lkp, oe-kbuild-all, David Lechner, Jonathan Cameron, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

Hi David,

kernel test robot noticed the following build warnings:

url:    https://github.com/intel-lab-lkp/linux/commits/David-Lechner/dt-bindings-iio-resolver-add-devicetree-bindings-for-ad2s1210/20230930-014031
base:   5e99f692d4e32e3250ab18d511894ca797407aec
patch link:    https://lore.kernel.org/r/20230929-ad2s1210-mainline-v3-26-fa4364281745%40baylibre.com
patch subject: [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events
config: x86_64-randconfig-161-20231002 (https://download.01.org/0day-ci/archive/20231003/202310031839.tKR53HoP-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce: (https://download.01.org/0day-ci/archive/20231003/202310031839.tKR53HoP-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202310031839.tKR53HoP-lkp@intel.com/

smatch warnings:
drivers/staging/iio/resolver/ad2s1210.c:436 ad2s1210_single_conversion() error: buffer overflow 'st->rx' 2 <= 2

vim +436 drivers/staging/iio/resolver/ad2s1210.c

ecf16f4922f691 David Lechner    2023-09-29  391  static int ad2s1210_single_conversion(struct iio_dev *indio_dev,
29148543c52146 Jonathan Cameron 2011-10-05  392  				      struct iio_chan_spec const *chan,
e9336a85ceb885 David Lechner    2023-09-29  393  				      int *val)
817e5c65c511d4 Graf Yang        2010-10-27  394  {
ecf16f4922f691 David Lechner    2023-09-29  395  	struct ad2s1210_state *st = iio_priv(indio_dev);
ecf16f4922f691 David Lechner    2023-09-29  396  	s64 timestamp;
69cc7fbdcdf2e3 David Lechner    2023-09-29  397  	int ret;
817e5c65c511d4 Graf Yang        2010-10-27  398  
817e5c65c511d4 Graf Yang        2010-10-27  399  	mutex_lock(&st->lock);
69cc7fbdcdf2e3 David Lechner    2023-09-29  400  	gpiod_set_value(st->sample_gpio, 1);
ecf16f4922f691 David Lechner    2023-09-29  401  	timestamp = iio_get_time_ns(indio_dev);
817e5c65c511d4 Graf Yang        2010-10-27  402  	/* delay (6 * tck + 20) nano seconds */
817e5c65c511d4 Graf Yang        2010-10-27  403  	udelay(1);
817e5c65c511d4 Graf Yang        2010-10-27  404  
29148543c52146 Jonathan Cameron 2011-10-05  405  	switch (chan->type) {
29148543c52146 Jonathan Cameron 2011-10-05  406  	case IIO_ANGL:
69cc7fbdcdf2e3 David Lechner    2023-09-29  407  		ret = ad2s1210_set_mode(st, MOD_POS);
29148543c52146 Jonathan Cameron 2011-10-05  408  		break;
29148543c52146 Jonathan Cameron 2011-10-05  409  	case IIO_ANGL_VEL:
69cc7fbdcdf2e3 David Lechner    2023-09-29  410  		ret = ad2s1210_set_mode(st, MOD_VEL);
29148543c52146 Jonathan Cameron 2011-10-05  411  		break;
29148543c52146 Jonathan Cameron 2011-10-05  412  	default:
29148543c52146 Jonathan Cameron 2011-10-05  413  		ret = -EINVAL;
29148543c52146 Jonathan Cameron 2011-10-05  414  		break;
29148543c52146 Jonathan Cameron 2011-10-05  415  	}
29148543c52146 Jonathan Cameron 2011-10-05  416  	if (ret < 0)
29148543c52146 Jonathan Cameron 2011-10-05  417  		goto error_ret;
ecf16f4922f691 David Lechner    2023-09-29  418  	ret = spi_read(st->sdev, &st->sample, 3);
29148543c52146 Jonathan Cameron 2011-10-05  419  	if (ret < 0)
817e5c65c511d4 Graf Yang        2010-10-27  420  		goto error_ret;
29148543c52146 Jonathan Cameron 2011-10-05  421  
29148543c52146 Jonathan Cameron 2011-10-05  422  	switch (chan->type) {
29148543c52146 Jonathan Cameron 2011-10-05  423  	case IIO_ANGL:
ecf16f4922f691 David Lechner    2023-09-29  424  		*val = be16_to_cpu(st->sample.raw);
29148543c52146 Jonathan Cameron 2011-10-05  425  		ret = IIO_VAL_INT;
29148543c52146 Jonathan Cameron 2011-10-05  426  		break;
29148543c52146 Jonathan Cameron 2011-10-05  427  	case IIO_ANGL_VEL:
ecf16f4922f691 David Lechner    2023-09-29  428  		*val = (s16)be16_to_cpu(st->sample.raw);
29148543c52146 Jonathan Cameron 2011-10-05  429  		ret = IIO_VAL_INT;
29148543c52146 Jonathan Cameron 2011-10-05  430  		break;
29148543c52146 Jonathan Cameron 2011-10-05  431  	default:
5e99f692d4e32e David Lechner    2023-09-21  432  		ret = -EINVAL;
5e99f692d4e32e David Lechner    2023-09-21  433  		break;
29148543c52146 Jonathan Cameron 2011-10-05  434  	}
29148543c52146 Jonathan Cameron 2011-10-05  435  
ecf16f4922f691 David Lechner    2023-09-29 @436  	ad2s1210_push_events(indio_dev, st->rx[2], timestamp);
                                                                                          ^^^^^^
Apparently ->rx only has 2 elements.

ecf16f4922f691 David Lechner    2023-09-29  437  
817e5c65c511d4 Graf Yang        2010-10-27  438  error_ret:
69cc7fbdcdf2e3 David Lechner    2023-09-29  439  	gpiod_set_value(st->sample_gpio, 0);
817e5c65c511d4 Graf Yang        2010-10-27  440  	/* delay (2 * tck + 20) nano seconds */
817e5c65c511d4 Graf Yang        2010-10-27  441  	udelay(1);
817e5c65c511d4 Graf Yang        2010-10-27  442  	mutex_unlock(&st->lock);
29148543c52146 Jonathan Cameron 2011-10-05  443  	return ret;
817e5c65c511d4 Graf Yang        2010-10-27  444  }

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


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

* Re: [PATCH v3 21/27] staging: iio: resolver: ad2s1210: convert LOT threshold attrs to event attrs
  2023-09-29 17:23 ` [PATCH v3 21/27] staging: iio: resolver: ad2s1210: convert LOT threshold attrs to event attrs David Lechner
  2023-09-30 15:29   ` Jonathan Cameron
@ 2023-10-03 11:11   ` kernel test robot
  1 sibling, 0 replies; 88+ messages in thread
From: kernel test robot @ 2023-10-03 11:11 UTC (permalink / raw)
  To: David Lechner, linux-iio, devicetree, linux-staging
  Cc: oe-kbuild-all, David Lechner, Jonathan Cameron, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

Hi David,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 5e99f692d4e32e3250ab18d511894ca797407aec]

url:    https://github.com/intel-lab-lkp/linux/commits/David-Lechner/dt-bindings-iio-resolver-add-devicetree-bindings-for-ad2s1210/20230930-014031
base:   5e99f692d4e32e3250ab18d511894ca797407aec
patch link:    https://lore.kernel.org/r/20230929-ad2s1210-mainline-v3-21-fa4364281745%40baylibre.com
patch subject: [PATCH v3 21/27] staging: iio: resolver: ad2s1210: convert LOT threshold attrs to event attrs
config: i386-randconfig-062-20231003 (https://download.01.org/0day-ci/archive/20231003/202310031828.N71Q1F9H-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231003/202310031828.N71Q1F9H-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202310031828.N71Q1F9H-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   drivers/staging/iio/resolver/ad2s1210.c:845:1: sparse: sparse: symbol 'iio_const_attr_in_phase0_mag_value_available' was not declared. Should it be static?
>> drivers/staging/iio/resolver/ad2s1210.c:850:1: sparse: sparse: symbol 'iio_dev_attr_in_angl1_thresh_rising_value_available' was not declared. Should it be static?
>> drivers/staging/iio/resolver/ad2s1210.c:851:1: sparse: sparse: symbol 'iio_dev_attr_in_angl1_thresh_rising_hysteresis_available' was not declared. Should it be static?

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
  2023-09-29 17:23 ` [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr David Lechner
  2023-09-30 15:32   ` Jonathan Cameron
  2023-09-30 15:42   ` Jonathan Cameron
@ 2023-10-03 14:21   ` kernel test robot
  2 siblings, 0 replies; 88+ messages in thread
From: kernel test robot @ 2023-10-03 14:21 UTC (permalink / raw)
  To: David Lechner, linux-iio, devicetree, linux-staging
  Cc: oe-kbuild-all, David Lechner, Jonathan Cameron, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

Hi David,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 5e99f692d4e32e3250ab18d511894ca797407aec]

url:    https://github.com/intel-lab-lkp/linux/commits/David-Lechner/dt-bindings-iio-resolver-add-devicetree-bindings-for-ad2s1210/20230930-014031
base:   5e99f692d4e32e3250ab18d511894ca797407aec
patch link:    https://lore.kernel.org/r/20230929-ad2s1210-mainline-v3-22-fa4364281745%40baylibre.com
patch subject: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
config: i386-randconfig-062-20231003 (https://download.01.org/0day-ci/archive/20231003/202310032242.jYDq0057-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231003/202310032242.jYDq0057-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202310032242.jYDq0057-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   drivers/staging/iio/resolver/ad2s1210.c:896:1: sparse: sparse: symbol 'iio_const_attr_in_phase0_mag_value_available' was not declared. Should it be static?
>> drivers/staging/iio/resolver/ad2s1210.c:901:1: sparse: sparse: symbol 'iio_const_attr_in_altvoltage0_thresh_falling_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:902:1: sparse: sparse: symbol 'iio_dev_attr_in_angl1_thresh_rising_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:903:1: sparse: sparse: symbol 'iio_dev_attr_in_angl1_thresh_rising_hysteresis_available' was not declared. Should it be static?

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v3 23/27] staging: iio: resolver: ad2s1210: convert DOS overrange threshold to event attr
  2023-09-29 17:23 ` [PATCH v3 23/27] staging: iio: resolver: ad2s1210: convert DOS overrange " David Lechner
  2023-09-30 15:33   ` Jonathan Cameron
@ 2023-10-03 17:21   ` kernel test robot
  1 sibling, 0 replies; 88+ messages in thread
From: kernel test robot @ 2023-10-03 17:21 UTC (permalink / raw)
  To: David Lechner, linux-iio, devicetree, linux-staging
  Cc: oe-kbuild-all, David Lechner, Jonathan Cameron, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

Hi David,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 5e99f692d4e32e3250ab18d511894ca797407aec]

url:    https://github.com/intel-lab-lkp/linux/commits/David-Lechner/dt-bindings-iio-resolver-add-devicetree-bindings-for-ad2s1210/20230930-014031
base:   5e99f692d4e32e3250ab18d511894ca797407aec
patch link:    https://lore.kernel.org/r/20230929-ad2s1210-mainline-v3-23-fa4364281745%40baylibre.com
patch subject: [PATCH v3 23/27] staging: iio: resolver: ad2s1210: convert DOS overrange threshold to event attr
config: i386-randconfig-062-20231003 (https://download.01.org/0day-ci/archive/20231004/202310040023.rI6mfueI-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231004/202310040023.rI6mfueI-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202310040023.rI6mfueI-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   drivers/staging/iio/resolver/ad2s1210.c:899:1: sparse: sparse: symbol 'iio_const_attr_in_phase0_mag_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:904:1: sparse: sparse: symbol 'iio_const_attr_in_altvoltage0_thresh_falling_value_available' was not declared. Should it be static?
>> drivers/staging/iio/resolver/ad2s1210.c:905:1: sparse: sparse: symbol 'iio_const_attr_in_altvoltage0_thresh_rising_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:906:1: sparse: sparse: symbol 'iio_dev_attr_in_angl1_thresh_rising_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:907:1: sparse: sparse: symbol 'iio_dev_attr_in_angl1_thresh_rising_hysteresis_available' was not declared. Should it be static?

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v3 24/27] staging: iio: resolver: ad2s1210: convert DOS mismatch threshold to event attr
  2023-09-29 17:23 ` [PATCH v3 24/27] staging: iio: resolver: ad2s1210: convert DOS mismatch " David Lechner
@ 2023-10-03 20:08   ` kernel test robot
  0 siblings, 0 replies; 88+ messages in thread
From: kernel test robot @ 2023-10-03 20:08 UTC (permalink / raw)
  To: David Lechner, linux-iio, devicetree, linux-staging
  Cc: oe-kbuild-all, David Lechner, Jonathan Cameron, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

Hi David,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 5e99f692d4e32e3250ab18d511894ca797407aec]

url:    https://github.com/intel-lab-lkp/linux/commits/David-Lechner/dt-bindings-iio-resolver-add-devicetree-bindings-for-ad2s1210/20230930-014031
base:   5e99f692d4e32e3250ab18d511894ca797407aec
patch link:    https://lore.kernel.org/r/20230929-ad2s1210-mainline-v3-24-fa4364281745%40baylibre.com
patch subject: [PATCH v3 24/27] staging: iio: resolver: ad2s1210: convert DOS mismatch threshold to event attr
config: i386-randconfig-062-20231003 (https://download.01.org/0day-ci/archive/20231004/202310040309.rX4s31l7-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231004/202310040309.rX4s31l7-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202310040309.rX4s31l7-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   drivers/staging/iio/resolver/ad2s1210.c:901:1: sparse: sparse: symbol 'iio_const_attr_in_phase0_mag_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:906:1: sparse: sparse: symbol 'iio_const_attr_in_altvoltage0_thresh_falling_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:907:1: sparse: sparse: symbol 'iio_const_attr_in_altvoltage0_thresh_rising_value_available' was not declared. Should it be static?
>> drivers/staging/iio/resolver/ad2s1210.c:908:1: sparse: sparse: symbol 'iio_const_attr_in_altvoltage0_mag_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:909:1: sparse: sparse: symbol 'iio_dev_attr_in_angl1_thresh_rising_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:910:1: sparse: sparse: symbol 'iio_dev_attr_in_angl1_thresh_rising_hysteresis_available' was not declared. Should it be static?

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH v3 25/27] staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs
  2023-09-29 17:23 ` [PATCH v3 25/27] staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs David Lechner
  2023-09-30 15:47   ` Jonathan Cameron
@ 2023-10-03 23:23   ` kernel test robot
  1 sibling, 0 replies; 88+ messages in thread
From: kernel test robot @ 2023-10-03 23:23 UTC (permalink / raw)
  To: David Lechner, linux-iio, devicetree, linux-staging
  Cc: oe-kbuild-all, David Lechner, Jonathan Cameron, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

Hi David,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 5e99f692d4e32e3250ab18d511894ca797407aec]

url:    https://github.com/intel-lab-lkp/linux/commits/David-Lechner/dt-bindings-iio-resolver-add-devicetree-bindings-for-ad2s1210/20230930-014031
base:   5e99f692d4e32e3250ab18d511894ca797407aec
patch link:    https://lore.kernel.org/r/20230929-ad2s1210-mainline-v3-25-fa4364281745%40baylibre.com
patch subject: [PATCH v3 25/27] staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs
config: i386-randconfig-062-20231003 (https://download.01.org/0day-ci/archive/20231004/202310040601.lZjvyOu7-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231004/202310040601.lZjvyOu7-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202310040601.lZjvyOu7-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   drivers/staging/iio/resolver/ad2s1210.c:900:1: sparse: sparse: symbol 'iio_const_attr_in_phase0_mag_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:905:1: sparse: sparse: symbol 'iio_const_attr_in_altvoltage0_thresh_falling_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:906:1: sparse: sparse: symbol 'iio_const_attr_in_altvoltage0_thresh_rising_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:907:1: sparse: sparse: symbol 'iio_const_attr_in_altvoltage0_mag_value_available' was not declared. Should it be static?
>> drivers/staging/iio/resolver/ad2s1210.c:908:1: sparse: sparse: symbol 'iio_dev_attr_in_altvoltage0_mag_reset_max' was not declared. Should it be static?
>> drivers/staging/iio/resolver/ad2s1210.c:911:1: sparse: sparse: symbol 'iio_const_attr_in_altvoltage0_mag_reset_max_available' was not declared. Should it be static?
>> drivers/staging/iio/resolver/ad2s1210.c:912:1: sparse: sparse: symbol 'iio_dev_attr_in_altvoltage0_mag_reset_min' was not declared. Should it be static?
>> drivers/staging/iio/resolver/ad2s1210.c:915:1: sparse: sparse: symbol 'iio_const_attr_in_altvoltage0_mag_reset_min_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:916:1: sparse: sparse: symbol 'iio_dev_attr_in_angl1_thresh_rising_value_available' was not declared. Should it be static?
   drivers/staging/iio/resolver/ad2s1210.c:917:1: sparse: sparse: symbol 'iio_dev_attr_in_angl1_thresh_rising_hysteresis_available' was not declared. Should it be static?

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* RE: [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210
  2023-09-30 14:34   ` Jonathan Cameron
@ 2023-10-04 10:41     ` Hennerich, Michael
  0 siblings, 0 replies; 88+ messages in thread
From: Hennerich, Michael @ 2023-10-04 10:41 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner
  Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-staging@lists.linux.dev, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sa, Nuno, Axel Haslam,
	Philip Molloy, linux-kernel@vger.kernel.org, Apelete Seketeli



> -----Original Message-----
> From: Jonathan Cameron <jic23@kernel.org>
> Sent: Samstag, 30. September 2023 16:34
> To: David Lechner <dlechner@baylibre.com>
> Cc: linux-iio@vger.kernel.org; devicetree@vger.kernel.org; linux-
> staging@lists.linux.dev; David Lechner <david@lechnology.com>; Rob Herring
> <robh+dt@kernel.org>; Krzysztof Kozlowski
> <krzysztof.kozlowski+dt@linaro.org>; Conor Dooley <conor+dt@kernel.org>;
> Hennerich, Michael <Michael.Hennerich@analog.com>; Sa, Nuno
> <Nuno.Sa@analog.com>; Axel Haslam <ahaslam@baylibre.com>; Philip Molloy
> <pmolloy@baylibre.com>; linux-kernel@vger.kernel.org; Apelete Seketeli
> <aseketeli@baylibre.com>
> Subject: Re: [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree
> bindings for ad2s1210
> 
> 
> On Fri, 29 Sep 2023 12:23:06 -0500
> David Lechner <dlechner@baylibre.com> wrote:
> 
> > From: David Lechner <david@lechnology.com>
> >
> > From: David Lechner <dlechner@baylibre.com>
> >
> > This adds new DeviceTree bindings for the Analog Devices, Inc.
> > AD2S1210 resolver-to-digital converter.
> >
> > Co-developed-by: Apelete Seketeli <aseketeli@baylibre.com>
> > Signed-off-by: Apelete Seketeli <aseketeli@baylibre.com>
> > Signed-off-by: David Lechner <dlechner@baylibre.com>
> 
> Michael, ideally I'd like your ack on this given it volunteers you as maintainer. If
> I don't hear I'm fine with leaving Michael listed because he's in MAINTAINERS
> anyway covering these bindings via a wild card entry:

Acked-by: Michael Hennerich <michael.hennerich@analog.com>

> 
> ANALOG DEVICES INC IIO DRIVERS
> M:	Lars-Peter Clausen <lars@metafoo.de>
> M:	Michael Hennerich <Michael.Hennerich@analog.com>
> ...
> F:	Documentation/devicetree/bindings/iio/*/adi,*
> 
> So any queries should hit Michael anyway.
> 
> LGTM but I'll also want the dt binding maintainers input before picking this up.
> 
> Jonathan
> 
> > ---
> >
> > v3 changes:
> > * Expanded top-level description of A0/A1 lines.
> > * Added required voltage -supply properties. (I did not pick up Rob's
> >   Reviewed-by since I wasn't sure if this was trivial enough.)
> >
> > v2 changes:
> > * Add Co-developed-by:
> > * Remove extraneous quotes on strings
> > * Remove extraneous pipe on some multi-line descriptions
> >
> >  .../bindings/iio/resolver/adi,ad2s1210.yaml        | 177
> +++++++++++++++++++++
> >  1 file changed, 177 insertions(+)
> >
> > diff --git
> > a/Documentation/devicetree/bindings/iio/resolver/adi,ad2s1210.yaml
> > b/Documentation/devicetree/bindings/iio/resolver/adi,ad2s1210.yaml
> > new file mode 100644
> > index 000000000000..8980b3cd8337
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/iio/resolver/adi,ad2s1210.yaml
> > @@ -0,0 +1,177 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id:
> > +https://urldefense.com/v3/__http://devicetree.org/schemas/iio/resolve
> >
> +r/adi,ad2s1210.yaml*__;Iw!!A3Ni8CS0y2Y!_mSGRdlDHlqAKev0r38paa3K51l2k
> G
> > +o8bShqK2TH4nAF_cYu2WixIa62xv0p-A70086DQmj4oN9FWvOlk78$
> > +$schema:
> > +https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.y
> >
> +aml*__;Iw!!A3Ni8CS0y2Y!_mSGRdlDHlqAKev0r38paa3K51l2kGo8bShqK2TH4n
> AF_c
> > +Yu2WixIa62xv0p-A70086DQmj4oN9FWzdE10U$
> > +
> > +title: Analog Devices AD2S1210 Resolver-to-Digital Converter
> > +
> > +maintainers:
> > +  - Michael Hennerich <michael.hennerich@analog.com>
> > +
> > +description: |
> > +  The AD2S1210 is a complete 10-bit to 16-bit resolution tracking
> > +  resolver-to-digital converter, integrating an on-board programmable
> > +  sinusoidal oscillator that provides sine wave excitation for
> > +  resolvers.
> > +
> > +  The AD2S1210 allows the user to read the angular position or the
> > + angular velocity data directly from the parallel outputs or through
> > + the serial interface.
> > +
> > +  The mode of operation of the communication channel (parallel or
> > + serial) is  selected by the A0 and A1 input pins. In normal mode,
> > + data is latched by  toggling the SAMPLE line and can then be read
> > + directly. In configuration mode,  data is read or written using a
> > + register access scheme (address byte with  read/write flag and data byte).
> > +
> > +    A1  A0  Result
> > +     0   0  Normal mode - position output
> > +     0   1  Normal mode - velocity output
> > +     1   0  Reserved
> > +     1   1  Configuration mode
> > +
> > +  In normal mode, the resolution of the digital output is selected
> > + using  the RES0 and RES1 input pins. In configuration mode, the
> > + resolution is  selected by setting the RES0 and RES1 bits in the control
> register.
> > +
> > +  RES1  RES0  Resolution (Bits)
> > +     0     0  10
> > +     0     1  12
> > +     1     0  14
> > +     1     1  16
> > +
> > +  Note on SPI connections: The CS line on the AD2S1210 should
> > + hard-wired to  logic low and the WR/FSYNC line on the AD2S1210
> > + should be connected to the  SPI CSn output of the SPI controller.
> > +
> > +  Datasheet:
> > +
> > + https://www.analog.com/media/en/technical-documentation/data-sheets/
> > + ad2s1210.pdf
> > +
> > +properties:
> > +  compatible:
> > +    const: adi,ad2s1210
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  spi-max-frequency:
> > +    maximum: 25000000
> > +
> > +  spi-cpha: true
> > +
> > +  avdd-supply:
> > +    description:
> > +      A 4.75 to 5.25 V regulator that powers the Analog Supply Voltage
> (AVDD)
> > +      pin.
> > +
> > +  dvdd-supply:
> > +    description:
> > +      A 4.75 to 5.25 V regulator that powers the Digital Supply Voltage (DVDD)
> > +      pin.
> > +
> > +  vdrive-supply:
> > +    description:
> > +      A 2.3 to 5.25 V regulator that powers the Logic Power Supply Input
> > +      (VDrive) pin.
> > +
> > +  clocks:
> > +    maxItems: 1
> > +    description: External oscillator clock (CLKIN).
> > +
> > +  reset-gpios:
> > +    description:
> > +      GPIO connected to the /RESET pin. As the line needs to be low for the
> > +      reset to be active, it should be configured as GPIO_ACTIVE_LOW.
> > +    maxItems: 1
> > +
> > +  sample-gpios:
> > +    description:
> > +      GPIO connected to the /SAMPLE pin. As the line needs to be low to
> trigger
> > +      a sample, it should be configured as GPIO_ACTIVE_LOW.
> > +    maxItems: 1
> > +
> > +  mode-gpios:
> > +    description:
> > +      GPIO lines connected to the A0 and A1 pins. These pins select the data
> > +      transfer mode.
> > +    minItems: 2
> > +    maxItems: 2
> > +
> > +  resolution-gpios:
> > +    description:
> > +      GPIO lines connected to the RES0 and RES1 pins. These pins select the
> > +      resolution of the digital output. If omitted, it is assumed that the
> > +      RES0 and RES1 pins are hard-wired to match the assigned-resolution-bits
> > +      property.
> > +    minItems: 2
> > +    maxItems: 2
> > +
> > +  fault-gpios:
> > +    description:
> > +      GPIO lines connected to the LOT and DOS pins. These pins combined
> indicate
> > +      the type of fault present, if any. As these pins a pulled low to indicate
> > +      a fault condition, they should be configured as GPIO_ACTIVE_LOW.
> > +    minItems: 2
> > +    maxItems: 2
> > +
> > +  adi,fixed-mode:
> > +    description:
> > +      This is used to indicate the selected mode if A0 and A1 are hard-wired
> > +      instead of connected to GPIOS (i.e. mode-gpios is omitted).
> > +    $ref: /schemas/types.yaml#/definitions/string
> > +    enum: [config, velocity, position]
> > +
> > +  assigned-resolution-bits:
> > +    description:
> > +      Resolution of the digital output required by the application. This
> > +      determines the precision of the angle and/or the maximum speed that
> can
> > +      be measured. If resolution-gpios is omitted, it is assumed that RES0 and
> > +      RES1 are hard-wired to match this value.
> > +    enum: [10, 12, 14, 16]
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - spi-cpha
> > +  - avdd-supply
> > +  - dvdd-supply
> > +  - vdrive-supply
> > +  - clocks
> > +  - sample-gpios
> > +  - assigned-resolution-bits
> > +
> > +oneOf:
> > +  - required:
> > +      - mode-gpios
> > +  - required:
> > +      - adi,fixed-mode
> > +
> > +allOf:
> > +  - $ref: /schemas/spi/spi-peripheral-props.yaml#
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/gpio/gpio.h>
> > +
> > +    spi {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        resolver@0 {
> > +            compatible = "adi,ad2s1210";
> > +            reg = <0>;
> > +            spi-max-frequency = <20000000>;
> > +            spi-cpha;
> > +            avdd-supply = <&avdd_regulator>;
> > +            dvdd-supply = <&dvdd_regulator>;
> > +            vdrive-supply = <&vdrive_regulator>;
> > +            clocks = <&ext_osc>;
> > +            sample-gpios = <&gpio0 90 GPIO_ACTIVE_LOW>;
> > +            mode-gpios = <&gpio0 86 0>, <&gpio0 87 0>;
> > +            resolution-gpios = <&gpio0 88 0>, <&gpio0 89 0>;
> > +            assigned-resolution-bits = <16>;
> > +        };
> > +    };
> >


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

* RE: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
  2023-09-30 15:32   ` Jonathan Cameron
@ 2023-10-04 11:01     ` Hennerich, Michael
  2023-10-05 14:16       ` Jonathan Cameron
  0 siblings, 1 reply; 88+ messages in thread
From: Hennerich, Michael @ 2023-10-04 11:01 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner
  Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-staging@lists.linux.dev, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sa, Nuno, Axel Haslam,
	Philip Molloy, linux-kernel@vger.kernel.org



> -----Original Message-----
> From: Jonathan Cameron <jic23@kernel.org>
> Sent: Samstag, 30. September 2023 17:32
> To: David Lechner <dlechner@baylibre.com>
> Cc: linux-iio@vger.kernel.org; devicetree@vger.kernel.org; linux-
> staging@lists.linux.dev; David Lechner <david@lechnology.com>; Rob Herring
> <robh+dt@kernel.org>; Krzysztof Kozlowski
> <krzysztof.kozlowski+dt@linaro.org>; Conor Dooley <conor+dt@kernel.org>;
> Hennerich, Michael <Michael.Hennerich@analog.com>; Sa, Nuno
> <Nuno.Sa@analog.com>; Axel Haslam <ahaslam@baylibre.com>; Philip Molloy
> <pmolloy@baylibre.com>; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS
> threshold to event attr
> 
> 
> On Fri, 29 Sep 2023 12:23:27 -0500
> David Lechner <dlechner@baylibre.com> wrote:
> 
> > From: David Lechner <david@lechnology.com>
> >
> > From: David Lechner <dlechner@baylibre.com>
> >
> > The AD2S1210 has a programmable threshold for the loss of signal (LOS)
> > fault. This fault is triggered when either the sine or cosine input
> > falls below the threshold voltage.
> >
> > This patch converts the custom device LOS threshold attribute to an
> > event falling edge threshold attribute on a new monitor signal channel.
> > The monitor signal is an internal signal that combines the amplitudes
> > of the sine and cosine inputs as well as the current angle and
> > position output. This signal is used to detect faults in the input signals.
> >
> > The attribute now uses millivolts instead of the raw register value in
> > accordance with the IIO ABI.
> >
> > Emitting the event will be implemented in a later patch.
> >
> > Signed-off-by: David Lechner <dlechner@baylibre.com>
> 
> I think I'm fine with treating these internal signals like this, but I would ideally
> like someone from Analog devices to take a look at how these are being done
> and make sure our interpretations of the signals make sense to them.  We are
> pushing the boundaries a little here (though we have done similar before for
> fault events I think.)

Hi Jonathan,
David and I we also had some internal discussion related to this.
I'm sure these fault events and thresholds are understood correctly.
Doing it this or the other way, it needs to be properly documented in order to make sense.
So from my perspective whatever makes the most sense from a IIO ABI
perspective, is the way to forward.

-Michael

> 
> Jonathan


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

* Re: [PATCH v3 13/27] staging: iio: resolver: ad2s1210: rework gpios
  2023-09-30 14:55   ` Jonathan Cameron
@ 2023-10-05 13:38     ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-10-05 13:38 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Sat, 30 Sep 2023 15:55:36 +0100
Jonathan Cameron <jic23@kernel.org> wrote:

> On Fri, 29 Sep 2023 12:23:18 -0500
> David Lechner <dlechner@baylibre.com> wrote:
> 
> > From: David Lechner <david@lechnology.com>
> > 
> > From: David Lechner <dlechner@baylibre.com>
> > 
> > - Remove "adi," prefix from gpio names.
> > - Sample gpio is now expected to be active low.
> > - Convert A0 and A1 gpios to "mode-gpios" gpio array.
> > - Convert RES0 and RES1 gpios to "resolution-gpios" gpio array.
> > - Remove extraneous lookup tables.
> > - Remove unused mode field from state struct.
> > - Swap argument order of ad2s1210_set_mode() while we are touching this.
> > 
> > Signed-off-by: David Lechner <dlechner@baylibre.com>  
> Applied,
0-day ran smatch on this and it picked up that a log isn't released in
an error path.  I've fixed that up with a goto error_ret and will push out a
fresh testing branch for 0-day to take another look at.

...

> > @@ -546,7 +537,9 @@ static int ad2s1210_initial(struct ad2s1210_state *st)
> >  	int ret;
> >  
> >  	mutex_lock(&st->lock);
> > -	ad2s1210_set_resolution_pin(st);
> > +	ret = ad2s1210_set_resolution_gpios(st, st->resolution);
> > +	if (ret < 0)
Exiting with lock held.  There is an error_ret label that releases the lock
so use that.

> > +		return ret;
> >  
> >  	/* Use default config register value plus resolution from devicetree. */
> >  	data = FIELD_PREP(AD2S1210_PHASE_LOCK_RANGE_44, 1);

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

* Re: [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210
  2023-10-02 15:18   ` Rob Herring
@ 2023-10-05 14:13     ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-10-05 14:13 UTC (permalink / raw)
  To: Rob Herring
  Cc: David Lechner, Philip Molloy, linux-staging, Axel Haslam,
	Apelete Seketeli, Rob Herring, Conor Dooley, linux-iio,
	Michael Hennerich, linux-kernel, Nuno Sá,
	Krzysztof Kozlowski, devicetree, David Lechner

On Mon, 2 Oct 2023 10:18:56 -0500
Rob Herring <robh@kernel.org> wrote:

> On Fri, 29 Sep 2023 12:23:06 -0500, David Lechner wrote:
> > From: David Lechner <david@lechnology.com>
> > 
> > From: David Lechner <dlechner@baylibre.com>
> > 
> > This adds new DeviceTree bindings for the Analog Devices, Inc. AD2S1210
> > resolver-to-digital converter.
> > 
> > Co-developed-by: Apelete Seketeli <aseketeli@baylibre.com>
> > Signed-off-by: Apelete Seketeli <aseketeli@baylibre.com>
> > Signed-off-by: David Lechner <dlechner@baylibre.com>
> > ---
> > 
> > v3 changes:
> > * Expanded top-level description of A0/A1 lines.
> > * Added required voltage -supply properties. (I did not pick up Rob's
> >   Reviewed-by since I wasn't sure if this was trivial enough.)
> > 
> > v2 changes:
> > * Add Co-developed-by:
> > * Remove extraneous quotes on strings
> > * Remove extraneous pipe on some multi-line descriptions
> > 
> >  .../bindings/iio/resolver/adi,ad2s1210.yaml        | 177 +++++++++++++++++++++
> >  1 file changed, 177 insertions(+)
> >   
> 
> Reviewed-by: Rob Herring <robh@kernel.org>
> 

Applied to the togreg branch of iio.git and pushed out as testing for
all the normal reasons.

Jonathan

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

* Re: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
  2023-10-04 11:01     ` Hennerich, Michael
@ 2023-10-05 14:16       ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-10-05 14:16 UTC (permalink / raw)
  To: Hennerich, Michael
  Cc: David Lechner, linux-iio@vger.kernel.org,
	devicetree@vger.kernel.org, linux-staging@lists.linux.dev,
	David Lechner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Sa, Nuno, Axel Haslam, Philip Molloy,
	linux-kernel@vger.kernel.org

On Wed, 4 Oct 2023 11:01:56 +0000
"Hennerich, Michael" <Michael.Hennerich@analog.com> wrote:

> > -----Original Message-----
> > From: Jonathan Cameron <jic23@kernel.org>
> > Sent: Samstag, 30. September 2023 17:32
> > To: David Lechner <dlechner@baylibre.com>
> > Cc: linux-iio@vger.kernel.org; devicetree@vger.kernel.org; linux-
> > staging@lists.linux.dev; David Lechner <david@lechnology.com>; Rob Herring
> > <robh+dt@kernel.org>; Krzysztof Kozlowski
> > <krzysztof.kozlowski+dt@linaro.org>; Conor Dooley <conor+dt@kernel.org>;
> > Hennerich, Michael <Michael.Hennerich@analog.com>; Sa, Nuno
> > <Nuno.Sa@analog.com>; Axel Haslam <ahaslam@baylibre.com>; Philip Molloy
> > <pmolloy@baylibre.com>; linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS
> > threshold to event attr
> > 
> > 
> > On Fri, 29 Sep 2023 12:23:27 -0500
> > David Lechner <dlechner@baylibre.com> wrote:
> >   
> > > From: David Lechner <david@lechnology.com>
> > >
> > > From: David Lechner <dlechner@baylibre.com>
> > >
> > > The AD2S1210 has a programmable threshold for the loss of signal (LOS)
> > > fault. This fault is triggered when either the sine or cosine input
> > > falls below the threshold voltage.
> > >
> > > This patch converts the custom device LOS threshold attribute to an
> > > event falling edge threshold attribute on a new monitor signal channel.
> > > The monitor signal is an internal signal that combines the amplitudes
> > > of the sine and cosine inputs as well as the current angle and
> > > position output. This signal is used to detect faults in the input signals.
> > >
> > > The attribute now uses millivolts instead of the raw register value in
> > > accordance with the IIO ABI.
> > >
> > > Emitting the event will be implemented in a later patch.
> > >
> > > Signed-off-by: David Lechner <dlechner@baylibre.com>  
> > 
> > I think I'm fine with treating these internal signals like this, but I would ideally
> > like someone from Analog devices to take a look at how these are being done
> > and make sure our interpretations of the signals make sense to them.  We are
> > pushing the boundaries a little here (though we have done similar before for
> > fault events I think.)  
> 
> Hi Jonathan,
> David and I we also had some internal discussion related to this.
> I'm sure these fault events and thresholds are understood correctly.
> Doing it this or the other way, it needs to be properly documented in order to make sense.
> So from my perspective whatever makes the most sense from a IIO ABI
> perspective, is the way to forward.

Great - as long as keep to a logical mapping I quite like the events
approach.  Most of these faults are real thresholds on things being measured
(even if those 'things' are signals from which stuff is derived for the main
measurements the device is making.)

Jonathan

> 
> -Michael
> 
> > 
> > Jonathan  
> 


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

* Re: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
  2023-10-02 16:09     ` David Lechner
@ 2023-10-05 14:37       ` Jonathan Cameron
  2023-10-05 19:25         ` David Lechner
  0 siblings, 1 reply; 88+ messages in thread
From: Jonathan Cameron @ 2023-10-05 14:37 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Mon, 2 Oct 2023 11:09:11 -0500
David Lechner <dlechner@baylibre.com> wrote:

> On Sat, Sep 30, 2023 at 10:42 AM Jonathan Cameron <jic23@kernel.org> wrote:
> >
> > On Fri, 29 Sep 2023 12:23:27 -0500
> > David Lechner <dlechner@baylibre.com> wrote:
> >  
> > > From: David Lechner <david@lechnology.com>
> > >
> > > From: David Lechner <dlechner@baylibre.com>
> > >
> > > The AD2S1210 has a programmable threshold for the loss of signal (LOS)
> > > fault. This fault is triggered when either the sine or cosine input
> > > falls below the threshold voltage.
> > >
> > > This patch converts the custom device LOS threshold attribute to an
> > > event falling edge threshold attribute on a new monitor signal channel.
> > > The monitor signal is an internal signal that combines the amplitudes
> > > of the sine and cosine inputs as well as the current angle and position
> > > output. This signal is used to detect faults in the input signals.  
> >
> > Hmm. Looking forwards, I'm less sure that we should be shoving all these
> > error conditions onto one channel. Fundamentally we have
> > sine and cosine inputs. I think we should treat those as separate channels
> > and include a third differential channel between them.  
> 
> At first, I did consider a differential channel as you suggested in
> v2. However, the datasheet is quite clear that the LOS and DOS faults
> (and only those faults) come from a signal it calls the "monitor
> signal". This signal is defined as:
> 
>     Monitor = A1 * sin(theta)  * sin(phi) + A2 * cos(theta) * cos(phi)
> 
> where A1 * sin(theta) is the the sine input, A2 * cos(theta) is the
> cosine input and phi is the position output. So mathematically
> speaking, there is no signal that is the difference between the two
> inputs. (See "Theory of Operation" section in the datasheet.)

Hmm. That's certainly a bit more complex than I expected.
Relying on the brief description led me astray.

It's related to the differences in the measured and  as if
theta == phi and A1 == A2 (ideal) then it will be A1.

I can see it's relevant to DOS, but not LOS.  The description of LOS
seems to overlap a number of different things unfortunately.



> 
> But if we want to hide these internal details and don't care about a
> strict definition of "differential", then what is suggested below
> seems fine.

Probably best to introduce that monitor signal though we'll have
to be a bit vague about what it is which has the side effect that
anyone trying to understand what on earth these faults are is going
to be confused (having read the datasheet section a couple of times
I'm not 100% sure...)

> 
> >
> > So this one becomes a double event (you need to signal it on both
> > cosine and sine channels).  The DOS overange is similar.
> > The DOS mismatch is a threshold on the differential channel giving
> >
> > events/in_altvoltage0_thresh_falling_value
> > events/in_altvoltage1_thresh_falling_value (these match)
> > events/in_altvoltage0_thresh_rising_value
> > events/in_altvoltage1_thresh_rising_value (matches previous which is fine)
> > events/in_altvoltage1-altvoltage0_mag_rising_value
> >
> > Does that work here?  Avoids smashing different types of signals together.
> > We could even do the LOT as differential between two angle channels
> > (tracking one and measured one) but meh that's getting complex.>
> > Note this will rely on channel labels to make the above make any sense at all.  
> 
> I think this could be OK - I think what matters most is having some
> documentation that maps the faults and registers on the chip to the
> iio names. Where would the sine/cosine clipping fault fit in though? I
> got a bit too creative and used X_OR_Y to differentiate it (see
> discussion in "staging: iio: resolver: ad2s1210: implement fault
> events"). Strictly speaking, it should probably be a type: threshold,
> direction: either event on both the sine and cosine input channels
> (another double event) since it occurs if either of the signal exceeds
> the power or ground rail voltage. But we already have threshold rising
> and threshold falling on these channels with a different meaning. I
> guess it could call it magnitude instead of a threshold?

Tricky indeed.  Though I guess we only hit the clipping case after
LOS or DOS fires or if their thresholds are set too wide (is that
even possible?).  So it is useful to report it as we are already in
error? Or can we combine the cases by treating it as a cap on the
threshold controls for LOS and DOS?

Even when they aren't just there for error reporting, designers
seem to always come up with new create signals to use for event
detection and sometimes it's a real struggle to map them to
something general.

Jonathan



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

* Re: [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events
  2023-10-02 16:58     ` David Lechner
  2023-10-02 18:49       ` David Lechner
@ 2023-10-05 14:52       ` Jonathan Cameron
  1 sibling, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-10-05 14:52 UTC (permalink / raw)
  To: David Lechner
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Mon, 2 Oct 2023 11:58:17 -0500
David Lechner <dlechner@baylibre.com> wrote:

> On Sat, Sep 30, 2023 at 11:00 AM Jonathan Cameron <jic23@kernel.org> wrote:
> >
> > On Fri, 29 Sep 2023 12:23:31 -0500
> > David Lechner <dlechner@baylibre.com> wrote:
> >  
> > > From: David Lechner <david@lechnology.com>
> > >
> > > From: David Lechner <dlechner@baylibre.com>
> > >
> > > When reading the position and velocity on the AD2S1210, there is also a
> > > 3rd byte following the two data bytes that contains the fault flag bits.
> > > This patch adds support for reading this byte and generating events when
> > > faults occur.
> > >
> > > The faults are mapped to various channels and event types in order to
> > > have a unique event for each fault.
> > >
> > > Signed-off-by: David Lechner <dlechner@baylibre.com>  
> >
> > Use of x and y modifiers is a little odd.  What was your reasoning?
> > Was it just that there was a X_OR_Y modifier?  If so, don't use that!
> > It seemed like a good idea at the time, but it's not nice to deal with
> > and requires a channel with that modifier to hang the controls off
> > + make sure userspace expects that event code.  
> 
> 
> Regarding the point about "requires a channel with that modifier to
> hang the controls off...". Although that comment was about modifiers,
> does it also apply in general.
> 
> There are several fault events that don't have any configurable
> parameters, namely _sine/cosine inputs clipping_ and _velocity exceeds
> max tracking rate_. So there won't be any attributes that contain the
> event specification for those (e.g. no `events/in_angl0_*`
> attributes). It sounds like this would be a problem as well?

It's fine to have a channel that doesn't have controls or the ability
to be read.

We do have history of doing what you have here (a couple
of accelerometers do it) but it's esoteric and rather hard for userspace
to comprehend so I'd rather not introduce it for other types of devices.

I think we should go with the most flexible option of allowing
events to trigger when they 'may be true' to incorporate this case.
Unfortunately I can't see another option that would scale to all the
random combinations of events that might occur.  There are all sorts
of extensions we could make to the event descriptions, but only at the
cost of breaking backwards compatibility and simplicity.

SWith hindsight the whole IIO_MOD_X_OR_Y_OR_Z mess was a design error :(
We can teach userspace code about that quirk for accelerations where
the one that would be hard to handle is the AND case used for
freefall detectors (you detect that the signal magnitude is near 0 for
all axes).  I can't think of another option for that one other than
the weird modifier (unlike this case)

> 
> Should we consider a IIO_EV_INFO_LABEL so that we can have some sort
> of attribute (namely `events/<dir>_<channel spec>_label`) so that
> userspace can enumerate expected events for non-configurable events?

Probably needs something similar to channel labelling, so a separate
callback given we don't handle strings, but sure something like this
would be useful and provide 'hints' along the lines of what the
datasheet calls a particular event.  Not however for what event is sent
as such info should be apparent from the event naming.

Jonathan

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

* Re: [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr
  2023-10-05 14:37       ` Jonathan Cameron
@ 2023-10-05 19:25         ` David Lechner
  0 siblings, 0 replies; 88+ messages in thread
From: David Lechner @ 2023-10-05 19:25 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: linux-iio, devicetree, linux-staging, David Lechner, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Michael Hennerich,
	Nuno Sá, Axel Haslam, Philip Molloy, linux-kernel

On Thu, Oct 5, 2023 at 9:37 AM Jonathan Cameron <jic23@kernel.org> wrote:
>
> On Mon, 2 Oct 2023 11:09:11 -0500
> David Lechner <dlechner@baylibre.com> wrote:
>
> > On Sat, Sep 30, 2023 at 10:42 AM Jonathan Cameron <jic23@kernel.org> wrote:
> > >
> > > On Fri, 29 Sep 2023 12:23:27 -0500
> > > David Lechner <dlechner@baylibre.com> wrote:
> > >
> > > > From: David Lechner <david@lechnology.com>
> > > >
> > > > From: David Lechner <dlechner@baylibre.com>
> > > >
> > > > The AD2S1210 has a programmable threshold for the loss of signal (LOS)
> > > > fault. This fault is triggered when either the sine or cosine input
> > > > falls below the threshold voltage.
> > > >
> > > > This patch converts the custom device LOS threshold attribute to an
> > > > event falling edge threshold attribute on a new monitor signal channel.
> > > > The monitor signal is an internal signal that combines the amplitudes
> > > > of the sine and cosine inputs as well as the current angle and position
> > > > output. This signal is used to detect faults in the input signals.
> > >
> > > Hmm. Looking forwards, I'm less sure that we should be shoving all these
> > > error conditions onto one channel. Fundamentally we have
> > > sine and cosine inputs. I think we should treat those as separate channels
> > > and include a third differential channel between them.
> >
> > At first, I did consider a differential channel as you suggested in
> > v2. However, the datasheet is quite clear that the LOS and DOS faults
> > (and only those faults) come from a signal it calls the "monitor
> > signal". This signal is defined as:
> >
> >     Monitor = A1 * sin(theta)  * sin(phi) + A2 * cos(theta) * cos(phi)
> >
> > where A1 * sin(theta) is the the sine input, A2 * cos(theta) is the
> > cosine input and phi is the position output. So mathematically
> > speaking, there is no signal that is the difference between the two
> > inputs. (See "Theory of Operation" section in the datasheet.)
>
> Hmm. That's certainly a bit more complex than I expected.
> Relying on the brief description led me astray.
>
> It's related to the differences in the measured and  as if
> theta == phi and A1 == A2 (ideal) then it will be A1.
>
> I can see it's relevant to DOS, but not LOS.  The description of LOS
> seems to overlap a number of different things unfortunately.
>

One thing to watch out for in the datasheet is the difference between
the fault output pins and the fault bits read over the bus. The LOS
output pin does indicate one or more of multiple faults, but we are
not currently using that. We are only looking at the fault bits which
are more granular.

>
>
> >
> > But if we want to hide these internal details and don't care about a
> > strict definition of "differential", then what is suggested below
> > seems fine.
>
> Probably best to introduce that monitor signal though we'll have
> to be a bit vague about what it is which has the side effect that
> anyone trying to understand what on earth these faults are is going
> to be confused (having read the datasheet section a couple of times
> I'm not 100% sure...)
>
> >
> > >
> > > So this one becomes a double event (you need to signal it on both
> > > cosine and sine channels).  The DOS overange is similar.
> > > The DOS mismatch is a threshold on the differential channel giving
> > >
> > > events/in_altvoltage0_thresh_falling_value
> > > events/in_altvoltage1_thresh_falling_value (these match)
> > > events/in_altvoltage0_thresh_rising_value
> > > events/in_altvoltage1_thresh_rising_value (matches previous which is fine)
> > > events/in_altvoltage1-altvoltage0_mag_rising_value
> > >
> > > Does that work here?  Avoids smashing different types of signals together.
> > > We could even do the LOT as differential between two angle channels
> > > (tracking one and measured one) but meh that's getting complex.>
> > > Note this will rely on channel labels to make the above make any sense at all.
> >
> > I think this could be OK - I think what matters most is having some
> > documentation that maps the faults and registers on the chip to the
> > iio names. Where would the sine/cosine clipping fault fit in though? I
> > got a bit too creative and used X_OR_Y to differentiate it (see
> > discussion in "staging: iio: resolver: ad2s1210: implement fault
> > events"). Strictly speaking, it should probably be a type: threshold,
> > direction: either event on both the sine and cosine input channels
> > (another double event) since it occurs if either of the signal exceeds
> > the power or ground rail voltage. But we already have threshold rising
> > and threshold falling on these channels with a different meaning. I
> > guess it could call it magnitude instead of a threshold?
>
> Tricky indeed.  Though I guess we only hit the clipping case after
> LOS or DOS fires or if their thresholds are set too wide (is that
> even possible?).

I suppose it _could_ be possible on the high side if the AVDD voltage
supply was selected to be less than the 4.4V max of the threshold
voltage registers.

> So it is useful to report it as we are already in
> error? Or can we combine the cases by treating it as a cap on the
> threshold controls for LOS and DOS?

I found the clipping error useful while developing this driver since
it help identify that we had a gain setting wrong on the excitation
output (on the circuit board) which in turn caused the inputs to be
overdriven. But, yes when this happened, it also always triggered at
least one or more of the LOS and DOS faults as well.

>
> Even when they aren't just there for error reporting, designers
> seem to always come up with new create signals to use for event
> detection and sometimes it's a real struggle to map them to
> something general.
>
> Jonathan
>
>

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

* Re: [PATCH v3 02/27] staging: iio: resolver: ad2s1210: fix use before initialization
  2023-10-02  9:17     ` Jonathan Cameron
@ 2023-10-06 14:48       ` Vincent Whitchurch
  2023-10-10  9:29         ` Jonathan Cameron
  0 siblings, 1 reply; 88+ messages in thread
From: Vincent Whitchurch @ 2023-10-06 14:48 UTC (permalink / raw)
  To: Jonathan.Cameron@Huawei.com, dan.carpenter@linaro.org
  Cc: linux-staging@lists.linux.dev, krzysztof.kozlowski+dt@linaro.org,
	Michael.Hennerich@analog.com, kernel,
	linux-kernel@vger.kernel.org, conor+dt@kernel.org,
	devicetree@vger.kernel.org, dlechner@baylibre.com,
	nuno.sa@analog.com, pmolloy@baylibre.com, Vincent Whitchurch,
	robh+dt@kernel.org, jic23@kernel.org, ahaslam@baylibre.com,
	linux-iio@vger.kernel.org, david@lechnology.com

On Mon, 2023-10-02 at 10:17 +0100, Jonathan Cameron wrote:
> Hmm. What happened to roadtest?  I was hoping that would solve this sort
> of issue by allowing simple testing of basic functionality...

Roadtest is alive and well.  Several of my coworkers have been using it
for development and testing of new drivers[0][1][2][3][4] and
patches[5][6], and this has resulted in easier testing and refactoring
during development, more robust code, and of course the ability to
easily detect regressions after the patches are merged.

[0] https://lore.kernel.org/lkml/20230323-add-opt4001-driver-v2-2-0bae0398669d@axis.com/
[1] https://lore.kernel.org/lkml/d218a1bc75402b5ebd6e12a563f7315f83fe966c.1689753076.git.waqar.hameed@axis.com/
[2] https://lore.kernel.org/lkml/7b856b74c4c0f8c6c539d7c692051c9203b103c0.1692699931.git.waqar.hameed@axis.com/
[3] https://lore.kernel.org/lkml/20231002-rx8111-add-timestamp0-v1-1-353727cf7f14@axis.com/
[4] https://lore.kernel.org/lkml/20230502-tps6287x-driver-v3-2-e25140a023f5@axis.com/
[5] https://lore.kernel.org/lkml/20221012102347.153201-1-chenhuiz@axis.com/
[6] https://lore.kernel.org/lkml/20220413114014.2204623-3-camel.guo@axis.com/

In fact, by running our roadtests on newer kernels we have found
numerous bugs[10][12][14] and regressions[7][8][9][11][15] in mainline,
including subsystem-level issues affecting other drivers too.

[7] https://lore.kernel.org/lkml/20230911-regulator-voltage-sel-v1-1-886eb1ade8d8@axis.com/
[8] https://lore.kernel.org/lkml/20230918-power-uaf-v1-1-73c397178c42@axis.com/
[9] https://lore.kernel.org/lkml/20230829-tps-voltages-v1-1-7ba4f958a194@axis.com/
[10] https://lore.kernel.org/lkml/20230613-genirq-nested-v3-1-ae58221143eb@axis.com/
[11] https://lore.kernel.org/lkml/20220503114333.456476-1-camel.guo@axis.com/
[12] https://lore.kernel.org/linux-iio/20220816080828.1218667-1-vincent.whitchurch@axis.com/
[13] https://lore.kernel.org/linux-iio/20220519091925.1053897-1-vincent.whitchurch@axis.com/
[14] https://lore.kernel.org/linux-iio/20220620144231.GA23345@axis.com/
[15] https://lore.kernel.org/linux-spi/YxBX4bXG02E4lSUW@axis.com/

(The above lists are not exhaustive.)

> Hope it is still headed for a new version / upstream!

I pushed out an update with a squash of (most parts of) our internal
version out to the following repo, it's based on v6.6-rc4.

  https://github.com/vwax/linux/tree/roadtest/devel

(There are currently 6 lines of --diff-filter=M against v6.6-rc4 on the
 linked repo.  Two of those are from a patch which is posted and waiting
 for review on the lists, and the rest are for enabling regmap debugfs
 writes which are used from some of the newer tests.)

Since roadtest itself does not require any patches to the kernel or any
out-of-tree modules, the maintenance of the framework would not really
be simplified by putting it in the upstream tree.  However, there is of
course a potentially large benefit to the quality of many kinds of
kernel drivers if roadtest gets used by others, and having it in-tree
could facilitate that.  And it would potentially allow regressions like
the ones we're finding to be caught _before_ they go in, since anyone
can run the tests without special hardware.

The idea of having to maintain it in-tree and doing all the work that
goes along with that (dealing with the expectations of maintainers,
wrangling patches from mailing lists, etc), is something I personally
have had a hard time warming up to, but I have some coworkers who may
potentially be interested in that kind of work, so I wouldn't rule out
another posting of the patch set targeting upstream sometime in the
future.

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

* Re: [PATCH v3 02/27] staging: iio: resolver: ad2s1210: fix use before initialization
  2023-10-06 14:48       ` Vincent Whitchurch
@ 2023-10-10  9:29         ` Jonathan Cameron
  0 siblings, 0 replies; 88+ messages in thread
From: Jonathan Cameron @ 2023-10-10  9:29 UTC (permalink / raw)
  To: Vincent Whitchurch
  Cc: Jonathan.Cameron@Huawei.com, dan.carpenter@linaro.org,
	linux-staging@lists.linux.dev, krzysztof.kozlowski+dt@linaro.org,
	Michael.Hennerich@analog.com, kernel,
	linux-kernel@vger.kernel.org, conor+dt@kernel.org,
	devicetree@vger.kernel.org, dlechner@baylibre.com,
	nuno.sa@analog.com, pmolloy@baylibre.com, robh+dt@kernel.org,
	ahaslam@baylibre.com, linux-iio@vger.kernel.org,
	david@lechnology.com, Mark Brown, Dmitry Torokhov, Jean Delvare,
	Guenter Roeck

On Fri, 6 Oct 2023 14:48:29 +0000
Vincent Whitchurch <Vincent.Whitchurch@axis.com> wrote:

Hi Vincent

Thanks for the update,

> On Mon, 2023-10-02 at 10:17 +0100, Jonathan Cameron wrote:
> > Hmm. What happened to roadtest?  I was hoping that would solve this sort
> > of issue by allowing simple testing of basic functionality...  
> 
> Roadtest is alive and well.  Several of my coworkers have been using it
> for development and testing of new drivers[0][1][2][3][4] and
> patches[5][6], and this has resulted in easier testing and refactoring
> during development, more robust code, and of course the ability to
> easily detect regressions after the patches are merged.
> 
> [0] https://lore.kernel.org/lkml/20230323-add-opt4001-driver-v2-2-0bae0398669d@axis.com/
> [1] https://lore.kernel.org/lkml/d218a1bc75402b5ebd6e12a563f7315f83fe966c.1689753076.git.waqar.hameed@axis.com/
> [2] https://lore.kernel.org/lkml/7b856b74c4c0f8c6c539d7c692051c9203b103c0.1692699931.git.waqar.hameed@axis.com/
> [3] https://lore.kernel.org/lkml/20231002-rx8111-add-timestamp0-v1-1-353727cf7f14@axis.com/
> [4] https://lore.kernel.org/lkml/20230502-tps6287x-driver-v3-2-e25140a023f5@axis.com/
> [5] https://lore.kernel.org/lkml/20221012102347.153201-1-chenhuiz@axis.com/
> [6] https://lore.kernel.org/lkml/20220413114014.2204623-3-camel.guo@axis.com/
> 
> In fact, by running our roadtests on newer kernels we have found
> numerous bugs[10][12][14] and regressions[7][8][9][11][15] in mainline,
> including subsystem-level issues affecting other drivers too.
> 
> [7] https://lore.kernel.org/lkml/20230911-regulator-voltage-sel-v1-1-886eb1ade8d8@axis.com/
> [8] https://lore.kernel.org/lkml/20230918-power-uaf-v1-1-73c397178c42@axis.com/
> [9] https://lore.kernel.org/lkml/20230829-tps-voltages-v1-1-7ba4f958a194@axis.com/
> [10] https://lore.kernel.org/lkml/20230613-genirq-nested-v3-1-ae58221143eb@axis.com/
> [11] https://lore.kernel.org/lkml/20220503114333.456476-1-camel.guo@axis.com/
> [12] https://lore.kernel.org/linux-iio/20220816080828.1218667-1-vincent.whitchurch@axis.com/
> [13] https://lore.kernel.org/linux-iio/20220519091925.1053897-1-vincent.whitchurch@axis.com/
> [14] https://lore.kernel.org/linux-iio/20220620144231.GA23345@axis.com/
> [15] https://lore.kernel.org/linux-spi/YxBX4bXG02E4lSUW@axis.com/
> 
> (The above lists are not exhaustive.)
> 

Great stuff!

> > Hope it is still headed for a new version / upstream!  
> 
> I pushed out an update with a squash of (most parts of) our internal
> version out to the following repo, it's based on v6.6-rc4.
> 
>   https://github.com/vwax/linux/tree/roadtest/devel

Thanks.

> 
> (There are currently 6 lines of --diff-filter=M against v6.6-rc4 on the
>  linked repo.  Two of those are from a patch which is posted and waiting
>  for review on the lists, and the rest are for enabling regmap debugfs
>  writes which are used from some of the newer tests.)
> 
> Since roadtest itself does not require any patches to the kernel or any
> out-of-tree modules, the maintenance of the framework would not really
> be simplified by putting it in the upstream tree.  However, there is of
> course a potentially large benefit to the quality of many kinds of
> kernel drivers if roadtest gets used by others, and having it in-tree
> could facilitate that.  And it would potentially allow regressions like
> the ones we're finding to be caught _before_ they go in, since anyone
> can run the tests without special hardware.

Exactly  - my main interest is the dream of getting to the point where
new drivers typically also come with roadtest tests, with the aim that
they will be used for regression testing. For IIO I might lean on
/ ask nicely  few of the bigger contributors to add fairly comprehensive
tests for say one in 3 of their drivers, providing a canary for any
subsystem level problems that might sneak in. The stability gained for
those drivers might also prove it's own benefit to push people to add tests.
At somepoint in the longer term I might even make it a requirement for
upstreaming a new driver + slowly tackle the backlog of existing ones.
From my experiments with it last year, this is a trivial burden fo

> 
> The idea of having to maintain it in-tree and doing all the work that
> goes along with that (dealing with the expectations of maintainers,
> wrangling patches from mailing lists, etc), is something I personally
> have had a hard time warming up to, but I have some coworkers who may
> potentially be interested in that kind of work, so I wouldn't rule out
> another posting of the patch set targeting upstream sometime in the
> future.

I fully appreciate your concern.  I just really like roadtest and want
a smooth way to integrate using it with my upstream maintenance (and occasional
development) process...  I of course can't expect you to commit to anything
though - I'd be delighted if someone else wants to take this forwards but
that would be very much their decision to make!

Having not yet waded into the latest code, how 'stable' is it from the point
of view of modifications to tests?  I can rebase the ones I have out of tree
and see, but I'm after an assessment that incorporates what you are
planning to change in future.

I guess the nasty stuff is if you have a few hundred additional drivers
in the test set, any modification to the way they interact with the core
of roadtest becomes very painful to push into those tests.

One starting point would be to separate the tests directory from the
directories containing roadtest frameworks etc as that would help to
limit scope of responsibility.

If a potential upstream roadtest maintainer is primarily concerned about
review + handling of the actual tests, other than potentially letting in
some ugly code, I'd imagine any subsystem maintainer who opts into this
will take that burden on - perhaps with the occasional question heading
your way. I'd certainly not expect you to have to deal with high patch flows
and would ensure that didn't happen for any IIO tests (any review people
have time for is of course welcome!)

+CC a few maintainers of other subsystems who may be interested (I know
one of them is ;)

Jonathan

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

end of thread, other threads:[~2023-10-10  9:29 UTC | newest]

Thread overview: 88+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-29 17:23 [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
2023-09-29 17:23 ` [PATCH v3 01/27] dt-bindings: iio: resolver: add devicetree bindings for ad2s1210 David Lechner
2023-09-30 14:34   ` Jonathan Cameron
2023-10-04 10:41     ` Hennerich, Michael
2023-10-02  8:02   ` Dan Carpenter
2023-10-02  9:03     ` Jonathan Cameron
2023-10-02 15:18   ` Rob Herring
2023-10-05 14:13     ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 02/27] staging: iio: resolver: ad2s1210: fix use before initialization David Lechner
2023-09-30 14:28   ` Jonathan Cameron
2023-10-02  8:07   ` Dan Carpenter
2023-10-02  9:17     ` Jonathan Cameron
2023-10-06 14:48       ` Vincent Whitchurch
2023-10-10  9:29         ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 03/27] staging: iio: resolver: ad2s1210: remove call to spi_setup() David Lechner
2023-09-30 14:35   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 04/27] staging: iio: resolver: ad2s1210: check return of ad2s1210_initial() David Lechner
2023-09-30 14:37   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 05/27] staging: iio: resolver: ad2s1210: remove spi_set_drvdata() David Lechner
2023-09-30 14:38   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 06/27] staging: iio: resolver: ad2s1210: sort imports David Lechner
2023-09-30 14:39   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 07/27] staging: iio: resolver: ad2s1210: always use 16-bit value for raw read David Lechner
2023-09-30 14:41   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 08/27] staging: iio: resolver: ad2s1210: implement IIO_CHAN_INFO_SCALE David Lechner
2023-09-30 14:43   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 09/27] staging: iio: resolver: ad2s1210: use devicetree to get CLKIN rate David Lechner
2023-09-30 14:44   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 10/27] staging: iio: resolver: ad2s1210: use regmap for config registers David Lechner
2023-09-30 14:51   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 11/27] staging: iio: resolver: ad2s1210: add debugfs reg access David Lechner
2023-09-30 14:52   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 12/27] staging: iio: resolver: ad2s1210: remove config attribute David Lechner
2023-09-30 14:53   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 13/27] staging: iio: resolver: ad2s1210: rework gpios David Lechner
2023-09-30 14:55   ` Jonathan Cameron
2023-10-05 13:38     ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 14/27] staging: iio: resolver: ad2s1210: implement hysteresis as channel attr David Lechner
2023-09-29 17:53   ` David Lechner
2023-09-30 15:00     ` Jonathan Cameron
2023-09-30 21:23       ` David Lechner
2023-09-30 15:03   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 15/27] staging: iio: resolver: ad2s1210: refactor setting excitation frequency David Lechner
2023-09-30 15:06   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 16/27] staging: iio: resolver: ad2s1210: read excitation frequency from control register David Lechner
2023-09-30 15:08   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 17/27] staging: iio: resolver: ad2s1210: convert fexcit to channel attribute David Lechner
2023-09-30 15:12   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 18/27] staging: iio: resolver: ad2s1210: convert resolution to devicetree property David Lechner
2023-09-30 15:15   ` Jonathan Cameron
2023-09-29 17:23 ` [PATCH v3 19/27] staging: iio: resolver: ad2s1210: add phase lock range support David Lechner
2023-09-30 15:18   ` Jonathan Cameron
2023-10-03  8:03   ` kernel test robot
2023-09-29 17:23 ` [PATCH v3 20/27] staging: iio: resolver: ad2s1210: add triggered buffer support David Lechner
2023-09-29 17:23 ` [PATCH v3 21/27] staging: iio: resolver: ad2s1210: convert LOT threshold attrs to event attrs David Lechner
2023-09-30 15:29   ` Jonathan Cameron
2023-10-03 11:11   ` kernel test robot
2023-09-29 17:23 ` [PATCH v3 22/27] staging: iio: resolver: ad2s1210: convert LOS threshold to event attr David Lechner
2023-09-30 15:32   ` Jonathan Cameron
2023-10-04 11:01     ` Hennerich, Michael
2023-10-05 14:16       ` Jonathan Cameron
2023-09-30 15:42   ` Jonathan Cameron
2023-09-30 15:46     ` Jonathan Cameron
2023-10-02 16:09     ` David Lechner
2023-10-05 14:37       ` Jonathan Cameron
2023-10-05 19:25         ` David Lechner
2023-10-03 14:21   ` kernel test robot
2023-09-29 17:23 ` [PATCH v3 23/27] staging: iio: resolver: ad2s1210: convert DOS overrange " David Lechner
2023-09-30 15:33   ` Jonathan Cameron
2023-10-03 17:21   ` kernel test robot
2023-09-29 17:23 ` [PATCH v3 24/27] staging: iio: resolver: ad2s1210: convert DOS mismatch " David Lechner
2023-10-03 20:08   ` kernel test robot
2023-09-29 17:23 ` [PATCH v3 25/27] staging: iio: resolver: ad2s1210: rename DOS reset min/max attrs David Lechner
2023-09-30 15:47   ` Jonathan Cameron
2023-10-02 17:06     ` David Lechner
2023-10-03 23:23   ` kernel test robot
2023-09-29 17:23 ` [PATCH v3 26/27] staging: iio: resolver: ad2s1210: implement fault events David Lechner
2023-09-30  3:55   ` kernel test robot
2023-09-30 16:00   ` Jonathan Cameron
2023-10-02 16:43     ` David Lechner
2023-10-02 16:58     ` David Lechner
2023-10-02 18:49       ` David Lechner
2023-10-05 14:52       ` Jonathan Cameron
2023-10-03 10:53   ` Dan Carpenter
2023-09-29 17:23 ` [PATCH v3 27/27] staging: iio: resolver: ad2s1210: add label attribute support David Lechner
2023-09-29 17:49 ` [PATCH v3 00/27] iio: resolver: move ad2s1210 out of staging David Lechner
2023-09-30 14:26   ` Jonathan Cameron
2023-09-29 22:02 ` David Lechner

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).