All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] rotary_encoder: increase/decrease on both rest states
@ 2010-05-12 13:04 Jelle Martijn Kok
  0 siblings, 0 replies; only message in thread
From: Jelle Martijn Kok @ 2010-05-12 13:04 UTC (permalink / raw)
  To: linux-input

Replaced the armed and dir states with a single last_state field. The 
rotary encoder does now increase on both "00" and "11".
It also fixes the "pumping" problem. If the rotary encoder is moved 
forward and backwards over a single pump, it will only increase or 
decrease in one direction.
An example for this "pumping" using gray codes
The encoder rotates one step: "11" => "10" => "00" (now it is increased)
The encoder rotates back: "00" => "10" => "11" (now it won't decrease)

Signed-off-by: Jelle Martijn Kok <jmkok@youcom.nl>
---
  drivers/input/misc/rotary_encoder.c |   77 
++++++++++++++++------------------
  1 files changed, 36 insertions(+), 41 deletions(-)

diff --git a/drivers/input/misc/rotary_encoder.c 
b/drivers/input/misc/rotary_encoder.c
index 1f8e010..24621b8 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -36,8 +36,7 @@ struct rotary_encoder {
      unsigned int irq_a;
      unsigned int irq_b;

-    bool armed;
-    unsigned char dir;    /* 0 - clockwise, 1 - CCW */
+    int last_state;
  };

  static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
@@ -52,51 +51,47 @@ static irqreturn_t rotary_encoder_irq(int irq, void 
*dev_id)
      b ^= pdata->inverted_b;
      state = (a << 1) | b;

-    switch (state) {
-
-    case 0x0:
-        if (!encoder->armed)
-            break;
-
-        if (pdata->relative_axis) {
-            input_report_rel(encoder->input, pdata->axis,
-                     encoder->dir ? -1 : 1);
-        } else {
-            unsigned int pos = encoder->pos;
+    if (((state == 0x0) || (state == 0x3)) && ((encoder->last_state == 
0x01) || (encoder->last_state == 0x02)))  {
+        int state_exor = state ^ encoder->last_state;
+        int dir = 0;
+        if (state_exor == 0x01) {
+            dir = +1;
+        }
+        else {
+            dir = -1;
+        }

-            if (encoder->dir) {
-                /* turning counter-clockwise */
-                if (pdata->rollover)
-                    pos += pdata->steps;
-                if (pos)
-                    pos--;
+        if (dir) {
+            if (pdata->relative_axis) {
+                input_report_rel(encoder->input, pdata->axis,
+                         dir);
              } else {
-                /* turning clockwise */
-                if (pdata->rollover || pos < pdata->steps)
-                    pos++;
+                unsigned int pos = encoder->pos;
+
+                if (dir == -1) {
+                    /* turning counter-clockwise */
+                    if (pdata->rollover)
+                        pos += pdata->steps;
+                    if (pos)
+                        pos--;
+                } else {
+                    /* turning clockwise */
+                    if (pdata->rollover || pos < pdata->steps)
+                        pos++;
+                }
+                if (pdata->rollover)
+                    pos %= pdata->steps;
+                encoder->pos = pos;
+                input_report_abs(encoder->input, pdata->axis,
+                         encoder->pos);
              }
-            if (pdata->rollover)
-                pos %= pdata->steps;
-            encoder->pos = pos;
-            input_report_abs(encoder->input, pdata->axis,
-                     encoder->pos);
+            input_sync(encoder->input);
          }
-        input_sync(encoder->input);
-
-        encoder->armed = false;
-        break;
-
-    case 0x1:
-    case 0x2:
-        if (encoder->armed)
-            encoder->dir = state - 1;
-        break;
-
-    case 0x3:
-        encoder->armed = true;
-        break;
      }

+    /* always store the state - even on 00 or 11 */
+    encoder->last_state = state;
+
      return IRQ_HANDLED;
  }

-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2010-05-12 13:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-12 13:04 [PATCH 1/3] rotary_encoder: increase/decrease on both rest states Jelle Martijn Kok

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.