1
0
Fork 0
forked from len0rd/rockbox

Fix button driver for ipod mini 1G.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9732 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Frank Dischner 2006-04-19 18:06:56 +00:00
parent 1903fab9c5
commit 5d9eccd85b
2 changed files with 64 additions and 46 deletions

View file

@ -103,7 +103,7 @@ static void memmove16(void *dest, const void *src, unsigned count)
} }
} }
#if CONFIG_KEYPAD == IPOD_4G_PAD #if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
/* check if number of seconds has past */ /* check if number of seconds has past */
int timer_check(int clock_start, unsigned int usecs) int timer_check(int clock_start, unsigned int usecs)
{ {
@ -195,13 +195,17 @@ static int key_pressed(void)
#if CONFIG_KEYPAD == IPOD_4G_PAD #if CONFIG_KEYPAD == IPOD_4G_PAD
#ifdef IPOD_MINI /* mini 1G only */ #ifdef IPOD_MINI /* mini 1G only */
state = GPIOA_INPUT_VAL & 0x3f; state = GPIOA_INPUT_VAL & 0x3f;
if ((state & 0x10) == 0) return BUTTON_LEFT;
if ((state & 0x2) == 0) return BUTTON_MENU;
if ((state & 0x4) == 0) return BUTTON_PLAY;
if ((state & 0x8) == 0) return BUTTON_RIGHT;
#else #else
state = opto_keypad_read(); state = opto_keypad_read();
#endif
if ((state & 0x4) == 0) return BUTTON_LEFT; if ((state & 0x4) == 0) return BUTTON_LEFT;
if ((state & 0x10) == 0) return BUTTON_MENU; if ((state & 0x10) == 0) return BUTTON_MENU;
if ((state & 0x8) == 0) return BUTTON_PLAY; if ((state & 0x8) == 0) return BUTTON_PLAY;
if ((state & 0x2) == 0) return BUTTON_RIGHT; if ((state & 0x2) == 0) return BUTTON_RIGHT;
#endif
#elif CONFIG_KEYPAD == IPOD_3G_PAD #elif CONFIG_KEYPAD == IPOD_3G_PAD
state = inb(0xcf000030); state = inb(0xcf000030);
if (((state & 0x20) == 0)) return BUTTON_HOLD; /* hold on */ if (((state & 0x20) == 0)) return BUTTON_HOLD; /* hold on */

View file

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