Index: apps/gui/gwps-common.c
===================================================================
--- apps/gui/gwps-common.c	(revision 12444)
+++ apps/gui/gwps-common.c	(working copy)
@@ -23,7 +23,6 @@
 #include <stdlib.h>
 #include "system.h"
 #include "settings.h"
-#include "rtc.h"
 #include "audio.h"
 #include "status.h"
 #include "power.h"
@@ -54,6 +53,9 @@
 #include "dsp.h"
 #include "action.h"
 #include "cuesheet.h"
+#ifdef CONFIG_RTC
+#include "rtc.h"
+#endif
 
 #ifdef HAVE_LCD_CHARCELLS
 static bool draw_player_progress(struct gui_wps *gwps);
@@ -972,6 +974,11 @@
 #ifdef CONFIG_RTC
        case 'c':  /* Real Time Clock display */
             *flags |= WPS_REFRESH_DYNAMIC;
+#if CONFIG_RTC == RTC_DS1339_DS3231
+            if(!rtc_detected) 
+                return NULL;
+            else
+#endif
             {
                 int value;
                 char *format = 0;
Index: apps/gui/statusbar.c
===================================================================
--- apps/gui/statusbar.c	(revision 12444)
+++ apps/gui/statusbar.c	(working copy)
@@ -32,6 +32,9 @@
 #include "button.h"
 #include "usb.h"
 #include "led.h"
+#ifdef CONFIG_RTC
+#include "rtc.h"
+#endif
 
 #include "status.h" /* needed for battery_state global var */
 #include "action.h" /* for keys_locked */
@@ -213,6 +216,9 @@
         bar->info.led = led_read(HZ/2); /* delay should match polling interval */
 #endif
 #ifdef CONFIG_RTC
+#if CONFIG_RTC == RTC_DS1339_DS3231
+    if(rtc_detected) 
+#endif
     {
         struct tm* tm = get_time();
         bar->info.hour = tm->tm_hour;
@@ -298,6 +304,9 @@
             gui_statusbar_icon_lock_remote(display);
 #endif
 #ifdef CONFIG_RTC
+#if CONFIG_RTC == RTC_DS1339_DS3231
+        if(rtc_detected) 
+#endif
         gui_statusbar_time(display, bar->info.hour, bar->info.minute);
 #endif /* CONFIG_RTC */
 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
Index: apps/main_menu.c
===================================================================
--- apps/main_menu.c	(revision 12444)
+++ apps/main_menu.c	(working copy)
@@ -51,6 +51,9 @@
 #include "plugin.h"
 #include "filetypes.h"
 #include "splash.h"
+#ifdef CONFIG_RTC
+#include "rtc.h"
+#endif
 
 #ifdef HAVE_RECORDING
 #include "recording.h"
Index: apps/menus/main_menu.c
===================================================================
--- apps/menus/main_menu.c	(revision 12444)
+++ apps/menus/main_menu.c	(working copy)
@@ -37,6 +37,9 @@
 #include "recording.h"
 #endif
 #include "bookmark.h"
+#ifdef CONFIG_RTC
+#include "rtc.h"
+#endif
 #include "yesno.h"
 #include "keyboard.h"
 #include "screens.h"
Index: apps/menus/settings_menu.c
===================================================================
--- apps/menus/settings_menu.c	(revision 12444)
+++ apps/menus/settings_menu.c	(working copy)
@@ -38,7 +38,15 @@
 #ifdef HAVE_ALARM_MOD
 #include "alarm_menu.h"
 #endif
+#ifdef CONFIG_RTC
+#include "rtc.h"
+#endif
 
+
+/* lazy coders can use this function if the needed callback 
+	is just to say if the item is shown or not */
+int dynamicitem_callback2(int action,const struct menu_item_ex *this_item);
+
 /***********************************/
 /*    TAGCACHE MENU                */
 #ifdef HAVE_TAGCACHE
@@ -204,7 +212,7 @@
     return result;
 }
 
-MENUITEM_FUNCTION(time_set, ID2P(LANG_TIME), timedate_set, NULL, NOICON);
+MENUITEM_FUNCTION(time_set, ID2P(LANG_TIME), timedate_set, dynamicitem_callback2, NOICON);
 MENUITEM_SETTING(timeformat, &global_settings.timeformat, NULL);
 MAKE_MENU(time_menu, ID2P(LANG_TIME_MENU), 0, NOICON, &time_set, &timeformat);
 #endif
@@ -246,7 +254,7 @@
                                                                 setting to the user */
 #ifdef HAVE_ALARM_MOD
 MENUITEM_FUNCTION(alarm_screen_call, ID2P(LANG_ALARM_MOD_ALARM_MENU),
-                   (menu_function)alarm_screen, NULL, NOICON);
+                   (menu_function)alarm_screen, dynamicitem_callback2, NOICON);
 #endif
 
 /* Limits menu */
