History

Input: rotary-encoder - support more than 2 gpios as input

This changes how the used gpios are stored (i.e. a struct gpio_descs instead of two struct gpio_desc) and as with >2 gpios the states are numbered differently the function rotary_encoder_get_state returns unencoded numbers instead of grey encoded numbers before. The latter has some implications on how the returned value is used and so the change is bigger than one might expect at first.

Uwe Kleine-König committed 10 years ago

Commit 7dde4e71 parent a9e340d2 files · +65 −93Browse files

Unified · Split

2 files
  1. Documentation/devicetree/bindings/input/rotary-encoder.txt +1 −1
  2. drivers/input/misc/rotary_encoder.c +64 −92
Documentation/devicetree/bindings/input/rotary-encoder.txt+1−1
@@ -1,7 +1,7 @@
11 Rotary encoder DT bindings
22
33 Required properties:
4−- gpios: a spec for two GPIOs to be used
4+- gpios: a spec for at least two GPIOs to be used, most significant first
55
66 Optional properties:
77 - linux,axis: the input subsystem axis to map to this rotary encoder.
drivers/input/misc/rotary_encoder.c+64−92
@@ -40,35 +40,42 @@ struct rotary_encoder { · 39 unmodified lines
4040
4141 unsigned int pos;
4242
43− struct gpio_desc *gpio_a;
44− struct gpio_desc *gpio_b;
43+ struct gpio_descs *gpios;
4544
46− unsigned int irq_a;
47− unsigned int irq_b;
45+ unsigned int *irq;
4846
4947 bool armed;
50− unsigned char dir; /* 0 - clockwise, 1 - CCW */
48+ signed char dir; /* 1 - clockwise, -1 - CCW */
5149
52− char last_stable;
50+ unsigned last_stable;
5351 };
5452
55−static int rotary_encoder_get_state(struct rotary_encoder *encoder)
53+static unsigned rotary_encoder_get_state(struct rotary_encoder *encoder)
5654 {
57− int a = !!gpiod_get_value_cansleep(encoder->gpio_a);
58− int b = !!gpiod_get_value_cansleep(encoder->gpio_b);
55+ int i;
56+ unsigned ret = 0;
5957
60− return ((a << 1) | b);
58+ for (i = 0; i < encoder->gpios->ndescs; ++i) {
59+ int val = gpiod_get_value_cansleep(encoder->gpios->desc[i]);
60+ /* convert from gray encoding to normal */
61+ if (ret & 1)
62+ val = !val;
63+
64+ ret = ret << 1 | val;
65+ }
66+
67+ return ret & 3;
6168 }
6269
6370 static void rotary_encoder_report_event(struct rotary_encoder *encoder)
6471 {
6572 if (encoder->relative_axis) {
6673 input_report_rel(encoder->input,
67− encoder->axis, encoder->dir ? -1 : 1);
74+ encoder->axis, encoder->dir);
6875 } else {
6976 unsigned int pos = encoder->pos;
7077
71− if (encoder->dir) {
78+ if (encoder->dir < 0) {
7279 /* turning counter-clockwise */
7380 if (encoder->rollover)
7481 pos += encoder->steps;
@@ -93,7 +100,7 @@ static void rotary_encoder_report_event(struct rotary_encoder *encoder) · 18 unmodified lines
93100 static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
94101 {
95102 struct rotary_encoder *encoder = dev_id;
96− int state;
103+ unsigned state;
97104
98105 mutex_lock(&encoder->access_mutex);
99106
@@ -108,12 +115,12 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) · 8 unmodified lines
108115 break;
109116
110117 case 0x1:
111− case 0x2:
118+ case 0x3:
112119 if (encoder->armed)
113− encoder->dir = state - 1;
120+ encoder->dir = 2 - state;
114121 break;
115122
116− case 0x3:
123+ case 0x2:
117124 encoder->armed = true;
118125 break;
119126 }
@@ -126,25 +133,19 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) · 6 unmodified lines
126133 static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
127134 {
128135 struct rotary_encoder *encoder = dev_id;
129− int state;
136+ unsigned int state;
130137
131138 mutex_lock(&encoder->access_mutex);
132139
133140 state = rotary_encoder_get_state(encoder);
134141
135− switch (state) {
136− case 0x00:
137− case 0x03:
142+ if (state & 1) {
143+ encoder->dir = ((encoder->last_stable - state + 1) % 4) - 1;
144+ } else {
138145 if (state != encoder->last_stable) {
139146 rotary_encoder_report_event(encoder);
140147 encoder->last_stable = state;
141148 }
142− break;
143−
144− case 0x01:
145− case 0x02:
146− encoder->dir = (encoder->last_stable + state) & 0x01;
147− break;
148149 }
149150
150151 mutex_unlock(&encoder->access_mutex);
@@ -155,46 +156,18 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id) · 4 unmodified lines
155156 static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id)
156157 {
157158 struct rotary_encoder *encoder = dev_id;
158− unsigned char sum;
159− int state;
159+ unsigned int state;
160160
161161 mutex_lock(&encoder->access_mutex);
162162
163163 state = rotary_encoder_get_state(encoder);
164164
165− /*
166− * We encode the previous and the current state using a byte.
167− * The previous state in the MSB nibble, the current state in the LSB
168− * nibble. Then use a table to decide the direction of the turn.
169− */
170− sum = (encoder->last_stable << 4) + state;
171− switch (sum) {
172− case 0x31:
173− case 0x10:
174− case 0x02:
175− case 0x23:
176− encoder->dir = 0; /* clockwise */
177− break;
178−
179− case 0x13:
180− case 0x01:
181− case 0x20:
182− case 0x32:
183− encoder->dir = 1; /* counter-clockwise */
184− break;
185−
186− default:
187− /*
188− * Ignore all other values. This covers the case when the
189− * state didn't change (a spurious interrupt) and the
190− * cases where the state changed by two steps, making it
191− * impossible to tell the direction.
192− *
193− * In either case, don't report any event and save the
194− * state for later.
195− */
165+ if ((encoder->last_stable + 1) % 4 == state)
166+ encoder->dir = 1;
167+ else if (encoder->last_stable == (state + 1) % 4)
168+ encoder->dir = -1;
169+ else
196170 goto out;
197− }
198171
199172 rotary_encoder_report_event(encoder);
200173
@@ -212,6 +185,7 @@ static int rotary_encoder_probe(struct platform_device *pdev) · 11 unmodified lines
212185 struct input_dev *input;
213186 irq_handler_t handler;
214187 u32 steps_per_period;
188+ unsigned int i;
215189 int err;
216190
217191 encoder = devm_kzalloc(dev, sizeof(struct rotary_encoder), GFP_KERNEL);
@@ -243,24 +217,16 @@ static int rotary_encoder_probe(struct platform_device *pdev) · 25 unmodified lines
243217 encoder->relative_axis =
244218 device_property_read_bool(dev, "rotary-encoder,relative-axis");
245219
246− encoder->gpio_a = devm_gpiod_get_index(dev, NULL, 0, GPIOD_IN);
247− if (IS_ERR(encoder->gpio_a)) {
248− err = PTR_ERR(encoder->gpio_a);
249− dev_err(dev, "unable to get GPIO at index 0: %d\n", err);
250− return err;
220+ encoder->gpios = devm_gpiod_get_array(dev, NULL, GPIOD_IN);
221+ if (IS_ERR(encoder->gpios)) {
222+ dev_err(dev, "unable to get gpios\n");
223+ return PTR_ERR(encoder->gpios);
251224 }
252−
253− encoder->irq_a = gpiod_to_irq(encoder->gpio_a);
254−
255− encoder->gpio_b = devm_gpiod_get_index(dev, NULL, 1, GPIOD_IN);
256− if (IS_ERR(encoder->gpio_b)) {
257− err = PTR_ERR(encoder->gpio_b);
258− dev_err(dev, "unable to get GPIO at index 1: %d\n", err);
259− return err;
225+ if (encoder->gpios->ndescs < 2) {
226+ dev_err(dev, "not enough gpios found\n");
227+ return -EINVAL;
260228 }
261229
262− encoder->irq_b = gpiod_to_irq(encoder->gpio_b);
263−
264230 input = devm_input_allocate_device(dev);
265231 if (!input)
266232 return -ENOMEM;
@@ -277,7 +243,7 @@ static int rotary_encoder_probe(struct platform_device *pdev) · 10 unmodified lines
277243 input_set_abs_params(input,
278244 encoder->axis, 0, encoder->steps, 0, 1);
279245
280− switch (steps_per_period) {
246+ switch (steps_per_period >> (encoder->gpios->ndescs - 2)) {
281247 case 4:
282248 handler = &rotary_encoder_quarter_period_irq;
283249 encoder->last_stable = rotary_encoder_get_state(encoder);
@@ -295,22 +261,26 @@ static int rotary_encoder_probe(struct platform_device *pdev) · 11 unmodified lines
295261 return -EINVAL;
296262 }
297263
298− err = devm_request_threaded_irq(dev, encoder->irq_a, NULL, handler,
299− IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
300− IRQF_ONESHOT,
301− DRV_NAME, encoder);
302− if (err) {
303− dev_err(dev, "unable to request IRQ %d\n", encoder->irq_a);
304− return err;
305− }
264+ encoder->irq =
265+ devm_kzalloc(dev,
266+ sizeof(*encoder->irq) * encoder->gpios->ndescs,
267+ GFP_KERNEL);
268+ if (!encoder->irq)
269+ return -ENOMEM;
306270
307− err = devm_request_threaded_irq(dev, encoder->irq_b, NULL, handler,
271+ for (i = 0; i < encoder->gpios->ndescs; ++i) {
272+ encoder->irq[i] = gpiod_to_irq(encoder->gpios->desc[i]);
273+
274+ err = devm_request_threaded_irq(dev, encoder->irq[i],
275+ NULL, handler,
308276 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
309277 IRQF_ONESHOT,
310278 DRV_NAME, encoder);
311− if (err) {
312− dev_err(dev, "unable to request IRQ %d\n", encoder->irq_b);
313− return err;
279+ if (err) {
280+ dev_err(dev, "unable to request IRQ %d (gpio#%d)\n",
281+ encoder->irq[i], i);
282+ return err;
283+ }
314284 }
315285
316286 err = input_register_device(input);
@@ -330,10 +300,11 @@ static int rotary_encoder_probe(struct platform_device *pdev) · 13 unmodified lines
330300 static int __maybe_unused rotary_encoder_suspend(struct device *dev)
331301 {
332302 struct rotary_encoder *encoder = dev_get_drvdata(dev);
303+ unsigned int i;
333304
334305 if (device_may_wakeup(dev)) {
335− enable_irq_wake(encoder->irq_a);
336− enable_irq_wake(encoder->irq_b);
306+ for (i = 0; i < encoder->gpios->ndescs; ++i)
307+ enable_irq_wake(encoder->irq[i]);
337308 }
338309
339310 return 0;
@@ -342,10 +313,11 @@ static int __maybe_unused rotary_encoder_suspend(struct device *dev) · 2 unmodified lines
342313 static int __maybe_unused rotary_encoder_resume(struct device *dev)
343314 {
344315 struct rotary_encoder *encoder = dev_get_drvdata(dev);
316+ unsigned int i;
345317
346318 if (device_may_wakeup(dev)) {
347− disable_irq_wake(encoder->irq_a);
348− disable_irq_wake(encoder->irq_b);
319+ for (i = 0; i < encoder->gpios->ndescs; ++i)
320+ disable_irq_wake(encoder->irq[i]);
349321 }
350322
351323 return 0;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t