Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) ============================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) rotary-encoder - a generic driver for GPIO connected devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) ============================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) :Author: Daniel Mack <daniel@caiaq.de>, Feb 2009
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) Function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) --------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) Rotary encoders are devices which are connected to the CPU or other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) peripherals with two wires. The outputs are phase-shifted by 90 degrees
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) and by triggering on falling and rising edges, the turn direction can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) be determined.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) Some encoders have both outputs low in stable states, others also have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) a stable state with both outputs high (half-period mode) and some have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) a stable state in all steps (quarter-period mode).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) The phase diagram of these two outputs look like this::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)                   _____       _____       _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)                  |     |     |     |     |     |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)   Channel A  ____|     |_____|     |_____|     |____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)                  :  :  :  :  :  :  :  :  :  :  :  :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)             __       _____       _____       _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)               |     |     |     |     |     |     |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)   Channel B   |_____|     |_____|     |_____|     |__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)                  :  :  :  :  :  :  :  :  :  :  :  :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)   Event          a  b  c  d  a  b  c  d  a  b  c  d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)                 |<-------->|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	          one step
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)                 |<-->|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	          one step (half-period mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)                 |<>|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	          one step (quarter-period mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) For more information, please see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	https://en.wikipedia.org/wiki/Rotary_encoder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) Events / state machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) ----------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) In half-period mode, state a) and c) above are used to determine the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) rotational direction based on the last stable state. Events are reported in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) states b) and d) given that the new stable state is different from the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) (i.e. the rotation was not reversed half-way).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) Otherwise, the following apply:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) a) Rising edge on channel A, channel B in low state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	This state is used to recognize a clockwise turn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) b) Rising edge on channel B, channel A in high state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	When entering this state, the encoder is put into 'armed' state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	meaning that there it has seen half the way of a one-step transition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) c) Falling edge on channel A, channel B in high state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	This state is used to recognize a counter-clockwise turn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) d) Falling edge on channel B, channel A in low state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	Parking position. If the encoder enters this state, a full transition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	should have happened, unless it flipped back on half the way. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	'armed' state tells us about that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) Platform requirements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) ---------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) As there is no hardware dependent call in this driver, the platform it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) used with must support gpiolib. Another requirement is that IRQs must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) able to fire on both edges.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) Board integration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) -----------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) To use this driver in your system, register a platform_device with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) name 'rotary-encoder' and associate the IRQs and some specific platform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) data with it. Because the driver uses generic device properties, this can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) be done either via device tree, ACPI, or using static board files, like in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) example below:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	/* board support file example */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	#include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	#include <linux/gpio/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	#include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	#define GPIO_ROTARY_A 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	#define GPIO_ROTARY_B 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	static struct gpiod_lookup_table rotary_encoder_gpios = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		.dev_id = "rotary-encoder.0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		.table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			GPIO_LOOKUP_IDX("gpio-0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 					GPIO_ROTARY_A, NULL, 0, GPIO_ACTIVE_LOW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			GPIO_LOOKUP_IDX("gpio-0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 					GPIO_ROTARY_B, NULL, 1, GPIO_ACTIVE_HIGH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	static const struct property_entry rotary_encoder_properties[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		PROPERTY_ENTRY_U32("rotary-encoder,steps-per-period", 24),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		PROPERTY_ENTRY_U32("linux,axis",		      ABS_X),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		PROPERTY_ENTRY_U32("rotary-encoder,relative_axis",    0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	static struct platform_device rotary_encoder_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		.name		= "rotary-encoder",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		.id		= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	gpiod_add_lookup_table(&rotary_encoder_gpios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	device_add_properties(&rotary_encoder_device, rotary_encoder_properties);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	platform_device_register(&rotary_encoder_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) Please consult device tree binding documentation to see all properties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) supported by the driver.