diff --git a/apps/debug_menu.c b/apps/debug_menu.c index f5dbbf17a5..2e075479bf 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -87,6 +87,10 @@ #include "ds2411.h" #endif #include "hwcompat.h" +#include "button.h" +#if CONFIG_RTC == RTC_PCF50605 +#include "pcf50605.h" +#endif #if CONFIG_CPU == DM320 || CONFIG_CPU == S3C2440 #include "debug-target.h" @@ -1167,14 +1171,20 @@ bool dbg_ports(void) lcd_puts(0, line++, buf); line++; - snprintf(buf, sizeof(buf), "GPO32: %08lx", GPO32_VAL); + snprintf(buf, sizeof(buf), "GPO32_VAL: %08lx", GPO32_VAL); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN); + snprintf(buf, sizeof(buf), "GPO32_EN: %08lx", GPO32_ENABLE); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "DEV_EN2: %08lx", DEV_EN2); + snprintf(buf, sizeof(buf), "DEV_EN: %08lx", DEV_EN); lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "DEV_EN3: %08lx", inl(0x60006044)); + snprintf(buf, sizeof(buf), "DEV_EN2: %08lx", DEV_EN2); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "DEV_EN3: %08lx", inl(0x60006044)); lcd_puts(0, line++, buf); /* to be verified */ + snprintf(buf, sizeof(buf), "DEV_INIT1: %08lx", DEV_INIT1); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "DEV_INIT2: %08lx", DEV_INIT2); + lcd_puts(0, line++, buf); #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) line++; @@ -1353,6 +1363,60 @@ bool dbg_ports(void) #endif /* !HAVE_LCD_BITMAP */ #endif /* !SIMULATOR */ +#if CONFIG_RTC == RTC_PCF50605 +static bool dbg_pcf(void) +{ + char buf[128]; + int line; + +#ifdef HAVE_LCD_BITMAP + lcd_setmargins(0, 0); + lcd_setfont(FONT_SYSFIXED); +#endif + lcd_clear_display(); + + while(1) + { + line = 0; + + snprintf(buf, sizeof(buf), "DCDC1: %02x", pcf50605_read(0x1b)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "DCDC2: %02x", pcf50605_read(0x1c)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "DCDC3: %02x", pcf50605_read(0x1d)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "DCDC4: %02x", pcf50605_read(0x1e)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "DCDEC1: %02x", pcf50605_read(0x1f)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "DCDEC2: %02x", pcf50605_read(0x20)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "DCUDC1: %02x", pcf50605_read(0x21)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "DCUDC2: %02x", pcf50605_read(0x22)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "IOREGC: %02x", pcf50605_read(0x23)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "D1REGC: %02x", pcf50605_read(0x24)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "D2REGC: %02x", pcf50605_read(0x25)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "D3REGC: %02x", pcf50605_read(0x26)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "LPREG1: %02x", pcf50605_read(0x27)); + lcd_puts(0, line++, buf); + + lcd_update(); + if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL)) + { + return false; + } + } + + return false; +} +#endif + #ifdef HAVE_ADJUSTABLE_CPU_FREQ static bool dbg_cpufreq(void) { @@ -2251,6 +2315,53 @@ static bool cpu_boost_log(void) } #endif +#if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR)) +extern bool wheel_is_touched; +extern int old_wheel_value; +extern int new_wheel_value; +extern int wheel_delta; +extern unsigned int accumulated_wheel_delta; +extern unsigned int wheel_velocity; + +static bool dbg_scrollwheel(void) +{ + char buf[64]; + unsigned int speed; + + lcd_setmargins(0, 0); + lcd_setfont(FONT_SYSFIXED); + + while (1) + { + if (action_userabort(HZ/10)) + return false; + + lcd_clear_display(); + + /* show internal variables of scrollwheel driver */ + snprintf(buf, sizeof(buf), "wheel touched: %s", (wheel_is_touched) ? "true" : "false"); + lcd_puts(0, 0, buf); + snprintf(buf, sizeof(buf), "new position: %2d", new_wheel_value); + lcd_puts(0, 1, buf); + snprintf(buf, sizeof(buf), "old position: %2d", old_wheel_value); + lcd_puts(0, 2, buf); + snprintf(buf, sizeof(buf), "wheel delta: %2d", wheel_delta); + lcd_puts(0, 3, buf); + snprintf(buf, sizeof(buf), "accumulated delta: %2d", accumulated_wheel_delta); + lcd_puts(0, 4, buf); + snprintf(buf, sizeof(buf), "velo [deg/s]: %4d", (int)wheel_velocity); + lcd_puts(0, 5, buf); + + /* show effective accelerated scrollspeed */ + speed = button_apply_acceleration( (1<<31)|(1<<24)|wheel_velocity); + snprintf(buf, sizeof(buf), "accel. speed: %4d", speed); + lcd_puts(0, 6, buf); + + lcd_update(); + } + return false; +} +#endif /****** The menu *********/ @@ -2269,6 +2380,9 @@ static const struct the_menu_item menuitems[] = { #if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440 { "View I/O ports", dbg_ports }, #endif +#if CONFIG_RTC == RTC_PCF50605 + { "View PCF registers", dbg_pcf }, +#endif #if defined(HAVE_TSC2100) && !defined(SIMULATOR) { "TSC2100 debug", tsc2100_debug }, #endif @@ -2327,6 +2441,9 @@ static const struct the_menu_item menuitems[] = { #endif #ifdef CPU_BOOST_LOGGING {"cpu_boost log",cpu_boost_log}, +#endif +#if (defined(HAVE_SCROLLWHEEL) && (CONFIG_KEYPAD==IPOD_4G_PAD) && !defined(SIMULATOR)) + {"Debug scrollwheel", dbg_scrollwheel}, #endif }; static int menu_action_callback(int btn, struct gui_synclist *lists) diff --git a/apps/main.c b/apps/main.c index 0ce8bcc7ac..92e7149fe8 100644 --- a/apps/main.c +++ b/apps/main.c @@ -351,6 +351,8 @@ static void init(void) settings_reset(); + i2c_init(); + power_init(); set_irq_level(0); @@ -374,8 +376,6 @@ static void init(void) #endif #endif - i2c_init(); - #if CONFIG_RTC rtc_init(); #endif diff --git a/firmware/drivers/audio/as3514.c b/firmware/drivers/audio/as3514.c index 2dc1513668..80ada46f80 100644 --- a/firmware/drivers/audio/as3514.c +++ b/firmware/drivers/audio/as3514.c @@ -146,11 +146,15 @@ void audiohw_init(void) DEV_RS |= DEV_I2S; DEV_RS &=~DEV_I2S; - /* device enable */ - DEV_EN |= (DEV_I2S | 0x7); + /* I2S device reset */ + DEV_RS |= DEV_I2S; + DEV_RS &=~DEV_I2S; + + /* I2S device enable */ + DEV_EN |= DEV_I2S; /* enable external dev clock clocks */ - DEV_EN |= 0x2; + DEV_EN |= DEV_EXTCLOCKS; /* external dev clock to 24MHz */ outl(inl(0x70000018) & ~0xc, 0x70000018); diff --git a/firmware/drivers/pcf50605.c b/firmware/drivers/pcf50605.c index d34e8512c1..afa0a5ca11 100644 --- a/firmware/drivers/pcf50605.c +++ b/firmware/drivers/pcf50605.c @@ -63,11 +63,20 @@ #define PSSC 0x18 #define PWROKM 0x19 #define PWROKS 0x1a +#define DCDC1 0x1b +#define DCDC2 0x1c +#define DCDC3 0x1d +#define DCDC4 0x1e +#define DCDEC1 0x1f +#define DCDEC2 0x20 +#define DCUDC1 0x21 +#define DCUDC2 0x22 +#define IOREGC 0x23 #define D1REGC1 0x24 - #define VOUT_3000mV 0xf5 - #define VOUT_3300mV 0xf8 #define D2REGC1 0x25 #define D3REGC1 0x26 +#define LPREG1C 0x27 + unsigned char pcf50605_wakeup_flags = 0; @@ -113,8 +122,30 @@ void pcf50605_standby_mode(void) void pcf50605_init(void) { - /* The following values were taken from the ipodlinux kernel source */ - pcf50605_write(D1REGC1, VOUT_3000mV); /* Unknown */ - pcf50605_write(D2REGC1, VOUT_3300mV); /* Dock Connector pin 17 */ - pcf50605_write(D3REGC1, VOUT_3000mV); /* Unknown */ +#if defined (IPOD_VIDEO) + /* I/O and GPO voltage supply (default: 0xf8 = 3.3V ON) */ + /* ECO not allowed regarding data sheet */ + pcf50605_write(IOREGC, 0xf8); /* 3.3V ON */ + + /* core voltage supply (default DCDC1/DCDC2: 0xec = 1.2V ON) */ + /* ECO not stable, assumed due to less precision of voltage in ECO mode */ + pcf50605_write(DCDC1, 0xec); /* 1.2V ON */ + pcf50605_write(DCDC2, 0x0c); /* OFF */ + + /* unknown (default: 0xe3 = 1.8V ON) */ + pcf50605_write(DCUDC1, 0xe3); /* 1.8V ON */ + + /* WM8758 voltage supply (default: 0xf5 = 3.0V ON) */ + /* ECO not allowed as max. current of 5mA is not sufficient */ + pcf50605_write(D1REGC1, 0xf0); /* 2.5V ON */ + + /* LCD voltage supply (default: 0xf5 = 3.0V ON) */ + pcf50605_write(D3REGC1, 0xf1); /* 2.6V ON */ +#else + /* keep initialization from svn for other iPods */ + pcf50605_write(D1REGC1, 0xf5); /* 3.0V ON */ + pcf50605_write(D3REGC1, 0xf5); /* 3.0V ON */ +#endif + /* Dock Connector pin 17 (default: OFF) */ + pcf50605_write(D2REGC1, 0xf8); /* 3.3V ON */ } diff --git a/firmware/export/config-c200.h b/firmware/export/config-c200.h index 53ff97326a..a0bb1aeb2c 100644 --- a/firmware/export/config-c200.h +++ b/firmware/export/config-c200.h @@ -113,9 +113,9 @@ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE -#define BATTERY_CAPACITY_DEFAULT 750 /* default battery capacity */ -#define BATTERY_CAPACITY_MIN 750 /* min. capacity selectable */ -#define BATTERY_CAPACITY_MAX 750 /* max. capacity selectable */ +#define BATTERY_CAPACITY_DEFAULT 530 /* default battery capacity */ +#define BATTERY_CAPACITY_MIN 530 /* min. capacity selectable */ +#define BATTERY_CAPACITY_MAX 530 /* max. capacity selectable */ #define BATTERY_CAPACITY_INC 0 /* capacity increment */ #define BATTERY_TYPES_COUNT 1 /* only one type */ diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h index 0666b5af37..56e14b3741 100644 --- a/firmware/export/powermgmt.h +++ b/firmware/export/powermgmt.h @@ -105,22 +105,26 @@ extern int trickle_sec; /* trickle charge: How many seconds per minute # define CURRENT_BACKLIGHT 23 /* FIXME: This needs to be measured, copied from H100 */ # define CURRENT_RECORD 110 /* additional current while recording */ #elif defined(IPOD_NANO) /* iPOD Nano */ -# define CURRENT_NORMAL 35 /* 8.5-9.0h playback out of 300mAh battery from IpodRuntime */ +# define CURRENT_NORMAL 32 /* MP3: ~9h playback out of 300mAh battery */ # define CURRENT_BACKLIGHT 20 /* FIXME: this needs adjusting */ #if defined(HAVE_RECORDING) # define CURRENT_RECORD 35 /* FIXME: this needs adjusting */ #endif #elif defined(IPOD_VIDEO) /* iPOD Video */ -# define CURRENT_NORMAL 42 /* 9.5h out of 400mAh battery (30GB) or 14h out of 600mAh (60GB) from IpodRuntime */ +# define CURRENT_NORMAL 35 /* MP3: ~11h out of 400mAh battery (30GB) or ~17h out of 600mAh (60GB) */ # define CURRENT_BACKLIGHT 20 /* FIXME: this needs adjusting */ #if defined(HAVE_RECORDING) # define CURRENT_RECORD 35 /* FIXME: this needs adjusting */ #endif -#elif defined(SANSA_E200) /* Sandisk players */ -# define CURRENT_NORMAL 50 /* Toni's measurements in spring 2007 suggests 50 ma during normal operation */ -# define CURRENT_BACKLIGHT 20 /* seems like a reasonible value for now */ -# define CURRENT_RECORD 35 /* FIXME: this needs adjusting */ -#else /* Not iriver H1x0, H3x0, nor Archos Ondio, nor iPODVideo, nor Sansas */ +#elif defined(SANSA_E200) /* Sandisk E200v1 */ +# define CURRENT_NORMAL 45 /* Mike's measurements in Jan 2008 */ +# define CURRENT_BACKLIGHT 40 /* Screen is about 20, blue LEDs are another 20, so 40 if both */ +# define CURRENT_RECORD 40 /* flash player, so this is just unboosted current*/ +#elif defined(SANSA_C200) /* Sandisk C200v1 */ +# define CURRENT_NORMAL 45 /* Should be nearly identical to E200 */ +# define CURRENT_BACKLIGHT 40 /* Screen is about 20, blue LEDs are another 20, so 40 if both */ +# define CURRENT_RECORD 40 /* flash player, so this is just unboosted current*/ +#else /* Not iriver H1x0, H3x0, nor Archos Ondio, nor iPod nano/Video, nor Sansas */ # define CURRENT_NORMAL 145 /* usual current in mA when using the AJB including some disk/backlight/... activity */ # define CURRENT_BACKLIGHT 30 /* additional current when backlight always on */ #if defined(HAVE_RECORDING) diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h index 845c89c616..0dcd7b362d 100644 --- a/firmware/export/pp5020.h +++ b/firmware/export/pp5020.h @@ -132,7 +132,9 @@ #define DEV_EN (*(volatile unsigned long *)(0x6000600c)) #define DEV_EN2 (*(volatile unsigned long *)(0x60006010)) +#define DEV_EXTCLOCKS 0x00000002 #define DEV_SYSTEM 0x00000004 +#define DEV_USB0 0x00000008 #define DEV_SER0 0x00000040 #define DEV_SER1 0x00000080 #define DEV_I2S 0x00000800 @@ -140,7 +142,8 @@ #define DEV_ATA 0x00004000 #define DEV_OPTO 0x00010000 #define DEV_PIEZO 0x00010000 -#define DEV_USB 0x00400000 +#define DEV_PWM 0x00020000 +#define DEV_USB1 0x00400000 #define DEV_FIREWIRE 0x00800000 #define DEV_IDE0 0x02000000 #define DEV_LCD 0x04000000 @@ -332,6 +335,8 @@ #define XMB_NOR_CFG (*(volatile unsigned long *)(0x70000038)) #define XMB_RAM_CFG (*(volatile unsigned long *)(0x7000003c)) +#define INIT_BUTTONS 0x00040000 +#define INIT_PLL 0x40000000 #define INIT_USB 0x80000000 /* 32 bit GPO port */ diff --git a/firmware/target/arm/adc-pp5020.c b/firmware/target/arm/adc-pp5020.c index 616ef04861..7ce5ac7011 100644 --- a/firmware/target/arm/adc-pp5020.c +++ b/firmware/target/arm/adc-pp5020.c @@ -119,6 +119,7 @@ void adc_init(void) ADC_ADDR |= 0x2000000; ADC_STATUS |= 0x2000; +#if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) /* Enable channel 2 (H10:remote) */ DEV_INIT1 &=~0x300; DEV_INIT1 |= 0x100; @@ -130,6 +131,7 @@ void adc_init(void) DEV_INIT1 |= 0x1000; ADC_ADDR |= 0x8000000; ADC_STATUS |= 0x20000000; +#endif /* Force a scan of all channels to get initial values */ adc_scan(0); diff --git a/firmware/target/arm/ipod/backlight-4g_color.c b/firmware/target/arm/ipod/backlight-4g_color.c index 982bfd53ac..4e46546ef6 100644 --- a/firmware/target/arm/ipod/backlight-4g_color.c +++ b/firmware/target/arm/ipod/backlight-4g_color.c @@ -53,7 +53,7 @@ bool _backlight_init(void) GPIOB_ENABLE |= 0x8; /* B03 enable */ GPO32_ENABLE |= 0x2000000; /* D01 enable */ GPO32_VAL |= 0x2000000; /* D01 =1 */ - DEV_EN |= 0x20000; /* PWM enable */ + DEV_EN |= DEV_PWM; /* PWM enable */ _backlight_on(); return true; diff --git a/firmware/target/arm/ipod/button-clickwheel.c b/firmware/target/arm/ipod/button-clickwheel.c index f01666a8b8..f8dd818a01 100644 --- a/firmware/target/arm/ipod/button-clickwheel.c +++ b/firmware/target/arm/ipod/button-clickwheel.c @@ -73,64 +73,40 @@ int int_btn = BUTTON_NONE; static void opto_i2c_init(void) { - int i, curr_value; - - /* wait for value to settle */ - i = 1000; - curr_value = (inl(0x7000c104) << 16) >> 24; - while (i > 0) - { - int new_value = (inl(0x7000c104) << 16) >> 24; - - if (new_value != curr_value) { - i = 10000; - curr_value = new_value; - } - else { - i--; - } - } - - GPIOB_OUTPUT_VAL |= 0x10; - DEV_EN |= 0x10000; - DEV_RS |= 0x10000; + DEV_EN |= DEV_OPTO; + DEV_RS |= DEV_OPTO; udelay(5); - DEV_RS &= ~0x10000; /* finish reset */ + DEV_RS &= ~DEV_OPTO; /* finish reset */ + DEV_INIT1 |= INIT_BUTTONS; /* enable buttons (needed for "hold"-detection) */ - outl(0xffffffff, 0x7000c120); - outl(0xffffffff, 0x7000c124); outl(0xc00a1f00, 0x7000c100); - outl(0x1000000, 0x7000c104); + outl(0x01000000, 0x7000c104); } static inline int ipod_4g_button_read(void) { int whl = -1; - - /* The ipodlinux source had a udelay(250) here, but testing has shown that - it is not needed - tested on Nano, Color/Photo and Video. */ - /* udelay(250);*/ - int btn = BUTTON_NONE; - unsigned reg = 0x7000c104; - if ((inl(0x7000c104) & 0x4000000) != 0) + + /* The following delay was 250 in the ipodlinux source, but 50 seems to + work fine - tested on Nano, Color/Photo and Video. */ + udelay(50); + + if ((inl(0x7000c104) & 0x04000000) != 0) { unsigned status = inl(0x7000c140); - reg = reg + 0x3C; /* 0x7000c140 */ - outl(0x0, 0x7000c140); /* clear interrupt status? */ - if ((status & 0x800000ff) == 0x8000001a) { - if (status & 0x100) + if (status & 0x00000100) btn |= BUTTON_SELECT; - if (status & 0x200) + if (status & 0x00000200) btn |= BUTTON_RIGHT; - if (status & 0x400) + if (status & 0x00000400) btn |= BUTTON_LEFT; - if (status & 0x800) + if (status & 0x00000800) btn |= BUTTON_PLAY; - if (status & 0x1000) + if (status & 0x00001000) btn |= BUTTON_MENU; if (status & 0x40000000) { @@ -263,19 +239,10 @@ static inline int ipod_4g_button_read(void) } } - else if (status == 0xffffffff) - { - opto_i2c_init(); - } } - if ((inl(reg) & 0x8000000) != 0) - { - outl(0xffffffff, 0x7000c120); - outl(0xffffffff, 0x7000c124); - } - /* Save the new absolute wheel position */ #ifdef HAVE_WHEEL_POSITION + /* Save the new absolute wheel position */ wheel_position = whl; #endif return btn; @@ -296,16 +263,12 @@ void wheel_send_events(bool send) void ipod_4g_button_int(void) { CPU_HI_INT_CLR = I2C_MASK; - /* The following delay was 250 in the ipodlinux source, but 50 seems to - work fine - tested on Nano, Color/Photo and Video. */ - udelay(50); - outl(0x0, 0x7000c140); + int_btn = ipod_4g_button_read(); - outl(inl(0x7000c104) | 0xC000000, 0x7000c104); + + outl(inl(0x7000c104) | 0x0c000000, 0x7000c104); outl(0x400a1f00, 0x7000c100); - GPIOB_OUTPUT_VAL |= 0x10; - CPU_INT_EN = 0x40000000; CPU_HI_INT_EN = I2C_MASK; } @@ -317,15 +280,8 @@ void button_init_device(void) GPIOA_ENABLE |= 0x20; GPIOA_OUTPUT_EN &= ~0x20; - /* hold button - set interrupt levels */ - GPIOA_INT_LEV = ~(GPIOA_INPUT_VAL & 0x20); - GPIOA_INT_CLR = GPIOA_INT_STAT & 0x20; - - /* enable interrupts */ - GPIOA_INT_EN = 0x20; - /* unmask interrupt */ - CPU_INT_EN = 0x40000000; + CPU_INT_EN = HI_MASK; CPU_HI_INT_EN = I2C_MASK; } @@ -342,7 +298,20 @@ int button_read_device(void) hold_button = button_hold(); if (hold_button != hold_button_old) + { backlight_hold_changed(hold_button); + + if (hold_button) + { + /* lock -> disable wheel sensor */ + DEV_EN &= ~DEV_OPTO; + } + else + { + /* unlock -> enable wheel sensor */ + DEV_EN |= DEV_OPTO; + } + } /* The int_btn variable is set in the button interrupt handler */ return int_btn; diff --git a/firmware/target/arm/ipod/power-ipod.c b/firmware/target/arm/ipod/power-ipod.c index 4c6f6a8db5..475e55c732 100644 --- a/firmware/target/arm/ipod/power-ipod.c +++ b/firmware/target/arm/ipod/power-ipod.c @@ -70,14 +70,26 @@ void ide_power_enable(bool on) #elif defined(IPOD_4G) || defined(IPOD_COLOR) \ || defined(IPOD_MINI) || defined(IPOD_MINI2G) if (on) + { GPIO_CLEAR_BITWISE(GPIOJ_OUTPUT_VAL, 0x04); + DEV_EN |= DEV_IDE0; + } else + { + DEV_EN &= ~DEV_IDE0; GPIO_SET_BITWISE(GPIOJ_OUTPUT_VAL, 0x04); + } #elif defined(IPOD_VIDEO) if (on) + { GPO32_VAL &= ~0x40000000; + DEV_EN |= DEV_IDE0; + } else + { + DEV_EN &= ~DEV_IDE0; GPO32_VAL |= 0x40000000; + } #else /* Nano */ (void)on; /* Do nothing. */ #endif diff --git a/firmware/target/arm/ipod/powermgmt-ipod-pcf.c b/firmware/target/arm/ipod/powermgmt-ipod-pcf.c index d2f88a20f2..aaf4fabf52 100644 --- a/firmware/target/arm/ipod/powermgmt-ipod-pcf.c +++ b/firmware/target/arm/ipod/powermgmt-ipod-pcf.c @@ -27,7 +27,7 @@ const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = #ifdef IPOD_NANO 3330 #elif defined IPOD_VIDEO - 3450 + 3300 #else /* FIXME: calibrate value for other 3G+ ipods */ 3380 @@ -39,7 +39,7 @@ const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = #ifdef IPOD_NANO 3230 #elif defined IPOD_VIDEO - 3450 + 3300 #else /* FIXME: calibrate value for other 3G+ ipods */ 3020 diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c index 4ca58208ad..0b5e9e1c13 100644 --- a/firmware/target/arm/system-pp502x.c +++ b/firmware/target/arm/system-pp502x.c @@ -161,97 +161,118 @@ void set_cpu_frequency(long frequency) #else static void pp_set_cpu_frequency(long frequency) #endif -{ +{ #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) spinlock_lock(&boostctrl_spin); #endif - scale_suspend_core(true); - - cpu_frequency = frequency; - switch (frequency) { - /* Note: The PP5022 PLL must be run at >= 96MHz + /* Note1: The PP5022 PLL must be run at >= 96MHz * Bits 20..21 select the post divider (1/2/4/8). * PP5026 is similar to PP5022 except it doesn't - * have this limitation (and the post divider?) */ - case CPUFREQ_MAX: - CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */ - DEV_TIMING1 = 0x00000303; -#ifdef IPOD_NANO - IDE0_CFG |= (0x10000000); /* Set CPU > 65MHz bit */ -#endif -#ifdef IPOD_MINI2G - MLCD_SCLK_DIV = 0x00000001; /* Mono LCD bridge serial clock divider */ -#endif -#if CONFIG_CPU == PP5020 - PLL_CONTROL = 0x8a020a03; /* 10/3 * 24MHz */ - PLL_STATUS = 0xd19b; /* unlock frequencies > 66MHz */ - PLL_CONTROL = 0x8a020a03; /* repeat setup */ - scale_suspend_core(false); - udelay(500); /* wait for relock */ -#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) - PLL_CONTROL = 0x8a121403; /* (20/3 * 24MHz) / 2 */ - scale_suspend_core(false); - udelay(250); - while (!(PLL_STATUS & 0x80000000)); /* wait for relock */ -#endif - scale_suspend_core(true); - break; - - case CPUFREQ_NORMAL: - CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */ - DEV_TIMING1 = 0x00000303; -#ifdef IPOD_NANO - IDE0_CFG &=~(0x10000000); /* clear > 65MHz bit */ -#endif -#ifdef IPOD_MINI2G - MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */ -#endif -#if CONFIG_CPU == PP5020 - PLL_CONTROL = 0x8a020504; /* 5/4 * 24MHz */ - scale_suspend_core(false); - udelay(500); /* wait for relock */ -#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) - PLL_CONTROL = 0x8a220501; /* (5/1 * 24MHz) / 4 */ - scale_suspend_core(false); - udelay(250); - while (!(PLL_STATUS & 0x80000000)); /* wait for relock */ -#endif - scale_suspend_core(true); - break; - + * have this limitation (and the post divider?) + * Note2: CLOCK_SOURCE is set via 0=32kHz, 1=16MHz, + * 2=24MHz, 3=33MHz, 4=48MHz, 5=SLOW, 6=FAST, 7=PLL. + * SLOW = 24MHz / (DIV_SLOW + 1), DIV = Bits 16-19 + * FAST = PLL / (DIV_FAST + 1), DIV = Bits 20-23 */ case CPUFREQ_SLEEP: - CLOCK_SOURCE = 0x10002202; /* source #2: 32kHz, #1, #3, #4: 24MHz */ - PLL_CONTROL &= ~0x80000000; /* disable PLL */ - scale_suspend_core(false); - udelay(10000); /* let 32kHz source stabilize? */ + cpu_frequency = CPUFREQ_SLEEP; + PLL_CONTROL |= 0x0c000000; scale_suspend_core(true); + CLOCK_SOURCE = 0x20000000; /* source #1, #2, #3, #4: 32kHz (#2 active) */ + scale_suspend_core(false); + PLL_CONTROL &= ~0x80000000; /* disable PLL */ + DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */ break; - + + case CPUFREQ_MAX: + cpu_frequency = CPUFREQ_MAX; + DEV_INIT2 |= INIT_PLL; /* enable PLL power */ + PLL_CONTROL |= 0x88000000; /* enable PLL */ + scale_suspend_core(true); + CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */ + DEV_TIMING1 = 0x00000303; + scale_suspend_core(false); +#if defined(IPOD_MINI2G) + MLCD_SCLK_DIV = 0x00000001; /* Mono LCD bridge serial clock divider */ +#elif defined(IPOD_NANO) + IDE0_CFG |= 0x10000000; /* set ">65MHz" bit */ +#endif +#if CONFIG_CPU == PP5020 + PLL_CONTROL = 0x8a020a03; /* 80 MHz = 10/3 * 24MHz */ + PLL_STATUS = 0xd19b; /* unlock frequencies > 66MHz */ + PLL_CONTROL = 0x8a020a03; /* repeat setup */ + udelay(500); /* wait for relock */ +#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) + PLL_CONTROL = 0x8a121403; /* 80 MHz = (20/3 * 24MHz) / 2 */ + while (!(PLL_STATUS & 0x80000000)); /* wait for relock */ +#endif + scale_suspend_core(true); + DEV_TIMING1 = 0x00000808; + CLOCK_SOURCE = 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */ + scale_suspend_core(false); + break; +#if 0 /******** CPUFREQ_NORMAL = 24MHz without PLL ********/ + case CPUFREQ_NORMAL: + cpu_frequency = CPUFREQ_NORMAL; + PLL_CONTROL |= 0x08000000; + scale_suspend_core(true); + CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */ + DEV_TIMING1 = 0x00000303; +#if defined(IPOD_MINI2G) + MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */ +#elif defined(IPOD_NANO) + IDE0_CFG &= ~0x10000000; /* clear ">65MHz" bit */ +#endif + scale_suspend_core(false); + PLL_CONTROL &= ~0x80000000; /* disable PLL */ + DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */ + break; +#else /******** CPUFREQ_NORMAL = 30MHz with PLL ********/ + case CPUFREQ_NORMAL: + cpu_frequency = CPUFREQ_NORMAL; + DEV_INIT2 |= INIT_PLL; /* enable PLL power */ + PLL_CONTROL |= 0x88000000; /* enable PLL */ + scale_suspend_core(true); + CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */ + DEV_TIMING1 = 0x00000303; + scale_suspend_core(false); +#if defined(IPOD_MINI2G) + MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */ +#elif defined(IPOD_NANO) + IDE0_CFG &= ~0x10000000; /* clear ">65MHz" bit */ +#endif +#if CONFIG_CPU == PP5020 + PLL_CONTROL = 0x8a020504; /* 30 MHz = 5/4 * 24MHz */ + udelay(500); /* wait for relock */ +#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) + PLL_CONTROL = 0x8a220501; /* 30 MHz = (5/1 * 24MHz) / 4 */ + while (!(PLL_STATUS & 0x80000000)); /* wait for relock */ +#endif + scale_suspend_core(true); + DEV_TIMING1 = 0x00000808; + CLOCK_SOURCE = 0x20007777; /* source #1, #2, #3, #4: PLL (#2 active) */ + scale_suspend_core(false); + break; +#endif /******** CPUFREQ_NORMAL end ********/ default: - CLOCK_SOURCE = 0x10002222; /* source #1, #2, #3, #4: 24MHz */ - DEV_TIMING1 = 0x00000303; -#ifdef IPOD_MINI2G - MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */ + cpu_frequency = CPUFREQ_DEFAULT; + PLL_CONTROL |= 0x08000000; + scale_suspend_core(true); + CLOCK_SOURCE = 0x20002222; /* source #1, #2, #3, #4: 24MHz (#2 active) */ + DEV_TIMING1 = 0x00000303; +#if defined(IPOD_MINI2G) + MLCD_SCLK_DIV = 0x00000000; /* Mono LCD bridge serial clock divider */ +#elif defined(IPOD_NANO) + IDE0_CFG &= ~0x10000000; /* clear ">65MHz" bit */ #endif -#ifdef IPOD_NANO - IDE0_CFG &=~(0x10000000); /* clear > 65MHz bit */ -#endif - PLL_CONTROL &= ~0x80000000; /* disable PLL */ - cpu_frequency = CPUFREQ_DEFAULT; - PROC_CTL(CURRENT_CORE) = 0x4800001f; nop; + scale_suspend_core(false); + PLL_CONTROL &= ~0x80000000; /* disable PLL */ + DEV_INIT2 &= ~INIT_PLL; /* disable PLL power */ break; } - - if (frequency == CPUFREQ_MAX) - DEV_TIMING1 = 0x00000808; - - CLOCK_SOURCE = (CLOCK_SOURCE & ~0xf0000000) | 0x20000000; /* select source #2 */ - - scale_suspend_core(false); - + #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) spinlock_unlock(&boostctrl_spin); #endif @@ -263,19 +284,84 @@ void system_init(void) #ifndef BOOTLOADER if (CURRENT_CORE == CPU) { -#if defined(SANSA_E200) || defined(SANSA_C200) - /* Reset all devices */ - DEV_RS2 |= 0x20; - DEV_RS = 0x3bfffef8; - DEV_RS2 = -1; - DEV_RS = 0; - DEV_RS2 = 0; -#elif defined (IRIVER_H10) || defined(MROBE_100) - DEV_RS = 0x3ffffef8; - DEV_RS2 = -1; - DEV_RS = 0; - DEV_RS2 = 0; - outl(inl(0x70000024) | 0xc0, 0x70000024); +#if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(IPOD_COLOR) + /* set minimum startup configuration */ + DEV_EN = 0xc2000124; + DEV_EN2 = 0x00002000; + CACHE_PRIORITY = 0x0000003f; + GPO32_VAL = 0x20000000; + DEV_INIT1 = 0xdc000000; + DEV_INIT2 = 0x40000000; + + /* reset all allowed devices */ + DEV_RS = 0x3ffffef8; + DEV_RS2 = 0xffffdfff; + DEV_RS = 0x00000000; + DEV_RS2 = 0x00000000; +#elif defined (IPOD_VIDEO) + /* set minimum startup configuration */ + DEV_EN = 0xc2000124; + DEV_EN2 = 0x00000000; + CACHE_PRIORITY = 0x0000003f; + GPO32_VAL = 0x00004000; + DEV_INIT1 = 0x00000000; + DEV_INIT2 = 0x40000000; + + /* reset all allowed devices */ + DEV_RS = 0x3ffffef8; + DEV_RS2 = 0xffffffff; + DEV_RS = 0x00000000; + DEV_RS2 = 0x00000000; +#elif defined (IPOD_NANO) + /* set minimum startup configuration */ + DEV_EN = 0xc2000124; + DEV_EN2 = 0x00002000; + CACHE_PRIORITY = 0x0000003f; + GPO32_VAL = 0x50000000; + DEV_INIT1 = 0xa8000000; + DEV_INIT2 = 0x40000000; + + /* reset all allowed devices */ + DEV_RS = 0x3ffffef8; + DEV_RS2 = 0xffffdfff; + DEV_RS = 0x00000000; + DEV_RS2 = 0x00000000; +#elif defined(SANSA_C200) || defined (SANSA_E200) + /* set minimum startup configuration */ + DEV_EN = 0xc4000124; + DEV_EN2 = 0x00000000; + CACHE_PRIORITY = 0x0000003f; + GPO32_VAL = 0x10000000; + DEV_INIT1 = 0x54000000; + DEV_INIT2 = 0x40000000; + + /* reset all allowed devices */ + DEV_RS = 0x3bfffef8; + DEV_RS2 = 0xffffffff; + DEV_RS = 0x00000000; + DEV_RS2 = 0x00000000; +#elif defined(IPOD_4G) + /* set minimum startup configuration */ + DEV_EN = 0xc2020124; + DEV_EN2 = 0x00000000; + CACHE_PRIORITY = 0x0000003f; + GPO32_VAL = 0x02000000; + DEV_INIT1 = 0x00000000; + DEV_INIT2 = 0x40000000; + + /* reset all allowed devices */ + DEV_RS = 0x3ffdfef8; + DEV_RS2 = 0xffffffff; + DEV_RS = 0x00000000; + DEV_RS2 = 0x00000000; +#elif defined (IPOD_MINI) + /* to be done */ +#elif defined (IPOD_MINI2G) + /* to be done */ +#elif defined (MROBE_100) + /* to be done */ +#elif defined (ELIO_TPJ1022) + /* to be done */ #endif #if !defined(SANSA_E200) && !defined(SANSA_C200) @@ -314,8 +400,6 @@ void system_init(void) outl(inl(0x6000a000) | 0x80000000, 0x6000a000); /* Init DMA controller? */ #endif - DEV_INIT2 |= 1 << 30; /* enable PLL power */ - #ifdef HAVE_ADJUSTABLE_CPU_FREQ #if NUM_CORES > 1 cpu_boost_init(); diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c index 7af699c064..0813ae1c59 100644 --- a/firmware/target/arm/usb-fw-pp502x.c +++ b/firmware/target/arm/usb-fw-pp502x.c @@ -33,18 +33,29 @@ void usb_init_device(void) { /* enable usb module */ - GPO32_ENABLE |= 0x200; - outl(inl(0x7000002C) | 0x3000000, 0x7000002C); - DEV_EN |= DEV_USB; + DEV_EN |= DEV_USB0; + DEV_EN |= DEV_USB1; - DEV_RS |= DEV_USB; /* reset usb start */ - DEV_RS &=~DEV_USB;/* reset usb end */ + /* reset both USBs */ + DEV_RS |= DEV_USB0; + DEV_RS &=~DEV_USB0; + DEV_RS |= DEV_USB1; + DEV_RS &=~DEV_USB1; +#if CONFIG_CPU == PP5020 DEV_INIT2 |= INIT_USB; +#endif while ((inl(0x70000028) & 0x80) == 0); outl(inl(0x70000028) | 0x2, 0x70000028); udelay(0x186A0); + + /* disable USB-devices until USB is detected via GPIO */ + DEV_EN &= ~DEV_USB0; + DEV_EN &= ~DEV_USB1; +#if CONFIG_CPU == PP5020 + DEV_INIT2 &= ~INIT_USB; +#endif #if defined(IPOD_COLOR) || defined(IPOD_4G) \ || defined(IPOD_MINI) || defined(IPOD_MINI2G) @@ -85,33 +96,46 @@ void usb_enable(bool on) static bool usb_pin_detect(void) { + bool retval = false; + #if defined(IPOD_4G) || defined(IPOD_COLOR) \ || defined(IPOD_MINI) || defined(IPOD_MINI2G) /* GPIO D bit 3 is usb detect */ if (GPIOD_INPUT_VAL & 0x08) - return true; + retval = true; #elif defined(IPOD_NANO) || defined(IPOD_VIDEO) /* GPIO L bit 4 is usb detect */ if (GPIOL_INPUT_VAL & 0x10) - return true; + retval = true; #elif defined(SANSA_C200) /* GPIO H bit 1 is usb detect */ if (GPIOH_INPUT_VAL & 0x02) - return true; + retval = true; #elif defined(SANSA_E200) /* GPIO B bit 4 is usb detect */ if (GPIOB_INPUT_VAL & 0x10) - return true; + retval = true; #elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) /* GPIO L bit 2 is usb detect */ if (GPIOL_INPUT_VAL & 0x4) - return true; + retval = true; #endif - return false; + + /* if USB is detected, re-enable the USB-devices */ + if (retval) + { + DEV_EN |= DEV_USB0; + DEV_EN |= DEV_USB1; +#if CONFIG_CPU == PP5020 + DEV_INIT2 |= INIT_USB; +#endif + } + + return retval; } /* detect host or charger (INSERTED or POWERED) */ diff --git a/firmware/target/arm/wmcodec-pp.c b/firmware/target/arm/wmcodec-pp.c index c9e034a188..3bd9d7fd2b 100644 --- a/firmware/target/arm/wmcodec-pp.c +++ b/firmware/target/arm/wmcodec-pp.c @@ -52,15 +52,15 @@ void audiohw_init(void) { DEV_INIT1 &=~0x3000000; /*mini2?*/ - /* device reset */ + /* I2S device reset */ DEV_RS |= DEV_I2S; DEV_RS &=~DEV_I2S; - /* device enable */ - DEV_EN |= (DEV_I2S | 0x7); + /* I2S device enable */ + DEV_EN |= DEV_I2S; /* enable external dev clock clocks */ - DEV_EN |= 0x2; + DEV_EN |= DEV_EXTCLOCKS; /* external dev clock to 24MHz */ outl(inl(0x70000018) & ~0xc, 0x70000018);