From 021c0868dd6a9ac01f01db36a7b08cf7ad6737df Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Fri, 27 Jul 2007 12:05:54 +0000 Subject: iPod 2nd gen: * Fake battery voltage of 4.00V so rockbox doesn't shutdown (ADC is not yet implemented). * Fix button hold polarity for main rockbox. * Implement backlight inversion (the 1st/2nd gen backlight works in a way that makes the LCD look inverted when active). * Fix default contrast and clean up target tree. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14022 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 6 +- firmware/export/config-ipod1g2g.h | 5 +- firmware/target/arm/ipod/1g2g/backlight-1g2g.c | 34 ++++ firmware/target/arm/ipod/3g/backlight-3g.c | 11 -- firmware/target/arm/ipod/3g/button-3g.c | 203 ------------------------ firmware/target/arm/ipod/adc-ipod.c | 10 +- firmware/target/arm/ipod/button-1g-3g.c | 207 +++++++++++++++++++++++++ firmware/target/arm/ipod/lcd-gray.c | 32 +++- 8 files changed, 288 insertions(+), 220 deletions(-) create mode 100644 firmware/target/arm/ipod/1g2g/backlight-1g2g.c delete mode 100644 firmware/target/arm/ipod/3g/button-3g.c create mode 100644 firmware/target/arm/ipod/button-1g-3g.c diff --git a/firmware/SOURCES b/firmware/SOURCES index 7d8efbe272..6470528746 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -625,7 +625,7 @@ target/arm/wmcodec-pp.c target/arm/i2s-pp.c target/arm/ipod/adc-ipod.c target/arm/ipod/3g/backlight-3g.c -target/arm/ipod/3g/button-3g.c +target/arm/ipod/button-1g-3g.c target/arm/ipod/lcd-gray.c target/arm/ipod/power-ipod.c target/arm/usb-pp.c @@ -638,8 +638,8 @@ target/arm/ata-pp5002.c target/arm/wmcodec-pp.c target/arm/i2s-pp.c target/arm/ipod/adc-ipod.c -target/arm/ipod/3g/backlight-3g.c /* FIXME */ -target/arm/ipod/3g/button-3g.c /* FIXME */ +target/arm/ipod/1g2g/backlight-1g2g.c +target/arm/ipod/button-1g-3g.c target/arm/ipod/lcd-gray.c target/arm/ipod/power-ipod.c #endif /* SIMULATOR */ diff --git a/firmware/export/config-ipod1g2g.h b/firmware/export/config-ipod1g2g.h index 40b158407d..bfff2b22ef 100644 --- a/firmware/export/config-ipod1g2g.h +++ b/firmware/export/config-ipod1g2g.h @@ -38,7 +38,7 @@ /* LCD contrast */ #define MIN_CONTRAST_SETTING 5 #define MAX_CONTRAST_SETTING 63 -#define DEFAULT_CONTRAST_SETTING 40 /* Match boot contrast */ +#define DEFAULT_CONTRAST_SETTING 28 /* Match boot contrast */ #define CONFIG_KEYPAD IPOD_1G2G_PAD @@ -63,6 +63,9 @@ /* Define this for LCD backlight available */ #define HAVE_BACKLIGHT +/* Define this if the backlight unverts LCD appearance */ +#define HAVE_BACKLIGHT_INVERSION + #define BATTERY_CAPACITY_DEFAULT 630 /* default battery capacity */ #ifndef SIMULATOR diff --git a/firmware/target/arm/ipod/1g2g/backlight-1g2g.c b/firmware/target/arm/ipod/1g2g/backlight-1g2g.c new file mode 100644 index 0000000000..88d638f4e3 --- /dev/null +++ b/firmware/target/arm/ipod/1g2g/backlight-1g2g.c @@ -0,0 +1,34 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "system.h" +#include "backlight.h" +#include "lcd.h" + +void __backlight_on(void) +{ + outl(inl(0xc0001000) | 0x02, 0xc0001000); + lcd_set_backlight_inversion(true); +} + +void __backlight_off(void) +{ + outl(inl(0xc0001000) & ~0x02, 0xc0001000); + lcd_set_backlight_inversion(false); +} diff --git a/firmware/target/arm/ipod/3g/backlight-3g.c b/firmware/target/arm/ipod/3g/backlight-3g.c index b676e2473b..251c722dae 100644 --- a/firmware/target/arm/ipod/3g/backlight-3g.c +++ b/firmware/target/arm/ipod/3g/backlight-3g.c @@ -17,18 +17,7 @@ * ****************************************************************************/ #include "config.h" -#include -#include "cpu.h" -#include "kernel.h" -#include "thread.h" -#include "i2c.h" -#include "debug.h" -#include "rtc.h" -#include "usb.h" -#include "power.h" #include "system.h" -#include "button.h" -#include "timer.h" #include "backlight.h" inline void __backlight_on(void) diff --git a/firmware/target/arm/ipod/3g/button-3g.c b/firmware/target/arm/ipod/3g/button-3g.c deleted file mode 100644 index aa26e30280..0000000000 --- a/firmware/target/arm/ipod/3g/button-3g.c +++ /dev/null @@ -1,203 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2002 by Daniel Stenberg - * - * iPod driver based on code from the ipodlinux project - http://ipodlinux.org - * Adapted for Rockbox in December 2005 - * Original file: linux/arch/armnommu/mach-ipod/keyboard.c - * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org) - * - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -/* - * Rockbox button functions - */ - -#include -#include "config.h" -#include "cpu.h" -#include "system.h" -#include "button.h" -#include "kernel.h" -#include "backlight.h" -#include "adc.h" -#include "serial.h" -#include "power.h" -#include "system.h" -#include "powermgmt.h" - -/* iPod 3G and mini 1G, mini 2G uses iPod 4G code */ -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}, - {1, 0, 0, -1}, - {0, -1, 1, 0} - }; - - 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) { - backlight_on(); - reset_poweroff_timer(); - 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 && queue_empty(&button_queue)) - queue_post(&button_queue, wheel_keycode, 0); - prev_scroll = new_scroll; -} - -static int ipod_3g_button_read(void) -{ - unsigned char source, state; - static int was_hold = 0; - int btn = BUTTON_NONE; - -#ifdef IPOD_3G - /* we need some delay for g3, cause hold generates several interrupts, - * some of them delayed */ - udelay(250); -#endif - - /* get source of interupts */ - source = GPIOA_INT_STAT; - - - /* get current keypad status */ - state = GPIOA_INPUT_VAL; - GPIOA_INT_LEV = ~state; - -#ifdef IPOD_3G - if (was_hold && source == 0x40 && state == 0xbf) { - /* ack any active interrupts */ - GPIOA_INT_CLR = source; - return BUTTON_NONE; - } - was_hold = 0; - - if ((state & 0x20) == 0) { - /* 3g hold switch is active low */ - was_hold = 1; - /* hold switch on 3g causes all outputs to go low */ - /* we shouldn't interpret these as key presses */ - GPIOA_INT_CLR = source; - return BUTTON_NONE; - } -#elif defined IPOD_1G2G - if (state & 0x20) - was_hold = 1; - else - was_hold = 0; -#endif - if ((state & 0x1) == 0) { - btn |= BUTTON_RIGHT; - } - if ((state & 0x2) == 0) { - btn |= BUTTON_SELECT; - } - if ((state & 0x4) == 0) { - btn |= BUTTON_PLAY; - } - if ((state & 0x8) == 0) { - btn |= BUTTON_LEFT; - } - if ((state & 0x10) == 0) { - btn |= BUTTON_MENU; - } - - if (source & 0xc0) { - handle_scroll_wheel((state & 0xc0) >> 6, was_hold, 0); - } - - /* ack any active interrupts */ - GPIOA_INT_CLR = source; - - return btn; -} - -void button_init_device(void) -{ - GPIOA_INT_LEV = ~GPIOA_INPUT_VAL; - GPIOA_INT_CLR = GPIOA_INT_STAT; - /* TODO: put additional G1 code here */ - GPIOA_INT_EN = 0xff; -} - -/* - * Get button pressed from hardware - */ -int button_read_device(void) -{ - static bool hold_button = false; - bool hold_button_old; - - /* normal buttons */ - hold_button_old = hold_button; - hold_button = button_hold(); - - if (hold_button != hold_button_old) - backlight_hold_changed(hold_button); - - return ipod_3g_button_read(); -} - -bool button_hold(void) -{ - return (GPIOA_INPUT_VAL & 0x20)?false:true; -} - -bool headphones_inserted(void) -{ - return (GPIOC_INPUT_VAL & 0x1)?true:false; -} diff --git a/firmware/target/arm/ipod/adc-ipod.c b/firmware/target/arm/ipod/adc-ipod.c index 493b98ef74..39463af30b 100644 --- a/firmware/target/arm/ipod/adc-ipod.c +++ b/firmware/target/arm/ipod/adc-ipod.c @@ -55,7 +55,7 @@ static unsigned short _adc_read(struct adc_struct *adc) } adc->data = value; return value; - } else + } else #endif { return adc->data; @@ -66,11 +66,19 @@ static unsigned short _adc_read(struct adc_struct *adc) unsigned short adc_scan(int channel) { struct adc_struct *adc = &adcdata[channel]; adc->timeout = 0; +#ifdef IPOD_1G2G + if (channel == ADC_UNREG_POWER) + return 681; /* FIXME fake 4.00V */ +#endif return _adc_read(adc); } /* Retrieve the ADC value, only does a scan periodically */ unsigned short adc_read(int channel) { +#ifdef IPOD_1G2G + if (channel == ADC_UNREG_POWER) + return 681; /* FIXME fake 4.00V */ +#endif return _adc_read(&adcdata[channel]); } diff --git a/firmware/target/arm/ipod/button-1g-3g.c b/firmware/target/arm/ipod/button-1g-3g.c new file mode 100644 index 0000000000..a546bea9b6 --- /dev/null +++ b/firmware/target/arm/ipod/button-1g-3g.c @@ -0,0 +1,207 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Daniel Stenberg + * + * iPod driver based on code from the ipodlinux project - http://ipodlinux.org + * Adapted for Rockbox in December 2005 + * Original file: linux/arch/armnommu/mach-ipod/keyboard.c + * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org) + * + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* + * Rockbox button functions + */ + +#include +#include "config.h" +#include "cpu.h" +#include "system.h" +#include "button.h" +#include "kernel.h" +#include "backlight.h" +#include "adc.h" +#include "serial.h" +#include "power.h" +#include "system.h" +#include "powermgmt.h" + +/* iPod 3G and mini 1G, mini 2G uses iPod 4G code */ +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}, + {1, 0, 0, -1}, + {0, -1, 1, 0} + }; + + 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) { + backlight_on(); + reset_poweroff_timer(); + 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 && queue_empty(&button_queue)) + queue_post(&button_queue, wheel_keycode, 0); + prev_scroll = new_scroll; +} + +static int ipod_3g_button_read(void) +{ + unsigned char source, state; + static int was_hold = 0; + int btn = BUTTON_NONE; + +#ifdef IPOD_3G + /* we need some delay for g3, cause hold generates several interrupts, + * some of them delayed */ + udelay(250); +#endif + + /* get source of interupts */ + source = GPIOA_INT_STAT; + + + /* get current keypad status */ + state = GPIOA_INPUT_VAL; + GPIOA_INT_LEV = ~state; + +#ifdef IPOD_3G + if (was_hold && source == 0x40 && state == 0xbf) { + /* ack any active interrupts */ + GPIOA_INT_CLR = source; + return BUTTON_NONE; + } + was_hold = 0; + + if ((state & 0x20) == 0) { + /* 3g hold switch is active low */ + was_hold = 1; + /* hold switch on 3g causes all outputs to go low */ + /* we shouldn't interpret these as key presses */ + GPIOA_INT_CLR = source; + return BUTTON_NONE; + } +#elif defined IPOD_1G2G + if (state & 0x20) + was_hold = 1; + else + was_hold = 0; +#endif + if ((state & 0x1) == 0) { + btn |= BUTTON_RIGHT; + } + if ((state & 0x2) == 0) { + btn |= BUTTON_SELECT; + } + if ((state & 0x4) == 0) { + btn |= BUTTON_PLAY; + } + if ((state & 0x8) == 0) { + btn |= BUTTON_LEFT; + } + if ((state & 0x10) == 0) { + btn |= BUTTON_MENU; + } + + if (source & 0xc0) { + handle_scroll_wheel((state & 0xc0) >> 6, was_hold, 0); + } + + /* ack any active interrupts */ + GPIOA_INT_CLR = source; + + return btn; +} + +void button_init_device(void) +{ + GPIOA_INT_LEV = ~GPIOA_INPUT_VAL; + GPIOA_INT_CLR = GPIOA_INT_STAT; + /* TODO: put additional G1 code here */ + GPIOA_INT_EN = 0xff; +} + +/* + * Get button pressed from hardware + */ +int button_read_device(void) +{ + static bool hold_button = false; + bool hold_button_old; + + /* normal buttons */ + hold_button_old = hold_button; + hold_button = button_hold(); + + if (hold_button != hold_button_old) + backlight_hold_changed(hold_button); + + return ipod_3g_button_read(); +} + +bool button_hold(void) +{ +#ifdef IPOD_1G2G + return (GPIOA_INPUT_VAL & 0x20); +#else + return !(GPIOA_INPUT_VAL & 0x20); +#endif +} + +bool headphones_inserted(void) +{ + return (GPIOC_INPUT_VAL & 0x1)?true:false; +} diff --git a/firmware/target/arm/ipod/lcd-gray.c b/firmware/target/arm/ipod/lcd-gray.c index 0a3a4ae797..7a60eb6470 100644 --- a/firmware/target/arm/ipod/lcd-gray.c +++ b/firmware/target/arm/ipod/lcd-gray.c @@ -68,6 +68,12 @@ static inline bool timer_check(int clock_start, int usecs) #define R_RAM_ADDR_SET 0x11 #define R_RAM_DATA 0x12 +#ifdef HAVE_BACKLIGHT_INVERSION +/* The backlight makes the LCD appear negative on the 1st/2nd gen */ +static bool lcd_inverted = false; +static bool lcd_backlit = false; +#endif + /* needed for flip */ static int addr_offset; #if defined(IPOD_MINI) || defined(IPOD_MINI2G) @@ -146,7 +152,9 @@ void lcd_init_device(void) int lcd_default_contrast(void) { -#if defined(IPOD_MINI) || defined(IPOD_MINI2G) || defined(IPOD_3G) +#ifdef IPOD_1G2G + return 28; +#elif defined(IPOD_MINI) || defined(IPOD_MINI2G) || defined(IPOD_3G) return 42; #else return 35; @@ -162,6 +170,27 @@ void lcd_set_contrast(int val) lcd_cmd_and_data(R_CONTRAST_CONTROL, 0x400 | (val + 64)); } +#ifdef HAVE_BACKLIGHT_INVERSION +static void invert_display(void) +{ + if (lcd_inverted ^ lcd_backlit) + lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0023); + else + lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0009); +} + +void lcd_set_invert_display(bool yesno) +{ + lcd_inverted = yesno; + invert_display(); +} + +void lcd_set_backlight_inversion(bool yesno) +{ + lcd_backlit = yesno; + invert_display(); +} +#else void lcd_set_invert_display(bool yesno) { if (yesno) @@ -169,6 +198,7 @@ void lcd_set_invert_display(bool yesno) else lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0009); } +#endif /* turn the display upside down (call lcd_update() afterwards) */ void lcd_set_flip(bool yesno) -- cgit v1.2.3