From 987879b958f87a9af7ef9edcf6ae417fe56db788 Mon Sep 17 00:00:00 2001 From: Dave Chapman Date: Sun, 5 Feb 2006 17:34:49 +0000 Subject: Further iPod 3G work from Seven Le Mesle git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8583 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 16 ++++-- firmware/app.lds | 2 +- firmware/backlight.c | 4 ++ firmware/boot.lds | 12 +++- firmware/kernel.c | 4 +- firmware/pcm_playback.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++ firmware/rolo.c | 6 +- firmware/system.c | 92 ++++++++++++++++++++++++++++++- firmware/timer.c | 6 +- firmware/usb.c | 4 +- 10 files changed, 270 insertions(+), 20 deletions(-) diff --git a/firmware/SOURCES b/firmware/SOURCES index b70ee7f118..ce7be4fe7a 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -50,15 +50,17 @@ drivers/lcd-player.c #ifdef HAVE_LCD_BITMAP arabjoin.c bidi.c -#if LCD_DEPTH == 2 -drivers/lcd-h100.c -#elif LCD_DEPTH == 1 +#if LCD_DEPTH == 1 drivers/lcd-recorder.c +#elif CONFIG_LCD==LCD_IPOD2BPP +drivers/lcd-2bit-horz.c +#elif LCD_DEPTH == 2 +drivers/lcd-h100.c #elif LCD_DEPTH == 16 drivers/lcd-16bit.c #endif #endif -#if CONFIG_LCD==LCD_IPODNANO || CONFIG_LCD==LCD_IPODCOLOR +#if CONFIG_LCD==LCD_IPODNANO || CONFIG_LCD==LCD_IPODCOLOR || CONFIG_LCD == LCD_IPOD2BPP drivers/lcd-ipod.c #endif #if CONFIG_LCD==LCD_IPODVIDEO @@ -97,6 +99,8 @@ tuner_philips.c drivers/i2c-coldfire.c #elif CONFIG_I2C == I2C_PP5020 drivers/i2c-pp5020.c +#elif CONFIG_I2C == I2C_PP5002 +drivers/i2c-pp5002.c #elif CONFIG_I2C == I2C_PNX0101 drivers/i2c-pnx0101.c #else @@ -108,7 +112,7 @@ drivers/mas.c #ifdef IRIVER_H300_SERIES drivers/pcf50606.c #endif -#if defined(APPLE_IPODCOLOR) || defined(APPLE_IPODNANO) || defined(APPLE_IPODVIDEO) +#if defined(APPLE_IPODCOLOR) || defined(APPLE_IPODNANO) || defined(APPLE_IPODVIDEO) || defined(APPLE_IPOD3G) drivers/pcf50605.c #endif #if (CONFIG_RTC == RTC_M41ST84W) || (CONFIG_RTC == RTC_PCF50606) @@ -157,6 +161,8 @@ drivers/lcd-h100-remote.c drivers/uda1380.c #elif defined(HAVE_WM8975) && !defined(SIMULATOR) drivers/wm8975.c +#elif defined(HAVE_WM8731L) && !defined(SIMULATOR) +drivers/wm8731l.c #elif defined(HAVE_TLV320) && !defined(SIMULATOR) drivers/tlv320.c #endif diff --git a/firmware/app.lds b/firmware/app.lds index d49949930d..e796f4a05b 100644 --- a/firmware/app.lds +++ b/firmware/app.lds @@ -122,7 +122,7 @@ _pluginbuf = 0; #define DRAMORIG 0x31000000 + STUBOFFSET #define IRAMORIG 0x10000000 #define IRAMSIZE 0xc000 -#elif CONFIG_CPU==PP5020 +#elif (CONFIG_CPU==PP5002) || (CONFIG_CPU==PP5020) #define DRAMORIG 0x00000000 + STUBOFFSET #define IRAMORIG 0x40000000 #define IRAMSIZE 0xc000 diff --git a/firmware/backlight.c b/firmware/backlight.c index 5e79e4e479..daf987791d 100644 --- a/firmware/backlight.c +++ b/firmware/backlight.c @@ -242,6 +242,8 @@ static void __backlight_on(void) /* set port L07 on */ outl(((0x100 | 1) << 7), 0x6000d12c); +#elif CONFIG_BACKLIGHT==BL_IPOD3G + lcd_enable(true); #elif CONFIG_BACKLIGHT==BL_IRIVER_IFP7XX GPIO3_SET = 1; #endif @@ -283,6 +285,8 @@ static void __backlight_off(void) outl(((0x100 | 0) << 7), 0x6000d12c); #elif CONFIG_BACKLIGHT==BL_IRIVER_IFP7XX GPIO3_CLR = 1; +#elif CONFIG_BACKLIGHT==BL_IPOD3G + lcd_enable(false); #endif } diff --git a/firmware/boot.lds b/firmware/boot.lds index f38f3c6a3a..fc0d2c82c2 100644 --- a/firmware/boot.lds +++ b/firmware/boot.lds @@ -4,7 +4,7 @@ ENTRY(start) #ifdef CPU_COLDFIRE OUTPUT_FORMAT(elf32-m68k) INPUT(crt0.o) -#elif CONFIG_CPU == PP5020 +#elif defined (CPU_ARM) OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) #else @@ -38,6 +38,12 @@ INPUT(crt0.o) #define IRAMSIZE 0x18000 #define FLASHORIG 0x001f0000 #define FLASHSIZE 2M +#elif CONFIG_CPU == PP5002 +#define DRAMORIG 0x28000000 +#define IRAMORIG 0x40000000 +#define IRAMSIZE 0x18000 +#define FLASHORIG 0x001f0000 +#define FLASHSIZE 2M #else #define DRAMORIG 0x09000000 #define IRAMORIG 0x0f000000 @@ -46,7 +52,7 @@ INPUT(crt0.o) #define FLASHSIZE 256K - ROM_START #endif -#if CONFIG_CPU!=PP5020 +#if (CONFIG_CPU!=PP5002) && (CONFIG_CPU!=PP5002) MEMORY { DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE @@ -56,7 +62,7 @@ MEMORY #endif SECTIONS -#if CONFIG_CPU==PP5020 +#if (CONFIG_CPU==PP5002) || (CONFIG_CPU==PP5020) { . = IRAMORIG; diff --git a/firmware/kernel.c b/firmware/kernel.c index 85dca37b84..c5edacabec 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c @@ -25,7 +25,7 @@ #include "system.h" #include "panic.h" -#if (CONFIG_CPU != PP5020) || !defined(BOOTLOADER) +#if ((CONFIG_CPU != PP5020) && (CONFIG_CPU != PP5002)) || !defined(BOOTLOADER) long current_tick = 0; #endif @@ -344,7 +344,7 @@ void tick_start(unsigned int interval_in_ms) IMR0 |= (1<<2); } -#elif CONFIG_CPU == PP5020 +#elif (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) #ifndef BOOTLOADER void TIMER1(void) diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c index 980f077b5e..0d9af14f2c 100644 --- a/firmware/pcm_playback.c +++ b/firmware/pcm_playback.c @@ -30,6 +30,8 @@ #include "wm8975.h" #elif defined(HAVE_TLV320) #include "tlv320.h" +#elif defined(HAVE_WM8731L) +#include "wm8731l.h" #endif #include "system.h" #endif @@ -451,6 +453,145 @@ long pcm_get_bytes_waiting(void) return size; } +#elif defined(HAVE_WM8731L) + +/* We need to unify this code with the uda1380 code as much as possible, but + we will keep it separate during early development. +*/ + +static bool pcm_playing; +static bool pcm_paused; +static int pcm_freq = 0x6; /* 44.1 is default */ + +static unsigned char *next_start; +static long next_size; + +/* Set up the DMA transfer that kicks in when the audio FIFO gets empty */ +static void dma_start(const void *addr, long size) +{ + pcm_playing = true; + + addr = (void *)((unsigned long)addr & ~3); /* Align data */ + size &= ~3; /* Size must be multiple of 4 */ + + /* Disable playback for now */ + pcm_playing = false; + return; + +/* This is the uda1380 code */ +#if 0 + /* Reset the audio FIFO */ + + /* Set up DMA transfer */ + SAR0 = ((unsigned long)addr); /* Source address */ + DAR0 = (unsigned long)&PDOR3; /* Destination address */ + BCR0 = size; /* Bytes to transfer */ + + /* Enable the FIFO and force one write to it */ + IIS2CONFIG = IIS_DEFPARM(pcm_freq); + + DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_SINC | DMA_START; +#endif +} + +/* Stops the DMA transfer and interrupt */ +static void dma_stop(void) +{ + pcm_playing = false; + +#if 0 +/* This is the uda1380 code */ + DCR0 = 0; + DSR0 = 1; + /* Reset the FIFO */ + IIS2CONFIG = IIS_RESET | IIS_DEFPARM(pcm_freq); +#endif + next_start = NULL; + next_size = 0; + pcm_paused = false; +} + + +void pcm_init(void) +{ + pcm_playing = false; + pcm_paused = false; + + /* Initialize default register values. */ + wm8731l_init(); + + /* The uda1380 needs a sleep(HZ) here - do we need one? */ + + /* Power on */ + wm8731l_enable_output(true); + + /* Unmute the master channel (DAC should be at zero point now). */ + wm8731l_mute(false); + + /* Call dma_stop to initialize everything. */ + dma_stop(); +} + +void pcm_set_frequency(unsigned int frequency) +{ + (void)frequency; + pcm_freq=frequency; +} + +/* the registered callback function to ask for more mp3 data */ +static void (*callback_for_more)(unsigned char**, long*) = NULL; + +void pcm_play_data(void (*get_more)(unsigned char** start, long* size)) +{ + unsigned char *start; + long size; + + callback_for_more = get_more; + + get_more((unsigned char **)&start, (long *)&size); + get_more(&next_start, &next_size); + + dma_start(start, size); +} + +void pcm_play_stop(void) +{ + if (pcm_playing) { + dma_stop(); + } +} + +void pcm_play_pause(bool play) +{ + if(pcm_paused && play && next_size) + { + logf("unpause"); + /* We need to enable DMA here */ + } + else if(!pcm_paused && !play) + { + logf("pause"); + /* We need to disable DMA here */ + } + pcm_paused = !play; +} + +bool pcm_is_paused(void) +{ + return pcm_paused; +} + +bool pcm_is_playing(void) +{ + return pcm_playing; +} + + +long pcm_get_bytes_waiting(void) +{ + return 0; +} + #elif CONFIG_CPU == PNX0101 /* TODO: Implement for iFP7xx @@ -530,6 +671,9 @@ void pcm_calculate_peaks(int *left, int *right) #elif defined(HAVE_WM8975) long samples = size / 4; short *addr = p; +#elif defined(HAVE_WM8731L) + long samples = next_size / 4; + short *addr = (short *)next_start; #elif defined(HAVE_TLV320) long samples = 4; /* TODO X5 */ short *addr = NULL; diff --git a/firmware/rolo.c b/firmware/rolo.c index 958db56322..f25f2ba6fe 100644 --- a/firmware/rolo.c +++ b/firmware/rolo.c @@ -73,7 +73,7 @@ void rolo_restart(const unsigned char* source, unsigned char* dest, : : "a"(dest) ); #endif -#if CONFIG_CPU == PP5020 +#if (CONFIG_CPU == PP5002) || (CONFIG_CPU==PP5020) /* TODO: Implement for iPod */ #endif } @@ -92,7 +92,7 @@ int rolo_load(const char* filename) { int fd; long length; -#if CONFIG_CPU == MCF5249 || CONFIG_CPU == PP5020 +#if (CONFIG_CPU == MCF5249) || (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) int i; unsigned long checksum,file_checksum; #else @@ -116,7 +116,7 @@ int rolo_load(const char* filename) length = filesize(fd) - FIRMWARE_OFFSET_FILE_DATA; -#if CONFIG_CPU == MCF5249 || CONFIG_CPU == PP5020 +#if (CONFIG_CPU == MCF5249) || (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) /* Read and save checksum */ lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET); if (read(fd, &file_checksum, 4) != 4) { diff --git a/firmware/system.c b/firmware/system.c index fc23edd6ef..df75fbb5a1 100644 --- a/firmware/system.c +++ b/firmware/system.c @@ -477,7 +477,7 @@ void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) = UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, UIE,UIE,UIE,TIMER0,TIMER1,UIE,UIE,UIE, /* lvl 3 lvl 4 */ - + TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7, TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15, @@ -1221,6 +1221,96 @@ void system_reboot(void) { } +int system_memory_guard(int newmode) +{ + (void)newmode; + return 0; +} +#elif CONFIG_CPU==PP5002 +unsigned int ipod_hw_rev; +#ifndef BOOTLOADER +extern void TIMER1(void); +extern void ipod_3g_button_int(void); + +void irq(void) +{ + if (CPU_INT_STAT & TIMER1_MASK) + TIMER1(); + else if (CPU_INT_STAT & GPIO_MASK) + ipod_3g_button_int(); +} +#endif + +/* TODO: The following two function have been lifted straight from IPL, and + hence have a lot of numeric addresses used straight. I'd like to use + #defines for these, but don't know what most of them are for or even what + they should be named. Because of this I also have no way of knowing how + to extend the funtions to do alternate cache configurations and/or + some other CPU frequency scaling. */ + +#ifndef BOOTLOADER +static void ipod_init_cache(void) +{ + int i =0; +/* Initialising the cache in the iPod bootloader prevents Rockbox from starting */ + outl(inl(0xcf004050) & ~0x700, 0xcf004050); + outl(0x4000, 0xcf004020); + + outl(0x2, 0xcf004024); + + /* PP5002 has 8KB cache */ + for (i = 0xf0004000; i < 0xf0006000; i += 16) { + outl(0x0, i); + } + + outl(0x0, 0xf000f020); + outl(0x3fc0, 0xf000f024); + + outl(0x3, 0xcf004024); +} + +static void ipod_set_cpu_speed(void) +{ + outl(0x02, 0xcf005008); + outl(0x55, 0xcf00500c); + outl(0x6000, 0xcf005010); +#if 1 + // 75 MHz (24/24 * 75) (default) + outl(24, 0xcf005018); + outl(75, 0xcf00501c); +#endif + +#if 0 + // 66 MHz (24/3 * 8) + outl(3, 0xcf005018); + outl(8, 0xcf00501c); +#endif + + outl(0xe000, 0xcf005010); + + udelay(2000); + + outl(0xa8, 0xcf00500c); +} +#endif + +void system_init(void) +{ +#ifndef BOOTLOADER + ipod_hw_rev = (*((volatile unsigned long*)(0x01fffffc))); + outl(-1, 0xcf00101c); + outl(-1, 0xcf001028); + outl(-1, 0xcf001038); + ipod_set_cpu_speed(); + ipod_init_cache(); +#endif +} + +void system_reboot(void) +{ + outl(inl(0xcf005030) | 0x4, 0xcf005030); +} + int system_memory_guard(int newmode) { (void)newmode; diff --git a/firmware/timer.c b/firmware/timer.c index d4ce069637..7d9c288cdd 100644 --- a/firmware/timer.c +++ b/firmware/timer.c @@ -56,7 +56,7 @@ static bool timer_set(long cycles, bool start) int phi = 0; /* bits for the prescaler */ int prescale = 1; -#if (CONFIG_CPU==PP5020) || (CONFIG_CPU==PNX0101) +#if (CONFIG_CPU==PP5002) || (CONFIG_CPU==PP5020) || (CONFIG_CPU==PNX0101) /* TODO: Implement for iPod and iFP */ (void)start; (void)phi; @@ -162,8 +162,8 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void), if (reg_prio <= timer_prio || cycles == 0) return false; -#if (CONFIG_CPU==PP5020) || (CONFIG_CPU==PNX0101) - /* TODO: Implement for iPod */ +#if (CONFIG_CPU==PP5002) || (CONFIG_CPU==PP5020) || (CONFIG_CPU==PNX0101) + /* TODO: Implement for iPod and iFP */ (void)int_prio; #endif diff --git a/firmware/usb.c b/firmware/usb.c index 80a8c98d8c..32e98ef6ce 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -68,7 +68,7 @@ void screen_dump(void); /* Nasty again. Defined in apps/ too */ #elif CONFIG_KEYPAD == ONDIO_PAD #define USBPOWER_BUTTON BUTTON_MENU #define USBPOWER_BTN_IGNORE BUTTON_OFF -#elif CONFIG_KEYPAD == IPOD_4G_PAD +#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD) #define USBPOWER_BUTTON BUTTON_MENU #define USBPOWER_BTN_IGNORE BUTTON_PLAY #elif CONFIG_KEYPAD == IRIVER_H300_PAD @@ -172,7 +172,7 @@ void usb_enable(bool on) if (on) { /* The following code is copied from ipodlinux */ -#ifdef APPLE_IPODCOLOR +#if defined (APPLE_IPODCOLOR) || defined(APPLE_IPOD3G) unsigned char* storage_ptr = (unsigned char *)0x40017F00; #elif defined(APPLE_IPODNANO) || defined(APPLE_IPODVIDEO) unsigned char* storage_ptr = (unsigned char *)0x4001FF00; -- cgit v1.2.3