I use the roatary_encooder driver.
https://www.kernel.org/doc/Documentation/input/rotary-encoder.txt
It has device tree bindings here:
http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/input/rotary-encoder.txt
My dts(device tree source) is:
/*
* wheelhat-overlay.dts
*/
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
fragment@0 {
target-path = "/soc/gpio";
__overlay__ {
wheel_pins: wheel_pins {
brcm,pins = <13 27>;
brcm,function = <0>;
brcm,pull = <2>;
};
};
};
fragment@1 {
target-path = "/soc";
__overlay__ {
wheel: wheel {
compatible = "rotary-encoder";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&wheel_pins>;
gpios = <&gpio 13 1>, <&gpio 27 1>;
linux,axis = <0>; /* REL_X */
rotary-encoder,relative-axis;
};
};
};
__overrides__ {
relative_axis = <&wheel>,"rotary-encoder,relative-axis";
linux_axis = <&wheel>,"linux,axis";
rollover = <&wheel>,"rotary-encoder,rollover";
half-period = <&wheel>,"rotary-encoder,half-period";
steps = <&wheel>,"rotary-encoder,steps";
};
};
The first fragment makes the pins have an input function with a pull-up. The rest is configuration and names exported to /boot/config.txt
. You compile the DTS file and put it in /boot/overlays
. The driver can do absolute x axis so you do not need to worry about losing interrupts. You need a Python event handler to catch x axis changes.