Commit c2a75666 authored by David Lechner's avatar David Lechner Committed by William Breathitt Gray
Browse files

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: default avatarDavid 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: default avatarWilliam Breathitt Gray <wbg@kernel.org>
parent 37f7a388
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -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;