Index: apps/debug_menu.c
===================================================================
RCS file: /cvsroot/rockbox/apps/debug_menu.c,v
retrieving revision 1.183
diff -u -r1.183 debug_menu.c
--- apps/debug_menu.c	25 Apr 2006 20:32:38 -0000	1.183
+++ apps/debug_menu.c	2 May 2006 15:12:39 -0000
@@ -52,6 +52,7 @@
 #include "dircache.h"
 #include "tagcache.h"
 #include "lcd-remote.h"
+#include "usb.h"
 
 #ifdef HAVE_LCD_BITMAP
 #include "widgets.h"
@@ -1379,6 +1380,14 @@
                 snprintf(buf, 30, "Charger: %s",
                          charger_inserted() ? "present" : "absent");
                 lcd_puts(0, 3, buf);
+                snprintf(buf, 30, "USB Inserted: %s",
+                         usb_inserted() ? "present" : "absent");
+                lcd_puts(0, 4, buf);
+#if defined IRIVER_H300_SERIES
+                snprintf(buf, 30, "USB Charging enabled: %s",
+                         usb_charging_enabled() ? "yes" : "no");
+                lcd_puts(0, 5, buf);
+#endif
 #endif
 #endif /* !HAVE_CHARGE_CTRL */
 #endif /* HAVE_CHARGING */
Index: apps/settings.c
===================================================================
RCS file: /cvsroot/rockbox/apps/settings.c,v
retrieving revision 1.381
diff -u -r1.381 settings.c
--- apps/settings.c	25 Apr 2006 00:14:21 -0000	1.381
+++ apps/settings.c	2 May 2006 13:24:31 -0000
@@ -322,8 +322,13 @@
 
     /* new stuff to be added here */
     /* If values are just added to the end, no need to bump the version. */
+#ifdef HAVE_USB_POWER
+#ifdef HAVE_CHARGING
+    {1, S_O(usb_charging), false, "usb charging", off_on },
+#endif
+#endif
 
-    /* Current sum of bits: 277 (worst case, but w/o remote lcd) */
+    /* Current sum of bits: 278 (worst case, but w/o remote lcd) */
     /* Sum of all bit sizes must not grow beyond 288! */
 };
 
@@ -1184,6 +1189,12 @@
     set_remote_backlight_filter_keypress(global_settings.remote_bl_filter_first_keypress);
 #endif
 #endif
+
+#ifdef HAVE_USB_POWER
+#ifdef HAVE_CHARGING
+    usb_charging_enable(global_settings.usb_charging);
+#endif
+#endif
 }
 
 
Index: apps/settings.h
===================================================================
RCS file: /cvsroot/rockbox/apps/settings.h,v
retrieving revision 1.216
diff -u -r1.216 settings.h
--- apps/settings.h	11 Apr 2006 13:49:05 -0000	1.216
+++ apps/settings.h	2 May 2006 12:31:08 -0000
@@ -494,6 +494,12 @@
 #ifdef HAVE_LCD_BITMAP
     unsigned char kbd_file[MAX_FILENAME+1]; /* last keyboard */
 #endif
+
+#ifdef HAVE_USB_POWER
+#ifdef HAVE_CHARGING
+    bool usb_charging;
+#endif
+#endif
 };
 
 enum optiontype { INT, BOOL };
Index: apps/settings_menu.c
===================================================================
RCS file: /cvsroot/rockbox/apps/settings_menu.c,v
retrieving revision 1.252
diff -u -r1.252 settings_menu.c
--- apps/settings_menu.c	15 Apr 2006 12:31:33 -0000	1.252
+++ apps/settings_menu.c	2 May 2006 12:36:09 -0000
@@ -377,6 +377,22 @@
                        &global_settings.battery_display, INT, names, 2, NULL);
 }
 
+#ifdef HAVE_USB_POWER
+#ifdef HAVE_CHARGING
+/**
+ * Menu to switch the USB charging on or off
+ */
+static bool usb_charging(void)
+{
+    return set_bool_options( str(LANG_USB_CHARGING),
+                             &global_settings.usb_charging,
+                             STR(LANG_SET_BOOL_NO),
+                             STR(LANG_SET_BOOL_YES),
+                             NULL);
+}
+#endif
+#endif
+
 /**
  * Menu to configure the volume display on status bar
  */
