diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 268ba8c..f021931 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -285,7 +285,7 @@ static const struct wps_tag all_tags[] = {
 #if (CONFIG_CODEC == SWCODEC)
     { WPS_TOKEN_SOUND_SPEED,              "Ss",  WPS_REFRESH_DYNAMIC, NULL },
 #endif
-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
     { WPS_TOKEN_VLED_HDD,                 "lh",  WPS_REFRESH_DYNAMIC, NULL },
 #endif

diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 879262f..f9e6d5d 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -882,7 +882,7 @@ const char *get_token_value(struct gui_wps *gwps,
                 return NULL;
 #endif

-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
         case WPS_TOKEN_VLED_HDD:
             if(led_read(HZ/2))
                 return "h";
diff --git a/apps/gui/skin_engine/skin_tokens.h b/apps/gui/skin_engine/skin_tokens.h
index 68a3fde..1f90bd0 100644
--- a/apps/gui/skin_engine/skin_tokens.h
+++ b/apps/gui/skin_engine/skin_tokens.h
@@ -188,7 +188,7 @@ enum wps_token_type {
   TOKEN_MARKER_MISC,
     WPS_TOKEN_BUTTON_VOLUME,
     WPS_TOKEN_LASTTOUCH,
-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
     /* Virtual LED */
     WPS_TOKEN_VLED_HDD,
 #endif
diff --git a/apps/gui/skin_engine/wps_debug.c b/apps/gui/skin_engine/wps_debug.c
index a0bf970..9cc7d94 100644
--- a/apps/gui/skin_engine/wps_debug.c
+++ b/apps/gui/skin_engine/wps_debug.c
@@ -473,7 +473,7 @@ static char *get_token_desc(struct wps_token *token, char *buf,
             break;
 #endif

-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
         case WPS_TOKEN_VLED_HDD:
             snprintf(buf, bufsize, "display virtual HDD LED");
             break;
diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c
index 4710eba..52494c9 100644
--- a/apps/gui/statusbar.c
+++ b/apps/gui/statusbar.c
@@ -122,7 +122,7 @@
                                                 7*ICONS_SPACING
 #define STATUSBAR_LOCKR_WIDTH                   5

-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
 #define STATUSBAR_DISK_WIDTH                    12
 #define STATUSBAR_DISK_X_POS(statusbar_width)   statusbar_width - \
                                                 STATUSBAR_DISK_WIDTH
@@ -145,7 +145,7 @@ static void gui_statusbar_icon_lock(struct screen * display);
 #ifdef HAS_REMOTE_BUTTON_HOLD
 static void gui_statusbar_icon_lock_remote(struct screen * display);
 #endif
-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
 static void gui_statusbar_led(struct screen * display);
 #endif
 #ifdef HAVE_RECORDING
@@ -262,7 +262,7 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw)
     bar->info.repeat = global_settings.repeat_mode;
     bar->info.playmode = current_playmode();

-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
     if(!display->has_disk_led)
         bar->info.led = led_read(HZ/2); /* delay should match polling interval */
 #endif
@@ -351,7 +351,7 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw)
         gui_statusbar_time(display, bar->time);
         bar->last_tm_min = bar->time->tm_min;
 #endif /* CONFIG_RTC */
-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
         if(!display->has_disk_led && bar->info.led)
             gui_statusbar_led(display);
 #endif
@@ -593,7 +593,7 @@ static void gui_statusbar_icon_lock_remote(struct screen * display)
 }
 #endif

-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
 /*
  * no real LED: disk activity in status bar
  */
diff --git a/apps/gui/statusbar.h b/apps/gui/statusbar.h
index 28c8105..15e7ba6 100644
--- a/apps/gui/statusbar.h
+++ b/apps/gui/statusbar.h
@@ -48,7 +48,7 @@ struct status_info {
 #ifdef HAS_REMOTE_BUTTON_HOLD
     bool keylockremote;
 #endif
-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
     bool led; /* disk LED simulation in the status bar */
 #endif

diff --git a/apps/main.c b/apps/main.c
index 3e98343..d2c8d09 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -446,6 +446,9 @@ static void init(void)
 #if CONFIG_TUNER
     radio_init();
 #endif
+#if CONFIG_LED
+    led_init();
+#endif

     /* Keep the order of this 3 (viewportmanager handles statusbars)
      * Must be done before any code uses the multi-screen API */
diff --git a/apps/recorder/icons.h b/apps/recorder/icons.h
index 5f2185e..6840fe2 100644
--- a/apps/recorder/icons.h
+++ b/apps/recorder/icons.h
@@ -138,7 +138,7 @@ extern void statusbar_icon_lock(void);
 #if CONFIG_RTC
 extern void statusbar_time(int hour, int minute);
 #endif
-#if (CONFIG_LED == LED_VIRTUAL)
+#if (CONFIG_LED & LED_VIRTUAL)
 extern void statusbar_led(void);
 #endif

diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index 17c10f7..d3c9ca7 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -63,7 +63,7 @@
 #include "talk.h"
 #include "sound.h"
 #include "storage.h"
-#if (CONFIG_STORAGE & STORAGE_ATA) && (CONFIG_LED == LED_REAL) \
+#if (CONFIG_STORAGE & STORAGE_ATA) && (CONFIG_LED & LED_REAL) \
    && !defined(SIMULATOR)
 #include "ata.h"
 #endif
@@ -1009,7 +1009,7 @@ bool recording_screen(bool no_source)
     int radio_status = (global_settings.rec_source != AUDIO_SRC_FMRADIO) ?
                             FMRADIO_OFF : get_radio_status();
 #endif
-#if (CONFIG_LED == LED_REAL)
+#if (CONFIG_LED & LED_REAL)
     bool led_state = false;
     int led_countdown = 2;
 #endif
@@ -1036,7 +1036,7 @@ bool recording_screen(bool no_source)
     struct audio_recording_options rec_options;
     rec_status = RCSTAT_IN_RECSCREEN;

-#if (CONFIG_STORAGE & STORAGE_ATA) && (CONFIG_LED == LED_REAL) \
+#if (CONFIG_STORAGE & STORAGE_ATA) && (CONFIG_LED & LED_REAL) \
    && !defined(SIMULATOR)
     ata_set_led_enabled(false);
 #endif
@@ -1245,7 +1245,7 @@ bool recording_screen(bool no_source)

         audio_stat = audio_status();

-#if (CONFIG_LED == LED_REAL)
+#if (CONFIG_LED & LED_REAL)

         /*
          * Flash the LED while waiting to record.  Turn it on while
@@ -1572,7 +1572,7 @@ bool recording_screen(bool no_source)
                     if(audio_stat != AUDIO_STATUS_RECORD)
 #endif
                 {
-#if (CONFIG_LED == LED_REAL)
+#if (CONFIG_LED & LED_REAL)
                     /* led is restored at begin of loop / end of function */
                     led(false);
 #endif
@@ -1598,7 +1598,7 @@ bool recording_screen(bool no_source)
             case ACTION_REC_F2:
                 if(audio_stat != AUDIO_STATUS_RECORD)
                 {
-#if (CONFIG_LED == LED_REAL)
+#if (CONFIG_LED & LED_REAL)
                     /* led is restored at begin of loop / end of function */
                     led(false);
 #endif
@@ -1622,7 +1622,7 @@ bool recording_screen(bool no_source)
                 }
                 else
                 {
-#if (CONFIG_LED == LED_REAL)
+#if (CONFIG_LED & LED_REAL)
                     /* led is restored at begin of loop / end of function */
                     led(false);
 #endif
@@ -1928,7 +1928,7 @@ rec_abort:
     if (rec_status & (RCSTAT_CREATED_DIRECTORY | RCSTAT_HAVE_RECORDED))
         reload_directory();

-#if (CONFIG_STORAGE & STORAGE_ATA) && (CONFIG_LED == LED_REAL) \
+#if (CONFIG_STORAGE & STORAGE_ATA) && (CONFIG_LED & LED_REAL) \
    && !defined(SIMULATOR)
     ata_set_led_enabled(true);
 #endif
diff --git a/apps/screen_access.c b/apps/screen_access.c
index 19ab776..2785029 100644
--- a/apps/screen_access.c
+++ b/apps/screen_access.c
@@ -118,7 +118,7 @@ struct screen screens[NB_SCREENS] =
 #endif
         .getcharwidth=screen_helper_getcharwidth,
         .getcharheight=screen_helper_getcharheight,
-#if (CONFIG_LED == LED_VIRTUAL)
+#if (CONFIG_LED & LED_VIRTUAL)
         .has_disk_led=false,
 #elif defined(HAVE_REMOTE_LCD)
         .has_disk_led=true,
diff --git a/apps/screen_access.h b/apps/screen_access.h
index be62478..a5017b0 100644
--- a/apps/screen_access.h
+++ b/apps/screen_access.h
@@ -61,7 +61,7 @@ struct screen
     int (*getcharwidth)(void);
     int (*getcharheight)(void);
     bool is_color;
-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
     bool has_disk_led;
 #endif
 #ifdef HAVE_BUTTONBAR
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 5221d3f..0d23853 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -112,7 +112,9 @@ backlight-sw-fading.c
 #endif /* CONFIG_BACKLIGHT_FADING */

 /* Misc. */
+#if CONFIG_LED
 drivers/led.c
+#endif
 drivers/button.c
 #ifndef SIMULATOR
 #ifdef HAVE_DAC3550A
@@ -487,6 +489,7 @@ drivers/i2c.c
 #ifdef ARCHOS_PLAYER
 #ifndef SIMULATOR
 target/sh/archos/ata-archos.c
+target/sh/archos/led-archos.c
 target/sh/archos/timer-archos.c
 target/sh/archos/ata-as-archos.S
 target/sh/archos/player/button-player.c
@@ -505,7 +508,8 @@ target/sh/archos/ata-archos.c
 target/sh/archos/timer-archos.c
 target/sh/archos/ata-as-archos.S
 target/sh/archos/lcd-archos-bitmap.c
-target/sh/archos/lcd-as-archos-bitmap.S   
+target/sh/archos/lcd-as-archos-bitmap.S
+target/sh/archos/led-archos.c   
 target/sh/archos/recorder/button-recorder.c
 target/sh/archos/recorder/power-recorder.c
 target/sh/archos/recorder/powermgmt-recorder.c
@@ -520,6 +524,7 @@ target/sh/archos/timer-archos.c
 target/sh/archos/ata-as-archos.S
 target/sh/archos/lcd-archos-bitmap.c
 target/sh/archos/lcd-as-archos-bitmap.S
+target/sh/archos/led-archos.c
 target/sh/archos/fm_v2/button-fm_v2.c
 target/sh/archos/fm_v2/power-fm_v2.c
 target/sh/archos/fm_v2/powermgmt-fm_v2.c
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 7c0164a..852fbd4 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -158,7 +158,7 @@ static struct mutex ata_mtx SHAREDBSS_ATTR;
 static int ata_device; /* device 0 (master) or 1 (slave) */

 static int spinup_time = 0;
-#if (CONFIG_LED == LED_REAL)
+#if (CONFIG_LED & LED_REAL)
 static bool ata_led_enabled = true;
 static bool ata_led_on = false;
 #endif
@@ -255,7 +255,7 @@ STATICIRAM ICODE_ATTR int wait_for_end_of_transfer(void)
            == STATUS_RDY;
 }    

-#if (CONFIG_LED == LED_REAL)
+#if (CONFIG_LED & LED_REAL)
 /* Conditionally block LED access for the ATA driver, so the LED can be
  * (mis)used for other purposes */
 static void ata_led(bool on) 
@@ -1411,7 +1411,7 @@ void ata_close(void)
 }
 #endif /* ATA_DRIVER_CLOSE */

-#if (CONFIG_LED == LED_REAL)
+#if (CONFIG_LED & LED_REAL)
 void ata_set_led_enabled(bool enabled) 
 {
     ata_led_enabled = enabled;
diff --git a/firmware/drivers/led.c b/firmware/drivers/led.c
index 2258336..bc67b2d 100644
--- a/firmware/drivers/led.c
+++ b/firmware/drivers/led.c
@@ -20,31 +20,19 @@
  ****************************************************************************/
 #include "config.h"
 #include <stdbool.h>
-#include "cpu.h"
 #include "led.h"
 #include "system.h"
 #include "kernel.h"
+#if CONFIG_LED & LED_REAL
+#include "led-target.h"
+#endif

-#if (CONFIG_LED == LED_REAL)
-
-void led(bool on)
-{
-    if ( on )
-    {
-        or_b(0x40, &PBDRL);
-    }
-    else
-    {
-        and_b(~0x40, &PBDRL);
-    }
-}
-
-#elif (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+#if (CONFIG_LED & LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)

 static bool current;
 static long last_on; /* timestamp of switching off */

-void led(bool on)
+void led_virtual(bool on)
 {
     if (current && !on) /* switching off */
     {
@@ -59,10 +47,25 @@ bool led_read(int delayticks) /* read by status bar update */
     return (current || TIME_BEFORE(current_tick, last_on+delayticks));
 }

-#else
+#endif

 void led(bool on)
 {
+#if CONFIG_LED & LED_REAL
+    led_target(on);
+#endif
+#if CONFIG_LED & LED_VIRTUAL
+    led_virtual(on);
+#endif
+
+#if CONFIG_LED == 0
     (void)on;
+#endif
+}
+
+void led_init(void)
+{
+#if CONFIG_LED & LED_REAL
+    led_init_device();
+#endif
 }
-#endif /* CONFIG_LED, HAVE_REMOTE_LCD */
diff --git a/firmware/export/ata.h b/firmware/export/ata.h
index 5be32da..b53d5f2 100644
--- a/firmware/export/ata.h
+++ b/firmware/export/ata.h
@@ -42,7 +42,7 @@ void ata_close(void);
 int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int count, void* buf);
 int ata_write_sectors(IF_MD2(int drive,) unsigned long start, int count, const void* buf);
 void ata_spin(void);
-#if (CONFIG_LED == LED_REAL)
+#if (CONFIG_LED & LED_REAL)
 void ata_set_led_enabled(bool enabled);
 #endif
 unsigned short* ata_get_identify(void);
diff --git a/firmware/export/config-mini2440.h b/firmware/export/config-mini2440.h
index 5dad250..e3dd280 100644
--- a/firmware/export/config-mini2440.h
+++ b/firmware/export/config-mini2440.h
@@ -50,6 +50,7 @@
    that needs spinups and can cause skips when shaked */
 /* #define HAVE_DISK_STORAGE */

+#define CONFIG_LED (LED_REAL|LED_VIRTUAL)
 /* Display */
 /* define this if you have a bitmap LCD display */
 #define HAVE_LCD_BITMAP
diff --git a/firmware/export/led.h b/firmware/export/led.h
index bcc9a31..401bf2e 100644
--- a/firmware/export/led.h
+++ b/firmware/export/led.h
@@ -24,6 +24,7 @@

 #include <stdbool.h>

+extern void led_init(void);
 extern void led( bool on );
 extern bool led_read(int delayticks);

diff --git a/firmware/storage.c b/firmware/storage.c
index d6700d1..8a3abce 100644
--- a/firmware/storage.c
+++ b/firmware/storage.c
@@ -368,7 +368,7 @@ void storage_spindown(int seconds)
 #endif
 }

-#if (CONFIG_LED == LED_REAL)
+#if (CONFIG_LED & LED_REAL)
 void storage_set_led_enabled(bool enabled)
 {
 #if (CONFIG_STORAGE & STORAGE_ATA)
@@ -391,7 +391,7 @@ void storage_set_led_enabled(bool enabled)
     ramdisk_set_led_enabled(enabled);
 #endif
 }
-#endif /* CONFIG_LED == LED_REAL */
+#endif /* CONFIG_LED & LED_REAL */

 long storage_last_disk_activity(void)
 {
diff --git a/firmware/target/arm/s3c2440/crt0.S b/firmware/target/arm/s3c2440/crt0.S
index 2188bc0..2bee37f 100644
--- a/firmware/target/arm/s3c2440/crt0.S
+++ b/firmware/target/arm/s3c2440/crt0.S
@@ -555,7 +555,7 @@ stackmunge:
     ldr     sp, =stackend

     /* Start the main function */
-    adr     lr, vectors
+    ldr     lr, =vectors
     ldr     pc, =main

     /* Should never get here, but let's restart in case (also needed for
diff --git a/firmware/target/arm/s3c2440/mini2440/led-mini2440.c b/firmware/target/arm/s3c2440/mini2440/led-mini2440.c
index f541d75..0b3ee12 100644
--- a/firmware/target/arm/s3c2440/mini2440/led-mini2440.c
+++ b/firmware/target/arm/s3c2440/mini2440/led-mini2440.c
@@ -21,10 +21,10 @@
 #include "config.h"
 #include "cpu.h"
 #include "kernel.h"
-
+#include "led-target.h"
 /* LED functions for debug */

-void led_init (void)
+void led_init_device (void)
 {
     S3C2440_GPIO_CONFIG (GPBCON, 5, GPIO_OUTPUT);
     S3C2440_GPIO_CONFIG (GPBCON, 6, GPIO_OUTPUT);
@@ -36,6 +36,15 @@ void led_init (void)
     S3C2440_GPIO_PULLUP (GPBUP, 7, GPIO_PULLUP_DISABLE);
     S3C2440_GPIO_PULLUP (GPBUP, 8, GPIO_PULLUP_DISABLE);
 }
+#define SD_ACTIVE_LED   LED4
+
+void led_target(bool on)
+{
+    if (on)
+        set_leds(SD_ACTIVE_LED);
+    else
+        clear_leds(SD_ACTIVE_LED);
+}

 /* Turn on one or more LEDS */
 void set_leds (int led_mask)
diff --git a/firmware/target/arm/s3c2440/mini2440/led-mini2440.h b/firmware/target/arm/s3c2440/mini2440/led-mini2440.h
deleted file mode 100644
index 0aaad1c..0000000
--- a/firmware/target/arm/s3c2440/mini2440/led-mini2440.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2009 by Bob Cousins
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#ifndef _LED_MINI2440_H_
-#define _LED_MINI2440_H_
-
-/* LED functions for debug etc */
-
-#define LED1        0x0020      /* GPB5 */
-#define LED2        0x0040      /* GPB6 */
-#define LED3        0x0080      /* GPB7 */
-#define LED4        0x0100      /* GPB8 */
-
-#define LED_NONE    0x0000
-#define LED_ALL (LED1|LED2|LED3|LED4)
-
-void led_init (void);
-
-/* Turn on one or more LEDS */
-void set_leds (int led_mask);
-
-/* Turn off one or more LEDS */
-void clear_leds (int led_mask);
-
-/* Alternate flash of pattern1 and pattern2 - never returns */
-void led_flash (int led_pattern1, int led_pattern2);
-
-#endif /* _LED_MINI2440_H_ */
diff --git a/firmware/target/arm/s3c2440/mini2440/led-target.h b/firmware/target/arm/s3c2440/mini2440/led-target.h
new file mode 100644
index 0000000..ed1d56a
--- /dev/null
+++ b/firmware/target/arm/s3c2440/mini2440/led-target.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2009 by Bob Cousins
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _LED_MINI2440_H_
+#define _LED_MINI2440_H_
+
+#include <stdbool.h>
+
+/* LED functions for debug etc */
+
+#define LED1        0x0020      /* GPB5 */
+#define LED2        0x0040      /* GPB6 */
+#define LED3        0x0080      /* GPB7 */
+#define LED4        0x0100      /* GPB8 */
+
+#define LED_NONE    0x0000
+#define LED_ALL (LED1|LED2|LED3|LED4)
+
+void led_init_device(void);
+void led_target(bool on);
+
+/* Turn on one or more LEDS */
+void set_leds (int led_mask);
+
+/* Turn off one or more LEDS */
+void clear_leds (int led_mask);
+
+/* Alternate flash of pattern1 and pattern2 - never returns */
+void led_flash (int led_pattern1, int led_pattern2);
+
+#endif /* _LED_MINI2440_H_ */
diff --git a/firmware/target/arm/s3c2440/mini2440/power-mini2440.c b/firmware/target/arm/s3c2440/mini2440/power-mini2440.c
index d4b0075..a90cde9 100644
--- a/firmware/target/arm/s3c2440/mini2440/power-mini2440.c
+++ b/firmware/target/arm/s3c2440/mini2440/power-mini2440.c
@@ -25,7 +25,7 @@
 #include "kernel.h"
 #include "system.h"
 #include "power.h"
-#include "led-mini2440.h"
+#include "led-target.h"

 void power_init(void)
 {
diff --git a/firmware/target/arm/s3c2440/sd-s3c2440.c b/firmware/target/arm/s3c2440/sd-s3c2440.c
index 8aa53d8..25d6837 100644
--- a/firmware/target/arm/s3c2440/sd-s3c2440.c
+++ b/firmware/target/arm/s3c2440/sd-s3c2440.c
@@ -37,7 +37,10 @@
 #endif
 #include "dma-target.h"     
 #include "system-target.h"
-#include "led-mini2440.h"
+#if CONFIG_LED & LED_REAL
+#include "led-target.h"
+#endif
+#include "led.h"

 /* The configuration method is not very flexible. */
 #define CARD_NUM_SLOT   0
@@ -75,7 +78,6 @@
 #define SD_CLK       24000000   /* Clock for SD cards */
 #define MMC_CLK      15000000   /* Clock for MMC cards */

-#define SD_ACTIVE_LED   LED4

 #ifdef SD_DEBUG
 #define dbgprintf uart_printf
@@ -683,7 +685,9 @@ static int sd_transfer_sectors(int card_no, unsigned long start,

     mutex_lock(&sd_mtx);
     sd_enable(true);
-    set_leds(SD_ACTIVE_LED);
+#if CONFIG_LED
+    led(true);
+#endif

 #ifdef HAVE_MULTIDRIVE
     curr_card = card_no;
@@ -851,8 +855,10 @@ sd_transfer_error:

     dma_release();

-    clear_leds(SD_ACTIVE_LED);
     sd_enable(false);
+#if CONFIG_LED
+    led(false);
+#endif

     if (ret)    /* error */
         card_info[card_no].initialized = 0;
diff --git a/firmware/target/sh/archos/led-archos.c b/firmware/target/sh/archos/led-archos.c
new file mode 100644
index 0000000..1f62c04
--- /dev/null
+++ b/firmware/target/sh/archos/led-archos.c
@@ -0,0 +1,38 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Thomas Martitz
+ * Copyright (C) 2002 by Alan Korr
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "cpu.h"
+#include <stdbool.h>
+#include "system.h"
+
+void led_target(bool on)
+{
+    if ( on )
+    {
+        or_b(0x40, &PBDRL);
+    }
+    else
+    {
+        and_b(~0x40, &PBDRL);
+    }
+}
diff --git a/firmware/target/sh/archos/led-target.h b/firmware/target/sh/archos/led-target.h
new file mode 100644
index 0000000..8c75918
--- /dev/null
+++ b/firmware/target/sh/archos/led-target.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2009 Thomas Martitz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef __LED_TARGET_H__
+#define __LED_TARGET_H__
+
+#include <stdbool.h>
+#define led_init_device()
+extern void led_target(bool on);
+#endif