Input: rotary_encoder - support binary encoding of states
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Wed, 27 Jul 2016 21:36:26 +0000 (14:36 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 28 Jul 2016 01:26:10 +0000 (18:26 -0700)
It's not advisable to use this encoding, but to support existing devices
add support for this to the driver.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Documentation/devicetree/bindings/input/rotary-encoder.txt
drivers/input/misc/rotary_encoder.c

index 6c9f0c8a846c89a18532d56c488b7b133327113b..e85ce3dea4806bfbf9769d27514458603166e632 100644 (file)
@@ -20,6 +20,8 @@ Optional properties:
   2: Half-period mode
   4: Quarter-period mode
 - wakeup-source: Boolean, rotary encoder can wake up the system.
+- rotary-encoder,encoding: String, the method used to encode steps.
+  Supported are "gray" (the default and more common) and "binary".
 
 Deprecated properties:
 - rotary-encoder,half-period: Makes the driver work on half-period mode.
@@ -34,6 +36,7 @@ Example:
                        compatible = "rotary-encoder";
                        gpios = <&gpio 19 1>, <&gpio 20 0>; /* GPIO19 is inverted */
                        linux,axis = <0>; /* REL_X */
+                       rotary-encoder,encoding = "gray";
                        rotary-encoder,relative-axis;
                };
 
@@ -42,5 +45,6 @@ Example:
                        gpios = <&gpio 21 0>, <&gpio 22 0>;
                        linux,axis = <1>; /* ABS_Y */
                        rotary-encoder,steps = <24>;
+                       rotary-encoder,encoding = "binary";
                        rotary-encoder,rollover;
                };
index c7fc8d4fb08034fec95eb3e6e6f98f960d5262e6..1588aecafff79d8fdb54d80b7fa03a2ee9036f00 100644 (file)
 
 #define DRV_NAME "rotary-encoder"
 
+enum rotary_encoder_encoding {
+       ROTENC_GRAY,
+       ROTENC_BINARY,
+};
+
 struct rotary_encoder {
        struct input_dev *input;
 
@@ -37,6 +42,7 @@ struct rotary_encoder {
        u32 axis;
        bool relative_axis;
        bool rollover;
+       enum rotary_encoder_encoding encoding;
 
        unsigned int pos;
 
@@ -57,8 +63,9 @@ static unsigned int rotary_encoder_get_state(struct rotary_encoder *encoder)
 
        for (i = 0; i < encoder->gpios->ndescs; ++i) {
                int val = gpiod_get_value_cansleep(encoder->gpios->desc[i]);
+
                /* convert from gray encoding to normal */
-               if (ret & 1)
+               if (encoder->encoding == ROTENC_GRAY && ret & 1)
                        val = !val;
 
                ret = ret << 1 | val;
@@ -213,6 +220,20 @@ static int rotary_encoder_probe(struct platform_device *pdev)
        encoder->rollover =
                device_property_read_bool(dev, "rotary-encoder,rollover");
 
+       if (!device_property_present(dev, "rotary-encoder,encoding") ||
+           !device_property_match_string(dev, "rotary-encoder,encoding",
+                                         "gray")) {
+               dev_info(dev, "gray");
+               encoder->encoding = ROTENC_GRAY;
+       } else if (!device_property_match_string(dev, "rotary-encoder,encoding",
+                                                "binary")) {
+               dev_info(dev, "binary");
+               encoder->encoding = ROTENC_BINARY;
+       } else {
+               dev_err(dev, "unknown encoding setting\n");
+               return -EINVAL;
+       }
+
        device_property_read_u32(dev, "linux,axis", &encoder->axis);
        encoder->relative_axis =
                device_property_read_bool(dev, "rotary-encoder,relative-axis");