@@ -1822,6 +1838,11 @@
 #if BATTERY_TYPES_COUNT > 1
         { ID2P(LANG_BATTERY_TYPE),     battery_type },
 #endif
+#ifdef HAVE_USB_POWER
+#ifdef HAVE_CHARGING
+        { ID2P(LANG_USB_CHARGING),    usb_charging },
+#endif
+#endif
 #else
 #ifndef HAVE_CHARGE_CTRL
         { "Dummy", NULL }, /* to have an entry at all, in the simulator */
Index: apps/gui/statusbar.c
===================================================================
RCS file: /cvsroot/rockbox/apps/gui/statusbar.c,v
retrieving revision 1.24
diff -u -r1.24 statusbar.c
--- apps/gui/statusbar.c	13 Mar 2006 16:11:30 -0000	1.24
+++ apps/gui/statusbar.c	2 May 2006 12:31:08 -0000
@@ -128,6 +128,9 @@
 #ifdef HAVE_CHARGING
     bar->info.inserted = (charger_input_state == CHARGER);
 #endif
+#ifdef HAVE_USB_POWER
+    bar->info.usb_inserted = usb_inserted();
+#endif /* HAVE_USB_POWER */
     bar->info.battlevel = battery_level();
     bar->info.battery_safe = battery_level_safe();
 
@@ -154,10 +157,6 @@
         bar->info.led = led_read(HZ/2); /* delay should match polling interval */
 #endif
 
-#ifdef HAVE_USB_POWER
-    bar->info.usb_power = usb_powered();
-#endif /* HAVE_USB_POWER */
-
     /* only redraw if forced to, or info has changed */
     if (force_redraw ||
         bar->info.inserted ||
@@ -235,7 +234,7 @@
             gui_statusbar_icon_battery(display, bar->info.battlevel, 
                                        bar->animated_level);
 #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,
Index: apps/gui/statusbar.h
===================================================================
RCS file: /cvsroot/rockbox/apps/gui/statusbar.h,v
retrieving revision 1.15
diff -u -r1.15 statusbar.h
--- apps/gui/statusbar.h	13 Mar 2006 16:11:30 -0000	1.15
+++ apps/gui/statusbar.h	2 May 2006 12:31:08 -0000
@@ -39,6 +39,9 @@
     int playmode;
     int repeat;
     bool inserted;
+#ifdef HAVE_USB_POWER
+    bool usb_inserted;
+#endif
     bool shuffle;
     bool keylock;
 #ifdef HAS_REMOTE_BUTTON_HOLD
@@ -50,9 +53,6 @@
     bool led; /* disk LED simulation in the status bar */
 #endif
 
-#ifdef HAVE_USB_POWER
-    bool usb_power;
-#endif
 };
 
 struct gui_statusbar
Index: apps/lang/english.lang
===================================================================
RCS file: /cvsroot/rockbox/apps/lang/english.lang,v
retrieving revision 1.250
diff -u -r1.250 english.lang
--- apps/lang/english.lang	27 Apr 2006 22:48:15 -0000	1.250
+++ apps/lang/english.lang	2 May 2006 12:31:08 -0000
@@ -3593,6 +3593,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 USB-Connection"
+  </voice>
+</phrase>
+<phrase>
   id: LANG_DISPLAY_GRAPHIC
   desc: Label for type of icon display
   user:
Index: firmware/powermgmt.c
===================================================================
RCS file: /cvsroot/rockbox/firmware/powermgmt.c,v
retrieving revision 1.113
diff -u -r1.113 powermgmt.c
--- firmware/powermgmt.c	16 Apr 2006 17:32:54 -0000	1.113
+++ firmware/powermgmt.c	2 May 2006 12:43:42 -0000
@@ -546,8 +546,11 @@
          * 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 HAVE_CHARGING
