All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wadim Mueller <wafgo01@gmail.com>
To: William Breathitt Gray <wbg@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Rob Herring <robh@kernel.org>, Conor Dooley <conor+dt@kernel.org>
Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, Wadim Mueller <wafgo01@gmail.com>
Subject: [PATCH v4 0/3] counter: add GPIO-based quadrature encoder driver
Date: Fri, 15 May 2026 17:36:13 +0200	[thread overview]
Message-ID: <20260515153616.157605-1-wafgo01@gmail.com> (raw)
In-Reply-To: <20260501200749.20029-1-wafgo01@gmail.com>

This series adds a new counter subsystem driver which implements
quadrature encoder position tracking using plain GPIO pins with
edge-triggered interrupts.

The driver targets low- to medium-speed rotary encoders on SoCs where
hardware quadrature counter peripherals (eQEP, FTM, ...) are either
not available or already in use. It complements interrupt-cnt.c by
providing full A/B/Index quadrature decoding instead of just pulse
counting.

The strategic question from v3 -- "why kernel and not libgpiod in
userspace?" -- was already discussed in the v3 cover thread. A
reproducible benchmark on AM64x (kernel counter vs gpiomon/libgpiod
2.1.2, 3-run sweeps from 1 kHz up to 200 kHz) was posted there and
is also mirrored at https://github.com/wafgo/qenc-bench. William
accepted the case for a kernel implementation based on this, so i
will not repeat the numbers here, only the link.

Changes in v4 address the detailed review feedback from William on
PATCH 3/3 of v3:

Counter ABI / generic semantics:
  - Drop the private gpio_qenc_function enum, store and exchange the
    function as enum counter_function directly. function_read/write
    become trivial accessors.
  - Support the full set of generic Count functions:
    INCREASE, DECREASE, PULSE_DIRECTION,
    QUADRATURE_X1_{A,B}, QUADRATURE_X2_{A,B}, QUADRATURE_X4.
  - Add COUNTER_SYNAPSE_ACTION_FALLING_EDGE to the synapse action
    list and report it from action_read for the function modes
    where it does apply.
  - In QUADRATURE_X1_{A,B} the reported synapse action is now
    direction-dependent (RISING_EDGE when going forward, FALLING_EDGE
    when going backward) to match the Counter ABI semantics.
  - Restructure action_read: default to NONE, handle the Index
    synapse as a single early-return case, drop the per-function
    if/else cascade.
  - Use a dedicated action list for the Index synapse with only NONE
    and RISING_EDGE, since the other synapse actions do not apply
    there.
  - Migrate the Index feature from a custom "index_enabled"
    COUNTER_COMP_COUNT_BOOL to the generic COUNTER_COMP_PRESET +
    COUNTER_COMP_PRESET_ENABLE pair. The Index ISR now loads the
    preset value into count when preset_enable is set, like
    intel-qep and other drivers do.

Driver internals:
  - Change priv->count from s64 to u64. ceiling now defaults to
    U64_MAX instead of using ceiling == 0 as a sentinel for "no
    ceiling", which i think is also more clean.
  - Rewrite gpio_qenc_update_count direction-first, +/-1, with
    proper saturation at 0 and at ceiling.
  - Introduce CREATE_QE_STATE(prev_a, prev_b, curr_a, curr_b) and a
    single 16-entry X4 transition table indexed by the macro. The
    delta == 2 "invalid transition" path is gone, the table just
    has 0 in that slot.
  - Use default: in the ISR switches instead of listing every
    ignored case.
  - Drop the now-redundant enabled flag in the ISRs. Gating happens
    via enable_irq/disable_irq anyway and enable_read derives the
    state from irq_get_irq_data() so there is only one source of
    truth.
  - Simplify enable_write: no !!, assign directly, split the two
    branches by return.
  - Drop the no-op events_configure() hook from counter_ops, this
    one was just left over.
  - Do not register a synapse for the Index signal when no Index
    GPIO is wired (no zombie entries) and drop the corresponding
    !gpio guard in signal_read which was only there to catch the
    zombie case.
  - Declare priv->cnts as a single-element array and use
    ARRAY_SIZE(priv->cnts) for counter->num_counts, for consistency
    with the rest of the subsystem.
  - Rename the Count from "Position" to the more generic "Count",
    since positioning is only one of the use cases for a quadrature
    encoder.

