summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/debug_menu.c21
-rw-r--r--apps/gui/statusbar.c4
-rw-r--r--apps/gui/statusbar.h2
-rw-r--r--apps/lang/deutsch.lang14
-rw-r--r--apps/lang/english.lang14
-rw-r--r--apps/settings.h6
-rw-r--r--apps/settings_list.c6
-rw-r--r--apps/settings_menu.c27
-rw-r--r--firmware/export/pcf50606.h5
-rw-r--r--firmware/export/usb.h4
-rw-r--r--firmware/powermgmt.c5
-rw-r--r--firmware/target/coldfire/iriver/h300/pcf50606-h300.c26
-rw-r--r--firmware/usb.c38
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
@@ -3570,6 +3570,20 @@
</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
user:
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
@@ -3611,6 +3611,20 @@
</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
user:
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