summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/ipod/button-1g-3g.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/firmware/target/arm/ipod/button-1g-3g.c b/firmware/target/arm/ipod/button-1g-3g.c
index 9eec8fd823..071df3294c 100644
--- a/firmware/target/arm/ipod/button-1g-3g.c
+++ b/firmware/target/arm/ipod/button-1g-3g.c
@@ -55,7 +55,7 @@ static int int_btn = BUTTON_NONE;
55#define WHEEL_REPEAT_VELOCITY 45 /* deg/s */ 55#define WHEEL_REPEAT_VELOCITY 45 /* deg/s */
56#define WHEEL_SMOOTHING_VELOCITY 100 /* deg/s */ 56#define WHEEL_SMOOTHING_VELOCITY 100 /* deg/s */
57 57
58static void handle_scroll_wheel(int new_scroll, int was_hold) 58static void handle_scroll_wheel(int new_scroll)
59{ 59{
60 static const signed char scroll_state[4][4] = { 60 static const signed char scroll_state[4][4] = {
61 {0, 1, -1, 0}, 61 {0, 1, -1, 0},
@@ -64,7 +64,7 @@ static void handle_scroll_wheel(int new_scroll, int was_hold)
64 {0, -1, 1, 0} 64 {0, -1, 1, 0}
65 }; 65 };
66 66
67 static int prev_scroll = 0; 67 static int prev_scroll = -1;
68 static int direction = 0; 68 static int direction = 0;
69 static int count = 0; 69 static int count = 0;
70 static long next_backlight_on = 0; 70 static long next_backlight_on = 0;
@@ -72,30 +72,30 @@ static void handle_scroll_wheel(int new_scroll, int was_hold)
72 static unsigned long last_wheel_usec = 0; 72 static unsigned long last_wheel_usec = 0;
73 static unsigned long wheel_delta = 1ul << 24; 73 static unsigned long wheel_delta = 1ul << 24;
74 static unsigned long wheel_velocity = 0; 74 static unsigned long wheel_velocity = 0;
75 static int prev_keypost = BUTTON_NONE;
75 76
76 int wheel_keycode = BUTTON_NONE; 77 int wheel_keycode = BUTTON_NONE;
77 int scroll = scroll_state[prev_scroll][new_scroll]; 78 int scroll;
78 unsigned long usec; 79 unsigned long usec;
79 unsigned long v; 80 unsigned long v;
80 81
82 if (prev_scroll == -1) {
83 prev_scroll = new_scroll;
84 return;
85 }
86
87 scroll = scroll_state[prev_scroll][new_scroll];
81 prev_scroll = new_scroll; 88 prev_scroll = new_scroll;
82 89
83 if (direction != scroll) { 90 if (direction != scroll) {
84 /* direction reversal - reset all */ 91 /* direction reversal or was hold - reset all */
85 direction = scroll; 92 direction = scroll;
93 prev_keypost = BUTTON_NONE;
86 wheel_velocity = 0; 94 wheel_velocity = 0;
87 wheel_delta = 1ul << 24; 95 wheel_delta = 1ul << 24;
88 count = 0; 96 count = 0;
89 } 97 }
90 98
91 if (was_hold) {
92 /* hold - reset all */
93 wheel_velocity = 0;
94 wheel_delta = 1ul << 24;
95 count = 0;
96 return;
97 }
98
99 /* poke backlight every 1/4s of activity */ 99 /* poke backlight every 1/4s of activity */
100 if (TIME_AFTER(current_tick, next_backlight_on)) { 100 if (TIME_AFTER(current_tick, next_backlight_on)) {
101 backlight_on(); 101 backlight_on();
@@ -160,14 +160,19 @@ static void handle_scroll_wheel(int new_scroll, int was_hold)
160 wheel_velocity = (7*wheel_velocity + v) / 8; 160 wheel_velocity = (7*wheel_velocity + v) / 8;
161 } 161 }
162 162
163 if (v >= WHEEL_REPEAT_VELOCITY) {
164 /* quick enough - generate repeats - use unsmoothed v to guage */
165 wheel_keycode |= BUTTON_REPEAT;
166 }
167
168 if (queue_empty(&button_queue)) { 163 if (queue_empty(&button_queue)) {
164 int key = wheel_keycode;
165
166 if (v >= WHEEL_REPEAT_VELOCITY && prev_keypost == key) {
167 /* quick enough and same key is being posted more than once in a
168 * row - generate repeats - use unsmoothed v to guage */
169 key |= BUTTON_REPEAT;
170 }
171
172 prev_keypost = wheel_keycode;
173
169 /* post wheel keycode with wheel data */ 174 /* post wheel keycode with wheel data */
170 queue_post(&button_queue, wheel_keycode, 175 queue_post(&button_queue, key,
171 (wheel_velocity >= WHEEL_ACCEL_START ? (1ul << 31) : 0) 176 (wheel_velocity >= WHEEL_ACCEL_START ? (1ul << 31) : 0)
172 | wheel_delta | wheel_velocity); 177 | wheel_delta | wheel_velocity);
173 /* message posted - reset delta */ 178 /* message posted - reset delta */
@@ -184,7 +189,7 @@ static void handle_scroll_wheel(int new_scroll, int was_hold)
184 last_wheel_usec = usec; 189 last_wheel_usec = usec;
185} 190}
186#else 191#else
187static void handle_scroll_wheel(int new_scroll, int was_hold) 192static void handle_scroll_wheel(int new_scroll)
188{ 193{
189 int wheel_keycode = BUTTON_NONE; 194 int wheel_keycode = BUTTON_NONE;
190 static int prev_scroll = -1; 195 static int prev_scroll = -1;
@@ -204,7 +209,7 @@ static void handle_scroll_wheel(int new_scroll, int was_hold)
204 direction = scroll_state[prev_scroll][new_scroll]; 209 direction = scroll_state[prev_scroll][new_scroll];
205 count = 0; 210 count = 0;
206 } 211 }
207 else if (!was_hold) { 212 else {
208 backlight_on(); 213 backlight_on();
209 reset_poweroff_timer(); 214 reset_poweroff_timer();
210 if (++count == 6) { /* reduce sensitivity */ 215 if (++count == 6) { /* reduce sensitivity */
@@ -233,22 +238,24 @@ static void handle_scroll_wheel(int new_scroll, int was_hold)
233static int ipod_3g_button_read(void) 238static int ipod_3g_button_read(void)
234{ 239{
235 unsigned char source, state; 240 unsigned char source, state;
236 static bool was_hold = false;
237 int btn = BUTTON_NONE; 241 int btn = BUTTON_NONE;
238 242
239 /* get source of interupts */ 243 /* get source of interupts */
240 source = GPIOA_INT_STAT; 244 source = GPIOA_INT_STAT;
241 245
242 /* get current keypad status */ 246 /* get current keypad status */
243 state = GPIOA_INPUT_VAL; 247 state = GPIOA_INPUT_VAL;
244 248
245 /* toggle interrupt level */ 249 /* toggle interrupt level */
246 GPIOA_INT_LEV = ~state; 250 GPIOA_INT_LEV = ~state;
247 251
252 /* ack any active interrupts */
253 GPIOA_INT_CLR = source;
254
248#ifdef IPOD_3G 255#ifdef IPOD_3G
256 static bool was_hold = false;
257
249 if (was_hold && source == 0x40 && state == 0xbf) { 258 if (was_hold && source == 0x40 && state == 0xbf) {
250 /* ack any active interrupts */
251 GPIOA_INT_CLR = source;
252 return BUTTON_NONE; 259 return BUTTON_NONE;
253 } 260 }
254 was_hold = false; 261 was_hold = false;
@@ -258,13 +265,11 @@ static int ipod_3g_button_read(void)
258 was_hold = true; 265 was_hold = true;
259 /* hold switch on 3g causes all outputs to go low */ 266 /* hold switch on 3g causes all outputs to go low */
260 /* we shouldn't interpret these as key presses */ 267 /* we shouldn't interpret these as key presses */
261 GPIOA_INT_CLR = source;
262 return BUTTON_NONE; 268 return BUTTON_NONE;
263 } 269 }
264#elif defined IPOD_1G2G 270#elif defined IPOD_1G2G
265 if (state & 0x20) { 271 if (state & 0x20) {
266 /* 1g/2g hold switch is active high */ 272 /* 1g/2g hold switch is active high */
267 GPIOA_INT_CLR = source;
268 return BUTTON_NONE; 273 return BUTTON_NONE;
269 } 274 }
270#endif 275#endif
@@ -285,12 +290,9 @@ static int ipod_3g_button_read(void)
285 } 290 }
286 291
287 if (source & 0xc0) { 292 if (source & 0xc0) {
288 handle_scroll_wheel((state & 0xc0) >> 6, was_hold); 293 handle_scroll_wheel((state & 0xc0) >> 6);
289 } 294 }
290 295
291 /* ack any active interrupts */
292 GPIOA_INT_CLR = source;
293
294 return btn; 296 return btn;
295} 297}
296 298