diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/button.c | 86 | ||||
-rw-r--r-- | firmware/export/button.h | 2 |
2 files changed, 33 insertions, 55 deletions
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c index 49ada65697..0502f73c92 100644 --- a/firmware/drivers/button.c +++ b/firmware/drivers/button.c | |||
@@ -122,7 +122,7 @@ static void opto_i2c_init(void) | |||
122 | outl(0x1000000, 0x7000c104); | 122 | outl(0x1000000, 0x7000c104); |
123 | } | 123 | } |
124 | 124 | ||
125 | static int ipod_4g_button_read(void) | 125 | static inline int ipod_4g_button_read(void) |
126 | { | 126 | { |
127 | /* The ipodlinux source had a udelay(250) here, but testing has shown that | 127 | /* The ipodlinux source had a udelay(250) here, but testing has shown that |
128 | it is not needed - tested on Nano, Color/Photo and Video. */ | 128 | it is not needed - tested on Nano, Color/Photo and Video. */ |
@@ -137,9 +137,11 @@ static int ipod_4g_button_read(void) | |||
137 | outl(0x0, 0x7000c140); /* clear interrupt status? */ | 137 | outl(0x0, 0x7000c140); /* clear interrupt status? */ |
138 | 138 | ||
139 | if ((status & 0x800000ff) == 0x8000001a) { | 139 | if ((status & 0x800000ff) == 0x8000001a) { |
140 | static int clickwheel_down IDATA_ATTR = 0; | ||
141 | static int old_wheel_value IDATA_ATTR = -1; | 140 | static int old_wheel_value IDATA_ATTR = -1; |
142 | 141 | /* NB: highest wheel = 0x5F, clockwise increases */ | |
142 | int new_wheel_value = (status << 9) >> 25; | ||
143 | int wheel_delta = new_wheel_value - old_wheel_value; | ||
144 | |||
143 | if (status & 0x100) | 145 | if (status & 0x100) |
144 | btn |= BUTTON_SELECT; | 146 | btn |= BUTTON_SELECT; |
145 | if (status & 0x200) | 147 | if (status & 0x200) |
@@ -151,66 +153,40 @@ static int ipod_4g_button_read(void) | |||
151 | if (status & 0x1000) | 153 | if (status & 0x1000) |
152 | btn |= BUTTON_MENU; | 154 | btn |= BUTTON_MENU; |
153 | if (status & 0x40000000) { | 155 | if (status & 0x40000000) { |
154 | /* NB: highest wheel = 0x5F, clockwise increases */ | ||
155 | int new_wheel_value = ((status << 9) >> 25) & 0xff; | ||
156 | |||
157 | /* scroll wheel down */ | ||
158 | clickwheel_down = 1; | ||
159 | backlight_on(); | 156 | backlight_on(); |
160 | if (old_wheel_value >= 0) { | 157 | /* The queue should have no other events when scrolling */ |
161 | int wheel_keycode = BUTTON_NONE; | 158 | if (queue_empty(&button_queue)) { |
162 | int wheel_delta; | 159 | |
163 | if (old_wheel_value > new_wheel_value + 48) { | 160 | if (old_wheel_value >= 0) { |
164 | /* Forward wrapping case */ | 161 | /* This is for later = BUTTON_SCROLL_TOUCH;*/ |
165 | wheel_delta = new_wheel_value + 96 - old_wheel_value; | 162 | unsigned long data; |
166 | } else { | 163 | |
167 | wheel_delta = new_wheel_value - old_wheel_value; | 164 | if (wheel_delta < -48) |
168 | if (wheel_delta > 48) | 165 | wheel_delta += 96; /* Forward wrapping case */ |
166 | else if (wheel_delta > 48) | ||
169 | wheel_delta -= 96; /* Backward wrapping case */ | 167 | wheel_delta -= 96; /* Backward wrapping case */ |
170 | } | ||
171 | 168 | ||
172 | /* TODO: these thresholds should most definitely be | 169 | if (wheel_delta > 4) { |
173 | settings, and we're probably going to want a more | 170 | old_wheel_value = new_wheel_value; |
174 | advanced scheme than this anyway. */ | 171 | data = (wheel_delta << 16) | new_wheel_value; |
175 | if (wheel_delta > 4) { | 172 | queue_post(&button_queue, BUTTON_SCROLL_FWD, |
176 | wheel_keycode = BUTTON_SCROLL_FWD; | 173 | (void *)data); |
177 | old_wheel_value = new_wheel_value; | 174 | } else if (wheel_delta < -4) { |
178 | } else if (wheel_delta < -4) { | 175 | old_wheel_value = new_wheel_value; |
179 | wheel_keycode = BUTTON_SCROLL_BACK; | 176 | data = (wheel_delta << 16) | new_wheel_value; |
177 | queue_post(&button_queue, BUTTON_SCROLL_BACK, | ||
178 | (void *)data); | ||
179 | } | ||
180 | |||
181 | } else | ||
180 | old_wheel_value = new_wheel_value; | 182 | old_wheel_value = new_wheel_value; |
181 | } | ||
182 | |||
183 | if (wheel_keycode != BUTTON_NONE) { | ||
184 | /* When you use the clickwheel, the queue should | ||
185 | usually have no other events in it, so we check if | ||
186 | it's empty to see whether pending clickwheel events | ||
187 | have been handled. This way, Rockbox will stop | ||
188 | responding to the clickwheel if it doesn't have time | ||
189 | to handle the events immediately. | ||
190 | Can also implement queue_peek() to do this in a | ||
191 | cleaner way. | ||
192 | */ | ||
193 | if (queue_empty(&button_queue)) | ||
194 | queue_post(&button_queue, wheel_keycode, NULL); | ||
195 | } | ||
196 | } | ||
197 | else { | ||
198 | old_wheel_value = new_wheel_value; | ||
199 | } | 183 | } |
200 | } | 184 | } else if (wheel_delta == 0) { |
201 | else if (clickwheel_down) { | ||
202 | /* scroll wheel up */ | 185 | /* scroll wheel up */ |
203 | old_wheel_value = -1; | 186 | old_wheel_value = -1; |
204 | clickwheel_down = 0; | ||
205 | } | 187 | } |
206 | } | 188 | |
207 | /* | 189 | } else if (status == 0xffffffff) { |
208 | Don't know why this should be needed, let me know if you do. | ||
209 | else if ((status & 0x800000FF) == 0x8000003A) { | ||
210 | wheel_value = status & 0x800000FF; | ||
211 | } | ||
212 | */ | ||
213 | else if (status == 0xffffffff) { | ||
214 | opto_i2c_init(); | 190 | opto_i2c_init(); |
215 | } | 191 | } |
216 | } | 192 | } |
diff --git a/firmware/export/button.h b/firmware/export/button.h index a1590ec353..be1efa7001 100644 --- a/firmware/export/button.h +++ b/firmware/export/button.h | |||
@@ -164,6 +164,8 @@ bool button_hold(void); | |||
164 | #define BUTTON_SELECT 0x0008 | 164 | #define BUTTON_SELECT 0x0008 |
165 | #define BUTTON_SCROLL_FWD 0x0010 | 165 | #define BUTTON_SCROLL_FWD 0x0010 |
166 | #define BUTTON_SCROLL_BACK 0x0020 | 166 | #define BUTTON_SCROLL_BACK 0x0020 |
167 | /* This is for later | ||
168 | #define BUTTON_SCROLL_TOUCH 0x0100*/ | ||
167 | 169 | ||
168 | #elif CONFIG_KEYPAD == IPOD_3G_PAD | 170 | #elif CONFIG_KEYPAD == IPOD_3G_PAD |
169 | 171 | ||