summaryrefslogtreecommitdiff
path: root/firmware/drivers/button.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/button.c')
-rw-r--r--firmware/drivers/button.c102
1 files changed, 58 insertions, 44 deletions
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index 0c2e1e51f5..caf08e131d 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -225,6 +225,8 @@ void handle_scroll_wheel(int new_scroll, int was_hold, int reverse)
{
int wheel_keycode = BUTTON_NONE;
static int prev_scroll = -1;
+ static int direction = 0;
+ static int count = 0;
static int scroll_state[4][4] = {
{0, 1, -1, 0},
{-1, 0, 0, 1},
@@ -235,32 +237,39 @@ void handle_scroll_wheel(int new_scroll, int was_hold, int reverse)
if ( prev_scroll == -1 ) {
prev_scroll = new_scroll;
}
+ else if (direction != scroll_state[prev_scroll][new_scroll]) {
+ direction = scroll_state[prev_scroll][new_scroll];
+ count = 0;
+ }
else if (!was_hold) {
- switch (scroll_state[prev_scroll][new_scroll]) {
- case 1:
- if (reverse) {
- /* 'r' keypress */
- wheel_keycode = BUTTON_SCROLL_FWD;
- }
- else {
- /* 'l' keypress */
- wheel_keycode = BUTTON_SCROLL_BACK;
- }
- break;
- case -1:
- if (reverse) {
- /* 'l' keypress */
- wheel_keycode = BUTTON_SCROLL_BACK;
- }
- else {
- /* 'r' keypress */
- wheel_keycode = BUTTON_SCROLL_FWD;
- }
- break;
- default:
- /* only happens if we get out of sync */
- break;
-
+ backlight_on();
+ if (++count == 6) { /* reduce sensitivity */
+ count = 0;
+ switch (direction) {
+ case 1:
+ if (reverse) {
+ /* 'r' keypress */
+ wheel_keycode = BUTTON_SCROLL_FWD;
+ }
+ else {
+ /* 'l' keypress */
+ wheel_keycode = BUTTON_SCROLL_BACK;
+ }
+ break;
+ case -1:
+ if (reverse) {
+ /* 'l' keypress */
+ wheel_keycode = BUTTON_SCROLL_BACK;
+ }
+ else {
+ /* 'r' keypress */
+ wheel_keycode = BUTTON_SCROLL_FWD;
+ }
+ break;
+ default:
+ /* only happens if we get out of sync */
+ break;
+ }
}
}
if (wheel_keycode != BUTTON_NONE)
@@ -273,13 +282,12 @@ void handle_scroll_wheel(int new_scroll, int was_hold, int reverse)
static int ipod_mini_button_read(void)
{
unsigned char source, wheel_source, state, wheel_state;
+ static bool was_hold = false;
int btn = BUTTON_NONE;
- /*
- * we need some delay for mini, cause hold generates several interrupts,
- * some of them delayed
- */
- udelay(250);
+ /* The ipodlinux source had a udelay(250) here, but testing has shown that
+ it is not needed - tested on mini 1g. */
+ /* udelay(250);*/
/* get source(s) of interupt */
source = GPIOA_INT_STAT & 0x3f;
@@ -297,21 +305,27 @@ static int ipod_mini_button_read(void)
GPIOA_INT_LEV = ~state;
GPIOB_INT_LEV = ~wheel_state;
- if (source & 0x1)
- btn |= BUTTON_SELECT;
- if (source & 0x2)
- btn |= BUTTON_MENU;
- if (source & 0x4)
- btn |= BUTTON_PLAY;
- if (source & 0x8)
- btn |= BUTTON_RIGHT;
- if (source & 0x10)
- btn |= BUTTON_LEFT;
+ /* hold switch causes all outputs to go low */
+ /* we shouldn't interpret these as key presses */
+ if ((state & 0x20)) {
+ if (!(state & 0x1))
+ btn |= BUTTON_SELECT;
+ if (!(state & 0x2))
+ btn |= BUTTON_MENU;
+ if (!(state & 0x4))
+ btn |= BUTTON_PLAY;
+ if (!(state & 0x8))
+ btn |= BUTTON_RIGHT;
+ if (!(state & 0x10))
+ btn |= BUTTON_LEFT;
- if (wheel_source & 0x30) {
- handle_scroll_wheel((wheel_state & 0x30) >> 4, 0, 1);
+ if (wheel_source & 0x30) {
+ handle_scroll_wheel((wheel_state & 0x30) >> 4, was_hold, 1);
+ }
}
+ was_hold = button_hold();
+
/* ack any active interrupts */
if (source)
GPIOA_INT_CLR = source;
@@ -645,8 +659,8 @@ void button_init(void)
GPIOA_INT_LEV = ~(GPIOA_INPUT_VAL & 0x3f);
GPIOA_INT_CLR = GPIOA_INT_STAT & 0x3f;
/* scroll wheel - set interrupt levels */
- GPIOB_INT_LEV = ~(GPIOB_INPUT_VAL & 0x3f);
- GPIOB_INT_CLR = GPIOB_INT_STAT & 0x3f;
+ GPIOB_INT_LEV = ~(GPIOB_INPUT_VAL & 0x30);
+ GPIOB_INT_CLR = GPIOB_INT_STAT & 0x30;
/* enable interrupts */
GPIOA_INT_EN = 0x3f;
GPIOB_INT_EN = 0x30;