From 348bfc5c8f6633d40d3708e826aa7e9b0360729f Mon Sep 17 00:00:00 2001 From: Cástor Muñoz Date: Thu, 17 Dec 2015 00:22:41 +0100 Subject: iPod Classic: clickwheel fixes Uses GPIO.E2 (Request To Send) to detect the holdswitch status, it is a temporal workaround that seems to work on all models. Holdswitch status must be detected to drive low GPIO.E2 (RTS) and GPIO.E4 (Data Out) when the holdswitch is locked, otherwise battery life decreases about 25%. Holdswitch unlock action is detected by reading the HELLO message that the external wheel controller sends when it is powered on, this allows to quickly capture clickwheel activity after unlock. GPIO.E2 is also used in case the HELLO message is missed because the holdswitch was unlocked before Rockbox/bootloader starts. These 2 lines (RTS and DOUT) can not be used to transmit messages to the external clickwheel controller, not a problem, actually no messages are sent while normal operation, only at initialization stage. Change-Id: I415fe54bfcbc2086d0f56d7affe6f789ce81a6db --- firmware/target/arm/ipod/button-clickwheel.c | 33 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/firmware/target/arm/ipod/button-clickwheel.c b/firmware/target/arm/ipod/button-clickwheel.c index 3af50b5112..5f138aaf1b 100644 --- a/firmware/target/arm/ipod/button-clickwheel.c +++ b/firmware/target/arm/ipod/button-clickwheel.c @@ -271,6 +271,12 @@ static inline int ipod_4g_button_read(void) semaphore_release(&button_init_wakeup); } #endif +#if CONFIG_CPU==S5L8702 + else if (status == 0xAAAAAAAA) + { + GPIOCMD = 0xe040f; /* DOUT = Output High */ + } +#endif #ifdef CPU_PP } @@ -362,9 +368,11 @@ static void s5l_clickwheel_init(void) WHEEL04 |= 1; PDAT10 &= ~2; #elif CONFIG_CPU==S5L8702 - /* enable and init internal (s5l8702) wheel controller */ - PWRCON(1) &= ~(1 << 1); - PCON(14) = (PCON(14) & ~0xffff0000) | 0x22220000; + PWRCON(1) &= ~(1 << 1); /* unmask clockgate */ + WHEEL00 = 0; /* stop s5l8702 controller */ + PUNB(14) &= ~(1 << 2); /* disable pull-up for GPIO E2 */ + udelay(100); + PCON(14) = (PCON(14) & ~0x00ffff00) | 0x00222200; WHEELINT = 7; WHEEL10 = 1; WHEEL00 = 0x380000; @@ -379,12 +387,15 @@ void button_init_device(void) semaphore_init(&button_init_wakeup, 1, 0); #if CONFIG_CPU==S5L8701 INTMSK |= (1<<26); -#elif CONFIG_CPU==S5L8702 - /* configure GPIO E2 as pull-up input */ - PUNB(14) |= (1 << 2); #endif s5l_clickwheel_init(); semaphore_wait(&button_init_wakeup, HZ / 10); +#if CONFIG_CPU==S5L8702 + /* configure GPIO E2 as pull-up input */ + PUNB(14) |= (1 << 2); + udelay(100); + GPIOCMD = 0xe0200; +#endif } bool button_hold(void) @@ -439,13 +450,7 @@ int button_read_device(void) WHEEL10 = 0; PWRCONEXT |= 1; #elif CONFIG_CPU==S5L8702 - /* disable external (CY8C21x34) wheel controller */ - GPIOCMD = 0xe040e; - - /* disable internal (s5l8702) wheel controller */ - WHEEL00 = 0; - WHEEL10 = 0; - PWRCON(1) |= (1 << 1); + GPIOCMD = 0xe040e; /* DOUT = Output Low */ #endif } else @@ -458,7 +463,7 @@ int button_read_device(void) pmu_ldo_power_on(1); /* enable clickwheel power supply */ s5l_clickwheel_init(); #elif CONFIG_CPU==S5L8702 - s5l_clickwheel_init(); + GPIOCMD = 0xe040f; /* DOUT = Output High */ #endif } } -- cgit v1.2.3