@@ -383,3 +391,23 @@
           &bookmark_settings_menu, &browse_langs, &voice_settings_menu );
 /*    SETTINGS MENU                */
 /***********************************/
+/* lazy coders can use this function if the needed 
+   callback is just to say if the item is shown or not */
+int dynamicitem_callback2(int action,const struct menu_item_ex *this_item)
+{
+    if (action != ACTION_ENTER_MENUITEM)
+        return action;
+	
+#if defined(CONFIG_RTC) && CONFIG_RTC == RTC_DS1339_DS3231
+    if ((this_item == &time_set) ||
+        (this_item == &alarm_screen_call))
+    {
+        if (!rtc_detected)
+            return ACTION_EXIT_MENUITEM;
+    }
+#else
+    (void)this_item;
+#endif
+
+    return action;
+}
Index: apps/misc.c
===================================================================
--- apps/misc.c	(revision 12444)
+++ apps/misc.c	(working copy)
@@ -60,6 +60,7 @@
 #include "gui/gwps-common.h"
 
 #include "misc.h"
+#include "rtc.h"
 
 /* Format a large-range value for output, using the appropriate unit so that
  * the displayed value is in the range 1 <= display < 1000 (1024 for "binary"
@@ -414,6 +415,12 @@
 #endif
 
 #ifdef CONFIG_RTC
+#if CONFIG_RTC == RTC_DS1339_DS3231
+    if(!rtc_detected) 
+        create_numbered_filename(filename, "", "dump_", ".bmp", 4
+                             IF_CNFN_NUM_(, NULL));
+    else
+#endif
     create_datetime_filename(filename, "", "dump ", ".bmp", false);
 #else
     create_numbered_filename(filename, "", "dump_", ".bmp", 4
Index: apps/plugins/clock.c
===================================================================
--- apps/plugins/clock.c	(revision 12444)
+++ apps/plugins/clock.c	(working copy)
@@ -277,7 +277,7 @@
 #define EXIT_BUTTON BUTTON_MENU
 #define MODE_NEXT_BUTTON BUTTON_RIGHT
 #define MODE_PREV_BUTTON BUTTON_LEFT
-#elif (CONFIG_KEYPAD == IRIVER_H300_PAD)
+#elif (CONFIG_KEYPAD == IRIVER_H300_PAD) || (CONFIG_KEYPAD == IRIVER_H100_PAD)
 #define COUNTER_TOGGLE_BUTTON (BUTTON_ON|BUTTON_REL)
 #define COUNTER_RESET_BUTTON (BUTTON_ON|BUTTON_REPEAT)
 #define MENU_BUTTON BUTTON_SELECT
Index: apps/recorder/recording.c
===================================================================
--- apps/recorder/recording.c	(revision 12444)
+++ apps/recorder/recording.c	(working copy)
@@ -68,6 +68,9 @@
 #include "screen_access.h"
 #include "action.h"
 #include "radio.h"
+#ifdef CONFIG_RTC
+#include "rtc.h"
+#endif
 #ifdef HAVE_RECORDING
 
 static bool in_screen = false;   
@@ -521,6 +524,12 @@
 #ifdef CONFIG_RTC 
     /* We'll wait at least up to the start of the next second so no duplicate
        names are created */
