From 338d94f4661643dcd4c6440aa1c12af6933da4a5 Mon Sep 17 00:00:00 2001 From: Steve Bavin Date: Thu, 1 Feb 2007 10:47:22 +0000 Subject: FS#4770 - Add USB charging for the H300 series git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12169 a1c6a512-1295-4272-9138-f99709370657 --- apps/debug_menu.c | 21 ++++++++++++ apps/gui/statusbar.c | 4 +-- apps/gui/statusbar.h | 2 +- apps/lang/deutsch.lang | 14 ++++++++ apps/lang/english.lang | 14 ++++++++ apps/settings.h | 6 ++++ apps/settings_list.c | 6 +++- apps/settings_menu.c | 27 +++++++++++++++ firmware/export/pcf50606.h | 5 +++ firmware/export/usb.h | 4 +++ firmware/powermgmt.c | 5 ++- .../target/coldfire/iriver/h300/pcf50606-h300.c | 26 +++++++++++++++ firmware/usb.c | 38 ++++++++++++++++++++++ 13 files changed, 167 insertions(+), 5 deletions(-) diff --git a/apps/debug_menu.c b/apps/debug_menu.c index c5240d0de8..99c00fa1eb 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -78,6 +78,9 @@ #include "spdif.h" #endif #endif +#ifdef IRIVER_H300_SERIES +#include "pcf50606.h" /* for pcf50606_read */ +#endif #ifdef IAUDIO_X5 #include "lcd-remote-target.h" @@ -1059,6 +1062,16 @@ bool dbg_ports(void) lcd_puts(0, line++, buf); snprintf(buf, sizeof(buf), "GPIO1_ENABLE: %08x", gpio1_enable); lcd_puts(0, line++, buf); +#if defined(IRIVER_H300_SERIES) + snprintf(buf, sizeof(buf), "GPOOD0: %08x", (unsigned int)pcf50606_read(0x37)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPOOD1: %08x", (unsigned int)pcf50606_read(0x38)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPOOD2: %08x", (unsigned int)pcf50606_read(0x39)); + lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPOOD3: %08x", (unsigned int)pcf50606_read(0x3A)); + lcd_puts(0, line++, buf); +#endif adc_buttons = adc_read(ADC_BUTTONS); adc_remote = adc_read(ADC_REMOTE); @@ -1422,6 +1435,14 @@ static bool view_battery(void) snprintf(buf, 30, "long delta: %d", long_delta); lcd_puts(0, 6, buf); lcd_puts(0, 7, power_message); + snprintf(buf, 30, "USB Inserted: %s", + usb_inserted() ? "yes" : "no"); + lcd_puts(0, 8, buf); +#if defined IRIVER_H300_SERIES + snprintf(buf, 30, "USB Charging Enabled: %s", + usb_charging_enabled() ? "yes" : "no"); + lcd_puts(0, 9, buf); +#endif #else /* CONFIG_CHARGING != CHARGING_CONTROL */ #if defined IPOD_NANO || defined IPOD_VIDEO int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false; diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c index ae8bba0538..2f6dfafc81 100644 --- a/apps/gui/statusbar.c +++ b/apps/gui/statusbar.c @@ -143,7 +143,7 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw) bar->info.battlevel = battery_level(); #ifdef HAVE_USB_POWER - bar->info.usb_power = usb_powered(); + bar->info.usb_inserted = usb_inserted(); #endif #ifdef CONFIG_CHARGING bar->info.inserted = (charger_input_state == CHARGER); @@ -238,7 +238,7 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw) gui_statusbar_icon_battery(display, bar->info.battlevel, bar->info.batt_charge_step); #ifdef HAVE_USB_POWER - if (bar->info.usb_power) + if (bar->info.usb_inserted) display->mono_bitmap(bitmap_icons_7x8[Icon_USBPlug], STATUSBAR_PLUG_X_POS, STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH, diff --git a/apps/gui/statusbar.h b/apps/gui/statusbar.h index 5ab97d09ea..516598dd00 100644 --- a/apps/gui/statusbar.h +++ b/apps/gui/statusbar.h @@ -44,7 +44,7 @@ struct status_info { bool inserted; #endif #ifdef HAVE_USB_POWER - bool usb_power; + bool usb_inserted; #endif bool battery_state; bool shuffle; diff --git a/apps/lang/deutsch.lang b/apps/lang/deutsch.lang index d9481b9dca..4ae438f64d 100644 --- a/apps/lang/deutsch.lang +++ b/apps/lang/deutsch.lang @@ -3569,6 +3569,20 @@ *: "Batterieanzeige" + + id: LANG_USB_CHARGING + desc: in Battery menu + user: + + *: "Charge During USB Connection" + + + *: "Laden bei USB-Verbindung" + + + *: "Laden bei U S B Verbindung" + + id: LANG_DISPLAY_GRAPHIC desc: Label for type of icon display diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 3f1fb11b35..e9c9f4c50c 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -3610,6 +3610,20 @@ *: "Battery Display" + + id: LANG_USB_CHARGING + desc: in Battery menu + user: + + *: "Charge During USB Connection" + + + *: "Charge During USB Connection" + + + *: "Charge During U S B Connection" + + id: LANG_DISPLAY_GRAPHIC desc: Label for type of icon display diff --git a/apps/settings.h b/apps/settings.h index 7b7f91abe0..e8db3289a1 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -611,6 +611,12 @@ struct user_settings unsigned char kbd_file[MAX_FILENAME+1]; /* last keyboard */ #endif +#ifdef HAVE_USB_POWER +#ifdef CONFIG_CHARGING + bool usb_charging; +#endif +#endif + #ifdef HAVE_WM8758 bool eq_hw_enabled; /* Enable hardware equalizer */ diff --git a/apps/settings_list.c b/apps/settings_list.c index a0651be4f3..6243607264 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -690,7 +690,11 @@ const struct settings_list settings[] = { #ifdef HAVE_LCD_BITMAP FILENAME_SETTING(0,kbd_file,"kbd","",ROCKBOX_DIR "/",".kbd",MAX_FILENAME+1), #endif - +#ifdef HAVE_USB_POWER +#ifdef CONFIG_CHARGING + OFFON_SETTING(0,usb_charging,LANG_USB_CHARGING,false,"usb charging",NULL), +#endif +#endif }; const int nb_settings = sizeof(settings)/sizeof(*settings); diff --git a/apps/settings_menu.c b/apps/settings_menu.c index 0b599ca0c6..b1204e2c1a 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -405,6 +405,12 @@ static bool clear_main_backdrop(void) } #endif +#ifdef HAVE_USB_POWER +#ifdef CONFIG_CHARGING +#include "usb.h" +#endif +#endif + #ifdef HAVE_LCD_COLOR /** * Menu for fore/back colors @@ -444,6 +450,22 @@ static bool reset_color(void) } #endif +#ifdef HAVE_USB_POWER +#ifdef CONFIG_CHARGING +/** + * Menu to switch the USB charging on or off + */ +static bool usb_charging(void) +{ + bool rc = set_bool(str(LANG_USB_CHARGING), + &global_settings.usb_charging); + /* if (usb_charging_enabled() != global_settings.usb_charging) */ + usb_charging_enable(global_settings.usb_charging); + return rc; +} +#endif +#endif + /** * Menu to configure the battery display on status bar */ @@ -2083,6 +2105,11 @@ static bool battery_settings_menu(void) #if BATTERY_TYPES_COUNT > 1 { ID2P(LANG_BATTERY_TYPE), battery_type }, #endif +#ifdef HAVE_USB_POWER +#ifdef CONFIG_CHARGING + { ID2P(LANG_USB_CHARGING), usb_charging }, +#endif +#endif #else { "Dummy", NULL }, /* to have an entry at all, in the simulator */ #endif diff --git a/firmware/export/pcf50606.h b/firmware/export/pcf50606.h index 1f4b6ba3ad..f01df520cf 100644 --- a/firmware/export/pcf50606.h +++ b/firmware/export/pcf50606.h @@ -24,6 +24,8 @@ int pcf50606_write_multiple(int address, const unsigned char* buf, int count); int pcf50606_write(int address, unsigned char val); int pcf50606_read_multiple(int address, unsigned char* buf, int count); int pcf50606_read(int address); +void pcf50606_set_usb_charging(bool on); +bool pcf50606_usb_charging_enabled(void); /* internal low level calls used by the eeprom driver for h300 */ void pcf50606_i2c_init(void); @@ -32,8 +34,11 @@ void pcf50606_i2c_start(void); void pcf50606_i2c_stop(void); void pcf50606_i2c_ack(bool ack); bool pcf50606_i2c_getack(void); +#if defined(IRIVER_H300_SERIES) +/* USB charging support */ void pcf50606_i2c_outb(unsigned char byte); unsigned char pcf50606_i2c_inb(bool ack); +#endif #if defined(IAUDIO_X5) && !defined(SIMULATOR) void pcf50606_reset_timeout(void); diff --git a/firmware/export/usb.h b/firmware/export/usb.h index b16c11a9b8..622db35543 100644 --- a/firmware/export/usb.h +++ b/firmware/export/usb.h @@ -31,6 +31,10 @@ bool usb_inserted(void); /* return the official value, what's been reported to t bool usb_detect(void); /* return the raw hardware value */ #ifdef HAVE_USB_POWER bool usb_powered(void); +#ifdef CONFIG_CHARGING +bool usb_charging_enable(bool on); +bool usb_charging_enabled(void); +#endif #endif #endif diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 5c7607413c..1b160af232 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -759,8 +759,11 @@ static void power_thread_sleep(int ticks) * transition to the appropriate steady state charger on/off state. */ if(charger_inserted() -#ifdef HAVE_USB_POWER +#ifdef HAVE_USB_POWER /* USB powered or USB inserted both provide power */ || usb_powered() +#ifdef CONFIG_CHARGING + || (usb_inserted() && usb_charging_enabled()) +#endif #endif ) { switch(charger_input_state) { diff --git a/firmware/target/coldfire/iriver/h300/pcf50606-h300.c b/firmware/target/coldfire/iriver/h300/pcf50606-h300.c index 3a67d541d3..7d101f7347 100644 --- a/firmware/target/coldfire/iriver/h300/pcf50606-h300.c +++ b/firmware/target/coldfire/iriver/h300/pcf50606-h300.c @@ -21,6 +21,9 @@ #include "kernel.h" #include "pcf50606.h" #include "button-target.h" +#include "logf.h" + +static bool usb_ch_enabled = false; /* These voltages were determined by measuring the output of the PCF50606 on a running H300, and verified by disassembling the original firmware */ @@ -70,6 +73,27 @@ static inline void enable_pmu_interrupts(void) or_l(0x03000000, &INTPRI5); /* INT38 - Priority 3 */ } +/* enables/disables USB charging + * ATTENTION: make sure to set the irq level + * to highest before calling this function! */ +void pcf50606_set_usb_charging(bool on) +{ + if (on) + pcf50606_write(0x39, 0x00); /* Set GPOOD2 to High-Z for USB Charge Enable */ + else + pcf50606_write(0x39, 0x07); /* Set GPOOD2 to pulled down to disable USB charging */ + + usb_ch_enabled = on; + + logf("pcf50606_set_usb_charging(%s)\n", on ? "on" : "off" ); +} + +bool pcf50606_usb_charging_enabled(void) +{ + /* TODO: read the state of the GPOOD2 register... */ + return usb_ch_enabled; +} + void pcf50606_init(void) { pcf50606_i2c_init(); @@ -82,6 +106,8 @@ void pcf50606_init(void) pcf50606_write(0x09, 0x05); /* USB and ON key debounce: 14ms */ pcf50606_write(0x29, 0x1C); /* Disable the unused MBC module */ + pcf50606_set_usb_charging(false); /* Disable USB charging atm. */ + pcf50606_write(0x35, 0x13); /* Backlight PWM = 512Hz 50/50 */ pcf50606_write(0x3a, 0x3b); /* PWM output on GPOOD1 */ diff --git a/firmware/usb.c b/firmware/usb.c index 651c17a4b3..0a329ad624 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -44,6 +44,10 @@ #ifdef TARGET_TREE #include "usb-target.h" #endif +#ifdef IRIVER_H300_SERIES +#include "pcf50606.h" /* for pcf50606_usb_charging_... */ +#endif +#include "logf.h" extern void dbg_ports(void); /* NASTY! defined in apps/ */ @@ -487,6 +491,40 @@ bool usb_powered(void) { return usb_state == USB_POWERED; } + +#ifdef CONFIG_CHARGING +bool usb_charging_enable(bool on) +{ + bool rc = false; +#ifdef IRIVER_H300_SERIES + int irqlevel; + logf("usb_charging_enable(%s)\n", on ? "on" : "off" ); + irqlevel = set_irq_level(HIGHEST_IRQ_LEVEL); + pcf50606_set_usb_charging(on); + rc = on; + (void)set_irq_level(irqlevel); +#else + /* TODO: implement it for other targets... */ + (void)on; +#endif + return rc; +} + +bool usb_charging_enabled(void) +{ + bool rc = false; +#ifdef IRIVER_H300_SERIES + /* TODO: read the state of the GPOOD2 register... + * (this also means to set the irq level here) */ + rc = pcf50606_usb_charging_enabled(); +#else + /* TODO: implement it for other targets... */ +#endif + + logf("usb_charging_enabled: %s\n", rc ? "true" : "false" ); + return rc; +} +#endif #endif #else -- cgit v1.2.3