From d4945dc0d07b23eced900075e8748ccc7fb3e424 Mon Sep 17 00:00:00 2001 From: Barry Wardell Date: Thu, 5 Oct 2006 10:58:51 +0000 Subject: Move all iPod targets into the target tree. FS#5890 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11129 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/ipod/3g/backlight-3g.c | 42 ++++ firmware/target/arm/ipod/3g/button-3g.c | 189 ++++++++++++++++ firmware/target/arm/ipod/adc-ipod.c | 80 +++++++ firmware/target/arm/ipod/adc-target.h | 29 +++ firmware/target/arm/ipod/backlight-4g_color.c | 48 +++++ firmware/target/arm/ipod/backlight-mini1g_mini2g.c | 44 ++++ firmware/target/arm/ipod/backlight-nano_video.c | 50 +++++ firmware/target/arm/ipod/backlight-target.h | 25 +++ firmware/target/arm/ipod/button-clickwheel.c | 237 +++++++++++++++++++++ firmware/target/arm/ipod/button-mini1g.c | 217 +++++++++++++++++++ firmware/target/arm/ipod/button-target.h | 61 ++++++ firmware/target/arm/ipod/power-ipod.c | 81 +++++++ firmware/target/arm/ipod/usb-ipod.c | 114 ++++++++++ firmware/target/arm/ipod/usb-target.h | 24 +++ 14 files changed, 1241 insertions(+) create mode 100644 firmware/target/arm/ipod/3g/backlight-3g.c create mode 100644 firmware/target/arm/ipod/3g/button-3g.c create mode 100644 firmware/target/arm/ipod/adc-ipod.c create mode 100644 firmware/target/arm/ipod/adc-target.h create mode 100644 firmware/target/arm/ipod/backlight-4g_color.c create mode 100644 firmware/target/arm/ipod/backlight-mini1g_mini2g.c create mode 100644 firmware/target/arm/ipod/backlight-nano_video.c create mode 100644 firmware/target/arm/ipod/backlight-target.h create mode 100644 firmware/target/arm/ipod/button-clickwheel.c create mode 100644 firmware/target/arm/ipod/button-mini1g.c create mode 100644 firmware/target/arm/ipod/button-target.h create mode 100644 firmware/target/arm/ipod/power-ipod.c create mode 100644 firmware/target/arm/ipod/usb-ipod.c create mode 100644 firmware/target/arm/ipod/usb-target.h (limited to 'firmware/target/arm/ipod') diff --git a/firmware/target/arm/ipod/3g/backlight-3g.c b/firmware/target/arm/ipod/3g/backlight-3g.c new file mode 100644 index 0000000000..b676e2473b --- /dev/null +++ b/firmware/target/arm/ipod/3g/backlight-3g.c @@ -0,0 +1,42 @@ +/*************************************************************************** + * __________ __ ___. + * 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 +#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) +{ + outl(inl(0xc0001000) | 0x02, 0xc0001000); +} + +inline void __backlight_off(void) +{ + outl(inl(0xc0001000) & ~0x02, 0xc0001000); +} diff --git a/firmware/target/arm/ipod/3g/button-3g.c b/firmware/target/arm/ipod/3g/button-3g.c new file mode 100644 index 0000000000..7244dd597b --- /dev/null +++ b/firmware/target/arm/ipod/3g/button-3g.c @@ -0,0 +1,189 @@ +/*************************************************************************** + * __________ __ ___. + * 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(); + 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, NULL); + prev_scroll = new_scroll; +} + +static int ipod_3g_button_read(void) +{ + unsigned char source, state; + static int was_hold = 0; + int btn = BUTTON_NONE; + /* + * we need some delay for g3, cause hold generates several interrupts, + * some of them delayed + */ + udelay(250); + + /* get source of interupts */ + source = GPIOA_INT_STAT; + + + /* get current keypad status */ + state = GPIOA_INPUT_VAL; + GPIOA_INT_LEV = ~state; + + 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; + } + 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; + 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; +} diff --git a/firmware/target/arm/ipod/adc-ipod.c b/firmware/target/arm/ipod/adc-ipod.c new file mode 100644 index 0000000000..d351f0ee81 --- /dev/null +++ b/firmware/target/arm/ipod/adc-ipod.c @@ -0,0 +1,80 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "cpu.h" +#include "system.h" +#include "kernel.h" +#include "thread.h" +#include "string.h" +#include "adc.h" +#include "pcf50605.h" + +struct adc_struct { + long timeout; + void (*conversion)(unsigned short *data); + short channelnum; + unsigned short data; +}; + +static struct adc_struct adcdata[NUM_ADC_CHANNELS] IDATA_ATTR; + +static unsigned short _adc_read(struct adc_struct *adc) +{ + if (adc->timeout < current_tick) { + unsigned char data[2]; + unsigned short value; + /* 5x per 2 seconds */ + adc->timeout = current_tick + (HZ * 2 / 5); + + /* ADCC1, 10 bit, start */ + pcf50605_write(0x2f, (adc->channelnum << 1) | 0x1); + pcf50605_read_multiple(0x30, data, 2); /* ADCS1, ADCS2 */ + value = data[0]; + value <<= 2; + value |= data[1] & 0x3; + + if (adc->conversion) { + adc->conversion(&value); + } + adc->data = value; + return value; + } else { + return adc->data; + } +} + +/* Force an ADC scan _now_ */ +unsigned short adc_scan(int channel) { + struct adc_struct *adc = &adcdata[channel]; + adc->timeout = 0; + return _adc_read(adc); +} + +/* Retrieve the ADC value, only does a scan periodically */ +unsigned short adc_read(int channel) { + return _adc_read(&adcdata[channel]); +} + +void adc_init(void) +{ + struct adc_struct *adc_battery = &adcdata[ADC_BATTERY]; + adc_battery->channelnum = 0x2; /* ADCVIN1, resistive divider */ + adc_battery->timeout = 0; + _adc_read(adc_battery); +} diff --git a/firmware/target/arm/ipod/adc-target.h b/firmware/target/arm/ipod/adc-target.h new file mode 100644 index 0000000000..8458779b59 --- /dev/null +++ b/firmware/target/arm/ipod/adc-target.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * __________ __ ___. + * 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. + * + ****************************************************************************/ +#ifndef _ADC_TARGET_H_ +#define _ADC_TARGET_H_ + +#define NUM_ADC_CHANNELS 1 + +#define ADC_BATTERY 0 +#define ADC_UNREG_POWER ADC_BATTERY + +/* Force a scan now */ +unsigned short adc_scan(int channel); +#endif diff --git a/firmware/target/arm/ipod/backlight-4g_color.c b/firmware/target/arm/ipod/backlight-4g_color.c new file mode 100644 index 0000000000..be1dff7c0b --- /dev/null +++ b/firmware/target/arm/ipod/backlight-4g_color.c @@ -0,0 +1,48 @@ +/*************************************************************************** + * __________ __ ___. + * 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 +#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) +{ + /* brightness full */ + outl(0x80000000 | (0xff << 16), 0x7000a010); + + /* set port b bit 3 on */ + outl(((0x100 | 1) << 3), 0x6000d824); +} + +inline void __backlight_off(void) +{ + /* fades backlight off on 4g */ + outl(inl(0x70000084) & ~0x2000000, 0x70000084); + outl(0x80000000, 0x7000a010); +} diff --git a/firmware/target/arm/ipod/backlight-mini1g_mini2g.c b/firmware/target/arm/ipod/backlight-mini1g_mini2g.c new file mode 100644 index 0000000000..6cfa8f889c --- /dev/null +++ b/firmware/target/arm/ipod/backlight-mini1g_mini2g.c @@ -0,0 +1,44 @@ +/*************************************************************************** + * __________ __ ___. + * 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 +#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) +{ + /* set port B03 on */ + outl(((0x100 | 1) << 3), 0x6000d824); +} + +inline void __backlight_off(void) +{ + /* set port B03 off */ + outl(((0x100 | 0) << 3), 0x6000d824); +} diff --git a/firmware/target/arm/ipod/backlight-nano_video.c b/firmware/target/arm/ipod/backlight-nano_video.c new file mode 100644 index 0000000000..5559709333 --- /dev/null +++ b/firmware/target/arm/ipod/backlight-nano_video.c @@ -0,0 +1,50 @@ +/*************************************************************************** + * __________ __ ___. + * 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 +#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) +{ + /* set port B03 on */ + outl(((0x100 | 1) << 3), 0x6000d824); + + /* set port L07 on */ + outl(((0x100 | 1) << 7), 0x6000d12c); +} + +inline void __backlight_off(void) +{ + /* set port B03 off */ + outl(((0x100 | 0) << 3), 0x6000d824); + + /* set port L07 off */ + outl(((0x100 | 0) << 7), 0x6000d12c); +} diff --git a/firmware/target/arm/ipod/backlight-target.h b/firmware/target/arm/ipod/backlight-target.h new file mode 100644 index 0000000000..d35dccdc4a --- /dev/null +++ b/firmware/target/arm/ipod/backlight-target.h @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Barry Wardell + * + * 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. + * + ****************************************************************************/ +#ifndef BACKLIGHT_TARGET_H +#define BACKLIGHT_TARGET_H + +void __backlight_on(void); +void __backlight_off(void); + +#endif diff --git a/firmware/target/arm/ipod/button-clickwheel.c b/firmware/target/arm/ipod/button-clickwheel.c new file mode 100644 index 0000000000..4c536343c4 --- /dev/null +++ b/firmware/target/arm/ipod/button-clickwheel.c @@ -0,0 +1,237 @@ +/*************************************************************************** + * __________ __ ___. + * 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" + +/* Variable to use for setting button status in interrupt handler */ +int int_btn = BUTTON_NONE; +#ifdef HAVE_WHEEL_POSITION + static int wheel_position = -1; + static bool send_events = true; +#endif + +static void opto_i2c_init(void) +{ + int i, curr_value; + + /* wait for value to settle */ + i = 1000; + curr_value = (inl(0x7000c104) << 16) >> 24; + while (i > 0) + { + int new_value = (inl(0x7000c104) << 16) >> 24; + + if (new_value != curr_value) { + i = 10000; + curr_value = new_value; + } + else { + i--; + } + } + + GPIOB_OUTPUT_VAL |= 0x10; + DEV_EN |= 0x10000; + DEV_RS |= 0x10000; + udelay(5); + DEV_RS &= ~0x10000; /* finish reset */ + + outl(0xffffffff, 0x7000c120); + outl(0xffffffff, 0x7000c124); + outl(0xc00a1f00, 0x7000c100); + outl(0x1000000, 0x7000c104); +} + +static inline int ipod_4g_button_read(void) +{ + int whl = -1; + + /* The ipodlinux source had a udelay(250) here, but testing has shown that + it is not needed - tested on Nano, Color/Photo and Video. */ + /* udelay(250);*/ + + int btn = BUTTON_NONE; + unsigned reg = 0x7000c104; + if ((inl(0x7000c104) & 0x4000000) != 0) { + unsigned status = inl(0x7000c140); + + reg = reg + 0x3C; /* 0x7000c140 */ + outl(0x0, 0x7000c140); /* clear interrupt status? */ + + if ((status & 0x800000ff) == 0x8000001a) { + static int old_wheel_value IDATA_ATTR = -1; + static int wheel_repeat = 0; + + if (status & 0x100) + btn |= BUTTON_SELECT; + if (status & 0x200) + btn |= BUTTON_RIGHT; + if (status & 0x400) + btn |= BUTTON_LEFT; + if (status & 0x800) + btn |= BUTTON_PLAY; + if (status & 0x1000) + btn |= BUTTON_MENU; + if (status & 0x40000000) { + /* NB: highest wheel = 0x5F, clockwise increases */ + int new_wheel_value = (status << 9) >> 25; + whl = new_wheel_value; + backlight_on(); + /* The queue should have no other events when scrolling */ + if (queue_empty(&button_queue) && old_wheel_value >= 0) { + + /* This is for later = BUTTON_SCROLL_TOUCH;*/ + int wheel_delta = new_wheel_value - old_wheel_value; + unsigned long data; + int wheel_keycode; + + if (wheel_delta < -48) + wheel_delta += 96; /* Forward wrapping case */ + else if (wheel_delta > 48) + wheel_delta -= 96; /* Backward wrapping case */ + + if (wheel_delta > 4) { + wheel_keycode = BUTTON_SCROLL_FWD; + } else if (wheel_delta < -4) { + wheel_keycode = BUTTON_SCROLL_BACK; + } else goto wheel_end; + +#ifdef HAVE_WHEEL_POSITION + if (send_events) +#endif + { + data = (wheel_delta << 16) | new_wheel_value; + queue_post(&button_queue, wheel_keycode | wheel_repeat, + (void *)data); + } + + if (!wheel_repeat) wheel_repeat = BUTTON_REPEAT; + } + + old_wheel_value = new_wheel_value; + } else if (old_wheel_value >= 0) { + /* scroll wheel up */ + old_wheel_value = -1; + wheel_repeat = 0; + } + + } else if (status == 0xffffffff) { + opto_i2c_init(); + } + } + +wheel_end: + + if ((inl(reg) & 0x8000000) != 0) { + outl(0xffffffff, 0x7000c120); + outl(0xffffffff, 0x7000c124); + } + /* Save the new absolute wheel position */ + wheel_position = whl; + return btn; +} + +#ifdef HAVE_WHEEL_POSITION +int wheel_status(void) +{ + return wheel_position; +} + +void wheel_send_events(bool send) +{ + send_events = send; +} +#endif + +void ipod_4g_button_int(void) +{ + CPU_HI_INT_CLR = I2C_MASK; + /* The following delay was 250 in the ipodlinux source, but 50 seems to + work fine - tested on Nano, Color/Photo and Video. */ + udelay(50); + outl(0x0, 0x7000c140); + int_btn = ipod_4g_button_read(); + outl(inl(0x7000c104) | 0xC000000, 0x7000c104); + outl(0x400a1f00, 0x7000c100); + + GPIOB_OUTPUT_VAL |= 0x10; + CPU_INT_EN = 0x40000000; + CPU_HI_INT_EN = I2C_MASK; +} + +void button_init_device(void) +{ + opto_i2c_init(); + /* hold button - enable as input */ + GPIOA_ENABLE |= 0x20; + GPIOA_OUTPUT_EN &= ~0x20; + /* hold button - set interrupt levels */ + GPIOA_INT_LEV = ~(GPIOA_INPUT_VAL & 0x20); + GPIOA_INT_CLR = GPIOA_INT_STAT & 0x20; + /* enable interrupts */ + GPIOA_INT_EN = 0x20; + /* unmask interrupt */ + CPU_INT_EN = 0x40000000; + CPU_HI_INT_EN = I2C_MASK; +} + +/* + * 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); + + /* The int_btn variable is set in the button interrupt handler */ + return int_btn; +} + +bool button_hold(void) +{ + return (GPIOA_INPUT_VAL & 0x20)?false:true; +} diff --git a/firmware/target/arm/ipod/button-mini1g.c b/firmware/target/arm/ipod/button-mini1g.c new file mode 100644 index 0000000000..07885bc159 --- /dev/null +++ b/firmware/target/arm/ipod/button-mini1g.c @@ -0,0 +1,217 @@ +/*************************************************************************** + * __________ __ ___. + * 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" + +/* Variable to use for setting button status in interrupt handler */ +int int_btn = BUTTON_NONE; +#ifdef HAVE_WHEEL_POSITION + static int wheel_position = -1; + static bool send_events = true; +#endif + +/* 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(); + 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, NULL); + prev_scroll = new_scroll; +} + +/* mini 1 only, mini 2G uses iPod 4G code */ +static int ipod_mini_button_read(void) +{ + unsigned char source, wheel_source, state, wheel_state; + static bool was_hold = false; + int btn = BUTTON_NONE; + + /* 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; + wheel_source = GPIOB_INT_STAT & 0x30; + + if (source == 0 && wheel_source == 0) { + return BUTTON_NONE; /* not for us */ + } + + /* get current keypad & wheel status */ + state = GPIOA_INPUT_VAL & 0x3f; + wheel_state = GPIOB_INPUT_VAL & 0x30; + + /* toggle interrupt level */ + GPIOA_INT_LEV = ~state; + GPIOB_INT_LEV = ~wheel_state; + + /* 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, was_hold, 1); + } + } + + was_hold = button_hold(); + + /* ack any active interrupts */ + if (source) + GPIOA_INT_CLR = source; + if (wheel_source) + GPIOB_INT_CLR = wheel_source; + + return btn; +} + +void ipod_mini_button_int(void) +{ + CPU_HI_INT_CLR = GPIO_MASK; + int_btn = ipod_mini_button_read(); + //CPU_INT_EN = 0x40000000; + CPU_HI_INT_EN = GPIO_MASK; +} + +void button_init_device(void) +{ + /* iPod Mini G1 */ + /* buttons - enable as input */ + GPIOA_ENABLE |= 0x3f; + GPIOA_OUTPUT_EN &= ~0x3f; + /* scroll wheel- enable as input */ + GPIOB_ENABLE |= 0x30; /* port b 4,5 */ + GPIOB_OUTPUT_EN &= ~0x30; /* port b 4,5 */ + /* buttons - set interrupt levels */ + 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 & 0x30); + GPIOB_INT_CLR = GPIOB_INT_STAT & 0x30; + /* enable interrupts */ + GPIOA_INT_EN = 0x3f; + GPIOB_INT_EN = 0x30; + /* unmask interrupt */ + CPU_INT_EN = 0x40000000; + CPU_HI_INT_EN = GPIO_MASK; +} + +/* + * 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); + + /* The int_btn variable is set in the button interrupt handler */ + return int_btn; +} + +bool button_hold(void) +{ + return (GPIOA_INPUT_VAL & 0x20)?false:true; +} diff --git a/firmware/target/arm/ipod/button-target.h b/firmware/target/arm/ipod/button-target.h new file mode 100644 index 0000000000..d736effb72 --- /dev/null +++ b/firmware/target/arm/ipod/button-target.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Barry Wardell + * + * 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. + * + ****************************************************************************/ +#ifndef _BUTTON_TARGET_H_ +#define _BUTTON_TARGET_H_ + +#include +#include "config.h" + +#define HAS_BUTTON_HOLD + +bool button_hold(void); +void button_init_device(void); +int button_read_device(void); + +void handle_scroll_wheel(int new_scroll, int was_hold, int reverse); +void ipod_mini_button_int(void); +void ipod_4g_button_int(void); + +/* iPod specific button codes */ + +#define BUTTON_SELECT 0x00000001 +#define BUTTON_MENU 0x00000002 + +#define BUTTON_LEFT 0x00000004 +#define BUTTON_RIGHT 0x00000008 +#define BUTTON_SCROLL_FWD 0x00000010 +#define BUTTON_SCROLL_BACK 0x00000020 + +#define BUTTON_PLAY 0x00000040 + +#define BUTTON_MAIN (BUTTON_SELECT|BUTTON_MENU\ + |BUTTON_LEFT|BUTTON_RIGHT|BUTTON_SCROLL_FWD\ + |BUTTON_SCROLL_BACK|BUTTON_PLAY) + +#define BUTTON_REMOTE 0 + +/* This is for later +#define BUTTON_SCROLL_TOUCH 0x00000200 +*/ + + +#define POWEROFF_BUTTON BUTTON_PLAY +#define POWEROFF_COUNT 40 + +#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/arm/ipod/power-ipod.c b/firmware/target/arm/ipod/power-ipod.c new file mode 100644 index 0000000000..8932b95cdd --- /dev/null +++ b/firmware/target/arm/ipod/power-ipod.c @@ -0,0 +1,81 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "cpu.h" +#include +#include "adc.h" +#include "kernel.h" +#include "system.h" +#include "power.h" +#include "hwcompat.h" +#include "logf.h" +#include "pcf50605.h" +#include "usb.h" +#include "lcd.h" + +void power_init(void) +{ + pcf50605_init(); +} + +bool charger_inserted(void) +{ +#ifdef IPOD_VIDEO + return (GPIOL_INPUT_VAL & 0x08)?false:true; +#else + /* This needs filling in for other ipods. */ + return false; +#endif +} + +/* Returns true if the unit is charging the batteries. */ +bool charging_state(void) { + return (GPIOB_INPUT_VAL & 0x01)?false:true; +} + + +void ide_power_enable(bool on) +{ + /* We do nothing on the iPod */ + (void)on; +} + +bool ide_powered(void) +{ + /* pretend we are always powered - we don't turn it off on the ipod */ + return true; +} + +void power_off(void) +{ +#if defined(HAVE_LCD_COLOR) + /* Clear the screen and backdrop to + remove ghosting effect on shutdown */ + lcd_set_backdrop(NULL); + lcd_set_background(LCD_WHITE); + lcd_clear_display(); + lcd_update(); + sleep(HZ/16); +#endif + +#ifndef BOOTLOADER + /* We don't turn off the ipod, we put it in a deep sleep */ + pcf50605_standby_mode(); +#endif +} diff --git a/firmware/target/arm/ipod/usb-ipod.c b/firmware/target/arm/ipod/usb-ipod.c new file mode 100644 index 0000000000..c481355768 --- /dev/null +++ b/firmware/target/arm/ipod/usb-ipod.c @@ -0,0 +1,114 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Linus Nielsen Feltzing + * + * iPod driver based on code from the ipodlinux project - http://ipodlinux.org + * Adapted for Rockbox in January 2006 + * Original file: podzilla/usb.c + * Copyright (C) 2005 Adam Johnston + * + * 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 "cpu.h" +#include "kernel.h" +#include "thread.h" +#include "system.h" +#include "debug.h" +#include "ata.h" +#include "fat.h" +#include "disk.h" +#include "panic.h" +#include "lcd.h" +#include "adc.h" +#include "usb.h" +#include "button.h" +#include "sprintf.h" +#include "string.h" +#include "hwcompat.h" + +void usb_init_device(void) +{ + int r0; + outl(inl(0x70000084) | 0x200, 0x70000084); + + outl(inl(0x7000002C) | 0x3000000, 0x7000002C); + outl(inl(0x6000600C) | 0x400000, 0x6000600C); + + outl(inl(0x60006004) | 0x400000, 0x60006004); /* reset usb start */ + outl(inl(0x60006004) & ~0x400000, 0x60006004); /* reset usb end */ + + outl(inl(0x70000020) | 0x80000000, 0x70000020); + while ((inl(0x70000028) & 0x80) == 0); + + outl(inl(0xc5000184) | 0x100, 0xc5000184); + while ((inl(0xc5000184) & 0x100) != 0); + + outl(inl(0xc50001A4) | 0x5F000000, 0xc50001A4); + if ((inl(0xc50001A4) & 0x100) == 0) { + outl(inl(0xc50001A8) & ~0x3, 0xc50001A8); + outl(inl(0xc50001A8) | 0x2, 0xc50001A8); + outl(inl(0x70000028) | 0x4000, 0x70000028); + outl(inl(0x70000028) | 0x2, 0x70000028); + } else { + outl(inl(0xc50001A8) | 0x3, 0xc50001A8); + outl(inl(0x70000028) &~0x4000, 0x70000028); + outl(inl(0x70000028) | 0x2, 0x70000028); + } + outl(inl(0xc5000140) | 0x2, 0xc5000140); + while((inl(0xc5000140) & 0x2) != 0); + r0 = inl(0xc5000184); + + /* Note from IPL source (referring to next 5 lines of code: + THIS NEEDS TO BE CHANGED ONCE THERE IS KERNEL USB */ + outl(inl(0x70000020) | 0x80000000, 0x70000020); + outl(inl(0x6000600C) | 0x400000, 0x6000600C); + while ((inl(0x70000028) & 0x80) == 0); + outl(inl(0x70000028) | 0x2, 0x70000028); + + udelay(0x186A0); +} + +void usb_enable(bool on) +{ + /* For the ipod, we can only do one thing with USB mode - reboot + into Apple's flash-based disk-mode. This does not return. */ + if (on) + { + /* The following code is copied from ipodlinux */ +#if defined(IPOD_COLOR) || defined(IPOD_3G) || \ + defined(IPOD_4G) || defined(IPOD_MINI) + unsigned char* storage_ptr = (unsigned char *)0x40017F00; +#elif defined(IPOD_NANO) || defined(IPOD_VIDEO) || defined(IPOD_MINI2G) + unsigned char* storage_ptr = (unsigned char *)0x4001FF00; +#endif + memcpy(storage_ptr, "diskmode\0\0hotstuff\0\0\1", 21); + DEV_RS |= 4; /* Reboot */ + } +} + +bool usb_detect(void) +{ + bool current_status; + + /* The following check is in the ipodlinux source, with the + comment "USB2D_IDENT is bad" if USB2D_IDENT != 0x22FA05 */ + if (USB2D_IDENT != 0x22FA05) { + return false; + } + current_status = (USB_STATUS & 0x800)?true:false; + + return current_status; +} diff --git a/firmware/target/arm/ipod/usb-target.h b/firmware/target/arm/ipod/usb-target.h new file mode 100644 index 0000000000..69a81472f8 --- /dev/null +++ b/firmware/target/arm/ipod/usb-target.h @@ -0,0 +1,24 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Barry Wardelll + * + * 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. + * + ****************************************************************************/ +#ifndef USB_TARGET_H +#define USB_TARGET_H + +bool usb_init_device(void); + +#endif -- cgit v1.2.3