+#if CONFIG_RTC == RTC_DS1339_DS3231
+    if(!rtc_detected) 
+        return create_numbered_filename(buffer, buffer, "rec_", ext, 4
+                                    IF_CNFN_NUM_(, &file_number));
+    else
+#endif
     return create_datetime_filename(buffer, buffer, "R", ext, true);
 #else
     return create_numbered_filename(buffer, buffer, "rec_", ext, 4
Index: apps/scrobbler.c
===================================================================
--- apps/scrobbler.c	(revision 12444)
+++ apps/scrobbler.c	(working copy)
@@ -35,6 +35,7 @@
 #ifdef CONFIG_RTC
 #include "time.h"
 #include "timefuncs.h"
+#include "rtc.h"
 #endif
 
 #include "scrobbler.h"
@@ -208,6 +209,11 @@
         logf("SCROBBLER: add pending");
         copy_mp3entry(&scrobbler_entry, id);
 #ifdef CONFIG_RTC
+#if CONFIG_RTC == RTC_DS1339_DS3231
+        if(!rtc_detected) 
+            timestamp = 0;
+        else
+#endif
         timestamp = mktime(get_time());
 #else
         timestamp = 0;
Index: firmware/common/timefuncs.c
===================================================================
--- firmware/common/timefuncs.c	(revision 12438)
+++ firmware/common/timefuncs.c	(working copy)
@@ -49,6 +49,19 @@
 #ifdef CONFIG_RTC
     static long timeout = 0;
 
+#if CONFIG_RTC == RTC_DS1339_DS3231
+    if(!rtc_detected) {
+        tm.tm_sec = 0;
+        tm.tm_min = 0;
+        tm.tm_hour = 0;
+        tm.tm_mday = 1;
+        tm.tm_mon = 0;
+        tm.tm_year = 70;
+        tm.tm_wday = 1;
+        tm.tm_yday = 0; /* Not implemented for now */
+        tm.tm_isdst = -1; /* Not implemented for now */
+    } else
+#endif
     /* Don't read the RTC more than once per second */
     if (current_tick > timeout) {
         char rtcbuf[7];
Index: firmware/drivers/eeprom_24cxx.c
===================================================================
--- firmware/drivers/eeprom_24cxx.c	(revision 12438)
+++ firmware/drivers/eeprom_24cxx.c	(working copy)
@@ -16,275 +16,21 @@
  * KIND, either express or implied.
  *
  ****************************************************************************/
-#include "lcd.h"
-#include "cpu.h"
-#include "system.h"
-#include "kernel.h"
-#include "thread.h"
-#include "debug.h"
+
 #include "logf.h"
-#include "sprintf.h"
 #include "string.h"
 #include "inttypes.h"
 
+#include "i2c-bitbang.h"
 #include "eeprom_24cxx.h"
 
-/**
- * I2C-functions are copied and ported from fmradio.c.
- */
-
-#define SW_I2C_WRITE 0
-#define SW_I2C_READ  1
-
 /* Use cache to speedup writing to the chip. */
 static char data_cache[EEPROM_SIZE];
 static uint8_t cached_bitfield[EEPROM_SIZE/8];
 
 #define IS_CACHED(addr) (cached_bitfield[addr/8] & (1 << (addr % 8)))
-#define SET_CACHED(addr) (cached_bitfield[addr/8] |= 1 << (addr % 8))
+#define SET_CACHED(addr) (cached_bitfield[addr/8] |= 1 << (addr % 8)) 
 
-/* h1x0 needs its own i2c driver,
-   h3x0 uses the pcf i2c driver */
-
-#ifdef IRIVER_H100_SERIES
-
-/* cute little functions, atomic read-modify-write */
-
-/* SCL is GPIO, 12 */
-#define SCL             ( 0x00001000 & GPIO_READ)
-#define SCL_OUT_LO and_l(~0x00001000, &GPIO_OUT)
-#define SCL_LO      or_l( 0x00001000, &GPIO_ENABLE)
-#define SCL_HI     and_l(~0x00001000, &GPIO_ENABLE)
-
-/* SDA is GPIO1, 13 */
-#define SDA             ( 0x00002000 & GPIO1_READ)
-#define SDA_OUT_LO and_l(~0x00002000, &GPIO1_OUT)
-#define SDA_LO      or_l( 0x00002000, &GPIO1_ENABLE)
-#define SDA_HI     and_l(~0x00002000, &GPIO1_ENABLE)
-
-/* delay loop to achieve 400kHz at 120MHz CPU frequency */
-#define DELAY    do { int _x; for(_x=0;_x<22;_x++);} while(0)
-
-static void sw_i2c_init(void)
-{
-    logf("sw_i2c_init");
-    or_l(0x00001000, &GPIO_FUNCTION);
-    or_l(0x00002000, &GPIO1_FUNCTION);
-    SDA_HI;
-    SCL_HI;
-    SDA_OUT_LO;
-    SCL_OUT_LO;
-}
-
-static void sw_i2c_start(void)
-{
-    SCL_LO;
-    DELAY;
-    SDA_HI;
-    DELAY;
-    SCL_HI;
-    DELAY;
-    SDA_LO;
-    DELAY;
-    SCL_LO;
-}
-
-static void sw_i2c_stop(void)
-{
-    SCL_HI;
-    DELAY;
-    SDA_HI;
-    DELAY;
-}
-
-static void sw_i2c_ack(void)
-{
-    SCL_LO;
-    DELAY;
-    SDA_LO;
-    DELAY;
-    
-    SCL_HI;
-    DELAY;
-}
-
-static bool sw_i2c_getack(void)
-{
-    bool ret = true;
-    int count = 10;
-
-    SCL_LO;
-    DELAY;
-    SDA_HI;   /* sets to input */
-    DELAY;
-    SCL_HI;
-    DELAY;
-
-    while (SDA && count--)
-        DELAY;
-    
-    if (SDA)
-        /* ack failed */
-        ret = false;
-    
-    SCL_LO;
-    DELAY;
-    SDA_LO;
-
-    return ret;
-}
-
-static void sw_i2c_outb(unsigned char byte)
-{
-    int i;
-
-    /* clock out each bit, MSB first */
-    for ( i=0x80; i; i>>=1 )
-    {
-        SCL_LO;
-        DELAY;
-        if ( i & byte )
-            SDA_HI;
-        else
-            SDA_LO;
-        DELAY;
-        SCL_HI;
-        DELAY;
-    }
-}
-
-static unsigned char sw_i2c_inb(void)
-{
-    int i;
-    unsigned char byte = 0;
-
-    SDA_HI;   /* sets to input */
-    
-    /* clock in each bit, MSB first */
-    for ( i=0x80; i; i>>=1 ) 
-    {
-        SCL_HI;
-        DELAY;
-        if ( SDA )
-            byte |= i;
-        SCL_LO;
-        DELAY;
-    }
-
-    sw_i2c_ack();
-    
-    return byte;
-}
-
-#else
-
-#include "pcf50606.h"
-
-#define sw_i2c_init()       /* no extra init required */
-#define sw_i2c_start()      pcf50606_i2c_start()
-#define sw_i2c_stop()       pcf50606_i2c_stop()
-#define sw_i2c_ack()        pcf50606_i2c_ack(true)
-#define sw_i2c_getack()     pcf50606_i2c_getack()
-#define sw_i2c_outb(x)      pcf50606_i2c_outb(x)
-#define sw_i2c_inb()        pcf50606_i2c_inb(false)
-
-#endif /* IRIVER_H100_SERIES */
-
-
-int sw_i2c_write(int location, const unsigned char* buf, int count)
-{
-    int i;
-
-    sw_i2c_start();
-    sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_WRITE);
-    if (!sw_i2c_getack())
-    {
-        sw_i2c_stop();
-        return -1;
-    }
-    
-    sw_i2c_outb(location);
-    if (!sw_i2c_getack())
-    {
-        sw_i2c_stop();
-        return -2;
-    }
-    
-    for (i=0; i<count; i++)
-    {
-        sw_i2c_outb(buf[i]);
-        if (!sw_i2c_getack())
-        {
-            sw_i2c_stop();
-            return -3;
-        }
-    }
-
-    sw_i2c_stop();
-    
-    return 0;
-}
-
-int sw_i2c_write_byte(int location, unsigned char byte)
-{
-    sw_i2c_start();
-    sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_WRITE);
-    if (!sw_i2c_getack())
-    {
-        sw_i2c_stop();
-        return -1;
-    }
-    
-    sw_i2c_outb(location);
-    if (!sw_i2c_getack())
-    {
-        sw_i2c_stop();
-        return -2;
-    }
-    
-    sw_i2c_outb(byte);
-    if (!sw_i2c_getack())
-    {
-        sw_i2c_stop();
-        return -3;
-    }
-
-    sw_i2c_stop();
-    
-    return 0;
-}
-
-int sw_i2c_read(unsigned char location, unsigned char* byte)
-{
-    sw_i2c_start();
-    sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_WRITE);
-    if (!sw_i2c_getack())
-    {
-        sw_i2c_stop();
-        return -1;
-    }
-
-    sw_i2c_outb(location);
-    if (!sw_i2c_getack())
-    {
-        sw_i2c_stop();
-        return -2;
-    }
-    
-    sw_i2c_start();
-    sw_i2c_outb((EEPROM_ADDR & 0xfe) | SW_I2C_READ);
-    if (!sw_i2c_getack())
-    {
-        sw_i2c_stop();
-        return -3;
-    }
-    
-    *byte = sw_i2c_inb();
-    sw_i2c_stop();
-    
-    return 0;
-}
-
 void eeprom_24cxx_init(void)
 {
     sw_i2c_init();
@@ -314,7 +60,7 @@
     *c = 0;
     do
     {
-        ret = sw_i2c_read(address, &byte);
+        ret = sw_i2c_read(EEPROM_ADDR, address, &byte, 1);
     } while (ret < 0 && count++ < 200);
 
     if (ret < 0)
@@ -357,7 +103,7 @@
     
     do
     {
-        ret = sw_i2c_write_byte(address, c);
+        ret = sw_i2c_write(EEPROM_ADDR, address, &c, 1);
     } while (ret < 0 && count++ < 200) ;
 
     if (ret < 0)
Index: firmware/drivers/fat.c
===================================================================
--- firmware/drivers/fat.c	(revision 12438)
+++ firmware/drivers/fat.c	(working copy)
@@ -30,6 +30,9 @@
 #include "kernel.h"
 #include "rbunicode.h"
 #include "logf.h"
+#ifdef CONFIG_RTC
+#include "rtc.h"
+#endif
 
 #define BYTES2INT16(array,pos) \
           (array[pos] | (array[pos+1] << 8 ))
@@ -953,6 +956,10 @@
 {
 #ifdef CONFIG_RTC
     struct tm* tm = get_time();
+#if CONFIG_RTC == RTC_DS1339_DS3231
+    if(rtc_detected) 
+    {  
+#endif /* CONFIG_RTC == RTC_DS1339_DS3231 */                    
 
     if (date)
         *date = ((tm->tm_year - 80) << 9) |
@@ -966,7 +973,14 @@
 
     if (tenth)
         *tenth = (tm->tm_sec & 1) * 100;
-#else
+        
+#if CONFIG_RTC == RTC_DS1339_DS3231
+    }  
+    else
+#endif /* CONFIG_RTC == RTC_DS1339_DS3231 */                    
+#endif /* CONFIG_RTC */                    
+#if !defined(CONFIG_RTC) || CONFIG_RTC == RTC_DS1339_DS3231
+    {
     /* non-RTC version returns an increment from the supplied time, or a
      * fixed standard time/date if no time given as input */
     bool next_day = false;
@@ -1033,9 +1047,9 @@
     }
     if (tenth)
         *tenth = 0;
-#endif /* CONFIG_RTC */
+    }  
+#endif /* !defined(CONFIG_RTC) || CONFIG_RTC == RTC_DS1339_DS3231 */   
 }
