summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2012-01-25 09:07:52 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2012-01-25 09:07:52 +0100
commit36281c4cc9d83203753bb55963fafb2487c2d2de (patch)
treeb77c1d421cb32ac7eee424339005e8d983427754
parent76440aa214765037139aa9d74c4450f4045f38e1 (diff)
downloadrockbox-36281c4cc9d83203753bb55963fafb2487c2d2de.tar.gz
rockbox-36281c4cc9d83203753bb55963fafb2487c2d2de.zip
MPIO HD300: Fix scrollstip issue at driver level.
Scrollstrip (as well as scrollwheel on ipods/sansas) works like quadrature encoder. The states of input lines are tracked by the gpio ISR and when the sequence is correct, appropriate button event is pushed to the button queue directly. The downside of this implementation is that scrollstrip doesn't emit _REL events which has some weird consequences. For the scrollwheels some hack have been crafted in action system to accomodate for this. I don't like this approach. IMO the correct fix is to properly emit _REL event when the user stops interacting with the device or reverses the direction of the move. This patch implements timeout which forces to emit _REL when expired. Change-Id: I588ac5810dd2ab00c68935d23a62979cb1c2a912
-rw-r--r--firmware/target/coldfire/mpio/hd300/button-hd300.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/firmware/target/coldfire/mpio/hd300/button-hd300.c b/firmware/target/coldfire/mpio/hd300/button-hd300.c
index 8239b54e28..95de05cbcf 100644
--- a/firmware/target/coldfire/mpio/hd300/button-hd300.c
+++ b/firmware/target/coldfire/mpio/hd300/button-hd300.c
@@ -29,10 +29,17 @@
29#include "powermgmt.h" 29#include "powermgmt.h"
30 30
31#define SLIDER_BASE_SENSITIVITY 8 31#define SLIDER_BASE_SENSITIVITY 8
32#define SLIDER_REL_TIMEOUT HZ/2
32 33
33/* GPI7 H-L, GPI6 H-L, GPI7 L-H, GPI6 L-H */ 34/* GPI7 H-L, GPI6 H-L, GPI7 L-H, GPI6 L-H */
34#define SLIDER_GPIO_MASK ((1<<15)|(1<<14)|(1<<7)|(1<<6)) 35#define SLIDER_GPIO_MASK ((1<<15)|(1<<14)|(1<<7)|(1<<6))
35 36
37static volatile struct scroll_state_t {
38 signed char dir;
39 long timeout;
40 bool rel;
41} scroll;
42
36static inline void disable_scrollstrip_interrupts(void) 43static inline void disable_scrollstrip_interrupts(void)
37{ 44{
38 and_l(~SLIDER_GPIO_MASK,&GPIO_INT_EN); 45 and_l(~SLIDER_GPIO_MASK,&GPIO_INT_EN);
@@ -89,10 +96,20 @@ void scrollstrip_isr(void)
89 96
90 scroll_dir = scroll_state[prev_scroll_lines][new_scroll_lines]; 97 scroll_dir = scroll_state[prev_scroll_lines][new_scroll_lines];
91 prev_scroll_lines = new_scroll_lines; 98 prev_scroll_lines = new_scroll_lines;
92 99
100 /* catch sequence error */
101 if (scroll_dir == BUTTON_NONE)
102 return;
103
104 /* direction reversal */
93 if (direction != scroll_dir) 105 if (direction != scroll_dir)
94 { 106 {
95 /* direction reversal */ 107 /* post release event to the button queue */
108 if (queue_empty(&button_queue))
109 queue_post(&button_queue, direction|BUTTON_REL, 0);
110
111 scroll.rel = true;
112
96 direction = scroll_dir; 113 direction = scroll_dir;
97 count = 0; 114 count = 0;
98 ack_scrollstrip_interrupt(); 115 ack_scrollstrip_interrupt();
@@ -121,6 +138,10 @@ void scrollstrip_isr(void)
121 if (queue_empty(&button_queue)) 138 if (queue_empty(&button_queue))
122 queue_post(&button_queue, scroll_dir, 0); 139 queue_post(&button_queue, scroll_dir, 0);
123 140
141 scroll.dir = scroll_dir;
142 scroll.timeout = current_tick + SLIDER_REL_TIMEOUT;
143 scroll.rel = false;
144
124 ack_scrollstrip_interrupt(); 145 ack_scrollstrip_interrupt();
125 enable_scrollstrip_interrupts(); 146 enable_scrollstrip_interrupts();
126} 147}
@@ -235,5 +256,15 @@ int button_read_device(void)
235 256
236 } /* !button_hold() */ 257 } /* !button_hold() */
237 258
259 if (!scroll.rel)
260 if (TIME_AFTER(current_tick, scroll.timeout))
261 {
262 if (queue_empty(&button_queue))
263 {
264 queue_post(&button_queue, scroll.dir|BUTTON_REL, 0);
265 scroll.rel = true;
266 }
267 }
268
238 return btn; 269 return btn;
239} 270}