Documentation / style:
  - Add a short comment to the priv spinlock.

Krzysztofs "drop const on scalar parameters" note from PATCH 2/3
of v2 is also taken care of in this rewrite -- v3 was Acked-by
Conor only and did not carry code changes yet, so the const scalar
parameters survived there. In v4 there are no const-qualified scalar
parameters left in the driver.

The follow-up scope which was discussed with William -- COMPARE/FLOOR
components plus OVERFLOW/UNDERFLOW/THRESHOLD/DIRECTION_CHANGE events
-- is on purpose not included in v4. I will send those as a separate
series on top of this one once it lands, so the diff size stays
reviewable.

Changes in v4:
  - Major review-driven rewrite of the driver (see above).

Changes in v3:
  - Pick up Acked-by: Conor Dooley on the DT binding patch.
  - No code changes.

Changes in v2:
  - DT binding: rephrase description to describe the hardware, not
    the driver/sysfs behaviour (Conor Dooley)
  - DT binding: drop redundant example without index GPIO (Conor Dooley)

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      |  60 ++
 MAINTAINERS                                   |   7 +
 drivers/counter/Kconfig                       |  15 +
 drivers/counter/Makefile                      |   1 +
 drivers/counter/gpio-quadrature-encoder.c     | 739 ++++++++++++++++++
 5 files changed, 822 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/counter/gpio-quadrature-encoder.yaml
 create mode 100644 drivers/counter/gpio-quadrature-encoder.c


base-commit: 3cd8b194bf3428dfa53120fee47e827a7c495815
-- 
2.52.0


  parent reply	other threads:[~2026-05-15 15:36 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-01 20:07 [PATCH v3 0/3] counter: add GPIO-based quadrature encoder driver Wadim Mueller
2026-05-01 20:07 ` [PATCH v3 1/3] dt-bindings: counter: add gpio-quadrature-encoder binding Wadim Mueller
2026-05-01 20:07 ` [PATCH v3 2/3] counter: add GPIO-based quadrature encoder driver Wadim Mueller
2026-05-04 20:54   ` Krzysztof Kozlowski
2026-05-04 21:15     ` Wadim Mueller
2026-05-15  5:48   ` William Breathitt Gray
2026-05-15 15:28     ` Wadim Mueller
2026-05-01 20:07 ` [PATCH v3 3/3] MAINTAINERS: add entry for GPIO quadrature encoder counter driver Wadim Mueller
2026-05-04  9:36 ` [PATCH v3 0/3] counter: add GPIO-based quadrature encoder driver William Breathitt Gray
2026-05-04 19:37   ` Wadim Mueller
2026-05-06  6:50   ` Wadim Mueller
2026-05-14 13:17     ` William Breathitt Gray
2026-05-15 15:36 ` Wadim Mueller [this message]
2026-05-15 15:36   ` [PATCH v4 1/3] dt-bindings: counter: add gpio-quadrature-encoder binding Wadim Mueller
2026-05-15 15:36   ` [PATCH v4 2/3] counter: add GPIO-based quadrature encoder driver Wadim Mueller
2026-05-15 16:14     ` sashiko-bot
2026-05-15 15:36   ` [PATCH v4 3/3] MAINTAINERS: add entry for GPIO quadrature encoder counter driver Wadim Mueller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260515153616.157605-1-wafgo01@gmail.com \
    --to=wafgo01@gmail.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=wbg@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.