-
 static int write_long_name(struct fat_file* file,
                            unsigned int firstentry,
                            unsigned int numentries,
Index: firmware/drivers/rtc/rtc_ds1339_ds3231.c
===================================================================
--- firmware/drivers/rtc/rtc_ds1339_ds3231.c	(revision 0)
+++ firmware/drivers/rtc/rtc_ds1339_ds3231.c	(revision 0)
@@ -0,0 +1,144 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id: rtc_ds1339_ds3231.c,v 1.1 2006-11-27 09:44:56 roolku Exp $
+ *
+ * Copyright (C) 2006 by Robert Kukla 
+ * based on Archos code by Linus Nielsen Feltzing, Uwe Freese, Laurent Baum   
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "rtc.h" 
+#include "logf.h"
+#include "i2c-bitbang.h"
+
+#define RTC_ADDR   0xD0
+
+bool rtc_detected = false; 
+
+void rtc_init(void)
+{
+    char byte;
+  
+    sw_i2c_init();
+
+    /* read one byte from RTC; 0 on success */
+    rtc_detected =  !sw_i2c_read(RTC_ADDR, 0, &byte, 1); 
+
+#ifdef HAVE_ALARM_MOD
+    /* Check + save alarm bit first, before the power thread starts watching */
+    rtc_check_alarm_started(false);
+#endif
+
+}
+
+#ifdef HAVE_ALARM_MOD    
+
+/* check whether the unit has been started by the RTC alarm function */
+/* (check for A2F, which => started using wakeup alarm) */
+bool rtc_check_alarm_started(bool release_alarm)
+{
+    static bool alarm_state, run_before;
+    bool rc;
+
+    if (run_before) {
+        rc = alarm_state;
+        alarm_state &= ~release_alarm;         
+    } else { 
+        /* This call resets AF, so we store the state for later recall */ 
+        rc = alarm_state = rtc_check_alarm_flag();
+        run_before = true; 
+    }
+ 
+    return rc;
+}
+/*
+ * Checks the A2F flag.  This call resets A2F once read.
+ *
+ */
+bool rtc_check_alarm_flag(void) 
+{
+    unsigned char buf[1];
+    bool flag = false;
+
+    sw_i2c_read(RTC_ADDR, 0x0f, buf, 1);        
+    if (buf[0] & 0x02) flag = true;
+      
+    rtc_enable_alarm(false);
+    
+    return flag;
+}
+
+/* set alarm time registers to the given time (repeat once per day) */
+void rtc_set_alarm(int h, int m)
+{
+    unsigned char buf[3];
+
+    buf[0] = (((m / 10) << 4) | (m % 10)) & 0x7f; /* minutes */
+    buf[1] = (((h / 10) << 4) | (h % 10)) & 0x3f; /* hour */
+    buf[2] = 0x80;                                /* repeat every day */
+    
+    sw_i2c_write(RTC_ADDR, 0x0b, buf, 3);        
+}
+
+/* read out the current alarm time */
+void rtc_get_alarm(int *h, int *m)
+{
+    unsigned char buf[2];
+     
+    sw_i2c_read(RTC_ADDR, 0x0b, buf, 2);        
+
+    *m = ((buf[0] & 0x70) >> 4) * 10 + (buf[0] & 0x0f);
+    *h = ((buf[1] & 0x30) >> 4) * 10 + (buf[1] & 0x0f);
+}
+
+/* turn alarm on or off by setting the alarm flag enable */
+/* the alarm is automatically disabled when the RTC gets Vcc power at startup */
+/* avoid that an alarm occurs when the device is on because this locks the ON key forever */
+/* returns false if alarm was set and alarm flag (output) is off */
+/* returns true if alarm flag went on, which would lock the device, so the alarm was disabled again */
+bool rtc_enable_alarm(bool enable)
+{
+    unsigned char buf[2];
+    
+    buf[0] = enable ? 0x26 : 0x04; /* BBSQI INTCN A2IE vs INTCH  only */
+    buf[1] = 0x00; /* reset alarm flags (and OSF for good measure) */
+    
+    sw_i2c_write(RTC_ADDR, 0x0e, buf, 2);        
+
+    return false; /* all ok */
+}
+
+#endif /* HAVE_ALARM_MOD */ 
+
+int rtc_read_datetime(unsigned char* buf)
+{
+    int i;
+
+    i = sw_i2c_read(RTC_ADDR, 0, buf, 7);        
+    
+    buf[3]--; /* timefuncs wants 0..6 for wday */
+
+    return i;
+}
+
+int rtc_write_datetime(unsigned char* buf)
+{
+    int i;
+
+    buf[3]++;       /* chip wants 1..7 for wday */
+    buf[5]|=0x80;   /* chip wants century (always 20xx) */
+
+    i = sw_i2c_write(RTC_ADDR, 0, buf, 7);
+
+    return i;
+}
+
Index: firmware/export/config-h120.h
===================================================================
--- firmware/export/config-h120.h	(revision 12438)
+++ firmware/export/config-h120.h	(working copy)
@@ -45,7 +45,13 @@
 /* Define this if you do software codec */
 #define CONFIG_CODEC SWCODEC
 
-/* Define this if you have an remote lcd */
+#ifndef SIMULATOR
+/* RTC is autodetected on target only */
+#define CONFIG_RTC RTC_DS1339_DS3231
+#define HAVE_ALARM_MOD
+#endif 
+
+ /* Define this if you have an remote lcd */
 #define HAVE_REMOTE_LCD
 
 #define CONFIG_LCD LCD_S1D15E06
Index: firmware/export/config.h
===================================================================
--- firmware/export/config.h	(revision 12438)
+++ firmware/export/config.h	(working copy)
@@ -153,6 +153,7 @@
 #define RTC_S3C2440  4
 #define RTC_E8564    5 /* iriver H10 */
 #define RTC_AS3514   6 /* Sandisk Sansa e200 series */
+#define RTC_DS1339_DS3231   7 /* h1x0 RTC mod */
 
 /* USB On-the-go */
 #define USBOTG_ISP1362 1362 /* iriver H300 */
Index: firmware/export/i2c-bitbang.h
===================================================================
--- firmware/export/i2c-bitbang.h	(revision 0)
+++ firmware/export/i2c-bitbang.h	(revision 0)
@@ -0,0 +1,27 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id: i2c-bitbang.h,v 1.1 2006-11-26 14:50:15 miipekk Exp $
+ *
+ * Copyright (C) 2006 by Miika Pekkarinen
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _I2C_BITBANG_H
+#define _I2C_BITBANG_H
+
+void sw_i2c_init(void);
+int sw_i2c_write(unsigned char chip, unsigned char location, const unsigned char* buf, int count);
+int sw_i2c_read (unsigned char chip, unsigned char location,       unsigned char* buf, int count);
+
+#endif
Index: firmware/export/rtc.h
===================================================================
--- firmware/export/rtc.h	(revision 12438)
+++ firmware/export/rtc.h	(working copy)
@@ -20,6 +20,7 @@
 #define _RTC_H_
 
 #include <stdbool.h> 
+#include <system.h> 
 
 #ifdef CONFIG_RTC
 
@@ -27,6 +28,10 @@
 
 extern const int monthname[];
 
+#if CONFIG_RTC == RTC_DS1339_DS3231
+extern bool rtc_detected; 
+#endif
+
 /* Common functions for all targets */
 void rtc_init(void);
 int rtc_read_datetime(unsigned char* buf);
@@ -40,6 +45,8 @@
 int rtc_read_multiple(unsigned char address, unsigned char *buf, int numbytes);
 int rtc_write(unsigned char address, unsigned char value);
 
+#endif /* RTC_M41ST84W */
+
 #ifdef HAVE_ALARM_MOD  
 void rtc_set_alarm(int h, int m);
 void rtc_get_alarm(int *h, int *m);
@@ -48,8 +55,6 @@
 bool rtc_check_alarm_flag(void);
 #endif /* HAVE_ALARM_MOD */
 
-#endif /* RTC_M41ST84W */
-
 #endif /* CONFIG_RTC */
 
 #endif
Index: firmware/SOURCES
===================================================================
--- firmware/SOURCES	(revision 12438)
+++ firmware/SOURCES	(working copy)
@@ -137,6 +137,8 @@
 drivers/rtc/rtc_pcf50605.c
 #elif (CONFIG_RTC == RTC_E8564)
 drivers/rtc/rtc_e8564.c
+#elif (CONFIG_RTC == RTC_DS1339_DS3231)
+drivers/rtc/rtc_ds1339_ds3231.c
 #elif (CONFIG_RTC == RTC_S3C2440)
 drivers/rtc/rtc_s3c2440.c
 #elif (CONFIG_RTC == RTC_AS3514)
@@ -379,6 +381,7 @@
 target/coldfire/pcf50606-coldfire.c
 target/coldfire/iriver/ata-iriver.c
 target/coldfire/iriver/system-iriver.c
+target/coldfire/iriver/i2c-bitbang.c
 target/coldfire/iriver/h300/adc-h300.c
 target/coldfire/iriver/h300/backlight-h300.c
 target/coldfire/iriver/h300/button-h300.c
@@ -398,6 +401,7 @@
 target/coldfire/ata-as-coldfire.S
 target/coldfire/iriver/ata-iriver.c
 target/coldfire/iriver/system-iriver.c
+target/coldfire/iriver/i2c-bitbang.c
 target/coldfire/iriver/h100/adc-h100.c
 target/coldfire/iriver/h100/backlight-h100.c
 target/coldfire/iriver/h100/button-h100.c
Index: firmware/target/coldfire/iriver/i2c-bitbang.c
===================================================================
--- firmware/target/coldfire/iriver/i2c-bitbang.c	(revision 0)
+++ firmware/target/coldfire/iriver/i2c-bitbang.c	(revision 0)
@@ -0,0 +1,281 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id: i2c-bitbang.c,v 1.1 2006-11-26 14:50:15 miipekk Exp $
+ *
+ * Copyright (C) 2006 by Miika Pekkarinen
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "system.h"
+#include "logf.h"
+#include "inttypes.h"
+
+#include "i2c-bitbang.h"
+
+/**
+ * I2C-functions are copied and ported from fmradio.c.
+ * later fixed, adapted and moved to a seperate file so they can be re-used by the rtc-ds1339c code by Robert Kukla
+ */
+
+#define SW_I2C_WRITE 0
+#define SW_I2C_READ  1
+
+/* h1x0 needs its own i2c driver,
+   h3x0 uses the pcf i2c driver */
+
+#ifdef IRIVER_H100_SERIES
+
+/* cute little functions, atomic read-modify-write */
+
+/* SCL is GPIO, 12 */
+#define SCL             ( 0x00001000 & GPIO_READ)
+#define SCL_OUT_LO and_l(~0x00001000, &GPIO_OUT)
+#define SCL_LO      or_l( 0x00001000, &GPIO_ENABLE)
+#define SCL_HI     and_l(~0x00001000, &GPIO_ENABLE)
+
+/* SDA is GPIO1, 13 */
+#define SDA             ( 0x00002000 & GPIO1_READ)
+#define SDA_OUT_LO and_l(~0x00002000, &GPIO1_OUT)
+#define SDA_LO      or_l( 0x00002000, &GPIO1_ENABLE)
+#define SDA_HI     and_l(~0x00002000, &GPIO1_ENABLE)
+
+/* delay loop to achieve 400kHz at 120MHz CPU frequency */
+#define DELAY    do { int _x; for(_x=0;_x<22;_x++);} while(0)
+
+void sw_i2c_init(void)
+{
+    or_l(0x00001000, &GPIO_FUNCTION);
+    or_l(0x00002000, &GPIO1_FUNCTION);
+    SDA_HI;
+    SCL_HI;
+    SDA_OUT_LO;
+    SCL_OUT_LO;
+}
+
+/*   in: C=? D=?
+ *  out: C=L D=L
+ */
+static void sw_i2c_start(void)
+{
+    SCL_LO;
+    DELAY;
+    SDA_HI;
+    DELAY;
+    SCL_HI;
+    DELAY;
+    SDA_LO;
+    DELAY;
+    SCL_LO;
+}
+
+/*   in: C=L D=?
+ *  out: C=H D=H
+ */
+static void sw_i2c_stop(void)
+{
+    SDA_LO;
+    DELAY;
+    SCL_HI;
+    DELAY;
+    SDA_HI;
+}
+
+/*   in: C=L D=H
+ *  out: C=L D=L
+ */
+static void sw_i2c_ack(void)
+{
+    SDA_LO;
+    DELAY;
+    
+    SCL_HI;
+    DELAY;
+    SCL_LO;
+}
+
+/*   in: C=L D=H
+ *  out: C=L D=H
+ */
+static void sw_i2c_nack(void)
+{
+    SDA_HI;          /* redundant */
+    DELAY;
+    
+    SCL_HI;
+    DELAY;
+    SCL_LO;
+}
+
+/*   in: C=L D=?
+ *  out: C=L D=H
+ */
+static bool sw_i2c_getack(void)
+{
+    bool ret = true;
+/*    int count = 10; */
+
+    SDA_HI;   /* sets to input */
+    DELAY;
+    SCL_HI;
+    DELAY;
+
+/*    while (SDA && count--) */
+/*        DELAY; */
+    
+    if (SDA)
+        /* ack failed */
+        ret = false;
+    
+    SCL_LO;
+
+    return ret;
+}
+
+/*   in: C=L D=?
+ *  out: C=L D=?
+ */
+static void sw_i2c_outb(unsigned char byte)
+{
+    int i;
+
+    /* clock out each bit, MSB first */
+    for ( i=0x80; i; i>>=1 )
+    {
+        if ( i & byte )
+            SDA_HI;
+        else
+            SDA_LO;
+        DELAY;
+
+        SCL_HI;
+        DELAY;
+        SCL_LO;
+    }
+}
+
+/*   in: C=L D=?
+ *  out: C=L D=H
+ */
+static unsigned char sw_i2c_inb(void)
+{
+    int i;
+    unsigned char byte = 0;
+
+    SDA_HI;   /* sets to input */
+    
+    /* clock in each bit, MSB first */
+    for ( i=0x80; i; i>>=1 ) 
+    {
+        DELAY;
+        do {
+          SCL_HI;
+          DELAY;
+        }
+        while(SCL==0);    /* wait for any SCL clock stretching */
+        if ( SDA )
+            byte |= i;
+        SCL_LO;
+    }
+
+    return byte;
+}
+
+#else
+
+#include "pcf50606.h"
+
+#define sw_i2c_init()       /* no extra init required */
+#define sw_i2c_start()      pcf50606_i2c_start()
+#define sw_i2c_stop()       pcf50606_i2c_stop()
+#define sw_i2c_ack()        pcf50606_i2c_ack(true)
+#define sw_i2c_getack()     pcf50606_i2c_getack()
+#define sw_i2c_outb(x)      pcf50606_i2c_outb(x)
+#define sw_i2c_inb()        pcf50606_i2c_inb(false)
+
+#endif /* IRIVER_H100_SERIES */
+
+int sw_i2c_write(unsigned char chip, unsigned char location, const unsigned char* buf, int count)
+{
+    int i;
+
+    sw_i2c_start();
+    sw_i2c_outb((chip & 0xfe) | SW_I2C_WRITE);
+    if (!sw_i2c_getack())
+    {
+        sw_i2c_stop();
+        return -1;
+    }
+    
+    sw_i2c_outb(location);
+    if (!sw_i2c_getack())
+    {
+        sw_i2c_stop();
+        return -2;
+    }
+    
+    for (i=0; i<count; i++)
+    {
+        sw_i2c_outb(buf[i]);
+        if (!sw_i2c_getack())
+        {
+            sw_i2c_stop();
+            return -3;
+        }
+    }
+
+    sw_i2c_stop();
+    
+    return 0;
+}
+
+int sw_i2c_read(unsigned char chip, unsigned char location, unsigned char* buf, int count)
+{
+    int i;
+  
+    sw_i2c_start();
+    sw_i2c_outb((chip & 0xfe) | SW_I2C_WRITE);
+    if (!sw_i2c_getack())
+    {
+        sw_i2c_stop();
+        return -1;
+    }
+
+    sw_i2c_outb(location);
+    if (!sw_i2c_getack())
+    {
+        sw_i2c_stop();
+        return -2;
+    }
+    
+    sw_i2c_start();
+    sw_i2c_outb((chip & 0xfe) | SW_I2C_READ);
+    if (!sw_i2c_getack())
+    {
+        sw_i2c_stop();
+        return -3;
+    }
+    
+    for (i=0; i<count-1; i++)
+    {
+      buf[i] = sw_i2c_inb();
+      sw_i2c_ack();
+    }
+
+    /* 1byte min */
+    buf[i] = sw_i2c_inb();
+    sw_i2c_nack();
+        
+    sw_i2c_stop();
+    
+    return 0;
+}
