summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/button.c86
-rw-r--r--firmware/export/button.h2
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
125static int ipod_4g_button_read(void) 125static 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