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:
parent
1903fab9c5
commit
5d9eccd85b
2 changed files with 64 additions and 46 deletions
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue