1rotary-encoder - a generic driver for GPIO connected devices 2Daniel Mack <daniel@caiaq.de>, Feb 2009 3 40. Function 5----------- 6 7Rotary encoders are devices which are connected to the CPU or other 8peripherals with two wires. The outputs are phase-shifted by 90 degrees 9and by triggering on falling and rising edges, the turn direction can 10be determined. 11 12Some encoders have both outputs low in stable states, whereas others also have 13a stable state with both outputs high (half-period mode). 14 15The phase diagram of these two outputs look like this: 16 17 _____ _____ _____ 18 | | | | | | 19 Channel A ____| |_____| |_____| |____ 20 21 : : : : : : : : : : : : 22 __ _____ _____ _____ 23 | | | | | | | 24 Channel B |_____| |_____| |_____| |__ 25 26 : : : : : : : : : : : : 27 Event a b c d a b c d a b c d 28 29 |<-------->| 30 one step 31 32 |<-->| 33 one step (half-period mode) 34 35For more information, please see 36 http://en.wikipedia.org/wiki/Rotary_encoder 37 38 391. Events / state machine 40------------------------- 41 42In half-period mode, state a) and c) above are used to determine the 43rotational direction based on the last stable state. Events are reported in 44states b) and d) given that the new stable state is different from the last 45(i.e. the rotation was not reversed half-way). 46 47Otherwise, the following apply: 48 49a) Rising edge on channel A, channel B in low state 50 This state is used to recognize a clockwise turn 51 52b) Rising edge on channel B, channel A in high state 53 When entering this state, the encoder is put into 'armed' state, 54 meaning that there it has seen half the way of a one-step transition. 55 56c) Falling edge on channel A, channel B in high state 57 This state is used to recognize a counter-clockwise turn 58 59d) Falling edge on channel B, channel A in low state 60 Parking position. If the encoder enters this state, a full transition 61 should have happened, unless it flipped back on half the way. The 62 'armed' state tells us about that. 63 642. Platform requirements 65------------------------ 66 67As there is no hardware dependent call in this driver, the platform it is 68used with must support gpiolib. Another requirement is that IRQs must be 69able to fire on both edges. 70 71 723. Board integration 73-------------------- 74 75To use this driver in your system, register a platform_device with the 76name 'rotary-encoder' and associate the IRQs and some specific platform 77data with it. 78 79struct rotary_encoder_platform_data is declared in 80include/linux/rotary-encoder.h and needs to be filled with the number of 81steps the encoder has and can carry information about externally inverted 82signals (because of an inverting buffer or other reasons). The encoder 83can be set up to deliver input information as either an absolute or relative 84axes. For relative axes the input event returns +/-1 for each step. For 85absolute axes the position of the encoder can either roll over between zero 86and the number of steps or will clamp at the maximum and zero depending on 87the configuration. 88 89Because GPIO to IRQ mapping is platform specific, this information must 90be given in separately to the driver. See the example below. 91 92---------<snip>--------- 93 94/* board support file example */ 95 96#include <linux/input.h> 97#include <linux/rotary_encoder.h> 98 99#define GPIO_ROTARY_A 1 100#define GPIO_ROTARY_B 2 101 102static struct rotary_encoder_platform_data my_rotary_encoder_info = { 103 .steps = 24, 104 .axis = ABS_X, 105 .relative_axis = false, 106 .rollover = false, 107 .gpio_a = GPIO_ROTARY_A, 108 .gpio_b = GPIO_ROTARY_B, 109 .inverted_a = 0, 110 .inverted_b = 0, 111 .half_period = false, 112}; 113 114static struct platform_device rotary_encoder_device = { 115 .name = "rotary-encoder", 116 .id = 0, 117 .dev = { 118 .platform_data = &my_rotary_encoder_info, 119 } 120}; 121 122