diff options
author | David Lechner <dlechner@baylibre.com> | 2025-01-11 03:22:07 +0300 |
---|---|---|
committer | William Breathitt Gray <wbg@kernel.org> | 2025-02-05 07:22:04 +0300 |
commit | c2a756660324fceca26780a50950e6d91dfdc210 (patch) | |
tree | 2701d6fcfcfa6c666b0d8aebfb9f583bdc525125 | |
parent | 37f7a388b3f1b14eaeb295c2fe554d15e34e8ab9 (diff) | |
download | linux-c2a756660324fceca26780a50950e6d91dfdc210.tar.xz |
counter: ti-eqep: add direction support
Add support for reading the direction and for emitting direction change
events to the ti-eqep counter driver.
Signed-off-by: David Lechner <dlechner@baylibre.com>
Link: https://lore.kernel.org/r/20250110-counter-ti-eqep-add-direction-support-v2-4-c6b6f96d2db9@baylibre.com
Signed-off-by: William Breathitt Gray <wbg@kernel.org>
-rw-r--r-- | drivers/counter/ti-eqep.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c index bc586eff0dae..d21c157e531a 100644 --- a/drivers/counter/ti-eqep.c +++ b/drivers/counter/ti-eqep.c @@ -107,6 +107,15 @@ #define QCLR_PCE BIT(1) #define QCLR_INT BIT(0) +#define QEPSTS_UPEVNT BIT(7) +#define QEPSTS_FDF BIT(6) +#define QEPSTS_QDF BIT(5) +#define QEPSTS_QDLF BIT(4) +#define QEPSTS_COEF BIT(3) +#define QEPSTS_CDEF BIT(2) +#define QEPSTS_FIMF BIT(1) +#define QEPSTS_PCEF BIT(0) + /* EQEP Inputs */ enum { TI_EQEP_SIGNAL_QEPA, /* QEPA/XCLK */ @@ -286,6 +295,9 @@ static int ti_eqep_events_configure(struct counter_device *counter) case COUNTER_EVENT_UNDERFLOW: qeint |= QEINT_PCU; break; + case COUNTER_EVENT_DIRECTION_CHANGE: + qeint |= QEINT_QDC; + break; } } @@ -298,6 +310,7 @@ static int ti_eqep_watch_validate(struct counter_device *counter, switch (watch->event) { case COUNTER_EVENT_OVERFLOW: case COUNTER_EVENT_UNDERFLOW: + case COUNTER_EVENT_DIRECTION_CHANGE: if (watch->channel != 0) return -EINVAL; @@ -368,11 +381,27 @@ static int ti_eqep_position_enable_write(struct counter_device *counter, return 0; } +static int ti_eqep_direction_read(struct counter_device *counter, + struct counter_count *count, + enum counter_count_direction *direction) +{ + struct ti_eqep_cnt *priv = counter_priv(counter); + u32 qepsts; + + regmap_read(priv->regmap16, QEPSTS, &qepsts); + + *direction = (qepsts & QEPSTS_QDF) ? COUNTER_COUNT_DIRECTION_FORWARD + : COUNTER_COUNT_DIRECTION_BACKWARD; + + return 0; +} + static struct counter_comp ti_eqep_position_ext[] = { COUNTER_COMP_CEILING(ti_eqep_position_ceiling_read, ti_eqep_position_ceiling_write), COUNTER_COMP_ENABLE(ti_eqep_position_enable_read, ti_eqep_position_enable_write), + COUNTER_COMP_DIRECTION(ti_eqep_direction_read), }; static struct counter_signal ti_eqep_signals[] = { @@ -439,6 +468,9 @@ static irqreturn_t ti_eqep_irq_handler(int irq, void *dev_id) if (qflg & QFLG_PCU) counter_push_event(counter, COUNTER_EVENT_UNDERFLOW, 0); + if (qflg & QFLG_QDC) + counter_push_event(counter, COUNTER_EVENT_DIRECTION_CHANGE, 0); + regmap_write(priv->regmap16, QCLR, qflg); return IRQ_HANDLED; |