+                || (usb_inserted() && usb_charging_enabled())
+#endif
 #endif
                 ) {
             switch(charger_input_state) {
Index: firmware/usb.c
===================================================================
RCS file: /cvsroot/rockbox/firmware/usb.c,v
retrieving revision 1.92
diff -u -r1.92 usb.c
--- firmware/usb.c	8 Apr 2006 09:08:33 -0000	1.92
+++ firmware/usb.c	2 May 2006 15:06:58 -0000
@@ -44,6 +44,9 @@
 #ifdef TARGET_TREE
 #include "usb-target.h"
 #endif
+#ifdef IRIVER_H300_SERIES
+#include "pcf50606.h"        /* for pcf50606_usb_charging_... */
+#endif
 
 extern void dbg_ports(void); /* NASTY! defined in apps/ */
 
@@ -617,6 +620,37 @@
 {
     return usb_state == USB_POWERED;
 }
+
+#ifdef HAVE_CHARGING
+bool usb_charging_enable(bool on)
+{
+    bool rc = false;
+#ifdef IRIVER_H300_SERIES
+    int irqlevel;
+    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
+    return rc;
+}
+#endif
 #endif
 
 #else
Index: firmware/drivers/pcf50606.c
===================================================================
RCS file: /cvsroot/rockbox/firmware/drivers/pcf50606.c,v
retrieving revision 1.13
diff -u -r1.13 pcf50606.c
--- firmware/drivers/pcf50606.c	17 Apr 2006 00:09:02 -0000	1.13
+++ firmware/drivers/pcf50606.c	2 May 2006 15:07:03 -0000
@@ -47,6 +47,10 @@
 
 static int i2c_delay IDATA_ATTR = 44;
 
+#ifdef IRIVER_H300_SERIES
+static bool usb_charging_enabled = false;
+#endif
+
 void pcf50606_i2c_recalc_delay(int cpu_clock)
 {
     i2c_delay = MAX(cpu_clock / (400000*2*3) - 7, 1);
@@ -517,6 +521,27 @@
     pcf50606_write_multiple(0x23, buf, 5);
 }
 
+#ifdef IRIVER_H300_SERIES
+/* 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_charging_enabled = on;
+}
+
+bool pcf50606_usb_charging_enabled(void)
+{
+    /* TODO: read the state of the GPOOD2 register... */
+    return usb_charging_enabled;
+}
+#endif
+
 void pcf50606_init(void)
 {
     /* Bit banged I2C */
@@ -532,7 +557,10 @@
     pcf50606_write(0x08, 0x60); /* Wake on USB and charger insertion */
     pcf50606_write(0x09, 0x05); /* USB and ON key debounce: 14ms */
     pcf50606_write(0x29, 0x1C); /* Disable the unused MBC module */
-    
+#ifdef IRIVER_H300_SERIES
+    pcf50606_set_usb_charging(false); /* Disable USB charging atm. */
+#endif
+
     pcf50606_write(0x35, 0x13); /* Backlight PWM = 512Hz 50/50 */
     pcf50606_write(0x3a, 0x3b); /* PWM output on GPOOD1 */
 }
Index: firmware/export/pcf50606.h
===================================================================
RCS file: /cvsroot/rockbox/firmware/export/pcf50606.h,v
retrieving revision 1.6
diff -u -r1.6 pcf50606.h
--- firmware/export/pcf50606.h	16 Apr 2006 23:16:32 -0000	1.6
+++ firmware/export/pcf50606.h	2 May 2006 14:42:20 -0000
@@ -25,5 +25,9 @@
 int pcf50606_write(int address, unsigned char val);
 int pcf50606_read_multiple(int address, unsigned char* buf, int count);
 int pcf50606_read(int address);
+#ifdef IRIVER_H300_SERIES
+void pcf50606_set_usb_charging(bool on);
+bool pcf50606_usb_charging_enabled(void);
+#endif
 
 #endif
Index: firmware/export/usb.h
===================================================================
RCS file: /cvsroot/rockbox/firmware/export/usb.h,v
retrieving revision 1.5
diff -u -r1.5 usb.h
--- firmware/export/usb.h	6 Dec 2005 12:12:29 -0000	1.5
+++ firmware/export/usb.h	2 May 2006 12:31:08 -0000
@@ -31,6 +31,10 @@
 bool usb_detect(void); /* return the raw hardware value */
 #ifdef HAVE_USB_POWER
 bool usb_powered(void);
+#ifdef HAVE_CHARGING
+bool usb_charging_enable(bool on);
+bool usb_charging_enabled(void);
+#endif
 #endif
 
 #endif
