diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/button.c | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c index 0502f73c92..d86b8d8d2d 100644 --- a/firmware/drivers/button.c +++ b/firmware/drivers/button.c | |||
@@ -138,9 +138,7 @@ static inline int ipod_4g_button_read(void) | |||
138 | 138 | ||
139 | if ((status & 0x800000ff) == 0x8000001a) { | 139 | if ((status & 0x800000ff) == 0x8000001a) { |
140 | static int old_wheel_value IDATA_ATTR = -1; | 140 | static int old_wheel_value IDATA_ATTR = -1; |
141 | /* NB: highest wheel = 0x5F, clockwise increases */ | 141 | static int wheel_repeat = 0; |
142 | int new_wheel_value = (status << 9) >> 25; | ||
143 | int wheel_delta = new_wheel_value - old_wheel_value; | ||
144 | 142 | ||
145 | if (status & 0x100) | 143 | if (status & 0x100) |
146 | btn |= BUTTON_SELECT; | 144 | btn |= BUTTON_SELECT; |
@@ -153,37 +151,40 @@ static inline int ipod_4g_button_read(void) | |||
153 | if (status & 0x1000) | 151 | if (status & 0x1000) |
154 | btn |= BUTTON_MENU; | 152 | btn |= BUTTON_MENU; |
155 | if (status & 0x40000000) { | 153 | if (status & 0x40000000) { |
154 | /* NB: highest wheel = 0x5F, clockwise increases */ | ||
155 | int new_wheel_value = (status << 9) >> 25; | ||
156 | backlight_on(); | 156 | backlight_on(); |
157 | /* The queue should have no other events when scrolling */ | 157 | /* The queue should have no other events when scrolling */ |
158 | if (queue_empty(&button_queue)) { | 158 | if (queue_empty(&button_queue) && old_wheel_value >= 0) { |
159 | 159 | ||
160 | if (old_wheel_value >= 0) { | 160 | /* This is for later = BUTTON_SCROLL_TOUCH;*/ |
161 | /* This is for later = BUTTON_SCROLL_TOUCH;*/ | 161 | int wheel_delta = new_wheel_value - old_wheel_value; |
162 | unsigned long data; | 162 | unsigned long data; |
163 | 163 | int wheel_keycode; | |
164 | if (wheel_delta < -48) | 164 | |
165 | wheel_delta += 96; /* Forward wrapping case */ | 165 | if (wheel_delta < -48) |
166 | else if (wheel_delta > 48) | 166 | wheel_delta += 96; /* Forward wrapping case */ |
167 | wheel_delta -= 96; /* Backward wrapping case */ | 167 | else if (wheel_delta > 48) |
168 | 168 | wheel_delta -= 96; /* Backward wrapping case */ | |
169 | if (wheel_delta > 4) { | 169 | |
170 | old_wheel_value = new_wheel_value; | 170 | if (wheel_delta > 4) { |
171 | data = (wheel_delta << 16) | new_wheel_value; | 171 | wheel_keycode = BUTTON_SCROLL_FWD; |
172 | queue_post(&button_queue, BUTTON_SCROLL_FWD, | 172 | } else if (wheel_delta < -4) { |
173 | (void *)data); | 173 | wheel_keycode = BUTTON_SCROLL_BACK; |
174 | } else if (wheel_delta < -4) { | 174 | } else goto wheel_end; |
175 | old_wheel_value = new_wheel_value; | 175 | |
176 | data = (wheel_delta << 16) | new_wheel_value; | 176 | data = (wheel_delta << 16) | new_wheel_value; |
177 | queue_post(&button_queue, BUTTON_SCROLL_BACK, | 177 | queue_post(&button_queue, wheel_keycode | wheel_repeat, |
178 | (void *)data); | 178 | (void *)data); |
179 | } | 179 | |
180 | 180 | if (!wheel_repeat) wheel_repeat = BUTTON_REPEAT; | |
181 | } else | ||
182 | old_wheel_value = new_wheel_value; | ||
183 | } | 181 | } |
184 | } else if (wheel_delta == 0) { | 182 | |
183 | old_wheel_value = new_wheel_value; | ||
184 | } else if (old_wheel_value >= 0) { | ||
185 | /* scroll wheel up */ | 185 | /* scroll wheel up */ |
186 | old_wheel_value = -1; | 186 | old_wheel_value = -1; |
187 | wheel_repeat = 0; | ||
187 | } | 188 | } |
188 | 189 | ||
189 | } else if (status == 0xffffffff) { | 190 | } else if (status == 0xffffffff) { |
@@ -191,6 +192,8 @@ static inline int ipod_4g_button_read(void) | |||
191 | } | 192 | } |
192 | } | 193 | } |
193 | 194 | ||
195 | wheel_end: | ||
196 | |||
194 | if ((inl(reg) & 0x8000000) != 0) { | 197 | if ((inl(reg) & 0x8000000) != 0) { |
195 | outl(0xffffffff, 0x7000c120); | 198 | outl(0xffffffff, 0x7000c120); |
196 | outl(0xffffffff, 0x7000c124); | 199 | outl(0xffffffff, 0x7000c124); |