counter: add GPIO-based quadrature encoder driver
Subsystems (3)
cover counter: add GPIO-based quadrature encoder driver
This series adds a new counter subsystem driver that implements quadrature encoder position tracking using plain GPIO pins with edge-triggered interrupts.
The driver is intended for low to medium speed rotary encoders where hardware counter peripherals (eQEP, FTM, etc.) are unavailable or already in use. It targets the same use-cases as interrupt-cnt.c but provides full quadrature decoding instead of simple pulse counting.
Features:
- X1, X2, X4 quadrature decoding and pulse-direction mode
- Optional index signal for zero-reset
- Configurable ceiling (position clamping)
- Standard counter subsystem sysfs + chrdev interface
- Enable/disable via sysfs with IRQ gating
Tested on TI AM64x (Cortex-A53) with a motor-driven rotary encoder at up to 2 kHz quadrature edge rate.
Wadim Mueller (3):
dt-bindings: counter: add gpio-quadrature-encoder binding
counter: add GPIO-based quadrature encoder driver
MAINTAINERS: add entry for GPIO quadrature encoder counter driver
.../counter/gpio-quadrature-encoder.yaml | 69 ++ MAINTAINERS | 7 + drivers/counter/Kconfig | 15 + drivers/counter/Makefile | 1 + drivers/counter/gpio-quadrature-encoder.c | 710 ++++++++++++++++++ 5 files changed, 802 insertions(+) create mode 100644 Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml create mode 100644 drivers/counter/gpio-quadrature-encoder.c
Signature · 1 line
2.52.0
PATCH 1/3 dt-bindings: counter: add gpio-quadrature-encoder binding
Add devicetree binding documentation for the GPIO-based quadrature encoder counter driver. The driver reads A/B quadrature signals and an optional index pulse via edge-triggered GPIO interrupts, supporting X1, X2, X4 quadrature decoding and pulse-direction mode.
This is useful on SoCs that lack a dedicated hardware quadrature decoder or where the encoder is wired to generic GPIO pins.
--- .../counter/gpio-quadrature-encoder.yaml | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +69 -0
@@ -0,0 +1,69 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/counter/gpio-quadrature-encoder.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: GPIO-based Quadrature Encoder + +maintainers: + - Wadim Mueller <[email protected]> + +description: | + A generic GPIO-based quadrature encoder counter. Reads A/B quadrature + signals and an optional index pulse via edge-triggered GPIO interrupts. + Supports X1, X2, X4 quadrature decoding and pulse-direction mode. + + This driver is useful on SoCs that lack a dedicated hardware quadrature + decoder (eQEP, QEI, etc.) or where the encoder is wired to generic GPIO + pins rather than to a dedicated peripheral. + +properties: + compatible: + const: gpio-quadrature-encoder + + encoder-a-gpios: + maxItems: 1 + description: + GPIO connected to the encoder's A (phase A) output. + + encoder-b-gpios: + maxItems: 1 + description: + GPIO connected to the encoder's B (phase B) output. + + encoder-index-gpios: + maxItems: 1 + description: + Optional GPIO connected to the encoder's index (Z) output. + When the index input is enabled via sysfs, the count resets + to zero on each index pulse. + +required: + - compatible + - encoder-a-gpios + - encoder-b-gpios + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + quadrature-encoder-0 { + compatible = "gpio-quadrature-encoder"; + encoder-a-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>; + encoder-b-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + }; + + - | + #include <dt-bindings/gpio/gpio.h> + + quadrature-encoder-1 { + compatible = "gpio-quadrature-encoder"; + encoder-a-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + encoder-b-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + encoder-index-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + }; + +...
Signature · 1 line
2.52.0
Re: [PATCH 1/3] dt-bindings: counter: add gpio-quadrature-encoder binding
Quoted 30 lines · Wadim Mueller
Add devicetree binding documentation for the GPIO-based quadrature encoder counter driver. The driver reads A/B quadrature signals and an optional index pulse via edge-triggered GPIO interrupts, supporting X1, X2, X4 quadrature decoding and pulse-direction mode.
This is useful on SoCs that lack a dedicated hardware quadrature decoder or where the encoder is wired to generic GPIO pins.
Signed-off-by Wadim Mueller <[email protected]>--- .../counter/gpio-quadrature-encoder.yaml | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yamlDocumentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +10
-0@@ -0,0 +1,69 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/counter/gpio-quadrature-encoder.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: GPIO-based Quadrature Encoder + +maintainers: + - Wadim Mueller <[email protected]>
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml line 19
Quoted 10 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +9
-0+ +description: | + A generic GPIO-based quadrature encoder counter. Reads A/B quadrature + signals and an optional index pulse via edge-triggered GPIO interrupts. + Supports X1, X2, X4 quadrature decoding and pulse-direction mode. + + This driver is useful on SoCs that lack a dedicated hardware quadrature + decoder (eQEP, QEI, etc.) or where the encoder is wired to generic GPIO + pins rather than to a dedicated peripheral.
Idea seems okay to me. Please rephrase this section to avoid talking about drivers...
Quoted 11 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +11
-0+ +properties: + compatible: + const: gpio-quadrature-encoder + + encoder-a-gpios: + maxItems: 1 + description: + GPIO connected to the encoder's A (phase A) output. + + encoder-b-gpios:
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml line 40
Quoted 10 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +10
-0+ maxItems: 1 + description: + GPIO connected to the encoder's B (phase B) output. + + encoder-index-gpios: + maxItems: 1 + description: + Optional GPIO connected to the encoder's index (Z) output. + When the index input is enabled via sysfs, the count resets + to zero on each index pulse.
...and this to stop talking about sysfs and driver behaviour though. Bindings are about hardware.
pw-bot: changes-requested
Quoted 17 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +17
-0+ +required: + - compatible + - encoder-a-gpios + - encoder-b-gpios + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + quadrature-encoder-0 { + compatible = "gpio-quadrature-encoder"; + encoder-a-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>; + encoder-b-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + };
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml line 67
Quoted 10 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +10
-0+ + - | + #include <dt-bindings/gpio/gpio.h> + + quadrature-encoder-1 { + compatible = "gpio-quadrature-encoder"; + encoder-a-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + encoder-b-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + encoder-index-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + };
I think this example alone is sufficient btw.
Cheers,
Conor.
Quoted 5 lines
+
+...Signature · 1 line
2.52.0
Re: [PATCH 1/3] dt-bindings: counter: add gpio-quadrature-encoder binding
On 2026-04-17 17:13, Conor Dooley wrote:
Thanks for the review
Quoted 38 lines · Wadim Mueller
Quoted 36 lines
Add devicetree binding documentation for the GPIO-based quadrature encoder counter driver. The driver reads A/B quadrature signals and an optional index pulse via edge-triggered GPIO interrupts, supporting X1, X2, X4 quadrature decoding and pulse-direction mode.
This is useful on SoCs that lack a dedicated hardware quadrature decoder or where the encoder is wired to generic GPIO pins.
Signed-off-by Wadim Mueller <[email protected]>--- .../counter/gpio-quadrature-encoder.yaml | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yamlDocumentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +16
-0@@ -0,0 +1,69 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/counter/gpio-quadrature-encoder.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: GPIO-based Quadrature Encoder + +maintainers: + - Wadim Mueller <[email protected]> + +description: | + A generic GPIO-based quadrature encoder counter. Reads A/B quadrature + signals and an optional index pulse via edge-triggered GPIO interrupts. + Supports X1, X2, X4 quadrature decoding and pulse-direction mode. +
Quoted 6 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml line 19
Quoted 3 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +3
-0+ This driver is useful on SoCs that lack a dedicated hardware quadrature + decoder (eQEP, QEI, etc.) or where the encoder is wired to generic GPIO + pins rather than to a dedicated peripheral.Idea seems okay to me. Please rephrase this section to avoid talking about drivers...
Thanks, will fix that in v2.
Quoted 18 lines
Quoted 18 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +17
-0+ +properties: + compatible: + const: gpio-quadrature-encoder + + encoder-a-gpios: + maxItems: 1 + description: + GPIO connected to the encoder's A (phase A) output. + + encoder-b-gpios: + maxItems: 1 + description: + GPIO connected to the encoder's B (phase B) output. + + encoder-index-gpios: + maxItems: 1
Quoted 9 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml line 40
Quoted 4 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +4
-0+ description: + Optional GPIO connected to the encoder's index (Z) output. + When the index input is enabled via sysfs, the count resets + to zero on each index pulse....and this to stop talking about sysfs and driver behaviour though. Bindings are about hardware.
pw-bot: changes-requested
Agreed, will rephrase to mention hardware signals only
Quoted 21 lines
Quoted 21 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +21
-0+ +required: + - compatible + - encoder-a-gpios + - encoder-b-gpios + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + quadrature-encoder-0 { + compatible = "gpio-quadrature-encoder"; + encoder-a-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>; + encoder-b-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + }; + + - | + #include <dt-bindings/gpio/gpio.h> +
Quoted 9 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml line 67
Quoted 6 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +6
-0+ quadrature-encoder-1 { + compatible = "gpio-quadrature-encoder"; + encoder-a-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + encoder-b-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + encoder-index-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + };I think this example alone is sufficient btw.
Ack, will drop the first example
Quoted 7 lines
Cheers,
Conor.Quoted 5 lines
Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml new file +2
-0+ +...Signature · 1 line
2.52.0
PATCH 2/3 counter: add GPIO-based quadrature encoder driver
In reply to Wadim MuellerAdd a platform driver that turns ordinary GPIOs into a quadrature encoder counter device. The driver requests edge-triggered interrupts on the A and B (and optional Index) GPIOs and decodes the quadrature signal in software using a classic state-table approach.
Supported counting modes:
- Quadrature X1 (count on A rising edge only)
- Quadrature X2 (count on both A edges)
- Quadrature X4 (count on every A and B edge)
- Pulse-direction (A = pulse, B = direction)
An optional index signal resets the count to zero on its rising edge when enabled through sysfs. A configurable ceiling clamps the count to [0, ceiling].
--- drivers/counter/Kconfig | 15 + drivers/counter/Makefile | 1 + drivers/counter/gpio-quadrature-encoder.c | 710 ++++++++++++++++++++++ 3 files changed, 726 insertions(+) create mode 100644 drivers/counter/gpio-quadrature-encoder.c
drivers/counter/Kconfig +15 -0
@@ -68,6 +68,21 @@ config INTEL_QEP To compile this driver as a module, choose M here: the module will be called intel-qep. +config GPIO_QUADRATURE_ENCODER + tristate "GPIO-based quadrature encoder counter driver" + depends on GPIOLIB + help + Select this option to enable the GPIO-based quadrature encoder + counter driver. It reads A/B quadrature signals and an optional + index pulse via edge-triggered GPIO interrupts, supporting X1, X2, + X4 quadrature decoding and pulse-direction mode. + + This is useful on SoCs that lack a dedicated hardware quadrature + decoder or where the encoder is wired to generic GPIO pins. + + To compile this driver as a module, choose M here: the + module will be called gpio-quadrature-encoder. + config INTERRUPT_CNT tristate "Interrupt counter driver" depends on GPIOLIB
drivers/counter/Makefile +1 -0
@@ -14,6 +14,7 @@ obj-$(CONFIG_STM32_TIMER_CNT) += stm32-timer-cnt.o obj-$(CONFIG_STM32_LPTIMER_CNT) += stm32-lptimer-cnt.o obj-$(CONFIG_TI_EQEP) += ti-eqep.o obj-$(CONFIG_FTM_QUADDEC) += ftm-quaddec.o +obj-$(CONFIG_GPIO_QUADRATURE_ENCODER) += gpio-quadrature-encoder.o obj-$(CONFIG_MICROCHIP_TCB_CAPTURE) += microchip-tcb-capture.o obj-$(CONFIG_INTEL_QEP) += intel-qep.o obj-$(CONFIG_TI_ECAP_CAPTURE) += ti-ecap-capture.o
drivers/counter/gpio-quadrature-encoder.c new file +710 -0
710 lines not on this page · raw message
Signature · 1 line
2.52.0
PATCH 3/3 MAINTAINERS: add entry for GPIO quadrature encoder counter driver
In reply to Wadim MuellerAdd myself as maintainer for the new gpio-quadrature-encoder counter driver and its devicetree binding.
--- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+)
MAINTAINERS +7 -0
@@ -11018,6 +11018,13 @@ F: Documentation/dev-tools/gpio-sloppy-logic-analyzer.rst F: drivers/gpio/gpio-sloppy-logic-analyzer.c F: tools/gpio/gpio-sloppy-logic-analyzer.sh +GPIO QUADRATURE ENCODER COUNTER DRIVER +M: Wadim Mueller <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml +F: drivers/counter/gpio-quadrature-encoder.c + GPIO SUBSYSTEM M: Linus Walleij <[email protected]> M: Bartosz Golaszewski <[email protected]>
Signature · 1 line
2.52.0