Index: apps/plugins/plugin.lds =================================================================== RCS file: /cvsroot/rockbox/apps/plugins/plugin.lds,v retrieving revision 1.30 diff -u -r1.30 plugin.lds --- apps/plugins/plugin.lds 18 Jan 2006 00:17:47 -0000 1.30 +++ apps/plugins/plugin.lds 5 Feb 2006 15:03:32 -0000 @@ -20,7 +20,7 @@ #define ARCH_IRIVER #endif -#if CONFIG_CPU==PP5020 +#if CONFIG_CPU==PP5020 || CONFIG_CPU==PP5002 #define ARCH_IPOD #endif Index: bootloader/SOURCES =================================================================== RCS file: /cvsroot/rockbox/bootloader/SOURCES,v retrieving revision 1.2 diff -u -r1.2 SOURCES --- bootloader/SOURCES 8 Nov 2005 00:52:39 -0000 1.2 +++ bootloader/SOURCES 5 Feb 2006 15:03:33 -0000 @@ -1,4 +1,4 @@ -#if (CONFIG_CPU == PP5020) +#if (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5002) ipod.c #else main.c Index: bootloader/ipod.c =================================================================== RCS file: /cvsroot/rockbox/bootloader/ipod.c,v retrieving revision 1.10 diff -u -r1.10 ipod.c --- bootloader/ipod.c 31 Jan 2006 09:40:21 -0000 1.10 +++ bootloader/ipod.c 5 Feb 2006 15:03:33 -0000 @@ -39,15 +39,27 @@ #include "power.h" #include "file.h" -#define DRAM_START 0x10000000 -#define IPOD_PP5020_RTC 0x60005010 +#define IPOD_PP5020_RTC 0x60005010 +#define IPOD_PP5002_RTC 0xcf001110 +#if (CONFIG_CPU == PP5020) +#define DRAM_START 0x10000000 +#define IPOD_RTC 0x60005010 +#else +#define IPOD_RTC 0xcf001110 +#define IPOD_LCD_BASE 0xc0001000 +#define DRAM_START 0x28000000 +#endif #define IPOD_HW_REVISION (*((volatile unsigned long*)(0x00002084))) + +#define BUTTON_HOLD 0 + /* We copy the hardware revision to the last four bytes of SDRAM and then re-read it after we have re-mapped SDRAM to 0x0 in Rockbox */ #define TMP_IPOD_HW_REVISION (*((volatile unsigned long*)(0x11fffffc))) + #define BUTTON_LEFT 1 #define BUTTON_MENU 2 #define BUTTON_RIGHT 3 @@ -75,6 +87,7 @@ int line=0; + static void memmove16(void *dest, const void *src, unsigned count) { struct bufstr { @@ -99,13 +112,13 @@ /* get current usec counter */ int timer_get_current(void) { - return inl(IPOD_PP5020_RTC); + return inl(IPOD_RTC); } /* check if number of seconds has past */ int timer_check(int clock_start, unsigned int usecs) { - if ((inl(IPOD_PP5020_RTC) - clock_start) >= usecs) { + if ((inl(IPOD_RTC) - clock_start) >= usecs) { return 1; } else { return 0; @@ -115,9 +128,9 @@ /* This isn't a sleep, but let's call it that. */ int usleep(unsigned int usecs) { - unsigned int start = inl(IPOD_PP5020_RTC); + unsigned int start = inl(IPOD_RTC); - while ((inl(IPOD_PP5020_RTC) - start) < usecs) { + while ((inl(IPOD_RTC) - start) < usecs) { // empty } @@ -202,11 +215,22 @@ { unsigned char state; - state = opto_keypad_read(); + +#if CONFIG_CPU == PP5020 + state = opto_keypad_read(); if ((state & 0x4) == 0) return BUTTON_LEFT; if ((state & 0x10) == 0) return BUTTON_MENU; if ((state & 0x8) == 0) return BUTTON_PLAY; if ((state & 0x2) == 0) return BUTTON_RIGHT; +#else + /** For iPod 3G **/ + state = inb(0xcf000030); + if (((state & 0x20) == 0)) return BUTTON_HOLD; /* hold on */ + if ((state & 0x08) == 0) return BUTTON_LEFT; + if ((state & 0x10) == 0) return BUTTON_MENU; + if ((state & 0x04) == 0) return BUTTON_PLAY; + if ((state & 0x01) == 0) return BUTTON_RIGHT; +#endif return 0; } @@ -336,7 +360,8 @@ /* set port L07 on */ outl(((0x100 | 1) << 7), 0x6000d12c); - +#elif CONFIG_BACKLIGHT==BL_IPOD3G + outl(inl(IPOD_LCD_BASE) | 0x2, IPOD_LCD_BASE); #endif TMP_IPOD_HW_REVISION = IPOD_HW_REVISION; @@ -353,7 +378,17 @@ button_init(); #endif - line=0; + /* Notes: iPod Color/Photo LCD is 220x176, Nano is 176x138 */ + + /* Display the 42x47 pixel iPodLinux logo */ + // lcd_bitmap(ipllogo, 20,6, 42,47); + + /* Display the 100x31 pixel Rockbox logo */ + // lcd_bitmap(rockboxlogo, 74,16, 100,31); + + line=1; + lcd_clear_display(); + lcd_update(); lcd_setfont(FONT_SYSFIXED); @@ -397,11 +432,11 @@ pinfo->type, pinfo->size / 2048); lcd_puts(0, line++, buf); lcd_update(); - +#if CONFIG_CPU == PP5020 /* Check for a keypress */ i=key_pressed(); - if ((i!=BUTTON_MENU) && (i!=BUTTON_PLAY)) { + if ((i==BUTTON_MENU)) { lcd_puts(0, line, "Loading Rockbox..."); lcd_update(); rc=load_rockbox(loadbuffer); @@ -441,12 +476,12 @@ } /* If everything else failed, try the original firmware */ - +#endif lcd_puts(0, line, "Loading original firmware..."); lcd_update(); /* Pause for 5 seconds so we can see what's happened */ -// usleep(5000000); + usleep(5000000); entry = tblp->addr + tblp->entryOffset; if (imageno || ((int)tblp->addr & 0xffffff) != 0) { Index: firmware/SOURCES =================================================================== RCS file: /cvsroot/rockbox/firmware/SOURCES,v retrieving revision 1.65 diff -u -r1.65 SOURCES --- firmware/SOURCES 25 Jan 2006 12:15:24 -0000 1.65 +++ firmware/SOURCES 5 Feb 2006 15:03:33 -0000 @@ -50,7 +50,7 @@ #ifdef HAVE_LCD_BITMAP arabjoin.c bidi.c -#if LCD_DEPTH == 2 +#if LCD_DEPTH == 2 && CONFIG_LCD!=LCD_IPOD2BPP drivers/lcd-h100.c #elif LCD_DEPTH == 1 drivers/lcd-recorder.c @@ -58,12 +58,15 @@ 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 drivers/lcd-ipodvideo.c #endif +#if CONFIG_LCD==LCD_IPOD2BPP +drivers/lcd-2bit-linear.c +#endif #if CONFIG_LCD==LCD_H300 drivers/lcd-h300.c #endif @@ -97,6 +100,8 @@ 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 +113,7 @@ #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 +162,8 @@ 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 Index: firmware/app.lds =================================================================== RCS file: /cvsroot/rockbox/firmware/app.lds,v retrieving revision 1.64 diff -u -r1.64 app.lds --- firmware/app.lds 24 Jan 2006 23:32:53 -0000 1.64 +++ firmware/app.lds 5 Feb 2006 15:03:33 -0000 @@ -126,6 +126,10 @@ #define DRAMORIG 0x00000000 + STUBOFFSET #define IRAMORIG 0x40000000 #define IRAMSIZE 0xc000 +#elif CONFIG_CPU==PP5002 +#define DRAMORIG 0x00000000 + STUBOFFSET +#define IRAMORIG 0x40000000 +#define IRAMSIZE 0xc000 #elif CONFIG_CPU==PNX0101 #define DRAMORIG 0x24000000 + STUBOFFSET #define IRAMORIG 0x400000 Index: firmware/backlight.c =================================================================== RCS file: /cvsroot/rockbox/firmware/backlight.c,v retrieving revision 1.71 diff -u -r1.71 backlight.c --- firmware/backlight.c 19 Jan 2006 13:10:15 -0000 1.71 +++ firmware/backlight.c 5 Feb 2006 15:03:33 -0000 @@ -242,6 +242,8 @@ /* 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 @@ outl(((0x100 | 0) << 7), 0x6000d12c); #elif CONFIG_BACKLIGHT==BL_IRIVER_IFP7XX GPIO3_CLR = 1; +#elif CONFIG_BACKLIGHT==BL_IPOD3G + lcd_enable(false); #endif } Index: firmware/boot.lds =================================================================== RCS file: /cvsroot/rockbox/firmware/boot.lds,v retrieving revision 1.14 diff -u -r1.14 boot.lds --- firmware/boot.lds 5 Feb 2006 00:09:50 -0000 1.14 +++ firmware/boot.lds 5 Feb 2006 15:03:33 -0000 @@ -4,7 +4,7 @@ #ifdef CPU_COLDFIRE OUTPUT_FORMAT(elf32-m68k) INPUT(crt0.o) -#elif CONFIG_CPU == PP5020 +#elif CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002 OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) #else @@ -38,6 +38,12 @@ #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 @@ #define FLASHSIZE 256K - ROM_START #endif -#if CONFIG_CPU!=PP5020 +#if CONFIG_CPU!=PP5020 && CONFIG_CPU!=PP5002 MEMORY { DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE @@ -56,7 +62,7 @@ #endif SECTIONS -#if CONFIG_CPU==PP5020 +#if CONFIG_CPU==PP5020 || CONFIG_CPU==PP5002 { . = IRAMORIG; Index: firmware/kernel.c =================================================================== RCS file: /cvsroot/rockbox/firmware/kernel.c,v retrieving revision 1.51 diff -u -r1.51 kernel.c --- firmware/kernel.c 24 Jan 2006 22:31:57 -0000 1.51 +++ firmware/kernel.c 5 Feb 2006 15:03:33 -0000 @@ -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 @@ -380,6 +380,42 @@ (void)interval_in_ms; #endif } +#elif CONFIG_CPU == PP5002 + +#ifndef BOOTLOADER +void TIMER1(void) +{ + int i; + + TIMER1_VAL; /* Read value to ack IRQ */ + /* Run through the list of tick tasks */ + for (i = 0;i < MAX_NUM_TICK_TASKS;i++) + { + if (tick_funcs[i]) + { + tick_funcs[i](); + } + } + + current_tick++; + wake_up_thread(); +} +#endif + +void tick_start(unsigned int interval_in_ms) +{ +#ifndef BOOTLOADER + TIMER1_CFG = 0x0; + TIMER1_VAL; + /* enable timer */ + TIMER1_CFG = 0xc0000000 | (interval_in_ms*1000); + /* unmask interrupt source */ + CPU_INT_EN = TIMER1_MASK; +#else + /* We don't enable interrupts in the bootloader */ + (void)interval_in_ms; +#endif +} #elif CONFIG_CPU == PNX0101 Index: firmware/pcm_playback.c =================================================================== RCS file: /cvsroot/rockbox/firmware/pcm_playback.c,v retrieving revision 1.88 diff -u -r1.88 pcm_playback.c --- firmware/pcm_playback.c 4 Feb 2006 00:01:15 -0000 1.88 +++ firmware/pcm_playback.c 5 Feb 2006 15:03:33 -0000 @@ -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 @@ 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 @@ #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; Index: firmware/rolo.c =================================================================== RCS file: /cvsroot/rockbox/firmware/rolo.c,v retrieving revision 1.23 diff -u -r1.23 rolo.c --- firmware/rolo.c 3 Feb 2006 23:14:42 -0000 1.23 +++ firmware/rolo.c 5 Feb 2006 15:03:33 -0000 @@ -73,7 +73,7 @@ : : "a"(dest) ); #endif -#if CONFIG_CPU == PP5020 +#if CONFIG_CPU == PP5020 || CONFIG_CPU==PP5002 /* TODO: Implement for iPod */ #endif } @@ -92,7 +92,7 @@ { int fd; long length; -#if CONFIG_CPU == MCF5249 || CONFIG_CPU == PP5020 +#if CONFIG_CPU == MCF5249 || CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002 int i; unsigned long checksum,file_checksum; #else @@ -116,7 +116,7 @@ length = filesize(fd) - FIRMWARE_OFFSET_FILE_DATA; -#if CONFIG_CPU == MCF5249 || CONFIG_CPU == PP5020 +#if CONFIG_CPU == MCF5249 || CONFIG_CPU == PP5020|| CONFIG_CPU == PP5002 /* Read and save checksum */ lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET); if (read(fd, &file_checksum, 4) != 4) { Index: firmware/system.c =================================================================== RCS file: /cvsroot/rockbox/firmware/system.c,v retrieving revision 1.87 diff -u -r1.87 system.c --- firmware/system.c 3 Feb 2006 23:26:14 -0000 1.87 +++ firmware/system.c 5 Feb 2006 15:03:34 -0000 @@ -1134,7 +1134,7 @@ } } -#if CONFIG_CPU==PP5020 +#if CONFIG_CPU==PP5020 unsigned int ipod_hw_rev; @@ -1226,6 +1226,97 @@ (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; + return 0; +} #elif CONFIG_CPU==PNX0101 Index: firmware/thread.c =================================================================== RCS file: /cvsroot/rockbox/firmware/thread.c,v retrieving revision 1.58 diff -u -r1.58 thread.c --- firmware/thread.c 31 Jan 2006 14:48:10 -0000 1.58 +++ firmware/thread.c 5 Feb 2006 15:03:34 -0000 @@ -243,6 +243,7 @@ \ } + #endif /*--------------------------------------------------------------------------- Index: firmware/timer.c =================================================================== RCS file: /cvsroot/rockbox/firmware/timer.c,v retrieving revision 1.5 diff -u -r1.5 timer.c --- firmware/timer.c 3 Feb 2006 23:14:42 -0000 1.5 +++ firmware/timer.c 5 Feb 2006 15:03:34 -0000 @@ -56,8 +56,9 @@ int phi = 0; /* bits for the prescaler */ int prescale = 1; -#if (CONFIG_CPU==PP5020) || (CONFIG_CPU==PNX0101) - /* TODO: Implement for iPod and iFP */ + +#if CONFIG_CPU==PP5020 || CONFIG_CPU==PP5002 || (CONFIG_CPU==PNX0101) + /* TODO: Implement for iPod */ (void)start; (void)phi; #endif @@ -162,7 +163,7 @@ if (reg_prio <= timer_prio || cycles == 0) return false; -#if (CONFIG_CPU==PP5020) || (CONFIG_CPU==PNX0101) +#if (CONFIG_CPU==PP5020) || (CONFIG_CPU==PNX0101) || (CONFIG_CPU==PP5002) /* TODO: Implement for iPod */ (void)int_prio; #endif Index: firmware/usb.c =================================================================== RCS file: /cvsroot/rockbox/firmware/usb.c,v retrieving revision 1.77 diff -u -r1.77 usb.c --- firmware/usb.c 4 Feb 2006 00:01:15 -0000 1.77 +++ firmware/usb.c 5 Feb 2006 15:03:34 -0000 @@ -68,7 +68,7 @@ #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_4G_PAD || CONFIG_KEYPAD == IPOD_3G_PAD #define USBPOWER_BUTTON BUTTON_MENU #define USBPOWER_BTN_IGNORE BUTTON_PLAY #elif CONFIG_KEYPAD == IRIVER_H300_PAD @@ -172,7 +172,7 @@ 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; Index: firmware/drivers/ata.c =================================================================== RCS file: /cvsroot/rockbox/firmware/drivers/ata.c,v retrieving revision 1.166 diff -u -r1.166 ata.c --- firmware/drivers/ata.c 2 Feb 2006 23:07:11 -0000 1.166 +++ firmware/drivers/ata.c 5 Feb 2006 15:03:34 -0000 @@ -71,13 +71,20 @@ #define SET_REG(reg,val) reg = ((val) << 8) #define SET_16BITREG(reg,val) reg = (val) -#elif CONFIG_CPU == PP5020 +#elif (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) /* don't use sh7034 assembler routines */ #define PREFER_C_READING #define PREFER_C_WRITING +#if (CONFIG_CPU == PP5002) +#define ATA_IOBASE 0xc00031e0 +#define ATA_CONTROL (*((volatile unsigned char*)(0xc00033f8))) +#elif (CONFIG_CPU == PP5020) #define ATA_IOBASE 0xc30001e0 +#define ATA_CONTROL (*((volatile unsigned char*)(0xc30003f8))) +#endif + #define ATA_DATA (*((volatile unsigned short*)(ATA_IOBASE))) #define ATA_ERROR (*((volatile unsigned char*)(ATA_IOBASE + 0x04))) #define ATA_NSECTOR (*((volatile unsigned char*)(ATA_IOBASE + 0x08))) @@ -86,7 +93,6 @@ #define ATA_HCYL (*((volatile unsigned char*)(ATA_IOBASE + 0x14))) #define ATA_SELECT (*((volatile unsigned char*)(ATA_IOBASE + 0x18))) #define ATA_COMMAND (*((volatile unsigned char*)(ATA_IOBASE + 0x1c))) -#define ATA_CONTROL (*((volatile unsigned char*)(0xc30003f8))) #define STATUS_BSY 0x80 #define STATUS_RDY 0x40 @@ -928,6 +934,7 @@ static int check_registers(void) { +#if CONFIG_CPU != PP5002 int i; if ( ATA_STATUS & STATUS_BSY ) return -1; @@ -946,6 +953,9 @@ } return -2; +#else + return 0; +#endif } static int freeze_lock(void) @@ -1123,6 +1133,9 @@ P1 &= ~0x04; sleep(1); */ +#elif CONFIG_CPU == PP5002 + + // sleep(1); #endif /* state HRR2 */ @@ -1254,7 +1267,7 @@ (void)on; #elif CONFIG_CPU == TCC730 -#elif CONFIG_CPU == PP5020 +#elif (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) /* TODO: Implement ata_enable() */ (void)on; #endif @@ -1407,10 +1420,12 @@ bool coldstart = (P1 & 0x80) == 0; #elif defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) bool coldstart = (GPIO_FUNCTION & 0x00080000) == 0; + #elif defined(IAUDIO_X5) /* X5 TODO */ bool coldstart = true; -#elif CONFIG_CPU == PP5020 +#elif CONFIG_CPU == PP5020 || (CONFIG_CPU == PP5002) + bool coldstart = false; /* TODO: Implement coldstart variable */ #else @@ -1440,13 +1455,21 @@ or_l(0x00080000, &GPIO_FUNCTION); /* FYI: The IDECONFIGx registers are set by set_cpu_frequency() */ +#elif CONFIG_CPU == PP5002 + /* From ipod-ide.c:ipod_ide_register() */ +/* PP5002 */ + outl(inl(0xc0003024) | (1 << 7), 0xc0003024); + outl(inl(0xc0003024) & ~(1<<2), 0xc0003024); + + outl(0x10, 0xc0003000); + outl(0x80002150, 0xc0003004); #elif CONFIG_CPU == PP5020 /* From ipod-ide.c:ipod_ide_register() */ - outl(inl(0xc3000028) | (1 << 5), 0xc3000028); - outl(inl(0xc3000028) & ~0x10000000, 0xc3000028); + outl(inl(0xc3000028) | (1 << 5), 0xc3000028); + outl(inl(0xc3000028) & ~0x10000000, 0xc3000028); - outl(0x10, 0xc3000000); - outl(0x80002150, 0xc3000004); + outl(0x10, 0xc3000000); + outl(0x80002150, 0xc3000004); #endif sleeping = false; Index: firmware/drivers/button.c =================================================================== RCS file: /cvsroot/rockbox/firmware/drivers/button.c,v retrieving revision 1.111 diff -u -r1.111 button.c --- firmware/drivers/button.c 5 Feb 2006 00:20:11 -0000 1.111 +++ firmware/drivers/button.c 5 Feb 2006 15:03:35 -0000 @@ -61,7 +61,7 @@ #define REPEAT_INTERVAL_FINISH 5 /* the power-off button and number of repeated keys before shutting off */ -#if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IRIVER_IFP7XX_PAD) +#if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IRIVER_IFP7XX_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) #define POWEROFF_BUTTON BUTTON_PLAY #define POWEROFF_COUNT 40 #else @@ -215,12 +215,138 @@ outl(inl(0x7000c104) | 0xC000000, 0x7000c104); outl(0x400a1f00, 0x7000c100); + GPIOB_OUTPUT_VAL |= 0x10; CPU_INT_EN = 0x40000000; CPU_HI_INT_EN = I2C_MASK; } #endif +#if CONFIG_KEYPAD == IPOD_3G_PAD +/* Variable to use for setting button status in interrupt handler */ +int int_btn = BUTTON_NONE; + +/** + * + * + */ +void handle_scroll_wheel(int new_scroll, int was_hold, int reverse) +{ + int wheel_keycode = BUTTON_NONE; + static int prev_scroll = -1; + 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 (!was_hold) { + switch (scroll_state[prev_scroll][new_scroll]) { + 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_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 = inb(0xcf000040); + if (source) { + + /* get current keypad status */ + state = inb(0xcf000030); + outb(~state, 0xcf000060); + + if (was_hold && source == 0x40 && state == 0xbf) { + /* ack any active interrupts */ + outb(source, 0xcf000070); + return BUTTON_NONE; + } + was_hold = 0; + + + if ( source & 0x20 ) { + /* 3g hold switch is active low */ + btn |= BUTTON_HOLD; + was_hold = 1; + /* hold switch on 3g causes all outputs to go low */ + /* we shouldn't interpret these as key presses */ + goto done; + } + if (source & 0x1) { + btn |= BUTTON_RIGHT; + } + if (source & 0x2) { + btn |= BUTTON_SELECT; + } + if (source & 0x4) { + btn |= BUTTON_PLAY; + } + if (source & 0x8) { + btn |= BUTTON_LEFT; + } + if (source & 0x10) { + btn |= BUTTON_MENU; + } + + if (source & 0xc0) { + handle_scroll_wheel((state & 0xc0) >> 6, was_hold, 0); + } + done: + + /* ack any active interrupts */ + outb(source, 0xcf000070); + } + return btn; +} +void ipod_3g_button_int(void) +{ + /** + * Theire is other things to do but for now ... + * TODO: implement this function in a better way + **/ + int_btn = ipod_3g_button_read(); + +} +#endif static void button_tick(void) { static int tick = 0; @@ -404,8 +530,15 @@ GPIOA_INT_EN = 0x20; CPU_INT_EN = 0x40000000; CPU_HI_INT_EN = I2C_MASK; -#endif /* CONFIG_KEYPAD */ +#elif CONFIG_KEYPAD == IPOD_3G_PAD + outb(~inb(GPIOA_INPUT_VAL), GPIOA_INT_LEV); + outb(inb(GPIOA_INT_STAT), GPIOA_INT_CLR); + outb(0xff, GPIOA_INT_EN); + + + +#endif /* CONFIG_KEYPAD */ queue_init(&button_queue); button_read(); lastbtn = button_read(); @@ -418,7 +551,7 @@ } #ifdef HAVE_LCD_BITMAP /* only bitmap displays can be flipped */ -#if (CONFIG_KEYPAD != IPOD_4G_PAD) +#if (CONFIG_KEYPAD != IPOD_4G_PAD) && (CONFIG_KEYPAD != IPOD_3G_PAD) /* * helper function to swap UP/DOWN, LEFT/RIGHT (and F1/F3 for Recorder) */ @@ -887,6 +1020,9 @@ (void)data; /* The int_btn variable is set in the button interrupt handler */ btn = int_btn; +#elif CONFIG_KEYPAD == IPOD_3G_PAD + (void)data; + btn = int_btn; #endif /* CONFIG_KEYPAD */ Index: firmware/drivers/lcd-ipod.c =================================================================== RCS file: /cvsroot/rockbox/firmware/drivers/lcd-ipod.c,v retrieving revision 1.11 diff -u -r1.11 lcd-ipod.c --- firmware/drivers/lcd-ipod.c 31 Jan 2006 01:50:07 -0000 1.11 +++ firmware/drivers/lcd-ipod.c 5 Feb 2006 15:03:35 -0000 @@ -29,9 +29,209 @@ #include "kernel.h" #include "system.h" -/*** definitions ***/ + +#if (CONFIG_LCD == LCD_IPOD2BPP) + +/*** hardware configuration ***/ + +#define IPOD_LCD_BASE 0xc0001000 +#define IPOD_LCD_BUSY_MASK 0x80000000 + +/* LCD command codes for HD66789R */ + + +#define LCD_CMD 0x08 +#define LCD_DATA 0x10 + +static unsigned int lcd_contrast = 0x6a; + + +/* check if number of useconds has past */ +static int timer_check(int clock_start, int usecs) +{ + if ( ((int)(USEC_TIMER - clock_start)) >= usecs ) { + return 1; + } else { + return 0; + } +} + +/* wait for LCD with timeout */ +static void lcd_wait_write(void) +{ + int start = USEC_TIMER; + + do { + if ((inl(IPOD_LCD_BASE) & 0x8000) == 0) break; + } while (timer_check(start, 1000) == 0); +} + + +/* send LCD data */ +static void lcd_send_data(int data_lo, int data_hi) +{ + lcd_wait_write(); + outl(data_lo, IPOD_LCD_BASE + LCD_DATA); + lcd_wait_write(); + outl(data_hi, IPOD_LCD_BASE + LCD_DATA); +} + +/* send LCD command */ +static void lcd_prepare_cmd(int cmd) +{ + lcd_wait_write(); + + outl(0x0, IPOD_LCD_BASE + LCD_CMD); + lcd_wait_write(); + outl(cmd, IPOD_LCD_BASE + LCD_CMD); + +} + +/* send LCD command and data */ +static void lcd_cmd_and_data(int cmd, int data_lo, int data_hi) +{ + lcd_prepare_cmd(cmd); + + lcd_send_data(data_lo, data_hi); +} + +int lcd_default_contrast(void) +{ + return 28; +} + + + +/* LCD init */ +#ifndef SIMULATOR + +/** + * + * LCD init + **/ +void lcd_init_device(void){ + /* driver output control - 160x128 */ + lcd_cmd_and_data(0x1, 0x1, 0xf); + lcd_cmd_and_data(0x5, 0x0, 0x10); +} + +/*** update functions ***/ +/* srccopy bitblt, opcode is currently ignored*/ + +#endif /* !SIMULATOR */ + + +void lcd_init(void) +{ + /* Nothing to do here */ +} + + +/* Performance function that works with an external buffer + note that x and bwidtht are in 8-pixel units! */ +void lcd_blit(const unsigned char* data, int x, int by, int width, + int bheight, int stride) +{ + /* TODO implement this on iPod */ + (void)data; + (void)x; + (void)by; + (void)width; + (void)bheight; + (void)stride; +} + +/* Rolls up the lcd display by the specified amount of lines. + * Lines that are rolled out over the top of the screen are + * rolled in from the bottom again. This is a hardware + * remapping only and all operations on the lcd are affected. + * -> + * @param int lines - The number of lines that are rolled. + * The value must be 0 <= pixels < LCD_HEIGHT. */ +void lcd_roll(int lines) +{ + /* TODO Implement lcd_roll() */ + lines &= LCD_HEIGHT-1; +} + +/*** hardware configuration ***/ + +/* Update the display. + This must be called after all other LCD functions that change the display. */ +void lcd_update(void) +{ + lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); +} + +void lcd_set_contrast(int val) +{ + lcd_cmd_and_data(0x4, 0x4, val); + lcd_contrast = val; +} + +void lcd_update_rect(int x, int y, int width, int height) +{ + int cursor_pos, xx; + int ny; + int sx = x, sy = y, mx = width, my = height; + + /* only update the ipod if we are writing to the screen */ + + sx >>= 3; + //mx = (mx+7)>>3; + mx >>= 3; + + cursor_pos = sx + (sy << 5); + + for ( ny = sy; ny <= my; ny++ ) { + unsigned char * img_data; + + + // move the cursor + lcd_cmd_and_data(0x11, cursor_pos >> 8, cursor_pos & 0xff); + + // setup for printing + lcd_prepare_cmd(0x12); + + img_data = &lcd_framebuffer[ny][sx<<1]; + + // 160/8 -> 20 == loops 20 times + // make sure we loop at least once + for ( xx = sx; xx <= mx; xx++ ) { + // display a character + lcd_send_data(*(img_data+1), *img_data); + + img_data += 2; + } + + // update cursor pos counter + cursor_pos += 0x20; + } +} + +/** Switch on or off the backlight **/ +void lcd_enable (bool on){ + int lcd_state; + + lcd_state = inl(IPOD_LCD_BASE); + if (on){ + lcd_state = lcd_state | 0x2; + outl(lcd_state, IPOD_LCD_BASE); + lcd_cmd_and_data(0x7, 0x0, 0x11); + } + else { + lcd_state = lcd_state & ~0x2; + outl(lcd_state, IPOD_LCD_BASE); + lcd_cmd_and_data(0x7, 0x0, 0x9); + } +} + +#else + #define IPOD_LCD_BASE 0x70008a0c #define IPOD_LCD_BUSY_MASK 0x80000000 +#define IPOD_RTC (*((volatile unsigned long*)0x60005010)) + /* LCD command codes for HD66789R */ #define LCD_CNTL_RAM_ADDR_SET 0x21 @@ -40,12 +240,21 @@ #define LCD_CNTL_VERT_RAM_ADDR_POS 0x45 /*** globals ***/ +#if (CONFIG_LCD == LCD_IPODCOLOR) || (CONFIG_LCD == LCD_IPODNANO) static int lcd_type = 1; /* 0 = "old" Color/Photo, 1 = "new" Color & Nano */ +#elif CONFIG_LCD == LCD_IPOD2BPP +static int lcd_type = 0; +#endif +#define LCD_CMD 0x08 +#define LCD_DATA 0x10 + +static unsigned int lcd_contrast = 0x6a; /* check if number of useconds has past */ static inline int timer_check(unsigned long clock_start, unsigned long usecs) { + if ( (USEC_TIMER - clock_start) >= usecs ) { return 1; } else { @@ -56,8 +265,10 @@ static void lcd_wait_write(void) { if ((inl(IPOD_LCD_BASE) & IPOD_LCD_BUSY_MASK) != 0) { + int start = USEC_TIMER; + do { if ((inl(IPOD_LCD_BASE) & IPOD_LCD_BUSY_MASK) == 0) break; } while (timer_check(start, 1000) == 0); @@ -76,6 +287,15 @@ outl(v | 0x81000000, IPOD_LCD_BASE); } +/* send LCD data */ +static void lcd_send_data(int data_lo, int data_hi) +{ + lcd_wait_write(); + outl(data_lo, IPOD_LCD_BASE + LCD_DATA); + lcd_wait_write(); + outl(data_hi, IPOD_LCD_BASE + LCD_DATA); +} + static void lcd_cmd_data(int cmd, int data) { if (lcd_type == 0) { @@ -89,6 +309,24 @@ } } +static void lcd_prepare_cmd(int cmd) +{ + lcd_wait_write(); + outl(0x0, IPOD_LCD_BASE + LCD_CMD); + lcd_wait_write(); + outl(cmd, IPOD_LCD_BASE + LCD_CMD); + +} +/* send LCD command and data */ +/* this is only used for b&w lcds */ +static void lcd_cmd_and_data(int cmd, int data_lo, int data_hi) +{ + lcd_prepare_cmd(cmd); + lcd_send_data(data_lo, data_hi); +} + + + /*** hardware configuration ***/ void lcd_set_contrast(int val) @@ -172,6 +410,7 @@ (void)stride; } + /* Update a fraction of the display. */ void lcd_update_rect(int x, int y, int width, int height) { @@ -281,6 +520,7 @@ } } + /* Update the display. This must be called after all other LCD functions that change the display. */ void lcd_update(void) @@ -288,3 +528,4 @@ lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); } +#endif Index: firmware/drivers/pcf50605.c =================================================================== RCS file: /cvsroot/rockbox/firmware/drivers/pcf50605.c,v retrieving revision 1.3 diff -u -r1.3 pcf50605.c --- firmware/drivers/pcf50605.c 21 Dec 2005 23:32:19 -0000 1.3 +++ firmware/drivers/pcf50605.c 5 Feb 2006 15:03:35 -0000 @@ -24,7 +24,11 @@ * ****************************************************************************/ #include "config.h" +#if CONFIG_I2C == I2C_PP5020 #include "i2c-pp5020.h" +#elif CONFIG_I2C == I2C_PP5002 +#include "i2c-pp5002.h" +#endif #include "rtc.h" #define OOCS 0x01 Index: firmware/drivers/power.c =================================================================== RCS file: /cvsroot/rockbox/firmware/drivers/power.c,v retrieving revision 1.69 diff -u -r1.69 power.c --- firmware/drivers/power.c 2 Feb 2006 23:07:11 -0000 1.69 +++ firmware/drivers/power.c 5 Feb 2006 15:03:35 -0000 @@ -84,7 +84,7 @@ pcf50606_init(); #endif #endif -#elif CONFIG_CPU == PP5020 +#elif CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002 /* TODO: Implement power_init() */ #else #ifdef HAVE_POWEROFF_ON_PB5 @@ -179,10 +179,13 @@ and_l(~0x80000000, &GPIO_OUT); else or_l(0x80000000, &GPIO_OUT); + #elif defined(IAUDIO_X5) /* X5 TODO */ -#elif CONFIG_CPU == PP5020 +#elif CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002 + /* We do nothing on the iPod */ + #elif defined(GMINI_ARCH) if(on) P1 |= 0x08; @@ -240,6 +243,9 @@ #elif CONFIG_CPU == PP5020 /* pretend we are always powered - we don't turn it off on the ipod */ return true; +#elif CONFIG_CPU == PP5002 + /* pretend we are always powered - we don't turn it off on the ipod */ + return true; #elif defined(GMINI_ARCH) return (P1 & 0x08?true:false); #else /* SH1 based archos */ @@ -271,9 +277,10 @@ set_irq_level(HIGHEST_IRQ_LEVEL); #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) and_l(~0x00080000, &GPIO1_OUT); + #elif defined(IAUDIO_X5) and_l(~0x00000008, &GPIO_OUT); -#elif CONFIG_CPU == PP5020 +#elif CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002 #ifndef BOOTLOADER /* We don't turn off the ipod, we put it in a deep sleep */ pcf50605_standby_mode(); Index: firmware/drivers/serial.c =================================================================== RCS file: /cvsroot/rockbox/firmware/drivers/serial.c,v retrieving revision 1.21 diff -u -r1.21 serial.c --- firmware/drivers/serial.c 4 Feb 2006 00:01:15 -0000 1.21 +++ firmware/drivers/serial.c 5 Feb 2006 15:03:35 -0000 @@ -27,7 +27,11 @@ #include "lcd.h" #include "serial.h" -#if (CONFIG_CPU != MCF5249) && (CONFIG_CPU != TCC730) && (CONFIG_CPU != PP5020) && (CONFIG_CPU != PNX0101) && (CONFIG_CPU != MCF5250) + +#if (CONFIG_CPU != MCF5249) && (CONFIG_CPU != TCC730) && \ + (CONFIG_CPU != PP5020) && (CONFIG_CPU != PNX0101) && \ + (CONFIG_CPU != PP5002) && (CONFIG_CPU != MCF5250) + /* FIX: this doesn't work on iRiver or Gmini or iPod yet */ /* iFP7xx has no remote */ Index: firmware/export/button.h =================================================================== RCS file: /cvsroot/rockbox/firmware/export/button.h,v retrieving revision 1.37 diff -u -r1.37 button.h --- firmware/export/button.h 4 Feb 2006 00:01:15 -0000 1.37 +++ firmware/export/button.h 5 Feb 2006 15:03:35 -0000 @@ -163,6 +163,18 @@ #define BUTTON_SCROLL_FWD 0x0010 #define BUTTON_SCROLL_BACK 0x0020 +#elif CONFIG_KEYPAD == IPOD_3G_PAD + +/* TODO: These codes should relate to the hardware */ + +#define BUTTON_MENU 0x0002 +#define BUTTON_PLAY 0x0004 +#define BUTTON_SELECT 0x0008 +#define BUTTON_SCROLL_FWD 0x0010 +#define BUTTON_SCROLL_BACK 0x0020 +#define BUTTON_HOLD 0x0100 + + #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD #define BUTTON_PLAY 0x0001 Index: firmware/export/config.h =================================================================== RCS file: /cvsroot/rockbox/firmware/export/config.h,v retrieving revision 1.54 diff -u -r1.54 config.h --- firmware/export/config.h 31 Jan 2006 10:08:53 -0000 1.54 +++ firmware/export/config.h 5 Feb 2006 15:03:35 -0000 @@ -44,15 +44,16 @@ #define PNX0101 101 /* CONFIG_KEYPAD */ -#define PLAYER_PAD 0 -#define RECORDER_PAD 1 -#define ONDIO_PAD 2 -#define IRIVER_H100_PAD 3 -#define GMINI100_PAD 4 -#define IRIVER_H300_PAD 5 -#define IAUDIO_X5_PAD 6 -#define IPOD_4G_PAD 7 -#define IRIVER_IFP7XX_PAD 8 +#define PLAYER_PAD 0 +#define RECORDER_PAD 1 +#define ONDIO_PAD 2 +#define IRIVER_H100_PAD 3 +#define GMINI100_PAD 4 +#define IRIVER_H300_PAD 5 +#define IAUDIO_X5_PAD 6 +#define IPOD_4G_PAD 7 +#define IPOD_3G_PAD 8 +#define IRIVER_IFP7XX_PAD 9 /* CONFIG_REMOTE_KEYPAD */ #define H100_REMOTE 1 @@ -77,7 +78,8 @@ #define LCD_IPODCOLOR 6 /* as used by iPod Color/Photo */ #define LCD_IPODNANO 7 /* as used by iPod Nano */ #define LCD_IPODVIDEO 8 /* as used by iPod Video */ -#define LCD_IFP7XX 9 /* as used by iRiver iFP 7xx/8xx */ +#define LCD_IPOD2BPP 9 /* as used by iPod 3g with dock */ +#define LCD_IFP7XX 10 /* as used by iRiver iFP 7xx/8xx */ /* LCD_PIXELFORMAT */ #define RGB565 565 @@ -91,8 +93,9 @@ #define BL_GMINI 4 /* Archos GMini */ #define BL_IPOD4G 5 /* Apple iPod 4G */ #define BL_IPODNANO 6 /* Apple iPod Nano and iPod Video*/ -#define BL_IRIVER_H300 7 /* IRiver PWM */ -#define BL_IRIVER_IFP7XX 8 /* IRiver GPIO */ +#define BL_IPOD3G 7 /* Apple iPod 3g with dock */ +#define BL_IRIVER_H300 8 /* IRiver PWM */ +#define BL_IRIVER_IFP7XX 9 /* IRiver GPIO */ /* CONFIG_I2C */ #define I2C_PLAYREC 0 /* Archos Player/Recorder style */ @@ -100,7 +103,8 @@ #define I2C_GMINI 2 /* Gmini style */ #define I2C_COLDFIRE 3 /* Coldfire style */ #define I2C_PP5020 4 /* PP5020 style */ -#define I2C_PNX0101 5 /* PNX0101 style */ +#define I2C_PP5002 5 /* PP5002 style */ +#define I2C_PNX0101 6 /* PNX0101 style */ /* CONFIG_LED */ #define LED_REAL 1 /* SW controlled LED (Archos recorders, player, Gmini) */ @@ -111,7 +115,7 @@ /* CONFIG_RTC */ #define RTC_M41ST84W 1 /* Archos Recorder */ -#define RTC_PCF50605 2 /* iPod 4G */ +#define RTC_PCF50605 2 /* iPod 4G && iPod 3G*/ #define RTC_PCF50606 3 /* iriver H300 */ /* else HW controlled LED (iRiver H1x0) */ @@ -147,6 +151,8 @@ #include "config-ipodnano.h" #elif defined(IPOD_VIDEO) #include "config-ipodvideo.h" +#elif defined(IPOD_3G) +#include "config-ipod3g.h" #elif defined(IRIVER_IFP7XX) #include "config-ifp7xx.h" #else @@ -172,7 +178,7 @@ #endif /* define for all cpus from ARM family */ -#if (CONFIG_CPU == PP5020) || (CONFIG_CPU == PNX0101) +#if (CONFIG_CPU == PP5002) ||(CONFIG_CPU == PP5020) || (CONFIG_CPU == PNX0101) #define CPU_ARM #endif @@ -193,6 +199,7 @@ (((CONFIG_CPU == SH7034) && !defined(PLUGIN)) || /* SH1 archos: core only */ \ (CONFIG_CPU == MCF5249) || /* Coldfire: core, plugins, codecs */ \ (CONFIG_CPU == PP5020) || /* iPod: core, plugins, codecs */ \ + (CONFIG_CPU == PP5002) || /* iPod: core, plugins, codecs */ \ (CONFIG_CPU == TCC730)) /* CalmRISC16: core, (plugins, codecs) */ #define ICODE_ATTR __attribute__ ((section(".icode"))) #define ICONST_ATTR __attribute__ ((section(".irodata"))) Index: firmware/export/cpu.h =================================================================== RCS file: /cvsroot/rockbox/firmware/export/cpu.h,v retrieving revision 1.6 diff -u -r1.6 cpu.h --- firmware/export/cpu.h 12 Jan 2006 00:35:50 -0000 1.6 +++ firmware/export/cpu.h 5 Feb 2006 15:03:35 -0000 @@ -33,6 +33,9 @@ #if CONFIG_CPU == PP5020 #include "pp5020.h" #endif +#if CONFIG_CPU == PP5002 +#include "pp5002.h" +#endif #if CONFIG_CPU == PNX0101 #include "pnx0101.h" #endif Index: firmware/export/kernel.h =================================================================== RCS file: /cvsroot/rockbox/firmware/export/kernel.h,v retrieving revision 1.23 diff -u -r1.23 kernel.h --- firmware/export/kernel.h 23 Jan 2006 10:53:47 -0000 1.23 +++ firmware/export/kernel.h 5 Feb 2006 15:03:35 -0000 @@ -70,6 +70,9 @@ /* We don't enable interrupts in the iPod bootloader, so we need to fake the current_tick variable */ #define current_tick ((*((volatile long*)0x60005010))/10000) + +#elif (CONFIG_CPU == PP5002) && defined(BOOTLOADER) +#define current_tick ((*((volatile long*)0xcf001110))/10000) #else extern long current_tick; #endif Index: firmware/export/lcd.h =================================================================== RCS file: /cvsroot/rockbox/firmware/export/lcd.h,v retrieving revision 1.55 diff -u -r1.55 lcd.h --- firmware/export/lcd.h 5 Feb 2006 00:17:53 -0000 1.55 +++ firmware/export/lcd.h 5 Feb 2006 15:03:35 -0000 @@ -192,15 +192,17 @@ /* Memory copy of display bitmap */ #if LCD_DEPTH == 1 extern fb_data lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH]; -#elif LCD_DEPTH == 2 +#elif LCD_DEPTH == 2 && CONFIG_LCD != LCD_IPOD2BPP extern fb_data lcd_framebuffer[LCD_HEIGHT/4][LCD_WIDTH]; -#elif LCD_DEPTH == 16 +#elif LCD_DEPTH == 2 && CONFIG_LCD == LCD_IPOD2BPP +extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH/4]; +#elif LCD_DEPTH == 16 extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH]; #elif LCD_DEPTH == 18 extern fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH]; #endif -#if CONFIG_BACKLIGHT==BL_IRIVER_H300 +#if (CONFIG_BACKLIGHT==BL_IRIVER_H300)|| (CONFIG_BACKLIGHT==BL_IPOD3G) extern void lcd_enable(bool on); #endif @@ -330,4 +332,5 @@ }; #endif + #endif /* __LCD_H__ */ Index: firmware/export/system.h =================================================================== RCS file: /cvsroot/rockbox/firmware/export/system.h,v retrieving revision 1.50 diff -u -r1.50 system.h --- firmware/export/system.h 31 Jan 2006 01:50:07 -0000 1.50 +++ firmware/export/system.h 5 Feb 2006 15:03:35 -0000 @@ -45,6 +45,22 @@ } #endif +#if CONFIG_CPU==PP5002 +#define inl(p) (*(volatile unsigned long *) (p)) +#define outl(v,p) (*(volatile unsigned long *) (p) = (v)) +#define inb(a) (*(volatile unsigned char *) (a)) +#define outb(a,b) (*(volatile unsigned char *) (b) = (a)) +#define inw(a) (*(volatile unsigned short *) (a)) +#define outw(a,b) (*(volatile unsigned short *) (b) = (a)) +extern unsigned int ipod_hw_rev; + +static inline void udelay(unsigned usecs) +{ + unsigned start = TIMER1_VAL; + while ((TIMER1_VAL - start) < usecs); +} + +#endif #ifdef HAVE_ADJUSTABLE_CPU_FREQ #define FREQ cpu_frequency void set_cpu_frequency(long frequency); Index: tools/configure =================================================================== RCS file: /cvsroot/rockbox/tools/configure,v retrieving revision 1.166 diff -u -r1.166 configure --- tools/configure 5 Feb 2006 00:08:29 -0000 1.166 +++ tools/configure 5 Feb 2006 15:03:36 -0000 @@ -406,6 +406,7 @@ echo "full path to the source code directory here:" firmdir=`input` + rootdir=$firmdir fi ##################################################################### @@ -447,7 +448,8 @@ echo "13 - iPod Color/Photo" echo "14 - iPod Nano" echo "15 - iPod Video" - echo "16 - iriver iFP-790" + echo "16 - iPod 3G" + echo "17 - iriver iFP-790" target_id=`input`; @@ -753,6 +755,25 @@ ;; 16) + archos="ipodcolor" + target="-DIPOD_3G" + memory=32 # always + arm7tdmicc + tool="$rootdir/tools/scramble -add=ipco" + bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" + bmp2rb_native="$rootdir/tools/bmp2rb -f 4" + output="rockbox.ipod" + appextra="recorder:gui" + archosrom="" + flash="" + plugins="yes" + codecs="libmad liba52 libffmpegFLAC libTremor libwavpack dumb libmusepack libalac libfaad libm4a" + # toolset is the tools within the tools directory that we build for + # this particular target. + toolset=$ipodbitmaptools + ;; + + 17) archos="ifp7xx" target="-DIRIVER_IFP7XX" memory=1 Index: firmware/drivers/i2c-pp5002.c =================================================================== RCS file: firmware/drivers/i2c-pp5002.c diff -N firmware/drivers/i2c-pp5002.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ firmware/drivers/i2c-pp5002.c 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,169 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: i2c-pp5002.c,v 1.4 2005/12/19 14:30:52 dave Exp $ + * + * PP5002 I2C driver + * + * Based on code from the ipodlinux project - http://ipodlinux.org/ + * Adapted for Rockbox in January 2006 + * + * Original file: linux/arch/armnommu/mach-ipod/hardware.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. + * + ****************************************************************************/ + +#include "cpu.h" +#include "kernel.h" +#include "logf.h" +#include "system.h" +#include "i2c-pp5002.h" + +/* Local functions definitions */ + +#define IPOD_I2C_BASE 0xc0008000 +#define IPOD_I2C_CTRL (IPOD_I2C_BASE+0x00) +#define IPOD_I2C_ADDR (IPOD_I2C_BASE+0x04) +#define IPOD_I2C_DATA0 (IPOD_I2C_BASE+0x0c) +#define IPOD_I2C_DATA1 (IPOD_I2C_BASE+0x10) +#define IPOD_I2C_DATA2 (IPOD_I2C_BASE+0x14) +#define IPOD_I2C_DATA3 (IPOD_I2C_BASE+0x18) +#define IPOD_I2C_STATUS (IPOD_I2C_BASE+0x1c) + +/* IPOD_I2C_CTRL bit definitions */ +#define IPOD_I2C_SEND 0x80 + +/* IPOD_I2C_STATUS bit definitions */ +#define IPOD_I2C_BUSY (1<<6) + +#define POLL_TIMEOUT (HZ) + +static int ipod_i2c_wait_not_busy(void) +{ + unsigned long timeout; + timeout = current_tick + POLL_TIMEOUT; + while (TIME_BEFORE(current_tick, timeout)) { + if (!(inb(IPOD_I2C_STATUS) & IPOD_I2C_BUSY)) { + return 0; + } + yield(); + } + + return -1; +} + + +/* Public functions */ + +int ipod_i2c_read_byte(unsigned int addr, unsigned int *data) +{ + if (ipod_i2c_wait_not_busy() < 0) + { + return -1; + } + + /* clear top 15 bits, left shift 1, or in 0x1 for a read */ + outb(((addr << 17) >> 16) | 0x1, IPOD_I2C_ADDR); + + outb(inb(IPOD_I2C_CTRL) | 0x20, IPOD_I2C_CTRL); + + outb(inb(IPOD_I2C_CTRL) | IPOD_I2C_SEND, IPOD_I2C_CTRL); + + if (ipod_i2c_wait_not_busy() < 0) + { + return -1; + } + + if (data) + { + *data = inb(IPOD_I2C_DATA0); + } + + return 0; +} + +int ipod_i2c_send_bytes(unsigned int addr, unsigned int len, unsigned char *data) +{ + int data_addr; + unsigned int i; + + if (len < 1 || len > 4) + { + return -1; + } + + if (ipod_i2c_wait_not_busy() < 0) + { + return -2; + } + + /* clear top 15 bits, left shift 1 */ + outb((addr << 17) >> 16, IPOD_I2C_ADDR); + + outb(inb(IPOD_I2C_CTRL) & ~0x20, IPOD_I2C_CTRL); + + data_addr = IPOD_I2C_DATA0; + for ( i = 0; i < len; i++ ) + { + outb(*data++, data_addr); + data_addr += 4; + } + + outb((inb(IPOD_I2C_CTRL) & ~0x26) | ((len-1) << 1), IPOD_I2C_CTRL); + + outb(inb(IPOD_I2C_CTRL) | IPOD_I2C_SEND, IPOD_I2C_CTRL); + + return 0x0; +} + +int ipod_i2c_send_byte(unsigned int addr, int data0) +{ + unsigned char data[1]; + + data[0] = data0; + + return ipod_i2c_send_bytes(addr, 1, data); +} + + +int i2c_readbyte(unsigned int dev_addr, int addr) +{ + int data; + + ipod_i2c_send_byte(dev_addr, addr); + ipod_i2c_read_byte(dev_addr, &data); + + return data; +} + +int ipod_i2c_send(unsigned int addr, int data0, int data1) +{ + unsigned char data[2]; + + data[0] = data0; + data[1] = data1; + + return ipod_i2c_send_bytes(addr, 2, data); +} + +void i2c_init(void) +{ + /* From ipodlinux */ + + // ipod_i2c_base = 0xc0008000; + outl(inl(0xcf005000) | 0x2, 0xcf005000); + + outl(inl(0xcf005030) | (1<<8), 0xcf005030); + outl(inl(0xcf005030) & ~(1<<8), 0xcf005030); +} Index: firmware/drivers/lcd-2bit-linear.c =================================================================== RCS file: firmware/drivers/lcd-2bit-linear.c diff -N firmware/drivers/lcd-2bit-linear.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ firmware/drivers/lcd-2bit-linear.c 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,812 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: lcd-ipodvideo.c,v 1.3 2005/12/21 23:47:43 dave Exp $ + * + * LCD driver for 2bit greyscale linear display + * + * Based on code from the rockbox lcd's driver + * + * Copyright (c) 2006 Seven Le Mesle (sevlm@free.fr) + * + * 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 "lcd.h" +#include "kernel.h" +#include "thread.h" +#include +#include +#include "file.h" +#include "debug.h" +#include "system.h" +#include "font.h" +#include "rbunicode.h" +#include "bidi.h" + +/*** definitions ***/ + +/* LCD command codes */ + +#define SCROLLABLE_LINES 26 + +/*** globals ***/ + +unsigned char lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH/4] IBSS_ATTR; + +static const unsigned char dibits[16] ICONST_ATTR = { + 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F, + 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF +}; + +static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ +static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */ +static int drawmode = DRMODE_SOLID; +static int xmargin = 0; +static int ymargin = 0; +static int curfont = FONT_SYSFIXED; + +/* scrolling */ +static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ +static void scroll_thread(void); +static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; +static const char scroll_name[] = "scroll"; +static int scroll_ticks = 12; /* # of ticks between updates*/ +static int scroll_delay = HZ/2; /* ticks delay before start */ +static int scroll_step = 6; /* pixels per scroll step */ +static int bidir_limit = 50; /* percent */ +static struct scrollinfo scroll[SCROLLABLE_LINES]; + +static const char scroll_tick_table[16] = { + /* Hz values: + 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ + 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 +}; + + +static unsigned char notmask[4] = { 0xfc, 0xf3, 0xcf, 0x3f }; + +/*** parameter handling ***/ + +void lcd_set_drawmode(int mode) +{ + drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); +} + +int lcd_get_drawmode(void) +{ + return drawmode; +} + +void lcd_set_foreground(unsigned brightness) +{ + fg_pattern = 0x55 * (~brightness & 3); +} + +unsigned lcd_get_foreground(void) +{ + return ~fg_pattern & 3; +} + +void lcd_set_background(unsigned brightness) +{ + bg_pattern = 0x55 * (~brightness & 3); +} + +unsigned lcd_get_background(void) +{ + return ~bg_pattern & 3; +} + +void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness) +{ + lcd_set_drawmode(mode); + lcd_set_foreground(fg_brightness); + lcd_set_background(bg_brightness); +} + +void lcd_setmargins(int x, int y) +{ + xmargin = x; + ymargin = y; +} + +int lcd_getxmargin(void) +{ + return xmargin; +} + +int lcd_getymargin(void) +{ + return ymargin; +} + +void lcd_setfont(int newfont) +{ + curfont = newfont; +} + +int lcd_getstringsize(const unsigned char *str, int *w, int *h) +{ + return font_getstringsize(str, w, h, curfont); +} + +/*** low-level drawing functions ***/ + +static void setpixel_value(int x, int y, unsigned val) +{ + unsigned char *data = &lcd_framebuffer[y][x>>2]; + + *data = (*data & notmask[x&3]) | (val << ((x&3)<<1)); +} + +static void setpixel(int x, int y) +{ + unsigned char *data = &lcd_framebuffer[y][x>>2]; + + *data = (*data & notmask[x&3]) | (fg_pattern << ((x&3)<<1)); +} + +static void clearpixel(int x, int y) +{ + unsigned char *data = &lcd_framebuffer[y][x>>2]; +*data = (*data & notmask[x&3]) | (bg_pattern << ((x&3)<<1)); +} + +static void flippixel(int x, int y) +{ + lcd_framebuffer[y][x>>2] ^= 3 << (2 * (x & 3)); +} + +static void nopixel(int x, int y) +{ + (void)x; + (void)y; +} + +lcd_pixelfunc_type* const lcd_pixelfuncs[8] = { + flippixel, nopixel, setpixel, setpixel, + nopixel, clearpixel, nopixel, clearpixel +}; + + +/*** drawing functions ***/ + +/* Clear the whole display */ +void lcd_clear_display(void) +{ + unsigned bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern; + + memset(lcd_framebuffer, bits, sizeof lcd_framebuffer); + scrolling_lines = 0; +} + +/* Set a single pixel */ +void lcd_drawpixel(int x, int y) +{ + if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) + lcd_pixelfuncs[drawmode](x, y); +} + +/* Draw a line */ +void lcd_drawline(int x1, int y1, int x2, int y2) +{ + int numpixels; + int i; + int deltax, deltay; + int d, dinc1, dinc2; + int x, xinc1, xinc2; + int y, yinc1, yinc2; + lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode]; + + deltax = abs(x2 - x1); + deltay = abs(y2 - y1); + xinc2 = 1; + yinc2 = 1; + + if (deltax >= deltay) + { + numpixels = deltax; + d = 2 * deltay - deltax; + dinc1 = deltay * 2; + dinc2 = (deltay - deltax) * 2; + xinc1 = 1; + yinc1 = 0; + } + else + { + numpixels = deltay; + d = 2 * deltax - deltay; + dinc1 = deltax * 2; + dinc2 = (deltax - deltay) * 2; + xinc1 = 0; + yinc1 = 1; + } + numpixels++; /* include endpoints */ + + if (x1 > x2) + { + xinc1 = -xinc1; + xinc2 = -xinc2; + } + + if (y1 > y2) + { + yinc1 = -yinc1; + yinc2 = -yinc2; + } + + x = x1; + y = y1; + + for (i = 0; i < numpixels; i++) + { + if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) + pfunc(x, y); + + if (d < 0) + { + d += dinc1; + x += xinc1; + y += yinc1; + } + else + { + d += dinc2; + x += xinc2; + y += yinc2; + } + } +} + +/* Draw a horizontal line (optimised) */ +void lcd_hline(int x1, int x2, int y) +{ + int x; + + lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode]; + + /* direction flip */ + if (x2 < x1) + { + x = x1; + x1 = x2; + x2 = x; + } + + /* nothing to draw? */ + if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) + return; + + /* clipping */ + if (x1 < 0) + x1 = 0; + if (x2 >= LCD_WIDTH) + x2 = LCD_WIDTH-1; + + + while(x1 <= x2) { + pfunc(x1,y); + ++x1; + } +} + +/* Draw a vertical line (optimised) */ +void lcd_vline(int x, int y1, int y2) +{ + int ny; + + lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode]; + + /* direction flip */ + if (y2 < y1) + { + ny = y1; + y1 = y2; + y2 = ny; + } + + /* nothing to draw? */ + if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) + return; + + /* clipping */ + if (y1 < 0) + y1 = 0; + if (y2 >= LCD_HEIGHT) + y2 = LCD_HEIGHT-1; + + + while(y1++ <= y2) { + pfunc(x, y1); + } +} + +/* Draw a rectangular box */ +void lcd_drawrect(int x, int y, int width, int height) +{ + if ((width <= 0) || (height <= 0)) + return; + + int x2 = x + width - 1; + int y2 = y + height - 1; + + lcd_vline(x, y, y2); + lcd_vline(x2, y, y2); + lcd_hline(x, x2, y); + lcd_hline(x, x2, y2); +} + +/* Fill a rectangular area */ +void lcd_fillrect(int x, int y, int width, int height) +{ + int ny; + + + /* nothing to draw? */ + if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) + || (x + width <= 0) || (y + height <= 0)) + return; + + /* clipping */ + if (x < 0) + { + width += x; + x = 0; + } + if (y < 0) + { + height += y; + y = 0; + } + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; + + ny = y; + while (ny <= height) + { + + lcd_hline (x, width, ny); + ny++; + } + +} + +/* About Rockbox' internal monochrome bitmap format: + * + * A bitmap contains one bit for every pixel that defines if that pixel is + * black (1) or white (0). Bits within a byte are arranged horizontally, LSB + * at top. + * The bytes are stored in row-major order, with byte 0 being top left, + * byte 1 2nd from left etc. The first row of bytes defines pixel row + * 0, the second row defines pixel row 1 etc. + * + * This is similar to the internal lcd hw format. */ + +/* Draw a partial monochrome bitmap */ +void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, + int stride, int x, int y, int width, int height) + ICODE_ATTR; +void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, + int stride, int x, int y, int width, int height) +{ + int ny, nx, ymax; + const unsigned char * src_end; + + /* nothing to draw? */ + if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) + || (x + width <= 0) || (y + height <= 0)) + return; + + /* clipping */ + if (x < 0) + { + width += x; + src_x -= x; + x = 0; + } + if (y < 0) + { + height += y; + src_y -= y; + y = 0; + } + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; + + src += stride * (src_y >> 3) + src_x; /* move starting point */ + src_y &= 7; + src_end = src + width; + + nx = x; + do + { + const unsigned char *src_col = src++; + unsigned data = *src_col >> src_y; + int numbits = 8 - ((int)src_y); + + ymax = y + height; + ny = y; + do + { + if (data & 0x01) + setpixel (nx,ny); + else + clearpixel (nx,ny); + + ny++; + + data >>= 1; + if (--numbits == 0) + { + src_col += stride; + data = *src_col; + numbits = 8; + } + } + while (ny < ymax); + nx++; + } + while (src < src_end); + +} + +/* Draw a full monochrome bitmap */ +void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int height) +{ + lcd_mono_bitmap_part(src, 0, 0, width, x, y, width, height); +} + +/* About Rockbox' internal native bitmap format: + * + * A bitmap contains two bits for every pixel. 00 = white, 01 = light grey, + * 10 = dark grey, 11 = black. Bits within a byte are arranged vertically, LSB + * at top. + * The bytes are stored in row-major order, with byte 0 being top left, + * byte 1 2nd from left etc. The first row of bytes defines pixel rows + * 0..3, the second row defines pixel row 4..7 etc. + * + * This is the same as the internal lcd hw format. */ + +/* Draw a partial native bitmap */ +void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y, + int stride, int x, int y, int width, int height) + ICODE_ATTR; +void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y, + int stride, int x, int y, int width, int height) +{ + int ny, nx, ymax; + const unsigned char * src_end; + + /* nothing to draw? */ + if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) + || (x + width <= 0) || (y + height <= 0)) + return; + + /* clipping */ + if (x < 0) + { + width += x; + src_x -= x; + x = 0; + } + if (y < 0) + { + height += y; + src_y -= y; + y = 0; + } + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; + + src += stride * (src_y >> 3) + src_x; /* move starting point */ + src_y &= 7; + src_end = src + width; + + nx = x; + do + { + const unsigned char *src_col = src++; + unsigned data = *src_col >> src_y; + int numbits = 8 - src_y; + + ymax = y + height; + ny = y; + do + { + if (data & 0x03) + setpixel_value (nx,ny, 0xFF); + else + if (data & 0x01) + setpixel_value (nx,ny, 0x3F); + else + if (data & 0x02) + setpixel_value (nx,ny, 0xCF); + else + setpixel_value (nx,ny, 0x00); + + ny++; + + data >>= 2; + if (--numbits == 0) + { + src_col += stride; + data = *src_col; + numbits = 4; + } + } + while (ny < ymax); + nx++; + } + while (src < src_end); + +} + +/* Draw a full native bitmap */ +void lcd_bitmap(const unsigned char *src, int x, int y, int width, int height) +{ + lcd_bitmap_part(src, 0, 0, width, x, y, width, height); +} + +/* put a string at a given pixel position, skipping first ofs pixel columns */ +static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) +{ + unsigned short ch; + unsigned short *ucs; + struct font* pf = font_get(curfont); + + ucs = bidi_l2v(str, 1); + + while ((ch = *ucs++) != 0 && x < LCD_WIDTH) + { + int width; + const unsigned char *bits; + + /* check input range */ + if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) + ch = pf->defaultchar; + ch -= pf->firstchar; + + /* get proportional width and glyph bits */ + width = font_get_width(pf,ch); + + if (ofs > width) + { + ofs -= width; + continue; + } + + bits = font_get_bits(pf, ch); + + lcd_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); + + x += width - ofs; + ofs = 0; + } +} + +/* put a string at a given pixel position */ +void lcd_putsxy(int x, int y, const unsigned char *str) +{ + lcd_putsxyofs(x, y, 0, str); +} + +/*** line oriented text output ***/ + +void lcd_puts_style(int x, int y, const unsigned char *str, int style) +{ + int xpos,ypos,w,h; + int lastmode = drawmode; + + /* make sure scrolling is turned off on the line we are updating */ + scrolling_lines &= ~(1 << y); + + if(!str || !str[0]) + return; + + lcd_getstringsize(str, &w, &h); + xpos = xmargin + x*w / utf8length((char *)str); + ypos = ymargin + y*h; + lcd_putsxy(xpos, ypos, str); + drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h); + if (style & STYLE_INVERT) + { + drawmode = DRMODE_COMPLEMENT; + lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h); + } + drawmode = lastmode; +} + +/* put a string at a given char position */ +void lcd_puts(int x, int y, const unsigned char *str) +{ + lcd_puts_style(x, y, str, STYLE_DEFAULT); +} + +/*** scrolling ***/ + +/* Reverse the invert setting of the scrolling line (if any) at given char + position. Setting will go into affect next time line scrolls. */ +void lcd_invertscroll(int x, int y) +{ + struct scrollinfo* s; + + (void)x; + + s = &scroll[y]; + s->invert = !s->invert; +} + +void lcd_stop_scroll(void) +{ + scrolling_lines=0; +} + +void lcd_scroll_speed(int speed) +{ + scroll_ticks = scroll_tick_table[speed]; +} + +void lcd_scroll_step(int step) +{ + scroll_step = step; +} + +void lcd_scroll_delay(int ms) +{ + scroll_delay = ms / (HZ / 10); +} + +void lcd_bidir_scroll(int percent) +{ + bidir_limit = percent; +} + +void lcd_puts_scroll(int x, int y, const unsigned char *string) +{ + lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); +} + +void lcd_puts_scroll_style(int x, int y, const unsigned char *string, int style) +{ + struct scrollinfo* s; + int w, h; + + s = &scroll[y]; + + s->start_tick = current_tick + scroll_delay; + s->invert = false; + if (style & STYLE_INVERT) { + s->invert = true; + lcd_puts_style(x,y,string,STYLE_INVERT); + } + else + lcd_puts(x,y,string); + + lcd_getstringsize(string, &w, &h); + + if (LCD_WIDTH - x * 8 - xmargin < w) { + /* prepare scroll line */ + char *end; + + memset(s->line, 0, sizeof s->line); + strcpy(s->line, (char *)string); + + /* get width */ + s->width = lcd_getstringsize((unsigned char *)s->line, &w, &h); + + /* scroll bidirectional or forward only depending on the string + width */ + if ( bidir_limit ) { + s->bidir = s->width < (LCD_WIDTH - xmargin) * + (100 + bidir_limit) / 100; + } + else + s->bidir = false; + + if (!s->bidir) { /* add spaces if scrolling in the round */ + strcat(s->line, " "); + /* get new width incl. spaces */ + s->width = lcd_getstringsize((unsigned char *)s->line, &w, &h); + } + + end = strchr(s->line, '\0'); + strncpy(end, (char *)string, LCD_WIDTH/2); + + s->len = utf8length((char *)string); + s->offset = 0; + s->startx = x; + s->backward = false; + scrolling_lines |= (1<start_tick)) + continue; + + if (s->backward) + s->offset -= scroll_step; + else + s->offset += scroll_step; + + pf = font_get(curfont); + xpos = xmargin + s->startx * s->width / s->len; + ypos = ymargin + index * pf->height; + + if (s->bidir) { /* scroll bidirectional */ + if (s->offset <= 0) { + /* at beginning of line */ + s->offset = 0; + s->backward = false; + s->start_tick = current_tick + scroll_delay * 2; + } + if (s->offset >= s->width - (LCD_WIDTH - xpos)) { + /* at end of line */ + s->offset = s->width - (LCD_WIDTH - xpos); + s->backward = true; + s->start_tick = current_tick + scroll_delay * 2; + } + } + else { + /* scroll forward the whole time */ + if (s->offset >= s->width) + s->offset %= s->width; + } + + lastmode = drawmode; + drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + drawmode = DRMODE_SOLID; + lcd_putsxyofs(xpos, ypos, s->offset, (unsigned char *)s->line); + if (s->invert) + { + drawmode = DRMODE_COMPLEMENT; + lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + } + drawmode = lastmode; + lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + } + + sleep(scroll_ticks); + } +} Index: firmware/drivers/wm8731l.c =================================================================== RCS file: firmware/drivers/wm8731l.c diff -N firmware/drivers/wm8731l.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ firmware/drivers/wm8731l.c 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,276 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: wm8975.c,v 1.3 2005/12/19 14:30:52 dave Exp $ + * + * Driver for WM8731l audio codec + * + * Based on code from the ipodlinux project - http://ipodlinux.org/ + * Adapted for Rockbox in January 2006 + * + * Original file: linux/arch/armnommu/mach-ipod/audio.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. + * + ****************************************************************************/ +#include "lcd.h" +#include "cpu.h" +#include "kernel.h" +#include "thread.h" +#include "power.h" +#include "debug.h" +#include "system.h" +#include "sprintf.h" +#include "button.h" +#include "string.h" +#include "file.h" +#include "buffer.h" +#include "audio.h" + +#include "i2c-pp5002.h" +#include "wm8731l.h" +#include "pcf50605.h" + +void wm8731l_reset(void); + +#define IPOD_PCM_LEVEL 0x65 /* -6dB */ + +#define RESET (0x0f<<1) +#define PWRMGMT1 (0x19<<1) +#define PWRMGMT2 (0x1a<<1) +#define AINTFCE (0x07<<1) +#define LOUT1VOL (0x02<<1) +#define ROUT1VOL (0x03<<1) +#define LOUT2VOL (0x28<<1) +#define ROUT2VOL (0x29<<1) + + +int wm8731l_mute(int mute) +{ + + if (mute) + { + /* Set DACMU = 1 to soft-mute the audio DACs. */ + ipod_i2c_send(0x1a, 0xa, 0x8); + } else { + /* Set DACMU = 0 to soft-un-mute the audio DACs. */ + ipod_i2c_send(0x1a, 0xa, 0x0); + } + + return 0; +} +/** From ipodLinux **/ +static void codec_set_active(int active) +{ + /* set active to 0x0 or 0x1 */ + if (active) { + ipod_i2c_send(0x1a, 0x12, 0x01); + } else { + ipod_i2c_send(0x1a, 0x12, 0x00); + } +} + +/* + * Reset the I2S BIT.FORMAT I2S, 16bit, FIFO.FORMAT 32bit + */ +static void i2s_reset(void) +{ + /* PP500x */ + + /* I2S device reset */ + outl(inl(0xcf005030) | 0x80, 0xcf005030); + outl(inl(0xcf005030) & ~0x80, 0xcf005030); + + /* I2S controller enable */ + outl(inl(0xc0002500) | 0x1, 0xc0002500); + + /* BIT.FORMAT [11:10] = I2S (default) */ + /* BIT.SIZE [9:8] = 24bit */ + /* FIFO.FORMAT = 24 bit LSB */ + + /* reset DAC and ADC fifo */ + outl(inl(0xc000251c) | 0x30000, 0xc000251c); +} + +/* + * Initialise the WM8975 for playback via headphone and line out. + * Note, I'm using the WM8750 datasheet as its apparently close. + */ +int wm8731l_init(void) { + /* reset I2C */ + i2c_init(); + + /* PP500x */ + + /* device reset */ + outl(inl(0xcf005030) | 0x80, 0xcf005030); + outl(inl(0xcf005030) & ~0x80, 0xcf005030); + + /* device enable */ + outl(inl(0xcf005000) | 0x80, 0xcf005000); + + /* GPIO D06 enable for output */ + outl(inl(0xcf00000c) | 0x40, 0xcf00000c); + outl(inl(0xcf00001c) & ~0x40, 0xcf00001c); +/* bits 11,10 == 01 */ + outl(inl(0xcf004040) | 0x400, 0xcf004040); + outl(inl(0xcf004040) & ~0x800, 0xcf004040); + + outl(inl(0xcf004048) & ~0x1, 0xcf004048); + + outl(inl(0xcf000004) & ~0xf, 0xcf000004); + outl(inl(0xcf004044) & ~0xf, 0xcf004044); + + /* C03 = 0 */ + outl(inl(0xcf000008) | 0x8, 0xcf000008); + outl(inl(0xcf000018) | 0x8, 0xcf000018); + outl(inl(0xcf000028) & ~0x8, 0xcf000028); + + return 0; +} + +/* Silently enable / disable audio output */ +void wm8731l_enable_output(bool enable) +{ + if (enable) + { + /* reset the I2S controller into known state */ + i2s_reset(); + + ipod_i2c_send(0x1a, 0x1e, 0x0); /*Reset*/ + + codec_set_active(0x0); + + /* DACSEL=1 */ + /* BYPASS=1 */ + ipod_i2c_send(0x1a, 0x8, 0x18); + + + /* set power register to POWEROFF=0 on OUTPD=0, DACPD=0 */ + ipod_i2c_send(0x1a, 0xc, 0x67); + + /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */ + /* IWL=00(16 bit) FORMAT=10(I2S format) */ + ipod_i2c_send(0x1a, 0xe, 0x42); + + wm8731l_set_sample_rate(WM8731L_44100HZ); + + /* set the volume to -6dB */ + ipod_i2c_send(0x1a, 0x4, IPOD_PCM_LEVEL); + ipod_i2c_send(0x1a, 0x6 | 0x1, IPOD_PCM_LEVEL); + + /* ACTIVE=1 */ + codec_set_active(1); + + /* 5. Set DACMU = 0 to soft-un-mute the audio DACs. */ + ipod_i2c_send(0x1a, 0xa, 0x0); + + wm8731l_mute(0); + } else { + wm8731l_mute(1); + } +} + +int wm8731l_set_master_vol(int vol_l, int vol_r) +{ + /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ + /* 1111111 == +6dB */ + /* 1111001 == 0dB */ + /* 0110000 == -73dB */ + /* 0101111 == mute (0x2f) */ + if (vol_l == vol_r) { + ipod_i2c_send(0x1a, 0x4 | 0x1, vol_l); + } else { + ipod_i2c_send(0x1a, 0x4, vol_l); + ipod_i2c_send(0x1a, 0x6, vol_r); + } + + return 0; +} + +int wm8975_set_mixer_vol(int channel1, int channel2) +{ + (void)channel1; + (void)channel2; + + return 0; +} + +void wm8731l_set_bass(int value) +{ + (void)value; +} + +void wm8731l_set_treble(int value) +{ + (void)value; +} + + + +/* Nice shutdown of WM8975 codec */ +void wm8731l_close(void) +{ + /* set DACMU=1 DEEMPH=0 */ + ipod_i2c_send(0x1a, 0xa, 0x8); + + /* ACTIVE=0 */ + codec_set_active(0x0); + + /* line in mute left & right*/ + ipod_i2c_send(0x1a, 0x0 | 0x1, 0x80); + + /* set DACSEL=0, MUTEMIC=1 */ + ipod_i2c_send(0x1a, 0x8, 0x2); + + /* set POWEROFF=0 OUTPD=0 DACPD=1 */ + ipod_i2c_send(0x1a, 0xc, 0x6f); + + /* set POWEROFF=1 OUTPD=1 DACPD=1 */ + ipod_i2c_send(0x1a, 0xc, 0xff); +} + +/* Change the order of the noise shaper, 5th order is recommended above 32kHz */ +void wm8731l_set_nsorder(int order) +{ + (void)order; +} + +/* */ +void wm8731l_set_sample_rate(int sampling_control) { + codec_set_active(0x0); + ipod_i2c_send(0x1a, 0x10, sampling_control); + codec_set_active(0x1); + +} + +void wm8731l_enable_recording(bool source_mic) { + + (void)source_mic; +} + +void wm8731l_disable_recording(void) { + +} + +void wm8731l_set_recvol(int left, int right, int type) { + + (void)left; + (void)right; + (void)type; +} + +void wm8731l_set_monitor(int enable) { + + (void)enable; +} Index: firmware/export/config-ipod3g.h =================================================================== RCS file: firmware/export/config-ipod3g.h diff -N firmware/export/config-ipod3g.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ firmware/export/config-ipod3g.h 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,100 @@ +/* + * This config file is for the Apple iPod 3g + */ +#define APPLE_IPOD3G 1 + +/* For Rolo and boot loader */ +#define MODEL_NUMBER 1 + +/* define this if you have recording possibility */ +/*#define HAVE_RECORDING 1*/ + +/* define this if you have a bitmap LCD display */ +#define HAVE_LCD_BITMAP 1 + +/* define this if you have a colour LCD */ +#define HAVE_LCD_COLOR 0 + +/* LCD dimensions */ +#define LCD_WIDTH 160 +#define LCD_HEIGHT 128 +#define LCD_DEPTH 2 /* 4 colours - 2bpp */ +#define CONFIG_LCD LCD_IPOD2BPP +//#define LCD_PIXELFORMAT RGB565SWAPPED /* rgb565 byte-swapped */ + +#define CONFIG_KEYPAD IPOD_3G_PAD + +/* Define this if you do software codec */ +#define CONFIG_CODEC SWCODEC + +/* define this if you have a real-time clock */ +#ifndef BOOTLOADER +#define CONFIG_RTC RTC_PCF50605 +#endif + +/* Define this if you have a software controlled poweroff */ +#define HAVE_SW_POWEROFF + +/* The number of bytes reserved for loadable codecs */ +#define CODEC_SIZE 0x80000 + +/* The number of bytes reserved for loadable plugins */ +#define PLUGIN_BUFFER_SIZE 0xC0000 + +/* Define this if you have the WM8731L audio codec */ +#define HAVE_WM8731L + +/* Define this for LCD backlight available */ +#define CONFIG_BACKLIGHT BL_IPOD3G /* port controlled */ + +#ifndef SIMULATOR + +/* Define this if you have a PortalPlayer PP5002 */ +#define CONFIG_CPU PP5002 + +/* Define this if you want to use the PP5002 i2c interface */ +#define CONFIG_I2C I2C_PP5002 + +/* Type of mobile power */ +//#define CONFIG_BATTERY BATT_LIPOL1300 + +#define BATTERY_SCALE_FACTOR 16665 /* FIX: this value is picked at random */ + +/* Define this if the platform can charge batteries */ +//#define HAVE_CHARGING 1 + +/* define this if the hardware can be powered off while charging */ +//#define HAVE_POWEROFF_WHILE_CHARGING + +/* The start address index for ROM builds */ +#define ROM_START 0x00000000 + +/* Define this to the CPU frequency */ +#define CPU_FREQ 11289600 + +#define CONFIG_LCD LCD_IPOD2BPP + +/* Offset ( in the firmware file's header ) to the file length */ +#define FIRMWARE_OFFSET_FILE_LENGTH 0 + +/* Offset ( in the firmware file's header ) to the file CRC */ +#define FIRMWARE_OFFSET_FILE_CRC 0 + +/* Offset ( in the firmware file's header ) to the real data */ +#define FIRMWARE_OFFSET_FILE_DATA 8 + +#define USB_IPODSTYLE + +/* define this if the unit can be powered or charged via USB */ +#define HAVE_USB_POWER + +/* Virtual LED (icon) */ +#define CONFIG_LED LED_VIRTUAL + +/* Define this if you have adjustable CPU frequency */ +//#define HAVE_ADJUSTABLE_CPU_FREQ + +#define BOOTFILE_EXT "ipod" +#define BOOTFILE "rockbox." BOOTFILE_EXT + +#endif Index: firmware/export/i2c-pp5002.h =================================================================== RCS file: firmware/export/i2c-pp5002.h diff -N firmware/export/i2c-pp5002.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ firmware/export/i2c-pp5002.h 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,34 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: i2c-pp5002.h,v 1.3 2005/12/11 10:52:17 dave Exp $ + * + * 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. + * + ****************************************************************************/ + +/* + * PP5002 i2c driver + * + */ + +#ifndef _I2C_PP5002_H +#define _I2C_PP5002_H + +/* TODO: Fully implement i2c driver */ + +void i2c_init(void); +int i2c_readbyte(unsigned int dev_addr, int addr); +int ipod_i2c_send(unsigned int addr, int data0, int data1); + +#endif Index: firmware/export/pp5002.h =================================================================== RCS file: firmware/export/pp5002.h diff -N firmware/export/pp5002.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ firmware/export/pp5002.h 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,105 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: pp5020.h,v 1.3 2006/01/07 00:43:48 dave Exp $ + * + * Copyright (C) 2004 by Thom Johansen + * + * 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 __PP5002_H__ +#define __PP5002_H__ + +/* All info gleaned and/or copied from the iPodLinux project. */ + +#define GPIOA_ENABLE (*(volatile unsigned long *)( 0xcf000000)) +#define GPIOB_ENABLE (*(volatile unsigned long *)(0xcf000004)) +#define GPIOC_ENABLE (*(volatile unsigned long *)(0xcf000008)) +#define GPIOD_ENABLE (*(volatile unsigned long *)(0xcf00000c)) +#define GPIOA_OUTPUT_EN (*(volatile unsigned long *)(0xcf000010)) +#define GPIOB_OUTPUT_EN (*(volatile unsigned long *)(0xcf000014)) +#define GPIOC_OUTPUT_EN (*(volatile unsigned long *)(0xcf000018)) +#define GPIOD_OUTPUT_EN (*(volatile unsigned long *)(0xcf00001c)) +#define GPIOA_OUTPUT_VAL (*(volatile unsigned long *)(0xcf000020)) +#define GPIOB_OUTPUT_VAL (*(volatile unsigned long *)(0xcf000024)) +#define GPIOC_OUTPUT_VAL (*(volatile unsigned long *)(0xcf000028)) +#define GPIOD_OUTPUT_VAL (*(volatile unsigned long *)(0xcf00002c)) +#define GPIOA_INPUT_VAL (*(volatile unsigned long *)(0xcf000030)) +#define GPIOB_INPUT_VAL (*(volatile unsigned long *)(0xcf000034)) +#define GPIOC_INPUT_VAL (*(volatile unsigned long *)(0xcf000038)) +#define GPIOD_INPUT_VAL (*(volatile unsigned long *)(0xcf00003c)) +#define GPIOA_INT_STAT (*(volatile unsigned long *)(0xcf000040)) +#define GPIOB_INT_STAT (*(volatile unsigned long *)(0xcf000044)) +#define GPIOC_INT_STAT (*(volatile unsigned long *)(0xcf000048)) +#define GPIOD_INT_STAT (*(volatile unsigned long *)(0xcf00004c)) +#define GPIOA_INT_EN (*(volatile unsigned long *)(0xcf000050)) +#define GPIOB_INT_EN (*(volatile unsigned long *)(0xcf000054)) +#define GPIOC_INT_EN (*(volatile unsigned long *)(0xcf000058)) +#define GPIOD_INT_EN (*(volatile unsigned long *)(0xcf00005c)) +#define GPIOA_INT_LEV (*(volatile unsigned long *)(0xcf000060)) +#define GPIOB_INT_LEV (*(volatile unsigned long *)(0xcf000064)) +#define GPIOC_INT_LEV (*(volatile unsigned long *)(0xcf000068)) +#define GPIOD_INT_LEV (*(volatile unsigned long *)(0xcf00006c)) +#define GPIOA_INT_CLR (*(volatile unsigned long *)(0xcf000070)) +#define GPIOB_INT_CLR (*(volatile unsigned long *)(0xcf000074)) +#define GPIOC_INT_CLR (*(volatile unsigned long *)(0xcf000078)) +#define GPIOD_INT_CLR (*(volatile unsigned long *)(0xcf00007c)) + +#define DEV_RS (*(volatile unsigned long *)( 0xcf005030)) +#define DEV_EN (*(volatile unsigned long *)( 0xcf005000)) + + +#define CPU_INT_STAT (*(volatile unsigned long*)(0xcf001000)) +#define CPU_INT_EN (*(volatile unsigned long*)(0xcf001024)) +#define CPU_INT_CLR (*(volatile unsigned long*)(0xcf001028)) + +#define USB2D_IDENT (*(volatile unsigned long*)(0xc5000000)) +#define USB_STATUS (*(volatile unsigned long*)(0xc50001a4)) + +#define IISCONFIG (*(volatile unsigned long*)(0xc0002500)) + +#define IISFIFO_CFG (*(volatile unsigned long*)(0xc000251c)) +#define IISFIFO_WR (*(volatile unsigned long*)(0xc0002540)) +#define IISFIFO_RD (*(volatile unsigned long*)(0xc0002580)) +/* PP5002 registers */ +#define PP5002_TIMER1 0xcf001100 +#define PP5002_TIMER1_ACK 0xcf001104 +#define PP5002_TIMER2 0xcf001108 +#define PP5002_TIMER2_ACK 0xcf00110c + +#define PP5002_TIMER_STATUS 0xcf001110 + +#define IDE_IRQ 1 +#define SER0_IRQ 4 +#define I2S_IRQ 5 +#define SER1_IRQ 7 +#define TIMER1_IRQ 11 +#define GPIO_IRQ 14 +#define DMA_OUT_IRQ 30 +#define DMA_IN_IRQ 31 + + + +#define TIMER1_MASK (1 << TIMER1_IRQ) +#define I2S_MASK (1 << I2S_IRQ) +#define IDE_MASK (1 << IDE_IRQ) +#define GPIO_MASK (1 << GPIO_IRQ) +#define SER0_MASK (1 << SER0_IRQ) +#define SER1_MASK (1 << SER1_IRQ) + +#define TIMER1_VAL (*(volatile unsigned long *)( 0xcf001104)) +#define TIMER1_CFG (*(volatile unsigned long *)( 0xcf001100)) +#define USEC_TIMER (*(volatile unsigned long *)( 0xcf001110)) + + + +#endif Index: firmware/export/wm8731l.h =================================================================== RCS file: firmware/export/wm8731l.h diff -N firmware/export/wm8731l.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ firmware/export/wm8731l.h 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,54 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: wm8975.h,v 1.3 2005/12/19 14:38:59 dave Exp $ + * + * Copyright (C) 2005 by Dave Chapman + * + * 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 _WM8731L_H +#define _WM8731L_H + +extern void wm8731l_reset(void); +extern int wm8731l_init(void); +extern void wm8731l_enable_output(bool enable); +extern int wm8731l_set_master_vol(int vol_l, int vol_r); +extern int wm8731l_set_mixer_vol(int channel1, int channel2); +extern void wm8731l_set_bass(int value); +extern void wm8731l_set_treble(int value); +extern int wm8731l_mute(int mute); +extern void wm8731l_close(void); +extern void wm8731l_set_nsorder(int order); +extern void wm8731l_set_sample_rate(int sampling_control); + +extern void wm8731l_enable_recording(bool source_mic); +extern void wm8731l_disable_recording(void); +extern void wm8731l_set_recvol(int left, int right, int type); +extern void wm8731l_set_monitor(int enable); + +/* Register settings for the supported samplerates: */ +#define WM8731L_8000HZ 0x4d +/* + IpodLinux don't seem to support those sampling rate with the wm8731L chip +#define WM8975_16000HZ 0x55 +#define WM8975_22050HZ 0x77 +#define WM8975_24000HZ 0x79 +*/ +#define WM8731L_32000HZ 0x59 +#define WM8731L_44100HZ 0x63 +#define WM8731L_48000HZ 0x41 +#define WM8731L_88200HZ 0x7f +#define WM8731L_96000HZ 0x5d + +#endif /* _WM8975_H */