summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/button.c61
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
195wheel_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);