FS#4770 - Add USB charging for the H300 series

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12169 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Steve Bavin 2007-02-01 10:47:22 +00:00
parent 73ee2379c5
commit 338d94f466
13 changed files with 167 additions and 5 deletions

View file

@ -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;

View file

@ -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,

View file

@ -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;

View file

@ -3569,6 +3569,20 @@
*: "Batterieanzeige"
</voice>
</phrase>
<phrase>
id: LANG_USB_CHARGING
desc: in Battery menu
user:
<source>
*: "Charge During USB Connection"
</source>
<dest>
*: "Laden bei USB-Verbindung"
</dest>
<voice>
*: "Laden bei U S B Verbindung"
</voice>
</phrase>
<phrase>
id: LANG_DISPLAY_GRAPHIC
desc: Label for type of icon display

View file

@ -3610,6 +3610,20 @@
*: "Battery Display"
</voice>
</phrase>
<phrase>
id: LANG_USB_CHARGING
desc: in Battery menu
user:
<source>
*: "Charge During USB Connection"
</source>
<dest>
*: "Charge During USB Connection"
</dest>
<voice>
*: "Charge During U S B Connection"
</voice>
</phrase>
<phrase>
id: LANG_DISPLAY_GRAPHIC
desc: Label for type of icon display

View file

@ -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 */

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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) {

View file

@ -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 */

View file

@ -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