commit a0ef56011d7035c048b3dc7436863b8697e90a5a
Author: Marcin Bukat <marcin.bukat@gmail.com>
Date:   Wed Oct 12 23:32:55 2011 +0200

    Move PortalPlayer stuff to subdir

diff --git a/bootloader/bootloader.make b/bootloader/bootloader.make
index 78b8b43..76dce43 100644
--- a/bootloader/bootloader.make
+++ b/bootloader/bootloader.make
@@ -11,7 +11,7 @@ INCLUDES += -I$(APPSDIR)
 SRC += $(call preprocess, $(APPSDIR)/SOURCES)
 
 CONFIGFILE := $(FIRMDIR)/export/config/$(MODELNAME).h
-BOOTLDS := $(FIRMDIR)/target/$(CPU)/$(MANUFACTURER)/boot.lds
+BOOTLDS := $(FIRMDIR)/target/$(CPU)/$(SOC)/$(MANUFACTURER)/boot.lds
 BOOTLINK := $(BUILDDIR)/boot.link
 
 CLEANOBJS += $(BUILDDIR)/bootloader.*
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 367241d..57b86d8 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -474,7 +474,7 @@ target/arm/ffs-arm.S
 target/arm/system-arm.c
 #endif
 #if CONFIG_I2C == I2C_PP5024 || CONFIG_I2C == I2C_PP5020 || CONFIG_I2C == I2C_PP5002
-target/arm/i2c-pp.c
+target/arm/portalplayer/i2c-pp.c
 #elif CONFIG_I2C == I2C_PNX0101
 target/arm/pnx0101/i2c-pnx0101.c
 #elif CONFIG_I2C == I2C_TCC780X || CONFIG_I2C == I2C_TCC77X 
@@ -560,26 +560,26 @@ target/arm/as3525/pcm-as3525.c
 #endif /* CONFIG_CPU == AS3525 */
 
 #if defined(CPU_PP)
-target/arm/kernel-pp.c
-target/arm/timer-pp.c
+target/arm/portalplayer/kernel-pp.c
+target/arm/portalplayer/timer-pp.c
 #if CONFIG_CPU == PP5002
-target/arm/system-pp5002.c
+target/arm/portalplayer/system-pp5002.c
 #elif defined CPU_PP502x
-target/arm/system-pp502x.c
+target/arm/portalplayer/system-pp502x.c
 #endif
 #ifdef BOOTLOADER
 #ifdef HAVE_BOOTLOADER_USB_MODE
-target/arm/crt0-pp502x-bl-usb.S
+target/arm/portalplayer/crt0-pp502x-bl-usb.S
 #else
-target/arm/crt0-pp-bl.S
+target/arm/portalplayer/crt0-pp-bl.S
 #endif /* HAVE_BOOTLOADER_USB_MODE */
 #else /* !BOOTLOADER */
-target/arm/pcm-pp.c
-target/arm/debug-pp.c
+target/arm/portalplayer/pcm-pp.c
+target/arm/portalplayer/debug-pp.c
 #if !defined(SANSA_E200) && !defined(SANSA_C200)
-target/arm/audio-pp.c
+target/arm/portalplayer/audio-pp.c
 #endif /* SANSA_E200 */
-target/arm/crt0-pp.S
+target/arm/portalplayer/crt0-pp.S
 #endif
 #elif CONFIG_CPU == PNX0101
 target/arm/pnx0101/crt0-pnx0101.S
@@ -701,19 +701,19 @@ target/sh/archos/ondio/fmradio_i2c-ondio.c
 #ifdef SANSA_E200
 #ifndef SIMULATOR
 target/arm/adc-as3514.c
-target/arm/ascodec-pp.c
-target/arm/ata-sd-pp.c
+target/arm/portalplayer/ascodec-pp.c
+target/arm/portalplayer/ata-sd-pp.c
 target/arm/lcd-as-memframe.S
 target/arm/powermgmt-ascodec.c
-target/arm/i2s-pp.c
-target/arm/usb-fw-pp502x.c
-target/arm/sandisk/backlight-c200_e200.c
-target/arm/sandisk/power-c200_e200.c
-target/arm/sandisk/sansa-e200/lcd-e200.c
-target/arm/sandisk/sansa-e200/button-e200.c
-target/arm/sandisk/sansa-e200/powermgmt-e200.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/usb-fw-pp502x.c
+target/arm/portalplayer/sandisk/backlight-c200_e200.c
+target/arm/portalplayer/sandisk/power-c200_e200.c
+target/arm/portalplayer/sandisk/sansa-e200/lcd-e200.c
+target/arm/portalplayer/sandisk/sansa-e200/button-e200.c
+target/arm/portalplayer/sandisk/sansa-e200/powermgmt-e200.c
 #ifndef BOOTLOADER
-target/arm/sandisk/audio-c200_e200.c
+target/arm/portalplayer/sandisk/audio-c200_e200.c
 #endif /* BOOTLOADER */
 #endif /* SIMULATOR */
 #endif /* SANSA_E200 */
@@ -721,19 +721,19 @@ target/arm/sandisk/audio-c200_e200.c
 #ifdef SANSA_C200
 #ifndef SIMULATOR
 target/arm/adc-as3514.c
-target/arm/ascodec-pp.c
-target/arm/ata-sd-pp.c
-target/arm/i2s-pp.c
+target/arm/portalplayer/ascodec-pp.c
+target/arm/portalplayer/ata-sd-pp.c
+target/arm/portalplayer/i2s-pp.c
 target/arm/powermgmt-ascodec.c
-target/arm/usb-fw-pp502x.c
-target/arm/sandisk/backlight-c200_e200.c
-target/arm/sandisk/power-c200_e200.c
+target/arm/portalplayer/usb-fw-pp502x.c
+target/arm/portalplayer/sandisk/backlight-c200_e200.c
+target/arm/portalplayer/sandisk/power-c200_e200.c
 target/arm/lcd-c200_c200v2.c
-target/arm/sandisk/sansa-c200/lcd-as-c200.S
-target/arm/sandisk/sansa-c200/button-c200.c
-target/arm/sandisk/sansa-c200/powermgmt-c200.c
+target/arm/portalplayer/sandisk/sansa-c200/lcd-as-c200.S
+target/arm/portalplayer/sandisk/sansa-c200/button-c200.c
+target/arm/portalplayer/sandisk/sansa-c200/powermgmt-c200.c
 #ifndef BOOTLOADER
-target/arm/sandisk/audio-c200_e200.c
+target/arm/portalplayer/sandisk/audio-c200_e200.c
 #endif /* BOOTLOADER */
 #endif /* SIMULATOR */
 #endif /* SANSA_C200 */
@@ -741,16 +741,16 @@ target/arm/sandisk/audio-c200_e200.c
 #ifdef SANSA_VIEW
 #ifndef SIMULATOR
 /* target/arm/ascodec-pp.c */
-target/arm/ata-sd-pp.c
+target/arm/portalplayer/ata-sd-pp.c
 target/arm/lcd-as-memframe.S
-target/arm/i2s-pp.c
+target/arm/portalplayer/i2s-pp.c
 /* target/arm/usb-fw-pp502x.c */
-target/arm/sandisk/sansa-view/backlight-view.c
-target/arm/sandisk/sansa-view/adc-view.c
-target/arm/sandisk/sansa-view/power-view.c
-target/arm/sandisk/sansa-view/lcd-view.c
-target/arm/sandisk/sansa-view/button-view.c
-target/arm/sandisk/sansa-view/powermgmt-view.c
+target/arm/portalplayer/sandisk/sansa-view/backlight-view.c
+target/arm/portalplayer/sandisk/sansa-view/adc-view.c
+target/arm/portalplayer/sandisk/sansa-view/power-view.c
+target/arm/portalplayer/sandisk/sansa-view/lcd-view.c
+target/arm/portalplayer/sandisk/sansa-view/button-view.c
+target/arm/portalplayer/sandisk/sansa-view/powermgmt-view.c
 #ifndef BOOTLOADER
 /* target/arm/sandisk/audio-view.c */
 #endif /* BOOTLOADER */
@@ -763,17 +763,17 @@ target/arm/sandisk/sansa-view/powermgmt-view.c
 drivers/synaptics-mep.c
 #endif /* BOOTLOADER */
 target/arm/adc-as3514.c
-target/arm/ascodec-pp.c
-target/arm/ata-sd-pp.c
-target/arm/i2s-pp.c
+target/arm/portalplayer/ascodec-pp.c
+target/arm/portalplayer/ata-sd-pp.c
+target/arm/portalplayer/i2s-pp.c
 target/arm/powermgmt-ascodec.c
-target/arm/usb-fw-pp502x.c
-target/arm/philips/sa9200/backlight-sa9200.c
-target/arm/philips/sa9200/button-sa9200.c
-target/arm/philips/sa9200/lcd-sa9200.c
-target/arm/philips/sa9200/lcd-as-sa9200.S
-target/arm/philips/sa9200/power-sa9200.c
-target/arm/philips/sa9200/powermgmt-sa9200.c
+target/arm/portalplayer/usb-fw-pp502x.c
+target/arm/portalplayer/philips/sa9200/backlight-sa9200.c
+target/arm/portalplayer/philips/sa9200/button-sa9200.c
+target/arm/portalplayer/philips/sa9200/lcd-sa9200.c
+target/arm/portalplayer/philips/sa9200/lcd-as-sa9200.S
+target/arm/portalplayer/philips/sa9200/power-sa9200.c
+target/arm/portalplayer/philips/sa9200/powermgmt-sa9200.c
 #endif /* SIMULATOR */
 #endif /* PHILIPS_SA9200 */
 
@@ -783,18 +783,18 @@ target/arm/philips/sa9200/powermgmt-sa9200.c
 drivers/synaptics-mep.c
 #endif /* BOOTLOADER */
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/adc-pp5020.c
-target/arm/philips/power-hdd.c
-target/arm/philips/fmradio_i2c-hdd.c
-target/arm/philips/hdd1630/backlight-hdd1630.c
-target/arm/philips/hdd1630/button-hdd1630.c
-target/arm/philips/hdd1630/lcd-hdd1630.c
-target/arm/philips/hdd1630/lcd-as-hdd1630.S
-target/arm/philips/hdd1630/powermgmt-hdd1630.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/adc-pp5020.c
+target/arm/portalplayer/philips/power-hdd.c
+target/arm/portalplayer/philips/fmradio_i2c-hdd.c
+target/arm/portalplayer/philips/hdd1630/backlight-hdd1630.c
+target/arm/portalplayer/philips/hdd1630/button-hdd1630.c
+target/arm/portalplayer/philips/hdd1630/lcd-hdd1630.c
+target/arm/portalplayer/philips/hdd1630/lcd-as-hdd1630.S
+target/arm/portalplayer/philips/hdd1630/powermgmt-hdd1630.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* PHILIPS_HDD1630 */
 
@@ -804,18 +804,18 @@ target/arm/usb-fw-pp502x.c
 drivers/synaptics-mep.c
 #endif /* BOOTLOADER */
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/adc-pp5020.c
-target/arm/philips/power-hdd.c
-target/arm/philips/fmradio_i2c-hdd.c
-target/arm/philips/hdd6330/backlight-hdd6330.c
-target/arm/philips/hdd6330/button-hdd6330.c
-target/arm/philips/hdd6330/lcd-hdd6330.c
-target/arm/philips/hdd6330/lcd-as-hdd6330.S
-target/arm/philips/hdd6330/powermgmt-hdd6330.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/adc-pp5020.c
+target/arm/portalplayer/philips/power-hdd.c
+target/arm/portalplayer/philips/fmradio_i2c-hdd.c
+target/arm/portalplayer/philips/hdd6330/backlight-hdd6330.c
+target/arm/portalplayer/philips/hdd6330/button-hdd6330.c
+target/arm/portalplayer/philips/hdd6330/lcd-hdd6330.c
+target/arm/portalplayer/philips/hdd6330/lcd-as-hdd6330.S
+target/arm/portalplayer/philips/hdd6330/powermgmt-hdd6330.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* PHILIPS_HDD6330 */
 
@@ -953,35 +953,35 @@ target/coldfire/iriver/h100/usb-h100.c
 #ifdef IRIVER_H10
 #ifndef SIMULATOR
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/adc-pp5020.c
-target/arm/iriver/h10/backlight-h10.c
-target/arm/iriver/h10/button-h10.c
-target/arm/iriver/h10/fmradio_i2c-h10.c
-target/arm/iriver/h10/lcd-h10_20gb.c
-target/arm/iriver/h10/lcd-as-h10.S
-target/arm/iriver/h10/power-h10.c
-target/arm/iriver/h10/powermgmt-h10.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/adc-pp5020.c
+target/arm/portalplayer/iriver/h10/backlight-h10.c
+target/arm/portalplayer/iriver/h10/button-h10.c
+target/arm/portalplayer/iriver/h10/fmradio_i2c-h10.c
+target/arm/portalplayer/iriver/h10/lcd-h10_20gb.c
+target/arm/portalplayer/iriver/h10/lcd-as-h10.S
+target/arm/portalplayer/iriver/h10/power-h10.c
+target/arm/portalplayer/iriver/h10/powermgmt-h10.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* IRIVER_H10 */
 
 #ifdef IRIVER_H10_5GB
 #ifndef SIMULATOR
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/adc-pp5020.c
-target/arm/iriver/h10/backlight-h10.c
-target/arm/iriver/h10/button-h10.c
-target/arm/iriver/h10/fmradio_i2c-h10.c
-target/arm/iriver/h10/lcd-h10_5gb.c
-target/arm/iriver/h10/power-h10.c
-target/arm/iriver/h10/powermgmt-h10.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/adc-pp5020.c
+target/arm/portalplayer/iriver/h10/backlight-h10.c
+target/arm/portalplayer/iriver/h10/button-h10.c
+target/arm/portalplayer/iriver/h10/fmradio_i2c-h10.c
+target/arm/portalplayer/iriver/h10/lcd-h10_5gb.c
+target/arm/portalplayer/iriver/h10/power-h10.c
+target/arm/portalplayer/iriver/h10/powermgmt-h10.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* IRIVER_H10_5GB */
 
@@ -1110,55 +1110,55 @@ target/arm/tms320dm320/creative-zvm/usb-creativezvm.c
 #ifndef SIMULATOR
 #ifndef BOOTLOADER
 drivers/synaptics-mep.c
-target/arm/olympus/mrobe-100/lcd-remote-mr100.c
+target/arm/portalplayer/olympus/mrobe-100/lcd-remote-mr100.c
 #endif /* BOOTLOADER */
 drivers/sw_i2c.c
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/adc-pp5020.c
-target/arm/olympus/mrobe-100/backlight-mr100.c
-target/arm/olympus/mrobe-100/button-mr100.c
-target/arm/olympus/mrobe-100/lcd-mr100.c
-target/arm/olympus/mrobe-100/lcd-as-mr100.S
-target/arm/olympus/mrobe-100/power-mr100.c
-target/arm/olympus/mrobe-100/powermgmt-mr100.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/adc-pp5020.c
+target/arm/portalplayer/olympus/mrobe-100/backlight-mr100.c
+target/arm/portalplayer/olympus/mrobe-100/button-mr100.c
+target/arm/portalplayer/olympus/mrobe-100/lcd-mr100.c
+target/arm/portalplayer/olympus/mrobe-100/lcd-as-mr100.S
+target/arm/portalplayer/olympus/mrobe-100/power-mr100.c
+target/arm/portalplayer/olympus/mrobe-100/powermgmt-mr100.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* MROBE_100 */
 
 #ifdef TATUNG_TPJ1022
 #ifndef SIMULATOR
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/adc-pp5020.c
-target/arm/tatung/tpj1022/backlight-tpj1022.c
-target/arm/tatung/tpj1022/button-tpj1022.c
-target/arm/tatung/tpj1022/lcd-tpj1022.c
-target/arm/tatung/tpj1022/power-tpj1022.c
-target/arm/tatung/tpj1022/powermgmt-tpj1022.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/adc-pp5020.c
+target/arm/portalplayer/tatung/tpj1022/backlight-tpj1022.c
+target/arm/portalplayer/tatung/tpj1022/button-tpj1022.c
+target/arm/portalplayer/tatung/tpj1022/lcd-tpj1022.c
+target/arm/portalplayer/tatung/tpj1022/power-tpj1022.c
+target/arm/portalplayer/tatung/tpj1022/powermgmt-tpj1022.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* TATUNG_TPJ1022 */
 
 #ifdef IPOD_4G
 #ifndef SIMULATOR
 drivers/pcf50605.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/ipod/adc-ipod-pcf.c
-target/arm/ipod/backlight-4g_color.c
-target/arm/ipod/button-clickwheel.c
-target/arm/ipod/lcd-as-gray.S
-target/arm/ipod/lcd-gray.c
-target/arm/ipod/power-ipod.c
-target/arm/ipod/powermgmt-ipod-pcf.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/ipod/adc-ipod-pcf.c
+target/arm/portalplayer/ipod/backlight-4g_color.c
+target/arm/portalplayer/ipod/button-clickwheel.c
+target/arm/portalplayer/ipod/lcd-as-gray.S
+target/arm/portalplayer/ipod/lcd-gray.c
+target/arm/portalplayer/ipod/power-ipod.c
+target/arm/portalplayer/ipod/powermgmt-ipod-pcf.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* IPOD_4G */
 
@@ -1166,17 +1166,17 @@ target/arm/usb-fw-pp502x.c
 #ifndef SIMULATOR
 drivers/pcf50605.c
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/ipod/adc-ipod-pcf.c
-target/arm/ipod/backlight-4g_color.c
-target/arm/ipod/button-clickwheel.c
-target/arm/ipod/lcd-color_nano.c
-target/arm/ipod/lcd-as-color-nano.S
-target/arm/ipod/power-ipod.c
-target/arm/ipod/powermgmt-ipod-pcf.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/ipod/adc-ipod-pcf.c
+target/arm/portalplayer/ipod/backlight-4g_color.c
+target/arm/portalplayer/ipod/button-clickwheel.c
+target/arm/portalplayer/ipod/lcd-color_nano.c
+target/arm/portalplayer/ipod/lcd-as-color-nano.S
+target/arm/portalplayer/ipod/power-ipod.c
+target/arm/portalplayer/ipod/powermgmt-ipod-pcf.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* IPOD_COLOR */
 
@@ -1184,17 +1184,17 @@ target/arm/usb-fw-pp502x.c
 #ifndef SIMULATOR
 drivers/pcf50605.c
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/ipod/adc-ipod-pcf.c
-target/arm/ipod/backlight-nano_video.c
-target/arm/ipod/button-clickwheel.c
-target/arm/ipod/lcd-color_nano.c
-target/arm/ipod/lcd-as-color-nano.S
-target/arm/ipod/power-ipod.c
-target/arm/ipod/powermgmt-ipod-pcf.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/ipod/adc-ipod-pcf.c
+target/arm/portalplayer/ipod/backlight-nano_video.c
+target/arm/portalplayer/ipod/button-clickwheel.c
+target/arm/portalplayer/ipod/lcd-color_nano.c
+target/arm/portalplayer/ipod/lcd-as-color-nano.S
+target/arm/portalplayer/ipod/power-ipod.c
+target/arm/portalplayer/ipod/powermgmt-ipod-pcf.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* IPOD_NANO */
 
@@ -1202,53 +1202,53 @@ target/arm/usb-fw-pp502x.c
 #ifndef SIMULATOR
 drivers/pcf50605.c
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/ipod/adc-ipod-pcf.c
-target/arm/ipod/backlight-nano_video.c
-target/arm/ipod/button-clickwheel.c
-target/arm/ipod/power-ipod.c
-target/arm/ipod/powermgmt-ipod-pcf.c
-target/arm/ipod/video/lcd-as-video.S
-target/arm/ipod/video/lcd-video.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/ipod/adc-ipod-pcf.c
+target/arm/portalplayer/ipod/backlight-nano_video.c
+target/arm/portalplayer/ipod/button-clickwheel.c
+target/arm/portalplayer/ipod/power-ipod.c
+target/arm/portalplayer/ipod/powermgmt-ipod-pcf.c
+target/arm/portalplayer/ipod/video/lcd-as-video.S
+target/arm/portalplayer/ipod/video/lcd-video.c
 #ifndef BOOTLOADER
-target/arm/ipod/video/battery-video.c
+target/arm/portalplayer/ipod/video/battery-video.c
 #endif /* BOOTLOADER */
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* IPOD_VIDEO */
 
 #ifdef IPOD_3G
 #ifndef SIMULATOR
 drivers/pcf50605.c
-target/arm/ata-pp5002.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/ipod/adc-ipod-pcf.c
-target/arm/ipod/3g/backlight-3g.c
-target/arm/ipod/button-1g-3g.c
-target/arm/ipod/lcd-as-gray.S
-target/arm/ipod/lcd-gray.c
-target/arm/ipod/power-ipod.c
-target/arm/ipod/powermgmt-ipod-pcf.c
-target/arm/usb-fw-pp5002.c
+target/arm/portalplayer/ata-pp5002.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/ipod/adc-ipod-pcf.c
+target/arm/portalplayer/ipod/3g/backlight-3g.c
+target/arm/portalplayer/ipod/button-1g-3g.c
+target/arm/portalplayer/ipod/lcd-as-gray.S
+target/arm/portalplayer/ipod/lcd-gray.c
+target/arm/portalplayer/ipod/power-ipod.c
+target/arm/portalplayer/ipod/powermgmt-ipod-pcf.c
+target/arm/portalplayer/usb-fw-pp5002.c
 #endif /* SIMULATOR */
 #endif /* IPOD_3G */
 
 #ifdef IPOD_1G2G
 #ifndef SIMULATOR
-target/arm/ata-pp5002.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/ipod/1g2g/adc-ipod-1g2g.c
-target/arm/ipod/1g2g/backlight-1g2g.c
-target/arm/ipod/1g2g/powermgmt-1g2g.c
-target/arm/ipod/button-1g-3g.c
-target/arm/ipod/lcd-as-gray.S
-target/arm/ipod/lcd-gray.c
-target/arm/ipod/power-ipod.c
-target/arm/usb-fw-pp5002.c
+target/arm/portalplayer/ata-pp5002.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/ipod/1g2g/adc-ipod-1g2g.c
+target/arm/portalplayer/ipod/1g2g/backlight-1g2g.c
+target/arm/portalplayer/ipod/1g2g/powermgmt-1g2g.c
+target/arm/portalplayer/ipod/button-1g-3g.c
+target/arm/portalplayer/ipod/lcd-as-gray.S
+target/arm/portalplayer/ipod/lcd-gray.c
+target/arm/portalplayer/ipod/power-ipod.c
+target/arm/portalplayer/usb-fw-pp5002.c
 #endif /* SIMULATOR */
 #endif /* IPOD_1G2G */
 
@@ -1256,17 +1256,17 @@ target/arm/usb-fw-pp5002.c
 #ifndef SIMULATOR
 drivers/pcf50605.c
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/ipod/adc-ipod-pcf.c
-target/arm/ipod/backlight-mini1g_mini2g.c
-target/arm/ipod/button-mini1g.c
-target/arm/ipod/lcd-as-gray.S
-target/arm/ipod/lcd-gray.c
-target/arm/ipod/power-ipod.c
-target/arm/ipod/powermgmt-ipod-pcf.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/ipod/adc-ipod-pcf.c
+target/arm/portalplayer/ipod/backlight-mini1g_mini2g.c
+target/arm/portalplayer/ipod/button-mini1g.c
+target/arm/portalplayer/ipod/lcd-as-gray.S
+target/arm/portalplayer/ipod/lcd-gray.c
+target/arm/portalplayer/ipod/power-ipod.c
+target/arm/portalplayer/ipod/powermgmt-ipod-pcf.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* IPOD_MINI */
 
@@ -1274,17 +1274,17 @@ target/arm/usb-fw-pp502x.c
 #ifndef SIMULATOR
 drivers/pcf50605.c
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/ipod/adc-ipod-pcf.c
-target/arm/ipod/backlight-mini1g_mini2g.c
-target/arm/ipod/button-clickwheel.c
-target/arm/ipod/lcd-as-gray.S
-target/arm/ipod/lcd-gray.c
-target/arm/ipod/power-ipod.c
-target/arm/ipod/powermgmt-ipod-pcf.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/ipod/adc-ipod-pcf.c
+target/arm/portalplayer/ipod/backlight-mini1g_mini2g.c
+target/arm/portalplayer/ipod/button-clickwheel.c
+target/arm/portalplayer/ipod/lcd-as-gray.S
+target/arm/portalplayer/ipod/lcd-gray.c
+target/arm/portalplayer/ipod/power-ipod.c
+target/arm/portalplayer/ipod/powermgmt-ipod-pcf.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif /* IPOD_MINI2G */
 
@@ -1768,51 +1768,51 @@ target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c
 #ifdef SAMSUNG_YH820
 #ifndef SIMULATOR
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/adc-pp5020.c
-target/arm/i2s-pp.c
-target/arm/usb-fw-pp502x.c
-target/arm/samsung/akcodec-yh82x_yh92x.c
-target/arm/samsung/button-yh82x_yh92x.c
-target/arm/samsung/power-yh82x_yh92x.c
-target/arm/samsung/yh820/backlight-yh820.c
-target/arm/samsung/yh820/lcd-yh820.c
-target/arm/samsung/yh820/lcd-as-yh820.S
-target/arm/samsung/yh820/powermgmt-yh820.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/adc-pp5020.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/usb-fw-pp502x.c
+target/arm/portalplayer/samsung/akcodec-yh82x_yh92x.c
+target/arm/portalplayer/samsung/button-yh82x_yh92x.c
+target/arm/portalplayer/samsung/power-yh82x_yh92x.c
+target/arm/portalplayer/samsung/yh820/backlight-yh820.c
+target/arm/portalplayer/samsung/yh820/lcd-yh820.c
+target/arm/portalplayer/samsung/yh820/lcd-as-yh820.S
+target/arm/portalplayer/samsung/yh820/powermgmt-yh820.c
 #endif /* SIMULATOR */
 #endif /* SAMSUNG_YH820 */
 
 #ifdef SAMSUNG_YH920
 #ifndef SIMULATOR
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/adc-pp5020.c
-target/arm/i2s-pp.c
-target/arm/usb-fw-pp502x.c
-target/arm/samsung/akcodec-yh82x_yh92x.c
-target/arm/samsung/button-yh82x_yh92x.c
-target/arm/samsung/power-yh82x_yh92x.c
-target/arm/samsung/yh920/backlight-yh920.c
-target/arm/samsung/yh920/lcd-yh920.c
-target/arm/samsung/yh920/lcd-as-yh920.S
-target/arm/samsung/yh920/powermgmt-yh920.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/adc-pp5020.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/usb-fw-pp502x.c
+target/arm/portalplayer/samsung/akcodec-yh82x_yh92x.c
+target/arm/portalplayer/samsung/button-yh82x_yh92x.c
+target/arm/portalplayer/samsung/power-yh82x_yh92x.c
+target/arm/portalplayer/samsung/yh920/backlight-yh920.c
+target/arm/portalplayer/samsung/yh920/lcd-yh920.c
+target/arm/portalplayer/samsung/yh920/lcd-as-yh920.S
+target/arm/portalplayer/samsung/yh920/powermgmt-yh920.c
 #endif /* SIMULATOR */
 #endif /* SAMSUNG_YH920 */
 
 #ifdef SAMSUNG_YH925
 #ifndef SIMULATOR
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/adc-pp5020.c
-target/arm/i2s-pp.c
-target/arm/usb-fw-pp502x.c
-target/arm/samsung/akcodec-yh82x_yh92x.c
-target/arm/samsung/button-yh82x_yh92x.c
-target/arm/samsung/power-yh82x_yh92x.c
-target/arm/samsung/yh925/backlight-yh925.c
-target/arm/samsung/yh925/lcd-yh925.c
-target/arm/samsung/yh925/lcd-as-yh925.S
-target/arm/samsung/yh925/powermgmt-yh925.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/adc-pp5020.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/usb-fw-pp502x.c
+target/arm/portalplayer/samsung/akcodec-yh82x_yh92x.c
+target/arm/portalplayer/samsung/button-yh82x_yh92x.c
+target/arm/portalplayer/samsung/power-yh82x_yh92x.c
+target/arm/portalplayer/samsung/yh925/backlight-yh925.c
+target/arm/portalplayer/samsung/yh925/lcd-yh925.c
+target/arm/portalplayer/samsung/yh925/lcd-as-yh925.S
+target/arm/portalplayer/samsung/yh925/powermgmt-yh925.c
 #endif /* SIMULATOR */
 #endif /* SAMSUNG_YH925 */
 
@@ -1837,17 +1837,17 @@ target/arm/s5l8700/yps3/power-yps3.c
 #ifndef SIMULATOR
 drivers/synaptics-mep.c
 target/arm/ata-as-arm.S
-target/arm/ata-pp5020.c
-target/arm/wmcodec-pp.c
-target/arm/i2s-pp.c
-target/arm/adc-pp5020.c
-target/arm/pbell/vibe500/lcd-vibe500.c
-target/arm/pbell/vibe500/button-vibe500.c
-target/arm/pbell/vibe500/power-vibe500.c
-target/arm/pbell/vibe500/backlight-vibe500.c
-target/arm/pbell/vibe500/lcd-as-vibe500.S
-target/arm/pbell/vibe500/powermgmt-vibe500.c
-target/arm/usb-fw-pp502x.c
+target/arm/portalplayer/ata-pp5020.c
+target/arm/portalplayer/wmcodec-pp.c
+target/arm/portalplayer/i2s-pp.c
+target/arm/portalplayer/adc-pp5020.c
+target/arm/portalplayer/pbell/vibe500/lcd-vibe500.c
+target/arm/portalplayer/pbell/vibe500/button-vibe500.c
+target/arm/portalplayer/pbell/vibe500/power-vibe500.c
+target/arm/portalplayer/pbell/vibe500/backlight-vibe500.c
+target/arm/portalplayer/pbell/vibe500/lcd-as-vibe500.S
+target/arm/portalplayer/pbell/vibe500/powermgmt-vibe500.c
+target/arm/portalplayer/usb-fw-pp502x.c
 #endif /* SIMULATOR */
 #endif
 
diff --git a/firmware/target/arm/adc-pp5020.c b/firmware/target/arm/adc-pp5020.c
deleted file mode 100644
index 2d75a7e..0000000
--- a/firmware/target/arm/adc-pp5020.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 "system.h"
-#include "kernel.h"
-#include "thread.h"
-#include "adc.h"
-
-#define ADC_ADDR            (*(volatile unsigned long*)(0x7000ad00))
-#define ADC_STATUS          (*(volatile unsigned long*)(0x7000ad04))
-#define ADC_DATA_1          (*(volatile unsigned long*)(0x7000ad20))
-#define ADC_DATA_2          (*(volatile unsigned long*)(0x7000ad24))
-#define ADC_INIT            (*(volatile unsigned long*)(0x7000ad2c))
-
-#if defined(PBELL_VIBE500)
-#define ADC_UNK             (*(volatile unsigned long*)(0x7000002c))
-#endif
-
-static unsigned short adcdata[NUM_ADC_CHANNELS];
-
-/* Scan ADC so that adcdata[channel] gets updated. */
-unsigned short adc_scan(int channel)
-{
-    unsigned int adc_data_1;
-    unsigned int adc_data_2;
-
-    if (channel >= NUM_ADC_CHANNELS)
-        return 0;
-
-    /* Start conversion */
-    ADC_ADDR |= 0x80000000;
-
-    /* Wait for conversion to complete */
-    while((ADC_STATUS & (0x40<<8*channel))==0);
-
-    /* Stop conversion */
-    ADC_ADDR &=~ 0x80000000;
-
-    /* ADC_DATA_1 and ADC_DATA_2 are both four bytes, one byte per channel.
-       For each channel, ADC_DATA_1 stores the 8-bit msb, ADC_DATA_2 stores the
-       2-bit lsb (in bits 0 and 1). Each channel is 10 bits total. */
-    adc_data_1 = ((ADC_DATA_1 >> (8*channel)) & 0xff);
-    adc_data_2 = ((ADC_DATA_2 >> (8*channel+6)) & 0x3);
-
-    adcdata[channel] = (adc_data_1<<2 | adc_data_2);
-
-#if !(defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330))
-    /* ADC values read low if PLL is enabled */
-    if(PLL_CONTROL & 0x80000000){
-        adcdata[channel] += 0x14;
-        if(adcdata[channel] > 0x400)
-            adcdata[channel] = 0x400;
-    }
-#endif
-
-    return adcdata[channel];
-}
-
-/* Read 10-bit channel data */
-unsigned short adc_read(int channel)
-{
-    return adcdata[channel];
-}
-
-static int adc_counter;
-
-static void adc_tick(void)
-{
-    if(++adc_counter == HZ)
-    {
-        adc_counter = 0;
-        adc_scan(0);
-        adc_scan(1);
-        adc_scan(2);
-        adc_scan(3);
-    }
-}
-
-/* Figured out from how the OF does things */
-void adc_init(void)
-{
-#if defined(PBELL_VIBE500)
-    ADC_UNK |= 0x1000;
-#endif
-
-#if defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
-    ADC_INIT = 0;
-#else
-    ADC_INIT |= 1;
-    ADC_INIT |= 0x40000000;
-#endif
-    udelay(100);
-
-    /* Reset ADC */
-    DEV_RS2 |= 0x20;
-    udelay(100);
-
-    DEV_RS2 &=~ 0x20;
-    udelay(100);
-
-    /* Enable ADC */
-    DEV_EN2 |= 0x20;
-    udelay(100);
-
-    ADC_CLOCK_SRC |= 0x3;
-    udelay(100);
-
-    ADC_ADDR = 0;
-    ADC_ADDR |= 0x40;
-
-#if !(defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330))
-    ADC_ADDR |= 0x20000000;
-    udelay(100);
-
-    ADC_INIT;
-    ADC_INIT = 0;
-    udelay(100);
-#endif
-
-    ADC_STATUS = 0;
-
-    /* Enable channel 0 (battery) */
-    DEV_INIT1  &=~0x3;
-    ADC_ADDR   |= 0x1000000;
-    ADC_STATUS |= 0x20;
-
-    /* Enable channel 1 (unknown) */
-    DEV_INIT1  &=~30;
-    ADC_ADDR   |= 0x2000000;
-    ADC_STATUS |= 0x2000;
-
-#if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || \
-    defined(MROBE_100)
-    /* Enable channel 2 (H10:remote) */
-    DEV_INIT1  &=~0x300;
-    DEV_INIT1  |= 0x100;
-    ADC_ADDR   |= 0x4000000;
-    ADC_STATUS |= 0x200000;
-
-    /* Enable channel 3 (H10:scroll pad) */
-    DEV_INIT1  &=~0x3000;
-    DEV_INIT1  |= 0x1000;
-    ADC_ADDR   |= 0x8000000;
-    ADC_STATUS |= 0x20000000;
-#endif
-
-#if defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
-    ADC_INIT |= 0x80000000;
-    udelay(100);
-    ADC_INIT = 0;
-#endif
-
-    /* Force a scan of all channels to get initial values */
-    adc_scan(0);
-    adc_scan(1);
-    adc_scan(2);
-    adc_scan(3);
-
-    tick_add_task(adc_tick);
-}
diff --git a/firmware/target/arm/ascodec-pp.c b/firmware/target/arm/ascodec-pp.c
deleted file mode 100644
index 49a69d1..0000000
--- a/firmware/target/arm/ascodec-pp.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Driver for AS3514 audio codec
- *
- * Copyright (c) 2007 Daniel Ankers
- * Copyright (c) 2007 Christian Gmeiner
- *
- * 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 "cpu.h"
-#include "system.h"
-
-#include "audiohw.h"
-#include "i2s.h"
-#include "ascodec-target.h"
-
-/*
- * Initialise the PP I2C and I2S.
- */
-void audiohw_init(void)
-{
-    /* normal outputs for CDI and I2S pin groups */
-    DEV_INIT2 &= ~0x300;
-
-    /*mini2?*/
-    DEV_INIT1 &=~0x3000000;
-    /*mini2?*/
-
-    /* I2S device reset */
-    DEV_RS |= DEV_I2S;
-    DEV_RS &=~DEV_I2S;
-
-    /* I2S device enable */
-    DEV_EN |= DEV_I2S;
-
-    /* enable external dev clock clocks */
-    DEV_EN |= DEV_EXTCLOCKS;
-
-    /* external dev clock to 24MHz */
-    outl(inl(0x70000018) & ~0xc, 0x70000018);
-
-#ifdef SANSA_E200
-    /* Prevent pops on startup */
-    GPIOG_ENABLE |= 0x08;
-    GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, 0x08);
-    GPIOG_OUTPUT_EN |= 0x08;
-#endif
-
-    i2s_reset();
-
-    audiohw_preinit();
-}
-
-void ascodec_suppressor_on(bool on)
-{
-    /* CHECK: Good for c200 too? */
-#ifdef SANSA_E200
-    if (on) {
-        /* Set pop prevention */
-        GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, 0x08);
-    } else {
-        /* Release pop prevention */
-        GPIO_CLEAR_BITWISE(GPIOG_OUTPUT_VAL, 0x08);
-    }
-#else
-    (void)on;
-#endif
-} 
diff --git a/firmware/target/arm/ascodec-target.h b/firmware/target/arm/ascodec-target.h
deleted file mode 100644
index 68d9905..0000000
--- a/firmware/target/arm/ascodec-target.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Driver for AS3514 audio codec
- *
- * Copyright (c) 2007 Daniel Ankers
- * Copyright (c) 2007 Christian Gmeiner
- *
- * 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 _ASCODEC_TARGET_H
-#define _ASCODEC_TARGET_H
-
-#include "config.h"
-
-#ifdef CPU_PP
-/* TODO: This header is actually portalplayer specific, and should be
- * moved into an appropriate subdir  */
-
-#include "as3514.h"
-#include "i2c-pp.h"
-
-static inline int ascodec_write(unsigned int reg, unsigned int value)
-{
-    return pp_i2c_send(AS3514_I2C_ADDR, reg, value);
-}
-
-static inline int ascodec_read(unsigned int reg)
-{
-    return i2c_readbyte(AS3514_I2C_ADDR, reg);
-}
-
-static inline int ascodec_readbytes(int addr, int len, unsigned char *data)
-{
-    return i2c_readbytes(AS3514_I2C_ADDR, addr, len, data);
-}
-
-static inline void ascodec_lock(void)
-{
-    i2c_lock();
-}
-
-static inline void ascodec_unlock(void)
-{
-    i2c_unlock();
-}
-
-static inline bool ascodec_chg_status(void)
-{
-    return ascodec_read(AS3514_IRQ_ENRD0) & CHG_STATUS;
-}
-
-static inline bool ascodec_endofch(void)
-{
-    return ascodec_read(AS3514_IRQ_ENRD0) & CHG_ENDOFCH;
-}
-
-static inline void ascodec_monitor_endofch(void)
-{
-    ascodec_write(AS3514_IRQ_ENRD0, IRQ_ENDOFCH);
-}
-
-static inline void ascodec_wait_adc_finished(void)
-{
-    /*
-     * FIXME: not implemented
-     *
-     * If irqs are not available on the target platform,
-     * this should be most likely implemented by polling
-     * AS3514_IRQ_ENRD2 in the same way powermgmt-ascodec.c
-     * is polling IRQ_ENDOFCH.
-     */
-}
-
-static inline void ascodec_write_charger(int value)
-{
-    ascodec_write(AS3514_CHARGER, value);
-}
-
-static inline int ascodec_read_charger(void)
-{
-    return ascodec_read(AS3514_CHARGER);
-}
-
-extern void ascodec_suppressor_on(bool on);
-
-#endif /* CPU_PP */
-
-#endif /* !_ASCODEC_TARGET_H */
diff --git a/firmware/target/arm/ata-pp5002.c b/firmware/target/arm/ata-pp5002.c
deleted file mode 100644
index 2c4bb3b..0000000
--- a/firmware/target/arm/ata-pp5002.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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.
- *
- ****************************************************************************/
-
-/* ATA stuff was taken from the iPod code */
-
-#include <stdbool.h>
-#include "system.h"
-#include "ata.h"
-#include "ata-target.h"
-
-void ata_reset() 
-{
-
-}
-
-void ata_enable(bool on)
-{
-    /* TODO: Implement ata_enable() */
-    (void)on;
-}
-
-bool ata_is_coldstart()
-{
-    return false;
-    /* TODO: Implement coldstart variable */
-}
-
-void ata_device_init()
-{
-   /* From ipod-ide.c:ipod_ide_register() */
-    outl(inl(0xc0003024) | (1 << 7), 0xc0003024);
-    outl(inl(0xc0003024) & ~(1<<2), 0xc0003024);
-
-    outl(0x10, 0xc0003000);
-    outl(0x80002150, 0xc0003004);
-}
diff --git a/firmware/target/arm/ata-pp5020.c b/firmware/target/arm/ata-pp5020.c
deleted file mode 100644
index 0eb6435..0000000
--- a/firmware/target/arm/ata-pp5020.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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.
- *
- ****************************************************************************/
-
-/* ATA stuff was taken from the iPod code */
-
-#include <stdbool.h>
-#include "system.h"
-#include "ata.h"
-#include "ata-target.h"
-
-void ata_reset() 
-{
-
-}
-
-void ata_enable(bool on)
-{
-    /* TODO: Implement ata_enable() */
-    (void)on;
-}
-
-bool ata_is_coldstart()
-{
-    return false;
-    /* TODO: Implement coldstart variable */
-}
-
-void ata_device_init()
-{
-#ifdef SAMSUNG_YH920
-    CPU_INT_DIS = (1<<IDE_IRQ);
-#endif
-#ifdef HAVE_ATA_DMA
-    IDE_DMA_CONTROL |= 2;
-    IDE_DMA_CONTROL &= ~1;
-    IDE0_CFG &= ~0x8010;
-    IDE0_CFG |= 0x20; 
-#else
-
-    /* From ipod-ide.c:ipod_ide_register() */
-    IDE0_CFG |= (1<<5);
-#ifdef IPOD_NANO
-    IDE0_CFG |= (0x10000000); /* cpu > 65MHz */
-#else
-    IDE0_CFG &=~(0x10000000); /* cpu < 65MHz */
-#endif
-#endif
-
-    IDE0_PRI_TIMING0 = 0x10;
-    IDE0_PRI_TIMING1 = 0x80002150;
-}
-
-/* These are PIO timings for 80 Mhz.  At 24 Mhz, 
-   the first value is 0 but the rest are the same.
-   They go in IDE0_PRI_TIMING0.
-   
-   Rockbox used 0x10, and test_disk shows that leads to faster PIO.   
-   If 0x10 is incorrect, these timings may be needed with some devices.
-static const unsigned long pio80mhz[] = {
-    0xC293, 0x43A2, 0x11A1, 0x7232, 0x3131
-}; 
-*/
-
-#ifdef HAVE_ATA_DMA
-/* Timings for multi-word and ultra DMA modes.
-   These go in IDE0_PRI_TIMING1
- */
-static const unsigned long tm_mwdma[] = {
-    0xF9F92, 0x56562, 0x45451 
-};
-
-static const unsigned long tm_udma[] = { 
-    0x800037C1, 0x80003491, 0x80003371, 
-#if ATA_MAX_UDMA > 2       
-    0x80003271, 0x80003071 
-#endif
-};
-
-#if ATA_MAX_UDMA > 2
-static bool dma_boosted = false;
-static bool dma_needs_boost;
-#endif
-
-/* This function sets up registers for 80 Mhz.
-   Ultra DMA mode 2 works at 30 Mhz.
- */
-void ata_dma_set_mode(unsigned char mode) {
-    int modeidx;
-
-    (*(volatile unsigned long *)(0x600060C4)) = 0xC0000000; /* 80 Mhz */
-#if !defined(IPOD_NANO)
-    IDE0_CFG &= ~0x10000000;
-#endif
-
-    modeidx = mode & 7;
-    mode &= 0xF8;
-    if (mode == 0x40 && modeidx <= ATA_MAX_UDMA) {
-        IDE0_PRI_TIMING1 = tm_udma[modeidx];
-#if ATA_MAX_UDMA > 2
-        if (modeidx > 2)
-            dma_needs_boost = true;
-        else
-            dma_needs_boost = false;
-#endif
-    } else if (mode == 0x20 && modeidx <= ATA_MAX_MWDMA)
-        IDE0_PRI_TIMING1 = tm_mwdma[modeidx];
-
-#if !defined(IPOD_NANO)
-    IDE0_CFG |= 0x20000000; /* >= 50 Mhz */
-#endif
-} 
-
-#define IDE_CFG_INTRQ           8
-#define IDE_DMA_CONTROL_READ    8
-
-/* This waits for an ATA interrupt using polling.
-   In ATA_CONTROL, CONTROL_nIEN must be cleared.
- */
-STATICIRAM ICODE_ATTR int ata_wait_intrq(void)
-{
-    long timeout = current_tick + HZ*10;
-    
-    do 
-    {
-        if (IDE0_CFG & IDE_CFG_INTRQ)
-            return 1;
-        ata_keep_active();
-        yield();
-    } while (TIME_BEFORE(current_tick, timeout));
-
-    return 0; /* timeout */
-}
-
-/* This function checks if parameters are appropriate for DMA, 
-   and if they are, it sets up for DMA.
-   
-   If return value is false, caller may use PIO for this transfer.
-   
-   If return value is true, caller must issue a DMA ATA command
-   and then call ata_dma_finish().
- */
-bool ata_dma_setup(void *addr, unsigned long bytes, bool write) {
-    /* Require cacheline alignment for reads to prevent interference. */
-    if (!write && ((unsigned long)addr & 15))
-        return false;
-
-    /* Writes only need to be word-aligned, but by default DMA
-     * is not used for writing as it appears to be slower.
-     */
-#ifdef ATA_DMA_WRITES
-    if (write && ((unsigned long)addr & 3))
-        return false;
-#else
-    if (write)
-        return false;
-#endif
-
-#if ATA_MAX_UDMA > 2
-    if (dma_needs_boost && !dma_boosted) {
-        cpu_boost(true);
-        dma_boosted = true;
-    }
-#endif
-
-    if (write) {
-        /* If unflushed, old data may be written to disk */
-        cpucache_flush();
-    }
-    else {
-        /* Invalidate cache because new data may be present in RAM */
-        cpucache_invalidate();
-    }
-
-    /* Clear pending interrupts so ata_dma_finish() can wait for an
-       interrupt from this transfer
-     */
-    IDE0_CFG |= IDE_CFG_INTRQ;
-
-    IDE_DMA_CONTROL |= 2;
-    IDE_DMA_LENGTH = bytes - 4;
-
-#if !defined(BOOTLOADER) || defined (HAVE_BOOTLOADER_USB_MODE)
-    if ((unsigned long)addr < DRAM_START)
-        /* Rockbox remaps DRAM to start at 0 */
-        IDE_DMA_ADDR = (unsigned long)addr + DRAM_START;
-    else
-#endif
-        IDE_DMA_ADDR = (unsigned long)addr;
-
-    if (write)
-        IDE_DMA_CONTROL &= ~IDE_DMA_CONTROL_READ;
-    else
-        IDE_DMA_CONTROL |= IDE_DMA_CONTROL_READ;
-
-    IDE0_CFG |= 0x8000;
-
-    return true;
-}
-
-/* This function waits for a DMA transfer to end.
-   It must be called to finish what ata_dma_setup started.
-   
-   Return value is true if DMA completed before the timeout, and false
-   if a timeout happened.
- */
-bool ata_dma_finish(void) {
-    bool res;
-    
-    /* It may be okay to put this at the end of setup */
-    IDE_DMA_CONTROL |= 1;
-
-    /* Wait for end of transfer.
-       Reading standard ATA status while DMA is in progress causes 
-       failures and hangs.  Because of that, another wait is used.
-     */
-    res = ata_wait_intrq();
-
-    IDE0_CFG &= ~0x8000;
-    IDE_DMA_CONTROL &= ~0x80000001;
-
-#if ATA_MAX_UDMA > 2
-    if (dma_boosted) {
-        cpu_boost(false);
-        dma_boosted = false;
-    }
-#endif
-
-    return res;
-}
-
-#endif /* HAVE_ATA_DMA */
diff --git a/firmware/target/arm/ata-sd-pp.c b/firmware/target/arm/ata-sd-pp.c
deleted file mode 100644
index f83bb60..0000000
--- a/firmware/target/arm/ata-sd-pp.c
+++ /dev/null
@@ -1,1387 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 Daniel Ankers
- *
- * 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" /* for HAVE_MULTIDRIVE */
-#include "fat.h"
-#include "sdmmc.h"
-#include "gcc_extensions.h"
-#ifdef HAVE_HOTSWAP
-#include "sd-pp-target.h"
-#endif
-#include "ata_idle_notify.h"
-#include "system.h"
-#include <string.h>
-#include "thread.h"
-#include "led.h"
-#include "disk.h"
-#include "cpu.h"
-#include "panic.h"
-#include "usb.h"
-#include "sd.h"
-#include "storage.h"
-
-#define SECTOR_SIZE     512
-#define BLOCKS_PER_BANK 0x7a7800
-
-/* Comparing documentations of various MMC/SD controllers revealed, */
-/* that this controller seems to be a mix of PXA27x, PXA255 and */
-/* some PP specific stuff. The register and bit definitions are */
-/* taken from the 'PXA27x Developers Manual', as it appears to be */
-/* the closest match. Known differences and obscurities are commented.*/
-
-#define MMC_STRPCL      (*(volatile unsigned int *)(0x70008200))
-#define MMC_STAT        (*(volatile unsigned int *)(0x70008204))
-#define MMC_CLKRT       (*(volatile unsigned int *)(0x70008208))
-#define MMC_SPI         (*(volatile unsigned int *)(0x7000820c))
-#define MMC_CMDAT       (*(volatile unsigned int *)(0x70008210))
-#define MMC_RESTO       (*(volatile unsigned int *)(0x70008214))
-#define MMC_RDTO        (*(volatile unsigned int *)(0x70008218))
-#define MMC_BLKLEN      (*(volatile unsigned int *)(0x7000821c))
-#define MMC_NUMBLK      (*(volatile unsigned int *)(0x70008220))
-#define MMC_I_MASK      (*(volatile unsigned int *)(0x70008224))
-#define MMC_CMD         (*(volatile unsigned int *)(0x70008228))
-#define MMC_ARGH        (*(volatile unsigned int *)(0x7000822c))
-#define MMC_ARGL        (*(volatile unsigned int *)(0x70008230))
-#define MMC_RES         (*(volatile unsigned int *)(0x70008234))
-
-/* PXA255/27x have separate RX/TX FIFOs with 32x8 bit */
-/* PP502x has a combined Data FIFO with 16x16 bit */
-#define MMC_DATA_FIFO   (*(volatile unsigned int *)(0x70008280))
-
-/* PP specific registers, no other controller seem to have such. */
-#define MMC_SD_STATE    (*(volatile unsigned int *)(0x70008238))
-#define MMC_INIT_1      (*(volatile unsigned int *)(0x70008240))
-#define MMC_INIT_2      (*(volatile unsigned int *)(0x70008244))
-
-/* MMC_STAT bits */
-#define STAT_SDIO_SUSPEND_ACK (1 << 16)
-#define STAT_SDIO_INT         (1 << 15)
-#define STAT_RD_STALLED       (1 << 14)
-#define STAT_END_CMD_RES      (1 << 13)
-#define STAT_PRG_DONE         (1 << 12)
-#define STAT_DATA_TRAN_DONE   (1 << 11)
-#define STAT_SPI_WR_ERR       (1 << 10)
-#define STAT_FLASH_ERR        (1 << 9)
-#define STAT_CLK_EN           (1 << 8)
-#define STAT_RECV_FIFO_FULL   (1 << 7)  /* taken from PXA255 */
-#define STAT_XMIT_FIFO_EMPTY  (1 << 6)  /* taken from PXA255 */
-#define STAT_RES_CRC_ERR      (1 << 5)
-#define STAT_DAT_ERR_TOKEN    (1 << 4)
-#define STAT_CRC_RD_ERR       (1 << 3)
-#define STAT_CRC_WR_ERR       (1 << 2)
-#define STAT_TIME_OUT_RES     (1 << 1)
-#define STAT_TIME_OUT_READ    (1)
-#define STAT_ERROR_BITS       (0x3f)
- 
-/* MMC_CMDAT bits */
-/* Some of the bits used by the OF don't make much sense with these */
-/* definitions. So they're probably different between PXA and PP502x */
-/* Bits 0-5 appear to match though. */
-#define CMDAT_SDIO_RESUME  (1 << 13)
-#define CMDAT_SDIO_SUSPEND (1 << 12)
-#define CMDAT_SDIO_INT_EN  (1 << 11)
-#define CMDAT_STOP_TRAN    (1 << 10)
-#define CMDAT_SD_4DAT      (1 << 8)
-#define CMDAT_DMA_EN       (1 << 7)
-#define CMDAT_INIT         (1 << 6)
-#define CMDAT_BUSY         (1 << 5)
-#define CMDAT_STRM_BLK     (1 << 4)
-#define CMDAT_WR_RD        (1 << 3)
-#define CMDAT_DATA_EN      (1 << 2)
-#define CMDAT_RES_TYPE3    (3)
-#define CMDAT_RES_TYPE2    (2)
-#define CMDAT_RES_TYPE1    (1)
- 
-/* MMC_I_MASK bits */
-/* PP502x apparently only has bits 0-3 */
-#define I_MASK_SDIO_SUSPEND_ACK  (1 << 12)
-#define I_MASK_SDIO_INT          (1 << 11)
-#define I_MASK_RD_STALLED        (1 << 10)
-#define I_MASK_RES_ERR           (1 << 9)
-#define I_MASK_DAT_ERR           (1 << 8)
-#define I_MASK_TINT              (1 << 7)
-#define I_MASK_TXFIFO_WR_REQ     (1 << 6)
-#define I_MASK_RXFIFO_RD_REQ     (1 << 5)
-#define I_MASK_CLK_IS_OFF        (1 << 4)
-#define I_MASK_STOP_CMD          (1 << 3)
-#define I_MASK_END_CMD_RES       (1 << 2)
-#define I_MASK_PRG_DONE          (1 << 1)
-#define I_MASK_DATA_TRAN_DONE    (1 << 0)
-
-#define FIFO_LEN        16          /* FIFO is 16 words deep */
-
-#define EC_OK                    0
-#define EC_FAILED                1
-#define EC_NOCARD                2
-#define EC_WAIT_STATE_FAILED     3
-#define EC_CHECK_TIMEOUT_FAILED  4
-#define EC_POWER_UP              5
-#define EC_READ_TIMEOUT          6
-#define EC_WRITE_TIMEOUT         7
-#define EC_TRAN_SEL_BANK         8
-#define EC_TRAN_READ_ENTRY       9
-#define EC_TRAN_READ_EXIT       10
-#define EC_TRAN_WRITE_ENTRY     11
-#define EC_TRAN_WRITE_EXIT      12
-#define EC_FIFO_SEL_BANK_EMPTY  13
-#define EC_FIFO_SEL_BANK_DONE   14
-#define EC_FIFO_ENA_BANK_EMPTY  15
-#define EC_FIFO_READ_FULL       16
-#define EC_FIFO_WR_EMPTY        17
-#define EC_FIFO_WR_DONE         18
-#define EC_COMMAND              19
-#define NUM_EC                  20
-
-/* for compatibility */
-static long last_disk_activity = -1;
-
-/** static, private data **/ 
-static bool initialized = false;
-static unsigned int sd_thread_id = 0;
-
-#define Q_CLOSE    1
-
-static long next_yield = 0;
-#define MIN_YIELD_PERIOD 1000
-
-static tCardInfo card_info[2];
-static tCardInfo *currcard = NULL; /* current active card */
-
-struct sd_card_status
-{
-    int retry;
-    int retry_max;
-};
-
-static struct sd_card_status sd_status[NUM_DRIVES] =
-{
-    { 0, 1  },
-#ifdef HAVE_MULTIDRIVE
-    { 0, 10 }
-#endif
-};
-
-/* Shoot for around 75% usage */
-static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
-static const char         sd_thread_name[] = "ata/sd";
-static struct mutex       sd_mtx SHAREDBSS_ATTR;
-static struct event_queue sd_queue SHAREDBSS_ATTR;
-
-#ifdef HAVE_HOTSWAP
-static int sd_first_drive = 0;
-#endif
-
-/* Posted when card plugged status has changed */
-#define SD_HOTSWAP    1
-/* Actions taken by sd_thread when card status has changed */
-enum sd_thread_actions
-{
-    SDA_NONE      = 0x0,
-    SDA_UNMOUNTED = 0x1,
-    SDA_MOUNTED   = 0x2
-};
-
-/* Private Functions */
-
-static unsigned int check_time[NUM_EC];
-
-static inline bool sd_check_timeout(long timeout, int id)
-{
-    return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout);
-}
-
-static bool sd_poll_status(unsigned int trigger, long timeout)
-{
-    long t = USEC_TIMER;
-
-    while ((MMC_STAT & trigger) == 0)
-    {
-        long time = USEC_TIMER;
-
-        if (TIME_AFTER(time, next_yield))
-        {
-            long ty = USEC_TIMER;
-            yield();
-            timeout += USEC_TIMER - ty;
-            next_yield = ty + MIN_YIELD_PERIOD;
-        }
-
-        if (TIME_AFTER(time, t + timeout))
-            return false;
-    }
-
-    return true;
-}
-
-static int sd_command(unsigned int cmd, unsigned long arg1,
-                      unsigned long *response, unsigned int cmdat)
-{
-    int i, words; /* Number of 16 bit words to read from MMC_RES */
-    unsigned int data[9];
-
-    MMC_CMD = cmd;
-    MMC_ARGH = (unsigned int)((arg1 & 0xffff0000) >> 16);
-    MMC_ARGL = (unsigned int)((arg1 & 0xffff));
-    MMC_CMDAT  = cmdat;
-
-    if (!sd_poll_status(STAT_END_CMD_RES, 100000))
-        return -EC_COMMAND;
-
-    if ((MMC_STAT & STAT_ERROR_BITS) != 0)
-        /* Error sending command */
-        return -EC_COMMAND - (MMC_STAT & STAT_ERROR_BITS)*100;
-
-    if (cmd == SD_GO_IDLE_STATE)
-        return 0; /* no response here */
-
-    words = (cmdat == CMDAT_RES_TYPE2) ? 9 : 3;
-
-    for (i = 0; i < words; i++) /* MMC_RES is read MSB first */
-        data[i] = MMC_RES; /* Read most significant 16-bit word */
-
-    if (response == NULL)
-    {
-        /* response discarded */
-    }
-    else if (cmdat == CMDAT_RES_TYPE2)
-    {
-        /* Response type 2 has the following structure:
-         * [135:135] Start Bit - '0'
-         * [134:134] Transmission bit - '0'
-         * [133:128] Reserved - '111111'
-         * [127:001] CID or CSD register including internal CRC7
-         * [000:000] End Bit - '1'
-         */
-        response[3] = (data[0]<<24) + (data[1]<<8) + (data[2]>>8);
-        response[2] = (data[2]<<24) + (data[3]<<8) + (data[4]>>8);
-        response[1] = (data[4]<<24) + (data[5]<<8) + (data[6]>>8);
-        response[0] = (data[6]<<24) + (data[7]<<8) + (data[8]>>8);
-    }
-    else
-    {
-        /* Response types 1, 1b, 3, 6, 7 have the following structure:
-         * Types 4 and 5 are not supported.
-         *
-         *     [47] Start bit - '0'
-         *     [46] Transmission bit - '0'
-         *  [45:40] R1, R1b, R6, R7: Command index
-         *          R3: Reserved - '111111'
-         *   [39:8] R1, R1b: Card Status
-         *          R3: OCR Register
-         *          R6: [31:16] RCA
-         *              [15: 0] Card Status Bits 23, 22, 19, 12:0
-         *                     [23] COM_CRC_ERROR
-         *                     [22] ILLEGAL_COMMAND
-         *                     [19] ERROR
-         *                   [12:9] CURRENT_STATE
-         *                      [8] READY_FOR_DATA
-         *                    [7:6]
-         *                      [5] SD_APP_CMD
-         *                      [4]
-         *                      [3] AKE_SEQ_ERROR
-         *                      [2] Reserved
-         *                    [1:0] Reserved for test mode
-         *          R7: [19:16] Voltage accepted
-         *              [15:8]  echo-back of check pattern
-         *    [7:1] R1, R1b: CRC7
-         *          R3: Reserved - '1111111'
-         *      [0] End Bit - '1'
-         */
-        response[0] = (data[0]<<24) + (data[1]<<8) + (data[2]>>8);
-    }
-
-    return 0;
-}
-
-static int sd_wait_for_state(unsigned int state, int id)
-{
-    unsigned long response = 0;
-    unsigned int timeout = 0x80000;
-
-    check_time[id] = USEC_TIMER;
-
-    while (1)
-    {
-        int ret = sd_command(SD_SEND_STATUS, currcard->rca, &response, CMDAT_RES_TYPE1);
-        long us;
-
-        if (ret < 0)
-            return ret*100 - id;
-
-        if (((response >> 9) & 0xf) == state)
-        {
-            MMC_SD_STATE = state;
-            return 0;
-        }
-
-        if (!sd_check_timeout(timeout, id))
-            return -EC_WAIT_STATE_FAILED*100 - id;
-
-        us = USEC_TIMER;
-        if (TIME_AFTER(us, next_yield))
-        {
-            yield();
-            timeout += USEC_TIMER - us;
-            next_yield = us + MIN_YIELD_PERIOD;
-        }
-    }
-}
-
-
-static inline bool card_detect_target(void)
-{
-#ifdef HAVE_HOTSWAP
-#ifdef SANSA_E200
-    return (GPIOA_INPUT_VAL & 0x80) == 0; /* low active */
-#elif defined SANSA_C200
-    return (GPIOL_INPUT_VAL & 0x08) != 0; /* high active */
-#endif
-#else
-    return false;
-#endif
-}
-
-
-static inline void copy_read_sectors_fast(unsigned char **buf)
-{
-    /* Copy one chunk of 16 words using best method for start alignment */
-    switch ( (intptr_t)*buf & 3 )
-    {
-    case 0:
-        asm volatile (
-            "ldmia  %[data], { r2-r9 }          \r\n"
-            "orr    r2, r2, r3, lsl #16         \r\n"
-            "orr    r4, r4, r5, lsl #16         \r\n"
-            "orr    r6, r6, r7, lsl #16         \r\n"
-            "orr    r8, r8, r9, lsl #16         \r\n"
-            "stmia  %[buf]!, { r2, r4, r6, r8 } \r\n"
-            "ldmia  %[data], { r2-r9 }          \r\n"
-            "orr    r2, r2, r3, lsl #16         \r\n"
-            "orr    r4, r4, r5, lsl #16         \r\n"
-            "orr    r6, r6, r7, lsl #16         \r\n"
-            "orr    r8, r8, r9, lsl #16         \r\n"
-            "stmia  %[buf]!, { r2, r4, r6, r8 } \r\n"
-            : [buf]"+&r"(*buf)
-            : [data]"r"(&MMC_DATA_FIFO)
-            : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9"
-        );
-        break;
-    case 1:
-        asm volatile (
-            "ldmia  %[data], { r2-r9 }          \r\n"
-            "orr    r3, r2, r3, lsl #16         \r\n"
-            "strb   r3, [%[buf]], #1            \r\n"
-            "mov    r3, r3, lsr #8              \r\n"
-            "strh   r3, [%[buf]], #2            \r\n"
-            "mov    r3, r3, lsr #16             \r\n"
-            "orr    r3, r3, r4, lsl #8          \r\n"
-            "orr    r3, r3, r5, lsl #24         \r\n"
-            "mov    r5, r5, lsr #8              \r\n"
-            "orr    r5, r5, r6, lsl #8          \r\n"
-            "orr    r5, r5, r7, lsl #24         \r\n"
-            "mov    r7, r7, lsr #8              \r\n"
-            "orr    r7, r7, r8, lsl #8          \r\n"
-            "orr    r7, r7, r9, lsl #24         \r\n"
-            "mov    r2, r9, lsr #8              \r\n"
-            "stmia  %[buf]!, { r3, r5, r7 }     \r\n"
-            "ldmia  %[data], { r3-r10 }         \r\n"
-            "orr    r2, r2, r3, lsl #8          \r\n"
-            "orr    r2, r2, r4, lsl #24         \r\n"
-            "mov    r4, r4, lsr #8              \r\n"
-            "orr    r4, r4, r5, lsl #8          \r\n"
-            "orr    r4, r4, r6, lsl #24         \r\n"
-            "mov    r6, r6, lsr #8              \r\n"
-            "orr    r6, r6, r7, lsl #8          \r\n"
-            "orr    r6, r6, r8, lsl #24         \r\n"
-            "mov    r8, r8, lsr #8              \r\n"
-            "orr    r8, r8, r9, lsl #8          \r\n"
-            "orr    r8, r8, r10, lsl #24        \r\n"
-            "mov    r10, r10, lsr #8            \r\n"
-            "stmia  %[buf]!, { r2, r4, r6, r8 } \r\n"
-            "strb   r10, [%[buf]], #1           \r\n"
-            : [buf]"+&r"(*buf)
-            : [data]"r"(&MMC_DATA_FIFO)
-            : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
-        );
-        break;
-    case 2:
-        asm volatile (
-            "ldmia  %[data], { r2-r9 }          \r\n"
-            "strh   r2, [%[buf]], #2            \r\n"
-            "orr    r3, r3, r4, lsl #16         \r\n"
-            "orr    r5, r5, r6, lsl #16         \r\n"
-            "orr    r7, r7, r8, lsl #16         \r\n"
-            "stmia  %[buf]!, { r3, r5, r7 }     \r\n"
-            "ldmia  %[data], { r2-r8, r10 }     \r\n"
-            "orr    r2, r9, r2, lsl #16         \r\n"
-            "orr    r3, r3, r4, lsl #16         \r\n"
-            "orr    r5, r5, r6, lsl #16         \r\n"
-            "orr    r7, r7, r8, lsl #16         \r\n"
-            "stmia  %[buf]!, { r2, r3, r5, r7 } \r\n"
-            "strh   r10, [%[buf]], #2           \r\n"
-            : [buf]"+&r"(*buf)
-            : [data]"r"(&MMC_DATA_FIFO)
-            : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
-        );
-        break;
-    case 3:
-        asm volatile (
-            "ldmia  %[data], { r2-r9 }          \r\n"
-            "orr    r3, r2, r3, lsl #16         \r\n"
-            "strb   r3, [%[buf]], #1            \r\n"
-            "mov    r3, r3, lsr #8              \r\n"
-            "orr    r3, r3, r4, lsl #24         \r\n"
-            "mov    r4, r4, lsr #8              \r\n"
-            "orr    r5, r4, r5, lsl #8          \r\n"
-            "orr    r5, r5, r6, lsl #24         \r\n"
-            "mov    r6, r6, lsr #8              \r\n"
-            "orr    r7, r6, r7, lsl #8          \r\n"
-            "orr    r7, r7, r8, lsl #24         \r\n"
-            "mov    r8, r8, lsr #8              \r\n"
-            "orr    r2, r8, r9, lsl #8          \r\n"
-            "stmia  %[buf]!, { r3, r5, r7 }     \r\n"
-            "ldmia  %[data], { r3-r10 }         \r\n"
-            "orr    r2, r2, r3, lsl #24         \r\n"
-            "mov    r3, r3, lsr #8              \r\n"
-            "orr    r4, r3, r4, lsl #8          \r\n"
-            "orr    r4, r4, r5, lsl #24         \r\n"
-            "mov    r5, r5, lsr #8              \r\n"
-            "orr    r6, r5, r6, lsl #8          \r\n"
-            "orr    r6, r6, r7, lsl #24         \r\n"
-            "mov    r7, r7, lsr #8              \r\n"
-            "orr    r8, r7, r8, lsl #8          \r\n"
-            "orr    r8, r8, r9, lsl #24         \r\n"
-            "mov    r9, r9, lsr #8              \r\n"
-            "orr    r10, r9, r10, lsl #8        \r\n"
-            "stmia  %[buf]!, { r2, r4, r6, r8 } \r\n"
-            "strh   r10, [%[buf]], #2           \r\n"
-            "mov    r10, r10, lsr #16           \r\n"
-            "strb   r10, [%[buf]], #1           \r\n"
-            : [buf]"+&r"(*buf)
-            : [data]"r"(&MMC_DATA_FIFO)
-            : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
-        );
-        break;
-    }
-}
-
-static inline void copy_read_sectors_slow(unsigned char** buf)
-{
-    int cnt = FIFO_LEN;
-    int t;
-
-    /* Copy one chunk of 16 words */
-    asm volatile (
-    "1:                                     \r\n"
-        "ldrh   %[t], [%[data]]             \r\n"
-        "strb   %[t], [%[buf]], #1          \r\n"
-        "mov    %[t], %[t], lsr #8          \r\n"
-        "strb   %[t], [%[buf]], #1          \r\n"
-        "subs   %[cnt], %[cnt], #1          \r\n"
-        "bgt    1b                          \r\n"
-        : [cnt]"+&r"(cnt), [buf]"+&r"(*buf),
-          [t]"=&r"(t)
-        : [data]"r"(&MMC_DATA_FIFO)
-    );
-}
-
-/* Writes have to be kept slow for now */
-static inline void copy_write_sectors(const unsigned char** buf)
-{
-    int cnt = FIFO_LEN - 1;
-    unsigned t;
-    long time;
-
-    time = USEC_TIMER + 3;
-    if  (((intptr_t)*buf & 3) == 0)
-    {
-        asm volatile (
-            "ldmia  %[buf]!, { r3, r5, r7, r9 } \r\n"
-            "mov    r4, r3, lsr #16             \r\n" 
-            "mov    r6, r5, lsr #16             \r\n" 
-            "mov    r8, r7, lsr #16             \r\n" 
-            "mov    r10, r9, lsr #16            \r\n" 
-            "stmia  %[data], { r3-r10 }         \r\n"
-            "ldmia  %[buf]!, { r3, r5, r7, r9 } \r\n"
-            "mov    r4, r3, lsr #16             \r\n" 
-            "mov    r6, r5, lsr #16             \r\n" 
-            "mov    r8, r7, lsr #16             \r\n" 
-            "mov    %[t], r9, lsr #16           \r\n" 
-            "stmia  %[data], { r3-r9 }          \r\n"
-            : [buf]"+&r"(*buf), [t]"=&r"(t) 
-            : [data]"r"(&MMC_DATA_FIFO)
-            : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
-        );
-    }
-    else
-    {
-        do
-        {
-            t  = *(*buf)++;
-            t |= *(*buf)++ << 8;
-            MMC_DATA_FIFO = t;
-        } while (--cnt > 0); /* tail loop is faster */
-        t  = *(*buf)++;
-        t |= *(*buf)++ << 8;
-    }
-    /* Don't write the last word before at least 3 usec have elapsed since FIFO_EMPTY */
-    /* This prevents the 'two bytes inserted' bug. */
-
-    while (!TIME_AFTER(USEC_TIMER, time));
-    MMC_DATA_FIFO = t;
-}
-
-static int sd_select_bank(unsigned char bank)
-{
-    unsigned char card_data[FIFO_LEN*2];// FIFO_LEN words=FIFO_LEN*2 bytes
-    const unsigned char* write_buf;
-    int i, ret;
-
-    memset(card_data, 0, sizeof card_data);
-
-    ret = sd_wait_for_state(SD_TRAN, EC_TRAN_SEL_BANK);
-    if (ret < 0)
-        return ret;
-
-    MMC_BLKLEN = 512;
-    MMC_NUMBLK = 1;
-
-    ret = sd_command(35, 0, NULL, /* CMD35 is vendor specific */
-                     0x1c00 | CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
-    if (ret < 0)
-        return ret;
-
-    MMC_SD_STATE = SD_PRG;
-
-    card_data[0] = bank;
-
-    /* Write the card data */
-    for (i = 0; i < SD_BLOCK_SIZE/2; i += FIFO_LEN)
-    {
-        write_buf = card_data;
-        /* Wait for the FIFO to empty */
-        if (sd_poll_status(STAT_XMIT_FIFO_EMPTY, 10000))
-        {
-            copy_write_sectors(&write_buf); /* Copy one chunk of 16 words */
-            /* clear buffer: only the first chunk contains interesting data (bank), the remaining is zero filling */
-            memset(card_data, 0, sizeof card_data);
-            continue;
-        }
-
-        return -EC_FIFO_SEL_BANK_EMPTY;
-    }
-
-    if (!sd_poll_status(STAT_PRG_DONE, 10000))
-        return -EC_FIFO_SEL_BANK_DONE;
-
-    currcard->current_bank = bank;
-
-    return 0;
-}
-
-static void sd_card_mux(int card_no)
-{
-/* Set the current card mux */
-#if defined(SANSA_E200)
-    if (card_no == 0)
-    {
-        GPO32_VAL |= 0x4;
-
-        GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x7a);
-        GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x7a);
-        GPIO_SET_BITWISE(GPIOD_ENABLE,  0x1f);
-        GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x1f);
-        GPIO_SET_BITWISE(GPIOD_OUTPUT_EN,  0x1f);
-
-        outl((inl(0x70000014) & ~(0x3ffff)) | 0x255aa, 0x70000014);
-    }
-    else
-    {
-        GPO32_VAL &= ~0x4;
-
-        GPIO_CLEAR_BITWISE(GPIOD_ENABLE, 0x1f);
-        GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x1f);
-        GPIO_SET_BITWISE(GPIOA_ENABLE, 0x7a);
-        GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x7a);
-        GPIO_SET_BITWISE( GPIOA_OUTPUT_EN, 0x7a);
-
-        outl(inl(0x70000014) & ~(0x3ffff), 0x70000014);
-    }
-#elif defined(SANSA_C200)
-    if (card_no == 0)
-    {
-        GPO32_VAL |= 0x4;
-
-        GPIO_CLEAR_BITWISE(GPIOD_ENABLE, 0x1f);
-        GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x1f);
-        GPIO_SET_BITWISE(GPIOA_ENABLE, 0x7a);
-        GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x7a);
-        GPIO_SET_BITWISE( GPIOA_OUTPUT_EN, 0x7a);
-
-        outl(inl(0x70000014) & ~(0x3ffff), 0x70000014);
-    }
-    else
-    {
-        GPO32_VAL &= ~0x4;
-
-        GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x7a);
-        GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x7a);
-        GPIO_SET_BITWISE(GPIOD_ENABLE,  0x1f);
-        GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x1f);
-        GPIO_SET_BITWISE(GPIOD_OUTPUT_EN,  0x1f);
-
-        outl((inl(0x70000014) & ~(0x3ffff)) | 0x255aa, 0x70000014);
-    }
-#elif defined(PHILIPS_SA9200)
-    /* only 1 "card" (no external memory card) */
-    (void)card_no;
-
-    GPIO_SET_BITWISE(GPIOH_ENABLE, 0x80);
-    GPIO_SET_BITWISE(GPIOH_OUTPUT_EN, 0x80);
-
-    outl(0x255aa, 0x70000014);
-
-    GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x04);
-    GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x04);
-
-    GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x7a);
-    GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x7a);
-
-    GPIO_SET_BITWISE(GPIOH_OUTPUT_VAL, 0x80);
-    GPIO_SET_BITWISE(GPIOH_OUTPUT_EN, 0x80);
-#endif
-}
-
-static void sd_init_device(int card_no)
-{
-/* SD Protocol registers */
-#ifdef HAVE_HOTSWAP
-    unsigned long response = 0;
-#endif
-    unsigned int  i;
-    unsigned char carddata[512];
-    unsigned char *dataptr;
-    unsigned long temp_reg[4];
-    int ret;
-
-/* Enable and initialise controller */
-    MMC_CLKRT = 6;  /* switch to lowest clock rate */
-
-/* Initialise card data as blank */
-    memset(currcard, 0, sizeof(*currcard));
-
-/* Switch card mux to card to initialize */
-    sd_card_mux(card_no);
-
-/* Init NAND */
-    MMC_INIT_1 |=  (1 << 15);
-    MMC_INIT_2 |=  (1 << 15);
-    MMC_INIT_2 &= ~(3 << 12);
-    MMC_INIT_2 |=  (1 << 13);
-    MMC_INIT_1 &= ~(3 << 12);
-    MMC_INIT_1 |=  (1 << 13);
-
-    DEV_EN |= DEV_ATA; /* Enable controller */
-    DEV_RS |= DEV_ATA; /* Reset controller */
-    DEV_RS &=~DEV_ATA; /* Clear Reset */
-
-    MMC_SD_STATE = SD_TRAN;
-
-    MMC_I_MASK = 0xf;  /* disable interrupts */
-
-    ret = sd_command(SD_GO_IDLE_STATE, 0, NULL, 0x100);
-    if (ret < 0)
-        goto card_init_error;
-
-    check_time[EC_POWER_UP] = USEC_TIMER;
-
-#ifdef HAVE_HOTSWAP
-    /* Check for SDHC:
-       - non-SDHC cards simply ignore SD_SEND_IF_COND (CMD8) and we get error -219,
-         which we can just ignore and assume we're dealing with standard SD.
-       - SDHC cards echo back the argument into the response. This is how we
-         tell if the card is SDHC.
-     */
-    ret = sd_command(SD_SEND_IF_COND,0x1aa, &response,
-                     CMDAT_DATA_EN | CMDAT_RES_TYPE3);
-    if ( (ret < 0) && (ret!=-219) )
-            goto card_init_error;
-#endif
-
-    while ((currcard->ocr & (1 << 31)) == 0) /* until card is powered up */
-    {
-        ret = sd_command(SD_APP_CMD, currcard->rca, NULL, CMDAT_RES_TYPE1);
-        if (ret < 0)
-            goto card_init_error;
-
-#ifdef HAVE_HOTSWAP
-        if(response == 0x1aa)
-        {
-            /* SDHC */
-            ret = sd_command(SD_APP_OP_COND, (1<<30)|0x100000,
-                             &currcard->ocr, CMDAT_RES_TYPE3);
-        }
-        else
-#endif /* HAVE_HOTSWAP */
-        {
-            /* SD Standard */
-            ret = sd_command(SD_APP_OP_COND, 0x100000, &currcard->ocr,
-                             CMDAT_RES_TYPE3);
-        }
-
-        if (ret < 0)
-            goto card_init_error;
-
-        if (!sd_check_timeout(5000000, EC_POWER_UP))
-        {
-            ret = -EC_POWER_UP;
-            goto card_init_error;
-        }
-    }
-
-    ret = sd_command(SD_ALL_SEND_CID, 0, temp_reg, CMDAT_RES_TYPE2);
-    if (ret < 0)
-        goto card_init_error;
-
-    for(i=0; i<4; i++)
-        currcard->cid[i] = temp_reg[3-i];
-
-    ret = sd_command(SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, CMDAT_RES_TYPE1);
-    if (ret < 0)
-        goto card_init_error;
-
-    ret = sd_command(SD_SEND_CSD, currcard->rca, temp_reg, CMDAT_RES_TYPE2);
-    if (ret < 0)
-        goto card_init_error;
-
-    for(i=0; i<4; i++)
-        currcard->csd[i] = temp_reg[3-i];
-
-    sd_parse_csd(currcard);
-    
-    MMC_CLKRT = 0;  /* switch to highest clock rate */
-
-    ret = sd_command(SD_SELECT_CARD, currcard->rca, NULL,
-                     0x80 | CMDAT_RES_TYPE1);
-    if (ret < 0)
-        goto card_init_error;
-
-    ret = sd_command(SD_APP_CMD, currcard->rca, NULL, CMDAT_RES_TYPE1);
-    if (ret < 0)
-        goto card_init_error;
-
-    ret = sd_command(SD_SET_BUS_WIDTH, currcard->rca | 2, NULL,
-                     CMDAT_RES_TYPE1); /* 4 bit */
-    if (ret < 0)
-        goto card_init_error;
-
-    ret = sd_command(SD_SET_BLOCKLEN, currcard->blocksize, NULL,
-                     CMDAT_RES_TYPE1);
-    if (ret < 0)
-        goto card_init_error;
-
-    MMC_BLKLEN = currcard->blocksize;
-
-    /* If this card is >4GB & not SDHC, then we need to enable bank switching */
-    if( (currcard->numblocks >= BLOCKS_PER_BANK) &&
-        ((currcard->ocr & (1<<30)) == 0) )
-    {
-        MMC_SD_STATE = SD_TRAN;
-        MMC_NUMBLK = 1;
-
-        ret = sd_command(SD_SWITCH_FUNC, 0x80ffffef, NULL,
-                         0x1c00 | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
-        if (ret < 0)
-            goto card_init_error;
-
-        /* Read 512 bytes from the card.
-        The first 512 bits contain the status information
-        TODO: Do something useful with this! */
-        dataptr = carddata;
-        for (i = 0; i < SD_BLOCK_SIZE/2; i += FIFO_LEN)
-        {
-            /* Wait for the FIFO to be full */
-            if (sd_poll_status(STAT_RECV_FIFO_FULL, 100000))
-            {
-                copy_read_sectors_slow(&dataptr);
-                continue;
-            }
-
-            ret = -EC_FIFO_ENA_BANK_EMPTY;
-            goto card_init_error;
-        }
-    }
-
-    currcard->initialized = 1;
-    return;
-
-    /* Card failed to initialize so disable it */
-card_init_error:
-    currcard->initialized = ret;
-}
-
-/* lock must already be aquired */
-static void sd_select_device(int card_no)
-{
-    currcard = &card_info[card_no];
-
-    if (card_no == 0)
-    {
-        /* Main card always gets a chance */
-        sd_status[0].retry = 0;
-    }
-
-    if (currcard->initialized > 0)
-    {
-        /* This card is already initialized - switch to it */
-        sd_card_mux(card_no);
-        return;
-    }
-
-    if (currcard->initialized == 0)
-    {
-        /* Card needs (re)init */
-        sd_init_device(card_no);
-    }
-}
-
-/* API Functions */
-
-int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
-                     void* inbuf)
-{
-#ifndef HAVE_MULTIDRIVE
-    const int drive = 0;
-#endif
-    int ret;
-    unsigned char *buf, *buf_end;
-    unsigned int bank;
-    
-    /* TODO: Add DMA support. */
-
-    mutex_lock(&sd_mtx);
-    sd_enable(true);
-    led(true);
-
-sd_read_retry:
-    if (drive != 0 && !card_detect_target())
-    {
-        /* no external sd-card inserted */
-        ret = -EC_NOCARD;
-        goto sd_read_error;
-    }
-
-    sd_select_device(drive);
-
-    if (currcard->initialized < 0)
-    {
-        ret = currcard->initialized;
-        goto sd_read_error;
-    }
-
-    last_disk_activity = current_tick;
-
-    /* Only switch banks with non-SDHC cards */
-    if((currcard->ocr & (1<<30))==0)
-    {
-        bank = start / BLOCKS_PER_BANK;
-
-        if (currcard->current_bank != bank)
-        {
-            ret = sd_select_bank(bank);
-            if (ret < 0)
-                goto sd_read_error;
-        }
-    
-        start -= bank * BLOCKS_PER_BANK;
-    }
-
-    ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_ENTRY);
-    if (ret < 0)
-        goto sd_read_error;
-
-    MMC_NUMBLK = incount;
-
-#ifdef HAVE_HOTSWAP
-    if(currcard->ocr & (1<<30) )
-    {
-        /* SDHC */
-        ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL,
-                         0x1c00 | CMDAT_BUSY | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
-    }
-    else
-#endif
-    {
-        ret = sd_command(SD_READ_MULTIPLE_BLOCK, start * SD_BLOCK_SIZE, NULL,
-                         0x1c00 | CMDAT_BUSY | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
-    }
-    if (ret < 0)
-        goto sd_read_error;
-
-    /* TODO: Don't assume SD_BLOCK_SIZE == SECTOR_SIZE */
-
-    buf_end = (unsigned char *)inbuf + incount * currcard->blocksize;
-    for (buf = inbuf; buf < buf_end;)
-    {
-        /* Wait for the FIFO to be full */
-        if (sd_poll_status(STAT_RECV_FIFO_FULL, 0x80000))
-        {
-            copy_read_sectors_fast(&buf); /* Copy one chunk of 16 words */
-            /* TODO: Switch bank if necessary */
-            continue;
-        }
-
-        ret = -EC_FIFO_READ_FULL;
-        goto sd_read_error;
-    }
-
-    last_disk_activity = current_tick;
-
-    ret = sd_command(SD_STOP_TRANSMISSION, 0, NULL, CMDAT_RES_TYPE1);
-    if (ret < 0)
-        goto sd_read_error;
-
-    ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_EXIT);
-    if (ret < 0)
-        goto sd_read_error;
-
-    while (1)
-    {
-        led(false);
-        sd_enable(false);
-        mutex_unlock(&sd_mtx);
-
-        return ret;
-
-sd_read_error:
-        if (sd_status[drive].retry < sd_status[drive].retry_max
-            && ret != -EC_NOCARD)
-        {
-            sd_status[drive].retry++;
-            currcard->initialized = 0;
-            goto sd_read_retry;
-        }
-    }
-}
-
-int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
-                      const void* outbuf)
-{
-/* Write support is not finished yet */
-/* TODO: The standard suggests using ACMD23 prior to writing multiple blocks
-   to improve performance */
-#ifndef HAVE_MULTIDRIVE
-    const int drive = 0;
-#endif
-    int ret;
-    const unsigned char *buf, *buf_end;
-    unsigned int bank;
-
-    mutex_lock(&sd_mtx);
-    sd_enable(true);
-    led(true);
-
-sd_write_retry:
-    if (drive != 0 && !card_detect_target())
-    {
-        /* no external sd-card inserted */
-        ret = -EC_NOCARD;
-        goto sd_write_error;
-    }
-
-    sd_select_device(drive);
-
-    if (currcard->initialized < 0)
-    {
-        ret = currcard->initialized;
-        goto sd_write_error;
-    }
-
-    /* Only switch banks with non-SDHC cards */
-    if((currcard->ocr & (1<<30))==0)
-    {
-        bank = start / BLOCKS_PER_BANK;
-
-        if (currcard->current_bank != bank)
-        {
-            ret = sd_select_bank(bank);
-            if (ret < 0)
-                goto sd_write_error;
-        }
-    
-        start -= bank * BLOCKS_PER_BANK;
-    }
-
-    check_time[EC_WRITE_TIMEOUT] = USEC_TIMER;
-
-    ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_ENTRY);
-    if (ret < 0)
-        goto sd_write_error;
-
-    MMC_NUMBLK = count;
-
-#ifdef HAVE_HOTSWAP
-    if(currcard->ocr & (1<<30) )
-    {
-        /* SDHC */
-        ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL,
-                         CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
-    }
-    else
-#endif
-    {
-        ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start*SD_BLOCK_SIZE, NULL,
-                         CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
-    }
-    if (ret < 0)
-        goto sd_write_error;
-
-    buf_end = outbuf + count * currcard->blocksize - 2*FIFO_LEN;
-
-    for (buf = outbuf; buf <= buf_end;)
-    {
-        if (buf == buf_end)
-        {
-            /* Set MMC_SD_STATE to SD_PRG for the last buffer fill */
-            MMC_SD_STATE = SD_PRG;
-        }
-
-        copy_write_sectors(&buf); /* Copy one chunk of 16 words */
-        /* TODO: Switch bank if necessary */
-
-        /* Wait for the FIFO to empty */
-        if (!sd_poll_status(STAT_XMIT_FIFO_EMPTY, 0x80000))
-        {
-            ret = -EC_FIFO_WR_EMPTY;
-            goto sd_write_error;
-        }
-    }
-
-    last_disk_activity = current_tick;
-
-    if (!sd_poll_status(STAT_PRG_DONE, 0x80000))
-    {
-        ret = -EC_FIFO_WR_DONE;
-        goto sd_write_error;
-    }
-
-    ret = sd_command(SD_STOP_TRANSMISSION, 0, NULL, CMDAT_RES_TYPE1);
-    if (ret < 0)
-        goto sd_write_error;
-
-    ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_EXIT);
-    if (ret < 0)
-        goto sd_write_error;
-
-    while (1)
-    {
-        led(false);
-        sd_enable(false);
-        mutex_unlock(&sd_mtx);
-
-        return ret;
-
-sd_write_error:
-        if (sd_status[drive].retry < sd_status[drive].retry_max
-            && ret != -EC_NOCARD)
-        {
-            sd_status[drive].retry++;
-            currcard->initialized = 0;
-            goto sd_write_retry;
-        }
-    }
-}
-
-#ifndef SD_DRIVER_CLOSE
-static void sd_thread(void) NORETURN_ATTR;
-#endif
-static void sd_thread(void)
-{
-    struct queue_event ev;
-    bool idle_notified = false;
-    
-    while (1)
-    {
-        queue_wait_w_tmo(&sd_queue, &ev, HZ);
-
-        switch ( ev.id ) 
-        {
-#ifdef HAVE_HOTSWAP
-        case SYS_HOTSWAP_INSERTED:
-        case SYS_HOTSWAP_EXTRACTED:
-            fat_lock();          /* lock-out FAT activity first -
-                                    prevent deadlocking via disk_mount that
-                                    would cause a reverse-order attempt with
-                                    another thread */
-            mutex_lock(&sd_mtx); /* lock-out card activity - direct calls
-                                    into driver that bypass the fat cache */
-
-            /* We now have exclusive control of fat cache and ata */
-
-            disk_unmount(sd_first_drive+1); /* release "by force", ensure file
-                                        descriptors aren't leaked and any busy
-                                        ones are invalid if mounting */
-
-            /* Force card init for new card, re-init for re-inserted one or
-             * clear if the last attempt to init failed with an error. */
-            card_info[1].initialized = 0;
-            sd_status[1].retry = 0; 
-
-            if (ev.id == SYS_HOTSWAP_INSERTED)
-                disk_mount(sd_first_drive+1);
-
-            queue_broadcast(SYS_FS_CHANGED, 0);
-
-            /* Access is now safe */
-            mutex_unlock(&sd_mtx);
-            fat_unlock();
-            break;
-#endif
-        case SYS_TIMEOUT:
-            if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
-            {
-                idle_notified = false;
-            }
-            else
-            {
-                /* never let a timer wrap confuse us */
-                next_yield = USEC_TIMER;
-
-                if (!idle_notified)
-                {
-                    call_storage_idle_notifys(false);
-                    idle_notified = true;
-                }
-            }
-            break;
-        case SYS_USB_CONNECTED:
-            usb_acknowledge(SYS_USB_CONNECTED_ACK);
-            /* Wait until the USB cable is extracted again */
-            usb_wait_for_disconnect(&sd_queue);
-            break;
-
-#ifdef SD_DRIVER_CLOSE
-        case Q_CLOSE:
-            return;
-#endif
-        }
-    }
-}
-
-#ifdef SD_DRIVER_CLOSE
-void sd_close(void)
-{
-    unsigned int thread_id = sd_thread_id;
-    
-    if (thread_id == 0)
-        return;
-
-    sd_thread_id = 0;
-
-    queue_post(&sd_queue, Q_CLOSE, 0);
-    thread_wait(thread_id);
-}
-#endif /* SD_DRIVER_CLOSE */
-
-void sd_enable(bool on)
-{
-    if(on)
-    {
-        DEV_EN |= DEV_ATA; /* Enable controller */
-    }
-    else
-    {
-        DEV_EN &= ~DEV_ATA; /* Disable controller */
-    }
-}
-
-
-int sd_init(void)
-{
-    int ret = 0;
-
-    if (!initialized)
-        mutex_init(&sd_mtx);
-
-    mutex_lock(&sd_mtx);
-
-    led(false);
-
-    if (!initialized)
-    {
-        initialized = true;
-
-        /* init controller */
-#if defined(PHILIPS_SA9200)
-        GPIOA_ENABLE = 0x00;
-        GPIO_SET_BITWISE(GPIOD_ENABLE, 0x01);
-#else
-        outl(inl(0x70000088) & ~(0x4), 0x70000088);
-        outl(inl(0x7000008c) & ~(0x4), 0x7000008c);
-        GPO32_ENABLE |= 0x4;
-
-        GPIO_SET_BITWISE(GPIOG_ENABLE, (0x3 << 5));
-        GPIO_SET_BITWISE(GPIOG_OUTPUT_EN, (0x3 << 5));
-        GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, (0x3 << 5));
-#endif
-
-#ifdef HAVE_HOTSWAP
-        /* enable card detection port - mask interrupt first */
-#ifdef SANSA_E200
-        GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80);
-
-        GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x80);
-        GPIO_SET_BITWISE(GPIOA_ENABLE, 0x80);
-#elif defined SANSA_C200
-        GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08);
-
-        GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_EN, 0x08);
-        GPIO_SET_BITWISE(GPIOL_ENABLE, 0x08);
-#endif
-#endif
-        sd_select_device(0);
-
-        if (currcard->initialized < 0)
-            ret = currcard->initialized;
-
-        queue_init(&sd_queue, true);
-        sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack),
-            0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
-            IF_COP(, CPU));
-
-        /* enable interupt for the mSD card */
-        sleep(HZ/10);
-#ifdef HAVE_HOTSWAP
-#ifdef SANSA_E200
-        CPU_INT_EN = HI_MASK;
-        CPU_HI_INT_EN = GPIO0_MASK;
-
-        GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80);
-
-        GPIOA_INT_CLR = 0x80;
-
-        /* enable the card detect interrupt */
-        GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80);
-#elif defined SANSA_C200
-        CPU_INT_EN = HI_MASK;
-        CPU_HI_INT_EN = GPIO2_MASK;
-
-        GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08);
-
-        GPIOL_INT_CLR = 0x08;
-    
-        /* enable the card detect interrupt */
-        GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08);
-#endif
-#endif
-    }
-
-    mutex_unlock(&sd_mtx);
-
-    return ret;
-}
-
-tCardInfo *card_get_info_target(int card_no)
-{
-    return &card_info[card_no];
-}
-#ifdef HAVE_HOTSWAP
-static int sd1_oneshot_callback(struct timeout *tmo)
-{
-    (void)tmo;
-
-    /* This is called only if the state was stable for 300ms - check state
-     * and post appropriate event. */
-    if (card_detect_target())
-        queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
-    else
-        queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
-
-    return 0;
-}
-
-/* called on insertion/removal interrupt */
-void microsd_int(void)
-{
-    static struct timeout sd1_oneshot;
-
-#ifdef SANSA_E200
-    GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80);
-    GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80);
-    GPIOA_INT_CLR = 0x80;
-    GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80);
-
-#elif defined SANSA_C200
-    GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08);
-    GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08);
-    GPIOL_INT_CLR = 0x08;
-    GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08);
-#endif
-    timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0);
-}
-#endif /* HAVE_HOTSWAP */
-
-long sd_last_disk_activity(void)
-{
-    return last_disk_activity;
-}
-
-#ifdef HAVE_HOTSWAP
-bool sd_removable(IF_MD_NONVOID(int drive))
-{
-#ifndef HAVE_MULTIDRIVE
-    const int drive=0;
-#endif
-    return (drive==1);
-}
-
-bool sd_present(IF_MD_NONVOID(int drive))
-{
-#ifndef HAVE_MULTIDRIVE
-    const int drive=0;
-#endif
-    if(drive==0)
-    {
-        return true;
-    }
-    else
-    {
-        return card_detect_target();
-    }
-}
-#endif
-
-#ifdef CONFIG_STORAGE_MULTI
-int sd_num_drives(int first_drive)
-{
-#ifdef HAVE_HOTSWAP
-    /* Store which logical drive number(s) we have been assigned */
-    sd_first_drive = first_drive;
-#else
-    (void)first_drive;
-#endif
-    
-#ifdef HAVE_MULTIDRIVE
-    return 2;
-#else
-    return 1;
-#endif
-}
-#endif
diff --git a/firmware/target/arm/ata-target.h b/firmware/target/arm/ata-target.h
deleted file mode 100644
index 779ebed..0000000
--- a/firmware/target/arm/ata-target.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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.
- *
- ****************************************************************************/
-
-#ifdef CPU_PP
-
-#ifdef HAVE_BOOTLOADER_USB_MODE
-#define ATA_DRIVER_CLOSE
-#endif
-
-/* primary channel */
-#define ATA_DATA        (*((volatile unsigned short*)(IDE_BASE + 0x1e0)))
-#define ATA_ERROR       (*((volatile unsigned char*)(IDE_BASE + 0x1e4)))
-#define ATA_NSECTOR     (*((volatile unsigned char*)(IDE_BASE + 0x1e8)))
-#define ATA_SECTOR      (*((volatile unsigned char*)(IDE_BASE + 0x1ec)))
-#define ATA_LCYL        (*((volatile unsigned char*)(IDE_BASE + 0x1f0)))
-#define ATA_HCYL        (*((volatile unsigned char*)(IDE_BASE + 0x1f4)))
-#define ATA_SELECT      (*((volatile unsigned char*)(IDE_BASE + 0x1f8)))
-#define ATA_COMMAND     (*((volatile unsigned char*)(IDE_BASE + 0x1fc)))
-#define ATA_CONTROL     (*((volatile unsigned char*)(IDE_BASE + 0x3f8)))
-
-#if (CONFIG_CPU == PP5002)
-
-#define ATA_OUT8(reg,val) do { reg = (val); \
-                              while (!(IDE_CFG_STATUS & 0x40)); \
-                          } while (0)
-
-/* Plain C reading and writing. See comment in ata-as-arm.S */
-
-#elif defined CPU_PP502x
-
-/* asm optimized reading and writing */
-#define ATA_OPTIMIZED_READING
-#define ATA_OPTIMIZED_WRITING
-void copy_read_sectors(unsigned char* buf, int wordcount);
-void copy_write_sectors(const unsigned char* buf, int wordcount);
-
-#endif /* CONFIG_CPU */
-
-#endif
-
-void ata_reset(void);
-bool ata_is_coldstart(void);
-void ata_device_init(void);
-
-#ifdef HAVE_ATA_DMA
-
-/* IDE DMA controller registers */
-#define IDE_DMA_CONTROL (*(volatile unsigned long *)(0xc3000400))
-#define IDE_DMA_LENGTH  (*(volatile unsigned long *)(0xc3000408))
-#define IDE_DMA_ADDR    (*(volatile unsigned long *)(0xc300040C))
-
-/* Maximum multi-word DMA mode supported by the controller */
-#define ATA_MAX_MWDMA 2
-
-#ifndef BOOTLOADER    
-/* The PP5020 supports UDMA 4, but it needs cpu boosting and only
- * improves performance by ~10% with a stock disk.
- * UDMA 2 is stable at 30 Mhz.
- * UDMA 1 is stable at 24 Mhz.
- */
-#if CPUFREQ_NORMAL >= 30000000
-#define ATA_MAX_UDMA 2
-#elif CPUFREQ_NORMAL >= 24000000
-#define ATA_MAX_UDMA 1
-#else
-#error "CPU speeds under 24Mhz have not been tested with DMA"
-#endif
-#else
-/* The bootloader runs at 24 Mhz and needs a slower mode */
-#define ATA_MAX_UDMA 1
-#endif
-
-void ata_dma_set_mode(unsigned char mode);
-bool ata_dma_setup(void *addr, unsigned long bytes, bool write);
-bool ata_dma_finish(void);
-
-#endif /* HAVE_ATA_DMA */
diff --git a/firmware/target/arm/audio-pp.c b/firmware/target/arm/audio-pp.c
deleted file mode 100644
index 6b5b082..0000000
--- a/firmware/target/arm/audio-pp.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Michael Sevakis
- *
- * 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 "system.h"
-#include "cpu.h"
-#include "audio.h"
-#include "sound.h"
-
-#if INPUT_SRC_CAPS != 0
-void audio_set_output_source(int source)
-{
-    if ((unsigned)source >= AUDIO_NUM_SOURCES)
-        source = AUDIO_SRC_PLAYBACK;
-} /* audio_set_output_source */
-
-void audio_input_mux(int source, unsigned flags)
-{
-    (void)flags;
-    /* Prevent pops from unneeded switching */
-    static int last_source = AUDIO_SRC_PLAYBACK;
-#ifdef HAVE_FMRADIO_REC 
-    bool recording = flags & SRCF_RECORDING;
-    static bool last_recording = false;
-#endif
-
-#if defined(IPOD_COLOR) || defined (IPOD_4G)
-    /* The usual magic from IPL - I'm guessing this configures the headphone
-       socket to be input or output. */
-    if ((flags & SRCF_RECORDING) && source != AUDIO_SRC_PLAYBACK)
-    {
-        /* input */
-        GPIO_CLEAR_BITWISE(GPIOI_OUTPUT_VAL, 0x40);
-        GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_VAL, 0x04);
-    }
-    else
-    {
-        /* output */
-        GPIO_SET_BITWISE(GPIOI_OUTPUT_VAL, 0x40);
-        GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x04);
-    }
-#endif /* IPOD_COLOR || IPOD_4G */
-
-    switch (source)
-    {
-        default:                        /* playback - no recording */
-            source = AUDIO_SRC_PLAYBACK;
-        case AUDIO_SRC_PLAYBACK:
-#ifdef HAVE_RECORDING
-            if (source != last_source)
-            {
-                audiohw_set_monitor(false);
-                audiohw_disable_recording();
-            }
-#endif
-        break;
-#ifdef HAVE_MIC_REC
-        case AUDIO_SRC_MIC:             /* recording only */
-            if (source != last_source)
-            {
-                audiohw_set_monitor(false);
-                audiohw_enable_recording(true);  /* source mic */
-            }
-        break;
-#endif
-#ifdef HAVE_LINE_REC
-        case AUDIO_SRC_LINEIN:          /* recording only */
-#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
-            /* Switch line in source to line-in */
-            GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x04);
-#endif
-            if (source != last_source)
-            {
-                audiohw_set_monitor(false);
-                audiohw_enable_recording(false); /* source line */
-            }
-        break;
-#endif
-#ifdef HAVE_FMRADIO_REC
-        case AUDIO_SRC_FMRADIO:         /* recording and playback */
-#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
-            /* Switch line in source to tuner */
-            GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x04);
-            /* Set line-in vol to +12dB, which is proper for H10's */
-            if (!recording)
-                audiohw_set_recvol(0x1f, 0x1f, AUDIO_GAIN_LINEIN);
-#else            /* Set line-in vol to 0dB*/
-            if (!recording)
-                audiohw_set_recvol(0x17, 0x17, AUDIO_GAIN_LINEIN);
-#endif
-
-            if (source == last_source && recording == last_recording)
-                break;
-
-            last_recording = recording;
-
-#if CONFIG_TUNER & IPOD_REMOTE_TUNER
-            /* Ipod FM tuner is in the remote connected to line-in */
-                audiohw_enable_recording(false); /* source line */
-                audiohw_set_monitor(true);  /* enable bypass mode */
-#else
-            if (recording)
-            {
-                audiohw_set_monitor(false);  /* disable bypass mode */
-                audiohw_enable_recording(false); /* select line-in source */
-            }
-            else
-            {
-                audiohw_disable_recording();
-                audiohw_set_monitor(true);  /* enable bypass mode */
-            }
-#endif
-        break;
-#endif
-    } /* end switch */
-
-    last_source = source;
-} /* audio_input_mux */
-#endif /* INPUT_SRC_CAPS != 0 */
diff --git a/firmware/target/arm/boot-pp502x-bl-usb.lds b/firmware/target/arm/boot-pp502x-bl-usb.lds
deleted file mode 100644
index 30a8c0e..0000000
--- a/firmware/target/arm/boot-pp502x-bl-usb.lds
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Will have been included from boot.lds */
-ENTRY(start)
-OUTPUT_FORMAT(elf32-littlearm)
-OUTPUT_ARCH(arm)
-STARTUP(target/arm/crt0-pp502x-bl-usb.o)
-
-#define DRAMORIG        0x01000000 /* Load at 16 MB */
-#define DRAMSIZE        0x00100000 /* 1MB for bootloader */
-#define MEMEND          (MEMORYSIZE*0x100000) /* From virtual mapping at 0 */
-#define NOCACHE_BASE    0x10000000
-#ifndef IRAMORIG
-#define IRAMORIG 0x40000000
-#endif
-#define IRAMSIZE 0x20000
-#define FLASHORIG 0x001f0000
-#define FLASHSIZE 2M
-
-#define CACHEALIGN_SIZE 16
-
-MEMORY
-{
-    DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
-    IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
-}
-
-SECTIONS
-{
-    . = DRAMORIG;
-    _loadaddress = . + NOCACHE_BASE;
-
-    .text :
-    {
-        *(.init.text)
-        *(.text*)
-        *(.glue_7)
-        *(.glue_7t)
-        . = ALIGN(0x4);
-    } > DRAM
-
-    .rodata :
-    {
-        *(.rodata)  /* problems without this, dunno why */
-        *(.rodata*)
-        *(.rodata.str1.1)
-        *(.rodata.str1.4)
-        . = ALIGN(0x4);
-    } > DRAM
-
-    .data :
-    {
-        *(.data*)
-        . = ALIGN(0x4);
-    } > DRAM
-
-    /* .ncdata section is placed at uncached physical alias address and is
-     * loaded at the proper cached virtual address - no copying is
-     * performed in the init code */
-    .ncdata . + NOCACHE_BASE :
-    {
-        . = ALIGN(CACHEALIGN_SIZE);
-        *(.ncdata*)
-        . = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-
-    /DISCARD/ . - NOCACHE_BASE :
-    {
-        *(.eh_frame)
-    } > DRAM
-
-    _noloaddram  = .;
-
-    .ibss IRAMORIG (NOLOAD) :
-    {
-        _iedata = .;
-        *(.qharray)
-        *(.ibss)
-        . = ALIGN(0x4);
-        _iend = .;
-    } > IRAM
-
-    .iram _iend :
-    {
-        _iramstart = .;
-        *(.icode)
-        *(.irodata)
-        *(.idata)
-        _iramend = .;
-    } > IRAM AT> DRAM
-
-    _iramcopy = LOADADDR(.iram);
-
-    .loadaddressend :
-    {
-        _loadaddressend = . + NOCACHE_BASE;
-    } AT> DRAM
-
-    .stack (NOLOAD) :
-    {
-        . = ALIGN(8);
-        *(.stack)
-        stackbegin = .;
-        . += 0x2000;
-        stackend = .;
-    } > IRAM
-
-    /* .bss and .ncbss are treated as a single section to use one init loop
-     * to zero them - note "_edata" and "_end" */
-    .bss _noloaddram (NOLOAD) :
-    {
-        _edata = .;
-        *(.bss*)
-        *(COMMON)
-    } > DRAM
-
-    .ncbss . + NOCACHE_BASE (NOLOAD) :
-    {
-        . = ALIGN(CACHEALIGN_SIZE);
-        *(.ncbss*)
-        . = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-
-    /* This will be aligned by preceding alignments */
-    .endaddr . - NOCACHE_BASE (NOLOAD) :
-    {
-        _end = .;
-    } > DRAM
-
-    /* Reference to all DRAM after loaded bootloader image */
-    .freebuffer _end (NOLOAD) :
-    {
-        . = ALIGN(4);
-        freebuffer = .;
-        . = MEMEND-1;
-        freebufferend = .;
-    }
-}
diff --git a/firmware/target/arm/crt0-pp-bl.S b/firmware/target/arm/crt0-pp-bl.S
deleted file mode 100644
index 0168128..0000000
--- a/firmware/target/arm/crt0-pp-bl.S
+++ /dev/null
@@ -1,217 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- *
- * 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"
-
-    .section .init.text,"ax",%progbits
-
-    .global    start
-start:
-
-/* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux 
- * loader
- *
- * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
- * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
- *
- */
-#if CONFIG_CPU == PP5002
-    .equ    PROC_ID,     0xc4000000
-    .equ    CPU_CTRL,    0xcf004054
-    .equ    CPU_STATUS,  0xcf004050
-    .equ    COP_CTRL,    0xcf004058
-    .equ    COP_STATUS,  0xcf004050
-    .equ    IIS_CONFIG,  0xc0002500
-    .equ    SLEEP,       0xca
-    .equ    WAKE,        0xce
-    .equ    CPUSLEEPING, 0x8000
-    .equ    COPSLEEPING, 0x4000
-    .equ    CACHE_CTRL,  0xcf004024
-    .equ    CACHE_ENAB,  0x2 /* Actually the CACHE_CTL_INIT flag */
-#else
-    .equ    PROC_ID,     0x60000000
-    .equ    CPU_CTRL,    0x60007000
-    .equ    CPU_STATUS,  0x60007000
-    .equ    COP_CTRL,    0x60007004
-    .equ    COP_STATUS,  0x60007004
-    .equ    IIS_CONFIG,  0x70002800
-    .equ    SLEEP,       0x80000000
-    .equ    WAKE,        0x0
-    .equ    CPUSLEEPING, 0x80000000
-    .equ    COPSLEEPING, 0x80000000
-    .equ    CACHE_CTRL,  0x6000c000
-    .equ    CACHE_ENAB,  0x1
-#endif
-
-    msr    cpsr_c, #0xdf /* enter sys mode, disable IRQ */
-#ifndef E200R_INSTALLER
-/* 1 - Copy the bootloader to IRAM */
-    /* get the high part of our execute address */
-    bic    r0, pc, #0xff /* r4 = pc & 0xffffff00 */
-
-    /* Copy bootloader to safe area - 0x40000000 (IRAM) */
-    mov    r1, #0x40000000
-    ldr    r2, =_dataend
-1:
-    cmp    r2, r1
-    ldrhi  r3, [r0], #4
-    strhi  r3, [r1], #4
-    bhi    1b
-
-#ifndef IPOD_ARCH
-    /* For builds on targets with mi4 firmware, scramble writes data to 
-       0xe0-0xeb, so jump past that. pad_skip must then exist at an
-       address >= 0xec */
-    b      pad_skip
-
-.space 60*4 
-
-pad_skip:
-#endif /* IPOD_ARCH */
-
-
-/* 2 - Jump both CPU and COP there */
-    ldr    pc, =start_loc    /* jump to the relocated start_loc:  */
-#endif /* E200R_INSTALLER */
-
-start_loc:
-    /* Find out which processor we are */
-    ldr    r0, =PROC_ID
-    ldrb   r0, [r0]
-    cmp    r0, #0x55
-    beq    cpu
-
-cop:
-    /* put us (co-processor) to sleep */
-    ldr    r0, =COP_CTRL
-    mov    r1, #SLEEP
-    str    r1, [r0]
-    nop
-    nop
-    
-    /* Invalidate cache */
-    mov    r0, #1
-    bl     cache_op
-
-    ldr    r0, =startup_loc
-    ldr    pc, [r0]
-
-cpu:
-    /* Wait for COP to be sleeping */
-    ldr    r0, =COP_STATUS
-1:
-    ldr    r1, [r0]
-    tst    r1, #COPSLEEPING
-    beq    1b
-    
-    /* Initialise bss section to zero */
-    ldr    r0, =_edata
-    ldr    r1, =_end
-    mov    r2, #0
-1:
-    cmp    r1, r0
-    strhi  r2, [r0], #4
-    bhi    1b
-       
-    /* Set up some stack and munge it with 0xdeadbeef */
-    ldr    sp, =stackend
-    ldr    r0, =stackbegin
-    ldr    r1, =0xdeadbeef
-1:
-    cmp    sp, r0
-    strhi  r1, [r0], #4
-    bhi    1b
-
-    /* execute the loader - this will load an image to 0x10000000 */
-    bl     main
-
-    /* store actual startup location returned by main() */
-    ldr    r1, =startup_loc
-    str    r0, [r1]
-
-    /* flush cache */    
-    mov    r0, #0
-    bl     cache_op
-
-    /* Wake up the coprocessor before executing the firmware */
-    ldr    r0, =COP_CTRL
-    mov    r1, #WAKE
-    str    r1, [r0]
-
-#if defined(SANSA_C200) || defined(PHILIPS_HDD1630)
-    /* Magic for loading the c200 OF */
-    ldr    r0, =0xb00d10ad
-    mov    r1, #0x700
-    ldr    r2, =0xfff0
-    mov    r3, #0x7
-#endif
-
-#if defined(PHILIPS_HDD6330)
-    /* Magic for loading the HDD6XX0 OF */
-    ldr    r0, =0xb00d10ad
-    mov    r1, #0x800
-    ldr    r2, =0xfff0
-    mov    r3, #0x7
-#endif
-
-    ldr    r4, =startup_loc
-    ldr    pc, [r4]
-
-startup_loc:
-    .word    0x0
-    
-#ifdef IPOD_ARCH
-.align 8    /* starts at 0x100 */
-.global boot_table
-boot_table:
-    /* here comes the boot table, don't move its offset - preceding
-       code+data must stay <= 256 bytes */
-    .space 400
-#endif
-
-cache_op:
-    ldr    r2, =CACHE_CTRL
-    ldr    r1, [r2]
-    tst    r1, #CACHE_ENAB
-    bxeq   lr
-    cmp    r0, #0
-#ifdef CPU_PP502x
-    ldr    r0, =0xf000f044
-    ldr    r1, [r0]
-    orrne  r1, r1, #0x6
-    orreq  r1, r1, #0x2
-    str    r1, [r0]
-1:
-    ldr    r1, [r2]
-    tst    r1, #0x8000
-    bne    1b
-#elif CONFIG_CPU == PP5002
-    ldrne  r0, =0xf0004000
-    ldreq  r0, =0xf000c000
-    add    r1, r0, #0x2000
-    mov    r2, #0
-1:
-    cmp    r1, r0
-    strhi  r2, [r0], #16
-    bhi    1b
-#endif /* CPU type */
-    bx     lr
-
diff --git a/firmware/target/arm/crt0-pp.S b/firmware/target/arm/crt0-pp.S
deleted file mode 100644
index 4a9d423..0000000
--- a/firmware/target/arm/crt0-pp.S
+++ /dev/null
@@ -1,430 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- *
- * 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"
-
-    .section .init.text,"ax",%progbits
-
-    .global    start
-start:
-
-/* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux 
- * loader
- *
- * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
- * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
- *
- */
-#if CONFIG_CPU == PP5002
-    .equ    PROC_ID,     0xc4000000
-    .equ    CPU_ICLR,    0xcf001028
-    .equ    CPU_CTRL,    0xcf004054
-    .equ    COP_ICLR,    0xcf001038
-    .equ    COP_CTRL,    0xcf004058
-    .equ    CPU_STATUS,  0xcf004050
-    .equ    COP_STATUS,  0xcf004050
-    .equ    SLEEP,       0x000000ca
-    .equ    WAKE,        0x000000ce
-    .equ    CPUSLEEPING, 0x00008000
-    .equ    COPSLEEPING, 0x00004000
-    .equ    CACHE_CTRL,  0xcf004024
-    .equ    MMAP_LOG,    0xf000f000 /* MMAP0 */
-    .equ    MMAP_PHYS,   0xf000f004
-#if MEMORYSIZE > 32
-    .equ    MMAP_MASK,   0x00003c00
-#else
-    .equ    MMAP_MASK,   0x00003e00
-#endif
-    .equ    MMAP_FLAGS,  0x00003f84
-#else
-    .equ    PROC_ID,     0x60000000
-    .equ    CPU_ICLR,    0x60004028
-    .equ    CPU_CTRL,    0x60007000
-    .equ    CPU_STATUS,  0x60007000
-    .equ    COP_ICLR,    0x60004038
-    .equ    COP_CTRL,    0x60007004
-    .equ    COP_STATUS,  0x60007004
-    .equ    SLEEP,       0x80000000
-    .equ    WAKE,        0x00000000
-    .equ    CPUSLEEPING, 0x80000000
-    .equ    COPSLEEPING, 0x80000000    
-    .equ    CACHE_CTRL,  0x6000c000
-    .equ    MMAP_LOG,    0xf000f000 /* MMAP0 */
-    .equ    MMAP_PHYS,   0xf000f004
-#if MEMORYSIZE > 32
-    .equ    MMAP_MASK,   0x00003c00
-#else
-    .equ    MMAP_MASK,   0x00003e00
-#endif
-    .equ    MMAP_FLAGS,  0x00000f84
-#endif
-
-    msr    cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
-    b      pad_skip
-
-.space 6*4  /* pad to offset 0x20 */
-
-    .ascii "Rockbox"    /* signature for bootloader checking osos */
-    .byte 1             /* osos boot version, only 1 exists for now */
-
-.space 56*4 /* (more than enough) space for exception vectors and mi4 magic */
-
-pad_skip:
-    /* Find out which processor we are - r0 should be preserved for the
-     * duration of the init to avoid constant reloading of the processor ID.
-     * For each stage, CPU proceeds first, then COP. 
-     */
-    ldr    r0, =PROC_ID
-    ldrb   r0, [r0]
-
-    /* We need to remap memory from wherever SDRAM is mapped natively, to
-       base address 0, so we can put our exception vectors there. We don't
-       want to do this remapping while executing from SDRAM, so we copy the
-       remapping code to IRAM, then execute from there. Hence, the following
-       code is compiled for address 0, but is currently executing at either
-       0x28000000 or 0x10000000, depending on chipset version. Do not use any
-       absolute addresses until remapping has been done. */
-
-    /* Cores are stepped though the init in turn: CPU then COP. The the remap
-       stage is completed by each core in turn and then the COP waits for the
-       CPU to finish initializing its kernel where the CPU will wake the COP
-       and wait for the COP to finish. This ensures no threading activity
-       starts until it is safe. */
-    cmp    r0, #0x55
-    
-    /* mask all interrupt sources before setting anything up */
-    ldreq  r2, =CPU_ICLR
-    ldrne  r2, =COP_ICLR    
-    mvn    r1, #0
-    str    r1, [r2]
-
-    /* put us (co-processor) to sleep and wait for CPU to remap */
-    ldrne  r2, =COP_CTRL
-    movne  r1, #SLEEP
-    strne  r1, [r2]
-    nop
-    nop
-    nop
-
-    /* wait for co-processor to sleep then CPU can begin its remapping */
-    ldreq  r2, =COP_STATUS
-1:
-    ldreq  r1, [r2]
-    tsteq  r1, #COPSLEEPING
-    beq    1b
-
-    /* disable cache and local interrupt vectors - it is really not desireable
-       to have them enabled here */
-    ldr    r2, =CACHE_CTRL
-    mov    r1, #0
-    str    r1, [r2]
-
-#if defined(IPOD_VIDEO)
-    /* detect 32mb vs 64mb model */
-    /* we do this here because after SDRAM is remapped, we already assumed */
-    /* its size to be whatever we were compiled for. */
-
-    mov    r2, #0x12000000
-    mov    r3, #64
-    strb   r3, [r2, #-1]   /* first write 64 to last byte of first 32MB bank */
-
-    mov    r2, #0x14000000
-    mov    r3, #32
-    strb   r3, [r2, #-1]   /* now write 32 to last byte of second 32MB bank */
-
-    /* now the last word of the first 32MB bank tells you the RAM size */
-    /* since on a 32MB model both writes will touch the same actual location */
-    /* this is read later on in boot */
-#endif
-
-    mov    r2, #0x40000000
-    ldr    r3, =remap_start
-    ldr    r4, =remap_end
-
-    and    r6, pc, #0xff000000 /* adjust for execute address */
-    orr    r3, r3, r6
-    orr    r4, r4, r6
-
-    /* copy the code to 0x40000000 */
-1:
-    ldr    r5, [r3], #4
-    str    r5, [r2], #4
-    cmp    r3, r4
-    blo    1b
-
-    ldr    r4, =MMAP_FLAGS
-    orr    r4, r4, r6      /* adjust for execute address */
-    ldr    r3, =MMAP_PHYS
-    ldr    r2, =MMAP_MASK  /* ldr is more flexible */
-    ldr    r1, =MMAP_LOG
-    mov    pc, #0x40000000 
-
-remap_start:
-    str    r2, [r1]
-    str    r4, [r3]
-    ldr    r1, L_post_remap
-    bx     r1
-L_post_remap:
-    .word remap_end
-remap_end:
-
-    cmp    r0, #0x55
-    ldr    r4, =COP_CTRL
-    /* Wakeup co-processor to let it do remappings */
-    moveq  r3, #WAKE
-    /* Sleep us (co-processor) and wait for CPU to do kernel initialization */
-    movne  r3, #SLEEP
-    str    r3, [r4]
-    nop
-    nop
-    nop
-
-    /* Jump to co-processor init */
-    ldrne  pc, =cop_init
-
-cpu_init:
-    /* Wait for COP to go to sleep before proceeding */
-    ldr    r4, =COP_STATUS
-1:
-    ldr    r3, [r4]
-    tst    r3, #COPSLEEPING
-    beq    1b
-    
-    /* Vectors and IRAM copy is done first since they are reclaimed for
-     * other uninitialized sections */
-
-    /* Copy exception handler code to address 0 */
-    ldr    r2, =_vectorsstart
-    ldr    r3, =_vectorsend
-    ldr    r4, =_vectorscopy
-1:
-    cmp    r3, r2
-    ldrhi  r5, [r4], #4
-    strhi  r5, [r2], #4
-    bhi    1b
-    
-    /* Copy the IRAM */
-    ldr    r2, =_iramcopy
-    ldr    r3, =_iramstart
-    ldr    r4, =_iramend
-1:
-    cmp    r4, r3
-    ldrhi  r5, [r2], #4
-    strhi  r5, [r3], #4
-    bhi    1b
-
-#ifdef HAVE_INIT_ATTR
-    /* copy init code to codec buffer */
-    ldr    r2, =_initstart
-    ldr    r3, =_initend
-    ldr    r4, =_initcopy
-
-1:
-    cmp     r3, r2
-    ldrhi   r5, [r4], #4
-    strhi   r5, [r2], #4
-    bhi 1b
-#endif
-
-    /* Zero out IBSS */
-    ldr    r2, =_iedata
-    ldr    r3, =_iend
-    mov    r4, #0
-1:
-    cmp    r3, r2
-    strhi  r4, [r2], #4
-    bhi    1b
-
-    /* Initialise bss section to zero */
-    ldr    r2, =_edata
-    ldr    r3, =_end
-    mov    r4, #0
-1:
-    cmp    r3, r2
-    strhi  r4, [r2], #4
-    bhi    1b
-
-#if NUM_CORES > 1
-    /* Set up idle stack and munge it with 0xdeadbeef */
-    ldr    r2, =cpu_idlestackbegin
-    ldr    r3, =cpu_idlestackend
-1:
-    cmp    r3, r2
-    strhi  r4, [r2], #4
-    bhi    1b
-#endif
-
-    /* Set up stack for IRQ mode */ 
-    msr    cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
-    ldr    sp, =irq_stack
-    /* Set up stack for FIQ mode */ 
-    msr    cpsr_c, #0xd1 /* IRQ/FIQ disabled */
-    ldr    sp, =fiq_stack
-
-    /* Let svc, abort and undefined modes use irq stack */
-    msr    cpsr_c, #0xd3 /* IRQ/FIQ disabled */
-    ldr    sp, =irq_stack
-    msr    cpsr_c, #0xd7 /* IRQ/FIQ disabled */
-    ldr    sp, =irq_stack
-    msr    cpsr_c, #0xdb /* IRQ/FIQ disabled */
-    ldr    sp, =irq_stack
-
-    /* Switch to sys mode */
-    msr    cpsr_c, #0xdf
-
-    /* Load stack munge value */    
-    ldr    r4, =0xdeadbeef
-
-    /* Set up some stack and munge it with 0xdeadbeef */
-    ldr    r2, =stackbegin
-    ldr    sp, =stackend
-1:
-    cmp    sp, r2
-    strhi  r4, [r2], #4
-    bhi    1b
-
-    /* Delay waking the COP until thread initialization is complete unless dual-core
-       support is not enabled in which case the cop_main function does not perform
-       any kernel or thread initialization. It's just a trivial sleep loop. */
-#if NUM_CORES == 1
-    ldr    r4, =COP_CTRL
-    mov    r3, #WAKE
-    str    r3, [r4]
-#endif
-
-    ldr    pc, =main
-    /* main() should never return */
-
-cop_init:
-#if NUM_CORES > 1
-    /* Wait for CPU to go to sleep at the end of its kernel init */
-    ldr    r4, =CPU_STATUS
-1:
-    ldr    r3, [r4]
-    tst    r3, #CPUSLEEPING
-    beq    1b
-#endif
-
-    /* Set up stack for IRQ mode */
-    msr    cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
-    ldr    sp, =cop_irq_stack
-    /* Set up stack for FIQ mode */
-    msr    cpsr_c, #0xd1 /* IRQ/FIQ disabled */
-    ldr    sp, =cop_fiq_stack
-
-    /* Let svc, abort and undefined modes use irq stack */
-    msr    cpsr_c, #0xd3 /* IRQ/FIQ disabled */
-    ldr    sp, =cop_irq_stack
-    msr    cpsr_c, #0xd7 /* IRQ/FIQ disabled */
-    ldr    sp, =cop_irq_stack
-    msr    cpsr_c, #0xdb /* IRQ/FIQ disabled */
-    ldr    sp, =cop_irq_stack
-
-    /* Switch to sys mode */
-    msr    cpsr_c, #0xdf
-
-    /* Set up idle stack for COP and munge it with 0xdeadbeef */
-    ldr    sp, =cop_idlestackend
-    ldr    r2, =cop_idlestackbegin
-    ldr    r4, =0xdeadbeef
-2:
-    cmp    sp, r2
-    strhi  r4, [r2], #4
-    bhi    2b
-   
-    /* Run cop_main() in apps/main.c */
-    ldr    pc, =cop_main
-
-/* Exception handlers. Will be copied to address 0 after memory remapping */
-    .section .vectors,"aw"
-    ldr    pc, [pc, #24]
-    ldr    pc, [pc, #24]
-    ldr    pc, [pc, #24]
-    ldr    pc, [pc, #24]
-    ldr    pc, [pc, #24]
-    ldr    pc, [pc, #24]
-    ldr    pc, [pc, #24]
-    ldr    pc, [pc, #24]
-
-    /* Exception vectors */
-    .global vectors
-vectors:
-    .word  start 
-    .word  undef_instr_handler
-    .word  software_int_handler
-    .word  prefetch_abort_handler
-    .word  data_abort_handler
-    .word  reserved_handler
-    .word  irq_handler
-    .word  fiq_handler
-
-    .text
-
-/* All illegal exceptions call into UIE with exception address as first
-   parameter. This is calculated differently depending on which exception
-   we're in. Second parameter is exception number, used for a string lookup
-   in UIE.
- */
-undef_instr_handler:
-    sub    r0, lr, #4
-    mov    r1, #0
-    b      UIE
-
-/* We run sys mode most of the time, and should never see a software
-   exception being thrown. Make it illegal and call UIE.
- */
-software_int_handler:
-reserved_handler:
-    sub    r0, lr, #4
-    mov    r1, #4
-    b      UIE
-
-prefetch_abort_handler:
-    sub    r0, lr, #4
-    mov    r1, #1
-    b      UIE
-
-data_abort_handler:
-    sub    r0, lr, #8 
-    mov    r1, #2
-    b      UIE
-
-/* Align stacks to cache line boundary */
-    .balign 32
-    
-/* 256 words of IRQ stack */
-    .space 256*4
-irq_stack:
-
-/* 256 words of COP IRQ stack */
-    .space 256*4
-cop_irq_stack:
-
-/* 256 words of FIQ stack */
-    .space 256*4
-fiq_stack:
-
-/* We'll need this soon - just reserve the symbol */
-#if 0
-/* 256 words of COP FIQ stack */
-    .space 256*4
-#endif
-cop_fiq_stack:
diff --git a/firmware/target/arm/crt0-pp502x-bl-usb.S b/firmware/target/arm/crt0-pp502x-bl-usb.S
deleted file mode 100644
index 7b0489b..0000000
--- a/firmware/target/arm/crt0-pp502x-bl-usb.S
+++ /dev/null
@@ -1,367 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- * Copyright (C) 2010 by Michael Sevakis
- *
- * 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"
-
-/* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux 
- * loader
- *
- * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
- * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
- *
- */
-    .equ    PROC_ID,     0x60000000
-    .equ    CPU_IDIS,    0x60004028
-    .equ    CPU_CTRL,    0x60007000
-    .equ    CPU_STATUS,  0x60007000
-    .equ    COP_IDIS,    0x60004038
-    .equ    COP_CTRL,    0x60007004
-    .equ    COP_STATUS,  0x60007004
-    .equ    CPU_SLEEPING,0x80000000
-    .equ    COP_SLEEPING,0x80000000
-    .equ    SLEEP,       0x80000000
-    .equ    WAKE,        0x00000000
-    .equ    MMAP_LOG,    0xf000f000 /* MMAP0 */
-    .equ    MMAP_PHYS,   0xf000f004
-    .equ    INT_VECT_TBL,0x6000f100
-    .equ    CACHE_CTRL,  0x6000c000
-    .equ    CACHE_ENAB,  0x1
-    .equ    CACHE_OP_COMMIT_DISCARD, 0x1
-    .equ    CACHE_OP_COMMIT        , 0x0
-#if MEMORYSIZE > 32
-    .equ    MMAP_MASK,   0x00003c00
-#else
-    .equ    MMAP_MASK,   0x00003e00
-#endif
-    .equ    MMAP_FLAGS,  0x00000f84
-
-/*
- * Entry point
- */
-    .section .init.text,"ax",%progbits
-    .global  start
-start:
-    b       newstart
-
-#ifdef IPOD_ARCH
-.align 8    /* starts at 0x100 */
-.global boot_table
-boot_table:
-    /* here comes the boot table, don't move its offset - preceding
-       code+data must stay <= 256 bytes */
-    .space  400
-#else /* !IPOD_ARCH */
-    /* (more than enough) space for exception vectors and mi4 magic */
-    .space  68*4
-#endif /* IPOD_ARCH */
-
-newstart:
-    msr     cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
-    adr     r4, start     /* cache initial load address */
-
-    /* Copy startup stub to IRAM since we need to both move the bootloader's
-     * location, which could overlap itself, and setup the memory mapper. */
-    adr     r0, start_stub_begin
-    mov     r1, #0x40000000
-    adr     r2, start_stub_end
-1:
-    ldr     r3, [r0], #4
-    str     r3, [r1], #4
-    cmp     r0, r2
-    blo     1b
-    mov     pc, #0x40000000
-
-start_stub_begin:
-    ldr     r0, =PROC_ID
-    ldrb    r0, [r0]
-    cmp     r0, #0x55
-    beq     cpu
-
-cop:
-    mov     r0, #CACHE_OP_COMMIT_DISCARD
-    bl      cache_operation
-
-    ldr     r1, =COP_CTRL
-    mov     r0, #SLEEP
-
-    /* sleep us (co-processor) while bootloader is copied */
-    str     r0, [r1]
-    nop
-    nop
-    nop
-
-    /* branch to final physical load address */
-    ldr     r2, =1f
-    and     r4, r4, #0xfc000000
-    add     pc, r2, r4
-1:
-    /* wait for bootloader to finish */
-    str     r0, [r1]
-    nop
-    nop
-    nop
-
-    /* branch to the address returned by main() */
-    adr     r0, startup_loc
-    ldr     pc, [r0]
-
-cpu:
-    /* wait for COP to sleep */
-    ldr     r1, =COP_STATUS
-1:
-    ldr     r0, [r1]
-    tst     r0, #COP_SLEEPING
-    beq     1b
-
-    mov     r0, #CACHE_OP_COMMIT_DISCARD
-    bl      cache_operation
-
-    /* move bootloader to the correct load address if needed */
-    ldr     r1, =_loadaddress
-    cmp     r4, r1
-    ldrne   r2, =_loadaddressend
-    movne   r0, r4
-    sublo   r3, r2, r1 /* size */
-    addlo   r0, r0, r3 /* initial load end addr */
-1: /* lower to higher move - copy up */
-    cmphi   r2, r1
-    ldrhi   r3, [r0], #4
-    strhi   r3, [r1], #4
-    bhi     1b
-1: /* higher to lower move - copy down */
-    cmplo   r1, r2
-    ldrlo   r3, [r0, #-4]!
-    strlo   r3, [r2, #-4]!
-    blo     1b
-
-    mov     r0, #CACHE_OP_COMMIT
-    bl      cache_operation
-
-    and     r4, r4, #0xfc000000
-
-    ldr     r0, =MMAP_FLAGS
-    orr     r0, r0, r4 /* adjust for execute address */
-    ldr     r1, =MMAP_MASK
-    ldr     r2, =MMAP_LOG
-    ldr     r3, =MMAP_PHYS
-    str     r1, [r2] /* MMAP_LOG = MMAP_MASK */
-    str     r0, [r3] /* MMAP_PHYS = MMAP_FLAGS | SDRAM base addr */
-
-    /* wake the COP to jump it to the correct place */
-    ldr     r1, =COP_CTRL
-    mov     r0, #WAKE
-    str     r0, [r1]
-
-    /* wait for COP to halt then loading may proceed */
-    ldr     r1, =COP_STATUS
-1:
-    ldr     r0, [r1]
-    tst     r0, #COP_SLEEPING
-    beq     1b
-
-    ldr     r0, =start_stub_end
-    add     pc, r0, r4
-
-cache_operation: /* (bool commit_discard) */
-    ldr     r2, =CACHE_CTRL
-    ldr     r1, [r2]
-    tst     r1, #CACHE_ENAB
-    bxeq    lr
-    cmp     r0, #CACHE_OP_COMMIT
-    ldr     r0, =0xf000f044
-    ldr     r1, [r0]
-    orrne   r1, r1, #0x6
-    orreq   r1, r1, #0x2
-    str     r1, [r0]
-1:
-    ldr     r1, [r2]
-    tst     r1, #0x8000
-    bne     1b
-    bx      lr
-    .ltorg /* constants used in stub come with us to IRAM */
-start_stub_end:
-    /* now executing from final physical address */
-
-    /* copy the vector addresses to the table */
-    ldr     r0, =INT_VECT_TBL
-    adr     r1, vectorsstart
-    adr     r2, vectorsend
-1:
-    cmp     r2, r1
-    ldrhi   r3, [r1], #4
-    strhi   r3, [r0], #4
-    bhi     1b
-
-    /* Copy the IRAM */
-    ldr     r0, =_iramcopy
-    ldr     r1, =_iramstart
-    ldr     r2, =_iramend
-1:
-    cmp     r2, r1
-    ldrhi   r3, [r0], #4
-    strhi   r3, [r1], #4
-    bhi     1b
-
-    mov     r0, #0
-
-    /* Zero out IBSS */
-    ldr     r1, =_iedata
-    ldr     r2, =_iend
-1:
-    cmp     r2, r1
-    strhi   r0, [r1], #4
-    bhi     1b
-
-    /* Initialise bss/ncbss sections to zero */
-    ldr     r1, =_edata
-    ldr     r2, =_end
-1:
-    cmp     r2, r1
-    strhi   r0, [r1], #4
-    bhi     1b
-
-    /* Set up stack for IRQ mode */ 
-    msr     cpsr_c, #0xd2 /* IRQ/FIQ disabled */
-    ldr     sp, =irq_stack
-    /* Let svc, abort and undefined modes use irq stack */
-    msr     cpsr_c, #0xd3
-    ldr     sp, =irq_stack
-    msr     cpsr_c, #0xd7 /* IRQ/FIQ disabled */
-    ldr     sp, =irq_stack
-    msr     cpsr_c, #0xdb /* IRQ/FIQ disabled */
-    ldr     sp, =irq_stack
-
-    /* Switch back to sys mode */
-    msr     cpsr_c, #0xdf
-
-    /* Set up some stack and munge it with 0xdeadbeef */
-    ldr     r0, =0xdeadbeef
-    ldr     r1, =stackbegin
-    ldr     sp, =stackend
-1:
-    cmp     sp, r1
-    strhi   r0, [r1], #4
-    bhi     1b
-
-    /* execute the loader - this will load an image to 0x10000000 */
-    ldr     r0, =main
-    mov     lr, pc
-    bx      r0
-
-    /* store actual startup location returned by main() */
-    ldr     r1, =startup_loc
-    str     r0, [r1]
-
-    /* write back anything loaded + startup_loc */
-    mov     r0, #CACHE_OP_COMMIT
-    bl      cache_operation
-
-    mov     r0, #0
-
-    /* disable memory mapper */
-    ldr     r1, =MMAP_LOG
-    ldr     r2, =MMAP_PHYS
-    str     r0, [r1]
-    str     r0, [r2]
-
-    /* bring COP back to life */
-    ldr     r1, =COP_CTRL
-    mov     r0, #WAKE
-    str     r0, [r1]
-
-    /* after this point, r0-r3 are reserved for OF magic */
-
-#if defined(SANSA_C200) || defined(PHILIPS_HDD1630)
-    /* Magic for loading the c200 OF */
-    ldr     r0, =0xb00d10ad
-    mov     r1, #0x700
-    ldr     r2, =0xfff0
-    mov     r3, #0x7
-#endif
-
-#if defined(PHILIPS_HDD6330)
-    /* Magic for loading the HDD6XX0 OF */
-    ldr     r0, =0xb00d10ad
-    mov     r1, #0x800
-    ldr     r2, =0xfff0
-    mov     r3, #0x7
-#endif
-
-    /* branch to the address returned by main() */
-    adr     r4, startup_loc
-    ldr     pc, [r4]
-
-startup_loc:
-    .word   0x00000000
-
-/* exception handlers: will be copied to local vector table */
-vectorsstart:
-    .word   newstart 
-    .word   undef_instr_handler
-    .word   software_int_handler
-    .word   prefetch_abort_handler
-    .word   data_abort_handler
-    .word   reserved_handler
-    .word   irq_handler
-    .word   fiq_handler
-vectorsend:
-
-    .text
-
-/* All illegal exceptions call into UIE with exception address as first
-   parameter. This is calculated differently depending on which exception
-   we're in. Second parameter is exception number, used for a string lookup
-   in UIE.
- */
-undef_instr_handler:
-    sub     r0, lr, #4
-    mov     r1, #0
-    b       UIE
-
-/* We run sys mode most of the time, and should never see a software
-   exception being thrown. Make it illegal and call UIE.
- */
-software_int_handler:
-reserved_handler:
-    sub     r0, lr, #4
-    mov     r1, #4
-    b       UIE
-
-prefetch_abort_handler:
-    sub     r0, lr, #4
-    mov     r1, #1
-    b       UIE
-
-data_abort_handler:
-    sub     r0, lr, #8 
-    mov     r1, #2
-    b       UIE
-
-/* should never happen in the bootloader */
-fiq_handler:
-    subs    pc, lr, #4
-
-/* 256 words of IRQ stack */
-    .section .bss
-    .balign 16
-    .space  256*4
-irq_stack:
diff --git a/firmware/target/arm/debug-pp.c b/firmware/target/arm/debug-pp.c
deleted file mode 100644
index 5f252db..0000000
--- a/firmware/target/arm/debug-pp.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 Dave Chapman
- *
- * 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 "system.h"
-#include <stdbool.h>
-#include "font.h"
-#include "lcd.h"
-#include "button.h"
-#include "powermgmt.h"
-#include "adc.h"
-#include "iap.h"
-#include "hwcompat.h"
-#include "debug-target.h"
-
-static int perfcheck(void)
-{
-    int result;
-
-    asm (
-        "mrs     r2, CPSR            \n"
-        "orr     r0, r2, #0xc0       \n" /* disable IRQ and FIQ */
-        "msr     CPSR_c, r0          \n"
-        "mov     %[res], #0          \n"
-        "ldr     r0, [%[timr]]       \n"
-        "add     r0, r0, %[tmo]      \n"
-    "1:                              \n"
-        "add     %[res], %[res], #1  \n"
-        "ldr     r1, [%[timr]]       \n"
-        "cmp     r1, r0              \n"
-        "bmi     1b                  \n"
-        "msr     CPSR_c, r2          \n" /* reset IRQ and FIQ state */
-        :
-        [res]"=&r"(result)
-        :
-        [timr]"r"(&USEC_TIMER),
-        [tmo]"r"(
-#if CONFIG_CPU == PP5002
-        16000
-#else /* PP5020/5022/5024 */
-        10226
-#endif
-        )
-        :
-        "r0", "r1", "r2"
-    );
-    return result;
-}
-
-bool dbg_ports(void)
-{
-    int line;
-
-    lcd_clear_display();
-    lcd_setfont(FONT_SYSFIXED);
-
-    while(1)
-    {
-        line = 0;
-#if defined(CPU_PP502x)
-#if (LCD_HEIGHT >= 176) /* Only for displays with appropriate height. */
-        lcd_puts(0, line++, "GPIO ENABLE:");
-        lcd_putsf(0, line++, "A: %02x  E: %02x  I: %02x",
-                               (unsigned int)GPIOA_ENABLE,
-                               (unsigned int)GPIOE_ENABLE,
-                               (unsigned int)GPIOI_ENABLE);
-        lcd_putsf(0, line++, "B: %02x  F: %02x  J: %02x",
-                               (unsigned int)GPIOB_ENABLE,
-                               (unsigned int)GPIOF_ENABLE,
-                               (unsigned int)GPIOJ_ENABLE);
-        lcd_putsf(0, line++, "C: %02x  G: %02x  K: %02x",
-                               (unsigned int)GPIOC_ENABLE,
-                               (unsigned int)GPIOG_ENABLE,
-                               (unsigned int)GPIOK_ENABLE);
-        lcd_putsf(0, line++, "D: %02x  H: %02x  L: %02x",
-                               (unsigned int)GPIOD_ENABLE,
-                               (unsigned int)GPIOH_ENABLE,
-                               (unsigned int)GPIOL_ENABLE);
-        line++;
-#endif
-        lcd_puts(0, line++, "GPIO INPUT VAL:");
-        lcd_putsf(0, line++, "A: %02x  E: %02x  I: %02x",
-                               (unsigned int)GPIOA_INPUT_VAL,
-                               (unsigned int)GPIOE_INPUT_VAL,
-                               (unsigned int)GPIOI_INPUT_VAL);
-        lcd_putsf(0, line++, "B: %02x  F: %02x  J: %02x",
-                               (unsigned int)GPIOB_INPUT_VAL,
-                               (unsigned int)GPIOF_INPUT_VAL,
-                               (unsigned int)GPIOJ_INPUT_VAL);
-        lcd_putsf(0, line++, "C: %02x  G: %02x  K: %02x",
-                               (unsigned int)GPIOC_INPUT_VAL,
-                               (unsigned int)GPIOG_INPUT_VAL,
-                               (unsigned int)GPIOK_INPUT_VAL);
-        lcd_putsf(0, line++, "D: %02x  H: %02x  L: %02x",
-                               (unsigned int)GPIOD_INPUT_VAL,
-                               (unsigned int)GPIOH_INPUT_VAL,
-                               (unsigned int)GPIOL_INPUT_VAL);
-        line++;
-        lcd_putsf(0, line++, "GPO32_VAL: %08lx", GPO32_VAL);
-        lcd_putsf(0, line++, "GPO32_EN:  %08lx", GPO32_ENABLE);
-        lcd_putsf(0, line++, "DEV_EN:    %08lx", DEV_EN);
-        lcd_putsf(0, line++, "DEV_EN2:   %08lx", DEV_EN2);
-        lcd_putsf(0, line++, "DEV_EN3:   %08lx", inl(0x60006044)); /* to be verified */
-        lcd_putsf(0, line++, "DEV_INIT1: %08lx", DEV_INIT1);
-        lcd_putsf(0, line++, "DEV_INIT2: %08lx", DEV_INIT2);
-#ifdef ADC_ACCESSORY
-        lcd_putsf(0, line++, "ACCESSORY: %d", adc_read(ADC_ACCESSORY));
-#endif
-#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
-        lcd_putsf(0, line++, "4066_ISTAT: %d", adc_read(ADC_4066_ISTAT));
-#endif
-
-#if defined(IPOD_ACCESSORY_PROTOCOL)
-        const unsigned char *serbuf = iap_get_serbuf();
-        lcd_putsf(0, line++, "IAP: %02x %02x %02x %02x %02x %02x %02x %02x", 
-         serbuf[0], serbuf[1], serbuf[2], serbuf[3], serbuf[4], serbuf[5],
-         serbuf[6], serbuf[7]);
-#endif
-
-#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
-        line++;
-        lcd_putsf(0, line++, "BATT: %03x UNK1: %03x",
-                                adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
-        lcd_putsf(0, line++, "REM:  %03x PAD: %03x",
-                                 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
-#elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
-        line++;
-        lcd_putsf(0, line++, "BATT: %03x UNK1: %03x",
-                                adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
-#elif defined(SANSA_E200) || defined(PHILIPS_SA9200)
-        lcd_putsf(0, line++, "ADC_BVDD:     %4d", adc_read(ADC_BVDD));
-        lcd_putsf(0, line++, "ADC_RTCSUP:   %4d", adc_read(ADC_RTCSUP));
-        lcd_putsf(0, line++, "ADC_UVDD:     %4d", adc_read(ADC_UVDD));
-        lcd_putsf(0, line++, "ADC_CHG_IN:   %4d", adc_read(ADC_CHG_IN));
-        lcd_putsf(0, line++, "ADC_CVDD:     %4d", adc_read(ADC_CVDD));
-        lcd_putsf(0, line++, "ADC_BATTEMP:  %4d", adc_read(ADC_BATTEMP));
-        lcd_putsf(0, line++, "ADC_MICSUP1:  %4d", adc_read(ADC_MICSUP1));
-        lcd_putsf(0, line++, "ADC_MICSUP2:  %4d", adc_read(ADC_MICSUP2));
-        lcd_putsf(0, line++, "ADC_VBE1:     %4d", adc_read(ADC_VBE1));
-        lcd_putsf(0, line++, "ADC_VBE2:     %4d", adc_read(ADC_VBE2));
-        lcd_putsf(0, line++, "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
-#if !defined(PHILIPS_SA9200)
-        lcd_putsf(0, line++, "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
-        lcd_putsf(0, line++, "ADC_VBAT:     %4d", adc_read(ADC_VBAT));
-#endif
-#endif
-
-#elif CONFIG_CPU == PP5002
-        lcd_putsf(0, line++, "GPIO_A: %02x GPIO_B: %02x",
-                 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
-        lcd_putsf(0, line++, "GPIO_C: %02x GPIO_D: %02x",
-                 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
-
-        lcd_putsf(0, line++, "DEV_EN:       %08lx", DEV_EN);
-        lcd_putsf(0, line++, "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
-        lcd_putsf(0, line++, "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
-        lcd_putsf(0, line++, "PLL_CONTROL:  %08lx", PLL_CONTROL);
-        lcd_putsf(0, line++, "PLL_DIV:      %08lx", PLL_DIV);
-        lcd_putsf(0, line++, "PLL_MULT:     %08lx", PLL_MULT);
-        lcd_putsf(0, line++, "TIMING1_CTL:  %08lx", TIMING1_CTL);
-        lcd_putsf(0, line++, "TIMING2_CTL:  %08lx", TIMING2_CTL);
-#endif
-        lcd_update();
-        if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
-        {
-            lcd_setfont(FONT_UI);
-            return false;
-        }
-    }
-    return false;
-}
-
-bool dbg_hw_info(void)
-{
-    int line = 0;
-#if defined(CPU_PP502x)
-    char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
-                          (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
-                          (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
-                          (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
-#elif CONFIG_CPU == PP5002
-    char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
-                          (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
-                          (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
-                          (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
-#endif
-
-    lcd_setfont(FONT_SYSFIXED);
-    lcd_clear_display();
-
-    lcd_puts(0, line++, "[Hardware info]");
-
-#ifdef IPOD_ARCH
-    lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
-#endif
-
-#if defined(IPOD_COLOR) || defined(IPOD_NANO)
-    extern int lcd_type; /* Defined in lcd-colornano.c */
-
-    lcd_putsf(0, line++, "LCD type: %d", lcd_type);
-#endif
-
-    lcd_putsf(0, line++, "PP version: %s", pp_version);
-
-    lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
-
-    lcd_update();
-
-    /* wait for exit */
-    while (button_get_w_tmo(HZ/10) != (DEBUG_CANCEL|BUTTON_REL));
-
-    lcd_setfont(FONT_UI);
-    return false;
-}
diff --git a/firmware/target/arm/debug-target.h b/firmware/target/arm/debug-target.h
deleted file mode 100644
index 28f9532..0000000
--- a/firmware/target/arm/debug-target.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2010 by Marcin Bukat
- *
- * 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.
- *
- ****************************************************************************/
-#if (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
-    (CONFIG_KEYPAD == IPOD_3G_PAD) || \
-    (CONFIG_KEYPAD == IPOD_4G_PAD)
-#   define DEBUG_CANCEL  BUTTON_MENU
-
-#elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
-#   define DEBUG_CANCEL  BUTTON_REW
-
-#elif (CONFIG_KEYPAD == MROBE100_PAD)
-#   define DEBUG_CANCEL  BUTTON_MENU
-
-#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
-      (CONFIG_KEYPAD == SANSA_C200_PAD)
-#   define DEBUG_CANCEL  BUTTON_LEFT
-
-#elif (CONFIG_KEYPAD == PHILIPS_SA9200_PAD) || \
-      (CONFIG_KEYPAD == PHILIPS_HDD1630_PAD)
-#   define DEBUG_CANCEL  BUTTON_POWER
-
-#elif (CONFIG_KEYPAD == PHILIPS_HDD6330_PAD)
-#   define DEBUG_CANCEL  BUTTON_PREV
-
-#elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
-#   define DEBUG_CANCEL  BUTTON_PLAY
-
-#elif (CONFIG_KEYPAD == PBELL_VIBE500_PAD)
-#   define DEBUG_CANCEL  BUTTON_CANCEL
-#endif
-bool dbg_ports(void);
-bool dbg_hw_info(void);
diff --git a/firmware/target/arm/i2c-pp.c b/firmware/target/arm/i2c-pp.c
deleted file mode 100644
index 58740b5..0000000
--- a/firmware/target/arm/i2c-pp.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * PP502X and PP5002 I2C driver
- *
- * Based on code from the ipodlinux project - http://ipodlinux.org/
- * Adapted for Rockbox in November 2005
- *
- * Original file: linux/arch/armnommu/mach-ipod/hardware.c
- *
- * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
- *
- * 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 "cpu.h"
-#include "kernel.h"
-#include "thread.h"
-#include "logf.h"
-#include "system.h"
-#include "i2c.h"
-#include "i2c-pp.h"
-#include "ascodec.h"
-#include "as3514.h"
-
-#define I2C_CTRL    (*(volatile unsigned char*)(I2C_BASE+0x00))
-#define I2C_ADDR    (*(volatile unsigned char*)(I2C_BASE+0x04))
-#define I2C_DATA(X) (*(volatile unsigned char*)(I2C_BASE+0xc+(4*X)))
-#define I2C_STATUS  (*(volatile unsigned char*)(I2C_BASE+0x1c))
-
-/* I2C_CTRL bit definitions */
-#define I2C_SEND    0x80
-
-/* I2C_STATUS bit definitions */
-#define I2C_BUSY    (1<<6)
-
-/* Local functions definitions */
-static struct mutex i2c_mtx SHAREDBSS_ATTR;
-
-#define POLL_TIMEOUT (HZ)
-
-static int pp_i2c_wait_not_busy(void)
-{
-    unsigned long timeout;
-    timeout = current_tick + POLL_TIMEOUT;
-    while (TIME_BEFORE(current_tick, timeout)) {
-         if (!(I2C_STATUS & I2C_BUSY)) {
-            return 0;
-         }
-         yield();
-    }
-
-    return -1;
-}
-
-static int pp_i2c_read_bytes(unsigned int addr, int len, unsigned char *data)
-{
-    int i;
-
-    if (len < 1 || len > 4)
-    {
-        return -1;
-    }
-
-    if (pp_i2c_wait_not_busy() < 0)
-    {
-        return -2;
-    }
-
-    {
-        int old_irq_level = disable_irq_save();
-
-        /* clear top 15 bits, left shift 1, or in 0x1 for a read */
-        I2C_ADDR = ((addr << 17) >> 16) | 0x1;
-
-        I2C_CTRL |= 0x20;
-
-        I2C_CTRL = (I2C_CTRL & ~0x6) | ((len-1) << 1);
-
-        I2C_CTRL |= I2C_SEND;
-
-        restore_irq(old_irq_level);
-
-        if (pp_i2c_wait_not_busy() < 0)
-        {
-            return -2;
-        }
-
-        old_irq_level = disable_irq_save();
-
-        if (data)
-        {
-            for ( i = 0; i < len; i++ )
-                *data++ = I2C_DATA(i);
-        }
-
-        restore_irq(old_irq_level);
-    }
-
-    return 0;
-}
-
-static int pp_i2c_send_bytes(unsigned int addr, int len, unsigned char *data)
-{
-    int i;
-
-    if (len < 1 || len > 4)
-    {
-        return -1;
-    }
-
-    if (pp_i2c_wait_not_busy() < 0)
-    {
-        return -2;
-    }
-
-    {
-        int old_irq_level = disable_irq_save();
-
-        /* clear top 15 bits, left shift 1 */
-        I2C_ADDR = (addr << 17) >> 16;
-
-        I2C_CTRL &= ~0x20;
-
-        for ( i = 0; i < len; i++ )
-        {
-            I2C_DATA(i) = *data++;
-        }
-
-        I2C_CTRL = (I2C_CTRL & ~0x6) | ((len-1) << 1);
-
-        I2C_CTRL |= I2C_SEND;
-
-        restore_irq(old_irq_level);
-    }
-
-    return 0;
-}
-
-static int pp_i2c_send_byte(unsigned int addr, int data0)
-{
-    unsigned char data[1];
-
-    data[0] = data0;
-
-    return pp_i2c_send_bytes(addr, 1, data);
-}
-
-/* Public functions */
-void i2c_lock(void)
-{
-    mutex_lock(&i2c_mtx);
-}
-
-void i2c_unlock(void)
-{
-    mutex_unlock(&i2c_mtx);
-}
-
-int i2c_readbytes(unsigned int dev_addr, int addr, int len, unsigned char *data)
-{
-    int i, n;
-
-    mutex_lock(&i2c_mtx);
-
-    if (addr >= 0)
-        pp_i2c_send_byte(dev_addr, addr);
-
-    i = 0;
-    while (len > 0)
-    {
-        n = (len < 4) ? len : 4;
-
-        if (pp_i2c_read_bytes(dev_addr, n, data + i) < 0)
-            break;
-
-        len -= n;
-        i   += n;
-    }
-
-    mutex_unlock(&i2c_mtx);
-
-    return i;
-}
-
-int i2c_readbyte(unsigned int dev_addr, int addr)
-{
-    unsigned char data;
-
-    mutex_lock(&i2c_mtx);
-    pp_i2c_send_byte(dev_addr, addr);
-    pp_i2c_read_bytes(dev_addr, 1, &data);
-    mutex_unlock(&i2c_mtx);
-
-    return (int)data;
-}
-
-int i2c_sendbytes(unsigned int addr, int len, const unsigned char *data)
-{
-    int i, n;
-
-    mutex_lock(&i2c_mtx);
-
-    i = 0;
-    while (len > 0)
-    {
-        n = (len < 4) ? len : 4;
-
-        if (pp_i2c_send_bytes(addr, n, (unsigned char *)(data + i)) < 0)
-            break;
-
-        len -= n;
-        i   += n;
-    }
-
-    mutex_unlock(&i2c_mtx);
-
-    return i;
-}
-
-int pp_i2c_send(unsigned int addr, int data0, int data1)
-{
-    int retval;
-    unsigned char data[2];
-
-    data[0] = data0;
-    data[1] = data1;
-
-    mutex_lock(&i2c_mtx);
-    retval = pp_i2c_send_bytes(addr, 2, data);
-    mutex_unlock(&i2c_mtx);
-
-    return retval;
-}
-
-void i2c_init(void)
-{
-    /* From ipodlinux */
-    mutex_init(&i2c_mtx);
-
-#ifdef IPOD_MINI
-    /* GPIO port C disable port 0x10 */
-    GPIOC_ENABLE &= ~0x10;
-
-    /* GPIO port C disable port 0x20 */
-    GPIOC_ENABLE &= ~0x20;
-#endif
-
-#if CONFIG_I2C == I2C_PP5002
-    DEV_EN |= 0x2;
-#else
-    DEV_EN |= DEV_I2C;  /* Enable I2C */
-#endif
-    DEV_RS |= DEV_I2C;  /* Start I2C Reset */
-    DEV_RS &=~DEV_I2C;  /* End I2C Reset */
-
-#if CONFIG_I2C == I2C_PP5020
-    outl(0x0, 0x600060a4);
-#if defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) || \
-    defined(SAMSUNG_YH820) || defined(SAMSUNG_YH920) || \
-    defined(SAMSUNG_YH925) || defined(PBELL_VIBE500)
-    outl(inl(0x600060a4) | 0x20, 0x600060a4);
-    outl(inl(0x7000c020) | 0x3, 0x7000c020);
-    outl(0x55, 0x7000c02c);
-    outl(0x54, 0x7000c030);
-#else
-    outl(0x80 | (0 << 8), 0x600060a4);
-#endif
-#elif CONFIG_I2C == I2C_PP5024
-#if defined(SANSA_E200) || defined(PHILIPS_SA9200)
-    /* Sansa OF sets this to 0x20 first, communicates with the AS3514
-       then sets it to 0x23 - this still works fine though */
-    outl(0x0, 0x600060a4);
-    outl(0x23, 0x600060a4);
-#elif defined(SANSA_C200)
-    /* This is the init sequence from the Sansa c200 bootloader.
-       I'm not sure what's really necessary. */
-    pp_i2c_wait_not_busy();
-
-    outl(0, 0x600060a4);
-    outl(0x64, 0x600060a4);
-
-    outl(0x55, 0x7000c02c);
-    outl(0x54, 0x7000c030);
-
-    outl(0, 0x600060a4);
-    outl(0x1e, 0x600060a4);
-
-    ascodec_write(AS3514_SUPERVISOR, 5);
-#elif defined(PHILIPS_SA9200)
-    outl(0x0, 0x600060a4);
-    outl(inl(0x600060a4) | 0x20, 0x600060a4);
-
-    outl(inl(0x7000c020) | 0x3, 0x7000c020);
-    outl(0x55, 0x7000c02c);
-    outl(0x54, 0x7000c030);
-#endif
-#endif
-
-    i2c_readbyte(0x8, 0);
-}
diff --git a/firmware/target/arm/i2s-pp.c b/firmware/target/arm/i2s-pp.c
deleted file mode 100644
index 83f3951..0000000
--- a/firmware/target/arm/i2s-pp.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Portalplayer specific code for I2S
- *
- * Based on code from the ipodlinux project - http://ipodlinux.org/
- * Adapted for Rockbox in December 2005
- *
- * Original file: linux/arch/armnommu/mach-ipod/audio.c
- *
- * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
- *
- * 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 "system.h"
-#include "cpu.h"
-#include "i2s.h"
-#if defined (SANSA_E200) || defined (SANSA_C200)
-#include "audiohw.h"
-#include "pcm_sampr.h"
-#endif
-
-#if CONFIG_CPU == PP5002
-void i2s_reset(void)
-{
-    /* I2S device reset */
-    DEV_RS |= DEV_I2S;
-    DEV_RS &= ~DEV_I2S;
-
-    /* I2S controller enable */
-    IISCONFIG |= IIS_ENABLE;
-
-    /* reset DAC and ADC fifo */
-    IISFIFO_CFG |= IIS_RXCLR | IIS_TXCLR;
-}
-#else /* PP502X */
-
-/*
- * Reset the I2S BIT.FORMAT I2S, 16bit, FIFO.FORMAT 32bit
- */
-void i2s_reset(void)
-{
-    /* I2S soft reset */
-    IISCONFIG |= IIS_RESET;
-    IISCONFIG &= ~IIS_RESET;
-
-    /* BIT.FORMAT */
-    IISCONFIG = ((IISCONFIG & ~IIS_FORMAT_MASK) | IIS_FORMAT_IIS);
-    /* BIT.SIZE */
-    IISCONFIG = ((IISCONFIG & ~IIS_SIZE_MASK) | IIS_SIZE_16BIT);
-
-    /* FIFO.FORMAT */
-    /* If BIT.SIZE < FIFO.FORMAT low bits will be 0 */
-#ifdef HAVE_AS3514
-    /* AS3514 can only operate as I2S Slave */
-    IISCONFIG |= IIS_MASTER;
-
-    /* Set I2S to 44.1kHz */
-#ifdef PHILIPS_SA9200
-    /* values taken from the SA9200 OF */
-    IISCLK = (IISCLK & ~0x1ff) | 31;
-    IISDIV = (IISDIV & ~0xc0000000) | (2 << 30);
-    IISDIV = (IISDIV & ~0x3f) | 16;
-#elif defined (SANSA_E200) || defined (SANSA_C200)
-    audiohw_set_sampr_dividers(HW_FREQ_DEFAULT);
-#else
-    IISCLK = (IISCLK & ~0x1ff) | 33;
-    IISDIV = 7;
-#endif
-#endif /* HAVE_AS3514 */
-
-    IISCONFIG = ((IISCONFIG & ~IIS_FIFO_FORMAT_MASK) | IIS_FIFO_FORMAT_LE16_2);
-
-    /* RX_ATN_LVL = when 12 slots full */
-    /* TX_ATN_LVL = DMA request when 4 slots empty */
-    IISFIFO_CFG |= IIS_RX_FULL_LVL_12 | IIS_TX_EMPTY_LVL_4;
-
-    /* Rx.CLR = 1, TX.CLR = 1 */
-    IISFIFO_CFG |= IIS_RXCLR | IIS_TXCLR;
-}
-
-#endif /* CONFIG_CPU == */
diff --git a/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c b/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c
deleted file mode 100644
index 37c719f..0000000
--- a/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2007 by Jens Arnold
- *
- * 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 "hwcompat.h"
-#include "kernel.h"
-#include "adc.h"
-#include "adc-target.h"
-#include "system-target.h"
-
-static struct mutex adc_mtx SHAREDBSS_ATTR;
-
-/* used in the 2nd gen ADC interrupt */
-static unsigned int_data;
-static int int_status = -1;
-
-unsigned short adc_scan(int channel)
-{
-    unsigned short data = 0;
-
-    (void)channel; /* there is only one */
-    mutex_lock(&adc_mtx);
-
-    if ((IPOD_HW_REVISION >> 16) == 1)
-    {
-        int i;
-        unsigned pval = GPIOB_OUTPUT_VAL;
-
-        GPIOB_OUTPUT_VAL = pval | 0x04;  /* B2 -> high */
-        udelay(2);
-
-        GPIOB_OUTPUT_VAL = pval;         /* B2 -> low */
-        udelay(10);
-
-        for (i = 0; i < 8; i++)
-        {
-            GPIOB_OUTPUT_VAL = pval | 0x02; /* B1 -> high */
-            udelay(1);
-
-            data = (data << 1) | ((GPIOB_INPUT_VAL & 0x08) >> 3);
-
-            GPIOB_OUTPUT_VAL = pval;     /* B1 -> low */
-            udelay(15);
-        }
-    }
-    else if ((IPOD_HW_REVISION >> 16) == 2)
-    {
-        int_status = 0;
-        GPIOB_INT_LEV    |= 0x04; /* high active */
-        GPIOB_INT_EN     |= 0x04; /* enable interrupt */
-        GPIOB_OUTPUT_VAL |= 0x0a; /* B1, B3 -> high: start conversion */
-
-        while (int_status >= 0)
-            yield();
-
-        data = int_data & 0xff;
-    }
-    mutex_unlock(&adc_mtx);
-    return data;
-}
-
-/* Used for 2nd gen only. Conversion can take several milliseconds there. */
-void ipod_2g_adc_int(void)
-{
-    if (GPIOB_INPUT_VAL & 0x04)
-    {
-        int_data = (int_data << 1) | ((GPIOB_INPUT_VAL & 0x10) >> 4);
-
-        GPIOB_OUTPUT_VAL &= ~0x0a; /* B1, B3 -> low */
-        /* B3 needs to be set low in the first call only, but then stays low
-         * anyway so no need for special handling */
-    }
-    else
-    {
-        if (++int_status > 8)
-        {
-            GPIOB_INT_EN &= ~0x04;
-            int_status = -1;
-        }
-        else
-            GPIOB_OUTPUT_VAL |= 0x02;  /* B1 -> high */
-    }
-    GPIOB_INT_LEV ^= 0x04; /* toggle interrupt level */
-    GPIOB_INT_CLR  = 0x04; /* acknowledge interrupt */
-}
-
-void adc_init(void)
-{
-    mutex_init(&adc_mtx);
-    
-    GPIOB_ENABLE |= 0x1e;  /* enable B1..B4 */
-
-    if ((IPOD_HW_REVISION >> 16) == 1)
-    {
-        GPIOB_OUTPUT_EN  = (GPIOB_OUTPUT_EN & ~0x08) | 0x16;
-                                         /* B1, B2, B4 -> output, B3 -> input */
-        GPIOB_OUTPUT_VAL = (GPIOB_OUTPUT_VAL & ~0x06) | 0x10;
-                                         /* B1, B2 -> low, B4 -> high */
-    }
-    else if ((IPOD_HW_REVISION >> 16) == 2)
-    {
-        GPIOB_OUTPUT_EN   = (GPIOB_OUTPUT_EN & ~0x14) | 0x0a;
-                                         /* B1, B3 -> output, B2, B4 -> input */
-        GPIOB_OUTPUT_VAL &= ~0x0a;       /* B1, B3 -> low */
-        while (GPIOB_INPUT_VAL & 0x04);  /* wait for B2 == 0 */
-    }
-}
diff --git a/firmware/target/arm/ipod/1g2g/adc-target.h b/firmware/target/arm/ipod/1g2g/adc-target.h
deleted file mode 100644
index 5b0ce4b..0000000
--- a/firmware/target/arm/ipod/1g2g/adc-target.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2007 by Jens Arnold
- *
- * 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 _ADC_TARGET_H_
-#define _ADC_TARGET_H_
-
-#define NUM_ADC_CHANNELS 1
-
-#define ADC_BATTERY 0
-#define ADC_UNREG_POWER ADC_BATTERY
-
-/* Force a scan now */
-unsigned short adc_scan(int channel);
-void ipod_2g_adc_int(void);
-static inline unsigned short adc_read(int channel)
-{ 
-    return adc_scan(channel); 
-}
-#endif
diff --git a/firmware/target/arm/ipod/1g2g/backlight-1g2g.c b/firmware/target/arm/ipod/1g2g/backlight-1g2g.c
deleted file mode 100644
index b779781..0000000
--- a/firmware/target/arm/ipod/1g2g/backlight-1g2g.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- *
- * 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 "system.h"
-#include "lcd.h"
-#include "backlight.h"
-#include "backlight-target.h"
-
-void _backlight_on(void)
-{
-    LCD1_CONTROL |= 0x02;
-    lcd_set_backlight_inversion(true);
-}
-
-void _backlight_off(void)
-{
-    LCD1_CONTROL &= ~0x02;
-    lcd_set_backlight_inversion(false);
-}
diff --git a/firmware/target/arm/ipod/1g2g/backlight-target.h b/firmware/target/arm/ipod/1g2g/backlight-target.h
deleted file mode 100644
index 2282605..0000000
--- a/firmware/target/arm/ipod/1g2g/backlight-target.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 BACKLIGHT_TARGET_H
-#define BACKLIGHT_TARGET_H
-
-#define _backlight_init() false
-void _backlight_on(void);
-void _backlight_off(void);
-
-#endif
diff --git a/firmware/target/arm/ipod/1g2g/powermgmt-1g2g.c b/firmware/target/arm/ipod/1g2g/powermgmt-1g2g.c
deleted file mode 100644
index 1bc5de9..0000000
--- a/firmware/target/arm/ipod/1g2g/powermgmt-1g2g.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
- * Revisions copyright (C) 2005 by Gerald Van Baren
- *
- * 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 "adc.h"
-#include "powermgmt.h"
-#include "hwcompat.h"
-
-/* FIXME: Properly calibrate values. Current values "inherited" from
- * iriver H100 */
-
-const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
-{
-    3380
-};
-
-const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
-{
-    3020
-};
-
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
-const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
-{
-    { 3370, 3650, 3700, 3740, 3780, 3820, 3870, 3930, 4000, 4080, 4160 }
-};
-
-#if CONFIG_CHARGING
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
-const unsigned short percent_to_volt_charge[11] =
-{
-    3540, 3860, 3930, 3980, 4000, 4020, 4040, 4080, 4130, 4180, 4230
-};
-#endif /* CONFIG_CHARGING */
-
-#define BATTERY_SCALE_FACTOR_1G 4200
-#define BATTERY_SCALE_FACTOR_2G 6630
-/* full-scale ADC readout (2^8) in millivolt */
-
-/* Returns battery voltage from ADC [millivolts] */
-unsigned int battery_adc_voltage(void)
-{
-    unsigned adcval = adc_read(ADC_UNREG_POWER);
-
-    if ((IPOD_HW_REVISION >> 16) == 1)
-        return (adcval * BATTERY_SCALE_FACTOR_1G) >> 8;
-    else
-        return (adcval * BATTERY_SCALE_FACTOR_2G) >> 8;
-}
diff --git a/firmware/target/arm/ipod/3g/backlight-3g.c b/firmware/target/arm/ipod/3g/backlight-3g.c
deleted file mode 100644
index 77088e3..0000000
--- a/firmware/target/arm/ipod/3g/backlight-3g.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- *
- * 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 "system.h"
-#include "backlight.h"
-#include "backlight-target.h"
-
-void _backlight_on(void)
-{
-    LCD1_CONTROL |= 0x02;
-}
-
-void _backlight_off(void)
-{
-    LCD1_CONTROL &= ~0x02;
-}
diff --git a/firmware/target/arm/ipod/adc-ipod-pcf.c b/firmware/target/arm/ipod/adc-ipod-pcf.c
deleted file mode 100644
index 5040e21..0000000
--- a/firmware/target/arm/ipod/adc-ipod-pcf.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- *
- * 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 "system.h"
-#include "kernel.h"
-#include "thread.h"
-#include "string.h"
-#include "adc.h"
-#include "pcf50605.h"
-#include "i2c-pp.h"
-
-struct adc_struct {
-    long timeout;
-    void (*conversion)(unsigned short *data);
-    short channelnum;
-    unsigned short data;
-};
-
-static struct adc_struct adcdata[NUM_ADC_CHANNELS] IDATA_ATTR;
-
-static unsigned short _adc_read(struct adc_struct *adc)
-{
-    if (TIME_AFTER(current_tick, adc->timeout)) {
-        unsigned char data[2];
-        unsigned short value;
-
-        i2c_lock();
-
-        /* 5x per 2 seconds */
-        adc->timeout = current_tick + (HZ * 2 / 5);
-
-        /* ADCC1, 10 bit, start */
-        pcf50605_write(0x2f, (adc->channelnum << 1) | 0x1);
-        pcf50605_read_multiple(0x30, data, 2); /* ADCS1, ADCS2 */
-        value   = data[0];
-        value <<= 2;
-        value  |= data[1] & 0x3;
-
-        if (adc->conversion) {
-            adc->conversion(&value);
-        }
-        adc->data = value;
-
-        i2c_unlock();
-        return value;
-    } else
-    {
-        return adc->data;
-    }
-}
-
-/* Force an ADC scan _now_ */
-unsigned short adc_scan(int channel) {
-    struct adc_struct *adc = &adcdata[channel];
-    adc->timeout = 0;
-    return _adc_read(adc);
-}
-
-/* Retrieve the ADC value, only does a scan periodically */
-unsigned short adc_read(int channel) {
-    return _adc_read(&adcdata[channel]);
-}
-
-void adc_init(void)
-{
-    struct adc_struct *adc_battery = &adcdata[ADC_BATTERY];
-    adc_battery->channelnum = 0x2; /* ADCVIN1, resistive divider */
-    adc_battery->timeout = 0;
-    adcdata[ADC_ACCESSORY].channelnum = 4;
-    adcdata[ADC_ACCESSORY].timeout = 0;
-#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
-    adcdata[ADC_4066_ISTAT].channelnum = 7;
-    adcdata[ADC_4066_ISTAT].timeout = 0;
-#endif
-    _adc_read(adc_battery);
-}
diff --git a/firmware/target/arm/ipod/adc-target.h b/firmware/target/arm/ipod/adc-target.h
deleted file mode 100644
index 6fa8877..0000000
--- a/firmware/target/arm/ipod/adc-target.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- *
- * 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 _ADC_TARGET_H_
-#define _ADC_TARGET_H_
-
-#define ADC_BATTERY 0
-#define ADC_ACCESSORY 1
-#define ADC_UNREG_POWER ADC_BATTERY
-#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
-#define ADC_4066_ISTAT 2
-#define NUM_ADC_CHANNELS 3
-#else
-#define NUM_ADC_CHANNELS 2
-#endif
- 
-/* Force a scan now */
-unsigned short adc_scan(int channel);
-#endif
diff --git a/firmware/target/arm/ipod/app.lds b/firmware/target/arm/ipod/app.lds
deleted file mode 100644
index 3fe08fe..0000000
--- a/firmware/target/arm/ipod/app.lds
+++ /dev/null
@@ -1,208 +0,0 @@
-#include "config.h"
-
-ENTRY(start)
-
-OUTPUT_FORMAT(elf32-littlearm)
-OUTPUT_ARCH(arm)
-STARTUP(target/arm/crt0-pp.o)
-
-#define PLUGINSIZE PLUGIN_BUFFER_SIZE
-#define CODECSIZE CODEC_SIZE
-
-#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - CODECSIZE
-
-#define DRAMORIG 0x00000000
-#define IRAMORIG 0x40000000
-#define IRAMSIZE 0xc000
-
-#ifdef CPU_PP502x
-#define NOCACHE_BASE 	0x10000000
-#else
-#define NOCACHE_BASE 	0x28000000
-#endif
-
-#define CACHEALIGN_SIZE 16
-
-/* End of the audio buffer, where the codec buffer starts */
-#define ENDAUDIOADDR  (DRAMORIG + DRAMSIZE)
-
-/* Where the codec buffer ends, and the plugin buffer starts */
-#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
-
-MEMORY
-{
-    DRAM : ORIGIN = DRAMORIG,     LENGTH = DRAMSIZE
-    IRAM : ORIGIN = IRAMORIG,     LENGTH = IRAMSIZE
-}
-
-SECTIONS
-{
-    .text :
-    {
-        loadaddress = .;
-        _loadaddress = .;
-        . = ALIGN(0x200);
-        *(.init.text)
-        *(.text*)
-        *(.glue_7)
-        *(.glue_7t)
-        . = ALIGN(0x4);
-    } > DRAM
-
-    .rodata :
-    {
-        *(.rodata)  /* problems without this, dunno why */
-        *(.rodata*)
-        *(.rodata.str1.1)
-        *(.rodata.str1.4)
-        . = ALIGN(0x4);
-
-        /* Pseudo-allocate the copies of the data sections */
-        _datacopy = .;
-    } > DRAM
-
-    /* TRICK ALERT! For RAM execution, we put the .data section at the
-       same load address as the copy. Thus, we don't waste extra RAM
-       when we don't actually need the copy.  */
-    .data : AT ( _datacopy )
-    {
-        _datastart = .;
-        *(.data*)
-        . = ALIGN(0x4);
-        _dataend  = .;
-    } > DRAM
-
-#if NOCACHE_BASE != 0
-    /* .ncdata section is placed at uncached physical alias address and is
-     * loaded at the proper cached virtual address - no copying is
-     * performed in the init code */
-    .ncdata . + NOCACHE_BASE :
-    {
-        . = ALIGN(CACHEALIGN_SIZE);
-        *(.ncdata*)
-        . = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-#endif
-    
-    /DISCARD/ :
-    {
-        *(.eh_frame)
-    }
-
-    .vectors 0x0 :
-    {
-        _vectorsstart = .;
-        *(.vectors);
-        _vectorsend = .;
-    } AT> DRAM
-
-    _vectorscopy = LOADADDR(.vectors);
-    _noloaddram  = LOADADDR(.vectors);
-
-    .ibss IRAMORIG (NOLOAD) :
-    {
-        _iedata = .;
-        *(.qharray)
-        *(.ibss)
-        . = ALIGN(0x4);
-        _iend = .;
-    } > IRAM
-
-    .iram _iend :
-    {
-        _iramstart = .;
-        *(.icode)
-        *(.irodata)
-        *(.idata)
-        . = ALIGN(0x4);
-        _iramend = .;
-    } > IRAM AT> DRAM
-
-    _iramcopy = LOADADDR(.iram);
-
-
-    .init ENDAUDIOADDR : 
-    {
-        . = ALIGN(4);
-        _initstart = .;
-        *(.init)
-        _initend = .;
-    } AT> DRAM
-
-    _initcopy = LOADADDR(.init);
-
-    .idle_stacks (NOLOAD) :
-    {
-       *(.idle_stacks)
-#if NUM_CORES > 1
-       cpu_idlestackbegin = .;
-       . += IDLE_STACK_SIZE;
-       cpu_idlestackend = .;
-#endif
-       cop_idlestackbegin = .;
-       . += IDLE_STACK_SIZE;
-       cop_idlestackend = .;
-    } > IRAM
-
-    .stack (NOLOAD) :
-    {
-       *(.stack)
-       stackbegin = .;
-       . += 0x2000;
-       stackend = .;
-    } > IRAM
-    
-    /* .bss and .ncbss are treated as a single section to use one init loop to
-     * zero it - note "_edata" and "_end" */
-    .bss _noloaddram (NOLOAD) :
-    {
-       _edata = .;
-        *(.bss*)
-        *(COMMON)
-        . = ALIGN(0x4);
-    } > DRAM
-
-#if NOCACHE_BASE != 0
-    .ncbss . + NOCACHE_BASE (NOLOAD):
-    {
-    	. = ALIGN(CACHEALIGN_SIZE);
-        *(.ncbss*)
-    	. = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-#endif
-
-    /* This will be aligned by preceding alignments */
-    .endaddr . - NOCACHE_BASE (NOLOAD) :
-    {
-        _end = .;
-    } > DRAM
-
-    .audiobuf (NOLOAD) :
-    {
-        _audiobuffer = .;
-        . = ALIGN(0x4);
-        audiobuffer = .;
-    } > DRAM
-    
-    .audiobufend ENDAUDIOADDR (NOLOAD) :
-    {
-#ifdef IPOD_VIDEO
-        audiobufend_lds = .;
-#else
-        audiobufend = .;
-#endif
-        _audiobufend = .;
-    } > DRAM
-
-    .codec ENDAUDIOADDR (NOLOAD) :
-    {
-        codecbuf = .;
-        _codecbuf = .;
-    }
-
-    .plugin ENDADDR (NOLOAD) :
-    {
-        _pluginbuf = .;
-        pluginbuf = .;
-    }
-}
diff --git a/firmware/target/arm/ipod/backlight-4g_color.c b/firmware/target/arm/ipod/backlight-4g_color.c
deleted file mode 100644
index befb036..0000000
--- a/firmware/target/arm/ipod/backlight-4g_color.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- *
- * 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 <stdlib.h>
-#include "cpu.h"
-#include "kernel.h"
-#include "thread.h"
-#include "i2c.h"
-#include "debug.h"
-#include "rtc.h"
-#include "usb.h"
-#include "power.h"
-#include "system.h"
-#include "button.h"
-#include "timer.h"
-#include "backlight.h"
-#include "backlight-target.h"
-
-/* Index 0 is a dummy, 1..31 are used */
-static unsigned char log_brightness[32] = {
-      0,   1,   2,   4,   6,   9,  12,  16,  20,  25,  30,  36,
-     42,  49,  56,  64,  72,  81,  90, 100, 110, 121, 132, 144,
-    156, 169, 182, 196, 210, 225, 240, 255
-};
-
-static unsigned brightness = 100;   /* 1 to 255 */
-static bool enabled = false;
-
-/* Handling B03 in _backlight_on() and _backlight_off() makes backlight go off
- * without delay. Not doing that does a short (fixed) fade out. Opt for the
- * latter. */
-
-void _backlight_on(void)
-{
-    /* brightness full */
-    outl(0x80000000 | (brightness << 16), 0x7000a010);
-    GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
-    enabled = true;
-}
-
-void _backlight_off(void)
-{
-    outl(0x80000000, 0x7000a010);
-    GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
-    enabled = false;
-}
-
-void _backlight_set_brightness(int val)
-{
-    brightness = log_brightness[val];
-    if (enabled)
-        outl(0x80000000 | (brightness << 16), 0x7000a010);
-}
-
-bool _backlight_init(void)
-{
-    GPIO_SET_BITWISE(GPIOB_ENABLE, 0x0c); /* B02 and B03 enable */
-    GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x08); /* B03 = 1 */
-    GPO32_ENABLE &= ~0x2000000; /* D01 disable, so pwm takes over */
-    DEV_EN |= DEV_PWM;   /* PWM enable */
-
-    _backlight_on();
-    return true;
-}
diff --git a/firmware/target/arm/ipod/backlight-mini1g_mini2g.c b/firmware/target/arm/ipod/backlight-mini1g_mini2g.c
deleted file mode 100644
index 1d57b77..0000000
--- a/firmware/target/arm/ipod/backlight-mini1g_mini2g.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- *
- * 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 <stdlib.h>
-#include "cpu.h"
-#include "kernel.h"
-#include "thread.h"
-#include "i2c.h"
-#include "debug.h"
-#include "rtc.h"
-#include "usb.h"
-#include "power.h"
-#include "system.h"
-#include "button.h"
-#include "timer.h"
-#include "backlight.h"
-#include "backlight-target.h"
-
-void _backlight_hw_on(void)
-{
-    GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
-}
-
-void _backlight_hw_off(void)
-{
-    GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
-}
diff --git a/firmware/target/arm/ipod/backlight-nano_video.c b/firmware/target/arm/ipod/backlight-nano_video.c
deleted file mode 100644
index 2f56f94..0000000
--- a/firmware/target/arm/ipod/backlight-nano_video.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- *
- * 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 <stdlib.h>
-#include "cpu.h"
-#include "kernel.h"
-#include "thread.h"
-#include "i2c.h"
-#include "debug.h"
-#include "rtc.h"
-#include "usb.h"
-#include "power.h"
-#include "system.h"
-#include "button.h"
-#include "timer.h"
-#include "backlight.h"
-#include "backlight-target.h"
-
-static int brightness = 1;   /* 1 to 32 */
-static int current_dim = 16; /* default after enabling the backlight dimmer */
-static bool enabled = false;
-
-void _backlight_set_brightness(int val)
-{
-    int oldlevel;
-
-    if (current_dim < val)
-    {
-        do
-        {
-            oldlevel = disable_irq_save();
-            GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
-            udelay(10);
-            GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
-            restore_irq(oldlevel);
-            udelay(10);
-        }
-        while (++current_dim < val);
-    }
-    else if (current_dim > val)
-    {
-        do
-        {
-            oldlevel = disable_irq_save();
-            GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
-            udelay(200);
-            GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
-            restore_irq(oldlevel);
-            udelay(10);
-        }
-        while (--current_dim > val);
-    }
-    brightness = val;
-}
-
-void _backlight_hw_enable(bool on)
-{
-#ifdef HAVE_LCD_SLEEP
-    if (on)
-        /* If the fade-out is interrupted, enabled will be true, but 
-           lcd_awake() needs to be called anyways because the LCD 
-           may be sleeping.
-         */
-        lcd_awake();
-#endif
-
-    if (on == enabled)
-        return;
-
-    if (on)
-    {
-        GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
-        GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
-        sleep(HZ/100);
-        current_dim = 16;
-        _backlight_set_brightness(brightness);
-    }
-    else
-    {
-        GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
-        GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
-        sleep(HZ/20);
-    }
-    enabled = on;
-}
-
-/* Switch the backlight on. Works only if the backlight circuit is enabled.
- * Called in ISR context for fading, so it must be fast. */
-void _backlight_led_on(void)
-{
-    GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 0x80);
-}
-
-/* Switch the backlight off. Keeps the backlight circuit enabled.
- * Called in ISR context for fading, so it must be fast. */
-void _backlight_led_off(void)
-{
-    GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_VAL, 0x80);
-}
-
-bool _backlight_init(void)
-{
-    GPIO_SET_BITWISE(GPIOB_ENABLE, 0x08);
-    GPIO_SET_BITWISE(GPIOB_OUTPUT_EN, 0x08);
-    GPIO_SET_BITWISE(GPIOD_ENABLE, 0x80);
-    GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x80);
-    _backlight_hw_enable(true);
-    GPIO_SET_BITWISE(GPIOL_ENABLE, 0x80);
-    GPIO_SET_BITWISE(GPIOL_OUTPUT_EN, 0x80);
-    GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 0x80);
-
-    return true;
-}
diff --git a/firmware/target/arm/ipod/backlight-target.h b/firmware/target/arm/ipod/backlight-target.h
deleted file mode 100644
index 9b6a96b..0000000
--- a/firmware/target/arm/ipod/backlight-target.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 BACKLIGHT_TARGET_H
-#define BACKLIGHT_TARGET_H
-
-#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
-
-bool _backlight_init(void);
-void _backlight_set_brightness(int val);
-void _backlight_led_on(void);
-void _backlight_led_off(void);
-void _backlight_hw_enable(bool on);
-
-#ifdef HAVE_LCD_SLEEP
-void lcd_awake(void);
-#endif
-
-#ifdef BOOTLOADER
-#define _backlight_on()  do { _backlight_hw_enable(true); \
-                              _backlight_led_on(); } while(0)
-#define _backlight_off() do { _backlight_led_off(); \
-                              _backlight_hw_enable(false); } while(0)
-#else /* !BOOTLOADER */
-#define _backlight_on_isr() _backlight_led_on()
-#define _backlight_off_isr() _backlight_led_off()
-#define _backlight_on_normal()  do { _backlight_hw_enable(true); \
-                                     _backlight_led_on(); } while(0)
-#define _backlight_off_normal() do { _backlight_led_off(); \
-                                     _backlight_hw_enable(false); } while(0)
-#define _BACKLIGHT_FADE_ENABLE
-#endif /* !BOOTLOADER */
-
-#elif defined(IPOD_4G) || defined(IPOD_COLOR)
-
-bool _backlight_init(void);
-void _backlight_on(void);
-void _backlight_off(void);
-void _backlight_set_brightness(int val);
-
-#elif defined(IPOD_MINI) || defined(IPOD_MINI2G)
-
-#define _backlight_init() true
-void _backlight_hw_on(void);
-void _backlight_hw_off(void);
-
-#ifdef BOOTLOADER
-#define _backlight_on() _backlight_hw_on()
-#define _backlight_off() _backlight_hw_off()
-#else
-#define _backlight_on_isr() _backlight_hw_on()
-#define _backlight_off_isr() _backlight_hw_off()
-#define _backlight_on_normal() _backlight_hw_on()
-#define _backlight_off_normal() _backlight_hw_off()
-#endif
-
-#elif defined(IPOD_1G2G) || defined(IPOD_3G)
-
-#define _backlight_init() true
-void _backlight_on(void);
-void _backlight_off(void);
-#endif
-
-#endif
diff --git a/firmware/target/arm/ipod/boot.lds b/firmware/target/arm/ipod/boot.lds
deleted file mode 100644
index 04843d0..0000000
--- a/firmware/target/arm/ipod/boot.lds
+++ /dev/null
@@ -1,80 +0,0 @@
-#include "config.h"
-
-ENTRY(start)
-OUTPUT_FORMAT(elf32-littlearm)
-OUTPUT_ARCH(arm)
-STARTUP(target/arm/crt0-pp-bl.o)
-
-#define DRAMSIZE (MEMORYSIZE * 0x100000)
-
-#if CONFIG_CPU == PP5020
-#define DRAMORIG 0x10000000
-#define IRAMORIG 0x40000000
-#define IRAMSIZE 0x18000
-#define FLASHORIG 0x001f0000
-#define FLASHSIZE 2M
-#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
-#define DRAMORIG 0x10000000
-#ifndef IRAMORIG
-#define IRAMORIG 0x40000000
-#endif
-#define IRAMSIZE 0x20000
-#define FLASHORIG 0x001f0000
-#define FLASHSIZE 2M
-#elif CONFIG_CPU == PP5002
-#define DRAMORIG 0x28000000
-#define IRAMORIG 0x40000000
-#define IRAMSIZE 0x18000
-#define FLASHORIG 0x001f0000
-#define FLASHSIZE 2M
-#endif
-
-MEMORY
-{
-    DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
-    IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
-}
-
-SECTIONS
-{
-  . = IRAMORIG;
-
-  .text : {
-    *(.init.text)
-    *(.text*)
-    *(.glue_7)
-    *(.glue_7t)
-  } > IRAM
-
-  .data : {
-    *(.icode)
-    *(.irodata)
-    *(.idata)
-    *(.data*)
-    *(.ncdata*)
-    *(.rodata*)
-    _dataend = . ;
-  } > IRAM
-
-  .stack (NOLOAD) : {
-     *(.stack)
-     _stackbegin = .;
-     stackbegin = .;
-     . += 0x2000;
-     _stackend = .;
-     stackend = .;
-  } > IRAM
-
-  /* The bss section is too large for IRAM - we just move it 16MB into the
-     DRAM */
-
-  . = DRAMORIG;
-  .bss . + (16*1024*1024) (NOLOAD) : {
-     _edata = .;
-     *(.bss*);
-     *(.ibss);
-     *(COMMON)
-     *(.ncbss*);
-     _end = .;
-  } > DRAM
-}
diff --git a/firmware/target/arm/ipod/button-1g-3g.c b/firmware/target/arm/ipod/button-1g-3g.c
deleted file mode 100644
index 045a0f6..0000000
--- a/firmware/target/arm/ipod/button-1g-3g.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Daniel Stenberg
- *
- * iPod driver based on code from the ipodlinux project - http://ipodlinux.org
- * Adapted for Rockbox in December 2005
- * Original file: linux/arch/armnommu/mach-ipod/keyboard.c
- * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
- *
- *
- * 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.
- *
- ****************************************************************************/
-
-/*
- * Rockbox button functions
- */
-
-#include <stdlib.h>
-#include "config.h"
-#include "cpu.h"
-#include "system.h"
-#include "button.h"
-#include "kernel.h"
-#include "backlight.h"
-#include "serial.h"
-#include "power.h"
-#include "powermgmt.h"
-#include "hwcompat.h"
-
-static int int_btn = BUTTON_NONE;
-#ifdef IPOD_1G2G
-/* The 1st Gen wheel draws ~12mA when enabled permanently. Therefore
- * we only enable it for a very short time to check for changes every
- * tick, and only keep it enabled if there is activity. */
-#define WHEEL_TIMEOUT (HZ/4)
-#endif
-
-#define WHEELCLICKS_PER_ROTATION  96
-#define WHEEL_BASE_SENSITIVITY     6 /* Compute every ... clicks */
-#define WHEEL_REPEAT_VELOCITY     45 /* deg/s */
-#define WHEEL_SMOOTHING_VELOCITY 100 /* deg/s */
-
-static void handle_scroll_wheel(int new_scroll)
-{
-    static const signed char scroll_state[4][4] = {
-        {0, 1, -1, 0},
-        {-1, 0, 0, 1},
-        {1, 0, 0, -1},
-        {0, -1, 1, 0}
-    };
-
-    static int prev_scroll = -1;
-    static int direction = 0;
-    static int count = 0;
-    static long next_backlight_on = 0;
-
-    static unsigned long last_wheel_usec = 0;
-    static unsigned long wheel_delta = 1ul << 24;
-    static unsigned long wheel_velocity = 0;
-    static int prev_keypost = BUTTON_NONE;
-
-    int wheel_keycode = BUTTON_NONE;
-    int scroll;
-    unsigned long usec;
-    unsigned long v;
-
-    if (prev_scroll == -1) {
-        prev_scroll = new_scroll;
-        return;
-    }
-
-    scroll = scroll_state[prev_scroll][new_scroll];
-    prev_scroll = new_scroll;
-
-    if (direction != scroll) {
-        /* direction reversal or was hold - reset all */
-        direction = scroll;
-        prev_keypost = BUTTON_NONE;
-        wheel_velocity = 0;
-        wheel_delta = 1ul << 24;
-        count = 0;
-    }
-
-    /* poke backlight every 1/4s of activity */
-    if (TIME_AFTER(current_tick, next_backlight_on)) {
-        backlight_on();
-        reset_poweroff_timer();
-        next_backlight_on = current_tick + HZ/4;
-    }
-
-    /* has wheel travelled far enough? */
-    if (++count < WHEEL_BASE_SENSITIVITY) {
-        return;
-    }
-
-    /* reset travel count and do calculations */
-    count = 0;
-
-    /* 1st..3rd Gen wheel has inverse direction mapping
-     * compared to Mini 1st Gen wheel. */
-    switch (direction) {
-        case 1:
-            wheel_keycode = BUTTON_SCROLL_BACK;
-            break;
-        case -1:
-            wheel_keycode = BUTTON_SCROLL_FWD;
-            break;
-        default:
-            /* only happens if we get out of sync */
-            return;
-    }
-
-    /* have a keycode */
-
-    usec = USEC_TIMER;
-    v = usec - last_wheel_usec;
-
-    /* calculate deg/s based upon sensitivity-adjusted interrupt period */
-
-    if ((long)v <= 0) {
-        /* timer wrapped (no activity for awhile), skip acceleration */
-        v = 0;
-        wheel_delta = 1ul << 24;
-    }
-    else {
-        if (v > 0xfffffffful/WHEELCLICKS_PER_ROTATION) {
-            v = 0xfffffffful/WHEELCLICKS_PER_ROTATION; /* check overflow below */
-        }
-
-        v = 360000000ul*WHEEL_BASE_SENSITIVITY / (v*WHEELCLICKS_PER_ROTATION);
-
-        if (v > 0xfffffful)
-            v = 0xfffffful; /* limit to 24 bits */
-    }
-
-    if (v < WHEEL_SMOOTHING_VELOCITY) {
-        /* very slow - no smoothing */
-        wheel_velocity = v;
-        /* ensure backlight never gets stuck for an extended period if tick
-         * wrapped such that next poke is very far ahead */
-        next_backlight_on = current_tick - 1;
-    }
-    else {
-        /* some velocity filtering to smooth things out */
-        wheel_velocity = (7*wheel_velocity + v) / 8;
-    }
-
-    if (queue_empty(&button_queue)) {
-        int key = wheel_keycode;
-
-        if (v >= WHEEL_REPEAT_VELOCITY && prev_keypost == key) {
-            /* quick enough and same key is being posted more than once in a
-             * row - generate repeats - use unsmoothed v to guage */
-            key |= BUTTON_REPEAT;
-        }
-
-        prev_keypost = wheel_keycode;
-
-        /* post wheel keycode with wheel data */
-        queue_post(&button_queue, key,
-                   (wheel_velocity >= WHEEL_ACCEL_START ? (1ul << 31) : 0)
-                    | wheel_delta | wheel_velocity);
-        /* message posted - reset delta */
-        wheel_delta = 1ul << 24;
-    }
-    else {
-        /* skipped post - increment delta and limit to 7 bits */
-        wheel_delta += 1ul << 24;
-
-        if (wheel_delta > (0x7ful << 24))
-            wheel_delta = 0x7ful << 24;
-    }
-
-    last_wheel_usec = usec;
-}
-
-static int ipod_3g_button_read(void)
-{
-    unsigned char source, state;
-    int btn = BUTTON_NONE;
-    
-    /* get source of interupts */
-    source = GPIOA_INT_STAT;
-
-    /* get current keypad status */
-    state = GPIOA_INPUT_VAL;
-    
-    /* toggle interrupt level */
-    GPIOA_INT_LEV = ~state;
-
-    /* ack any active interrupts */
-    GPIOA_INT_CLR = source;
-
-#ifdef IPOD_3G
-    static bool was_hold = false;
-
-    if (was_hold && source == 0x40 && state == 0xbf) {
-        return BUTTON_NONE;
-    }
-    was_hold = false;
-
-    if ((state & 0x20) == 0) {
-        /* 3g hold switch is active low */
-        was_hold = true;
-        /* hold switch on 3g causes all outputs to go low */
-        /* we shouldn't interpret these as key presses */
-        return BUTTON_NONE;
-    }
-#elif defined IPOD_1G2G
-    if (state & 0x20) {
-        /* 1g/2g hold switch is active high */
-        return BUTTON_NONE;
-    }
-#endif
-    if ((state & 0x1) == 0) {
-        btn |= BUTTON_RIGHT;
-    }
-    if ((state & 0x2) == 0) {
-        btn |= BUTTON_SELECT;
-    }
-    if ((state & 0x4) == 0) {
-        btn |= BUTTON_PLAY;
-    }
-    if ((state & 0x8) == 0) {
-        btn |= BUTTON_LEFT;
-    }
-    if ((state & 0x10) == 0) {
-        btn |= BUTTON_MENU;
-    }
-
-    if (source & 0xc0) {
-        handle_scroll_wheel((state & 0xc0) >> 6);
-    }
-
-    return btn;
-}
-
-void ipod_3g_button_int(void)
-{
-    CPU_INT_DIS = GPIO_MASK;
-    int_btn = ipod_3g_button_read();
-    CPU_INT_EN = GPIO_MASK;
-}
-
-void button_init_device(void)
-{
-    GPIOA_ENABLE = 0xff;
-    GPIOA_OUTPUT_EN = 0;
-
-    GPIOA_INT_LEV = ~GPIOA_INPUT_VAL;
-    GPIOA_INT_CLR = GPIOA_INT_STAT;
-
-#ifdef IPOD_1G2G
-    if ((IPOD_HW_REVISION >> 16) == 1)
-    {   /* enable scroll wheel */
-        GPIOB_ENABLE |= 0x01;
-        GPIOB_OUTPUT_EN |= 0x01;
-        GPIOB_OUTPUT_VAL |= 0x01;
-    }
-#endif
-    GPIOA_INT_EN  = 0xff;
-
-    CPU_INT_EN = GPIO_MASK;
-}
-
-/*
- * Get button pressed from hardware
- */
-int button_read_device(void)
-{
-    static bool hold_button = false;
-    bool hold_button_old;
-#ifdef IPOD_1G2G
-    static int wheel_timeout = 0;
-    static unsigned char last_wheel_value = 0;
-    unsigned char wheel_value;
-
-    if ((IPOD_HW_REVISION >> 16) == 1)
-    {
-        if (!hold_button && (wheel_timeout == 0))
-        {
-            GPIOB_OUTPUT_VAL |= 0x01; /* enable wheel */
-            udelay(50);               /* let the voltage settle */
-        }
-        wheel_value = GPIOA_INPUT_VAL >> 6;
-        if (wheel_value != last_wheel_value)
-        {
-            last_wheel_value = wheel_value;
-            wheel_timeout = WHEEL_TIMEOUT; /* keep wheel enabled */
-            GPIOA_INT_EN = 0xff;      /* enable wheel interrupts */
-        }
-        if (wheel_timeout)
-            wheel_timeout--;
-        else
-        {
-            GPIOA_INT_EN = 0x3f;       /* disable wheel interrupts */
-            GPIOB_OUTPUT_VAL &= ~0x01; /* disable wheel */
-        }
-    }
-#endif
-
-    /* normal buttons */
-    hold_button_old = hold_button;
-    hold_button = button_hold();
-
-    if (hold_button != hold_button_old)
-        backlight_hold_changed(hold_button);
-
-    return int_btn;
-}
-
-bool button_hold(void)
-{
-#ifdef IPOD_1G2G
-    return (GPIOA_INPUT_VAL & 0x20);
-#else
-    return !(GPIOA_INPUT_VAL & 0x20);
-#endif
-}
-
-bool headphones_inserted(void)
-{
-#ifdef IPOD_1G2G
-    if ((IPOD_HW_REVISION >> 16) == 2)
-    {
-        /* 2G uses GPIO B bit 0 */
-        return (GPIOB_INPUT_VAL & 0x1)?true:false;
-    }
-    else
-    {
-        /* 1G has no headphone detection, so fake insertion */
-        return (true);
-    }
-#else
-    /* 3G uses GPIO C bit 0 */
-    return (GPIOC_INPUT_VAL & 0x1)?true:false;
-#endif
-}
-
-
diff --git a/firmware/target/arm/ipod/button-clickwheel.c b/firmware/target/arm/ipod/button-clickwheel.c
deleted file mode 100644
index 2c15e0e..0000000
--- a/firmware/target/arm/ipod/button-clickwheel.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Daniel Stenberg
- *
- * iPod driver based on code from the ipodlinux project - http://ipodlinux.org
- * Adapted for Rockbox in December 2005
- * Original file: linux/arch/armnommu/mach-ipod/keyboard.c
- * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
- *
- *
- * 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.
- *
- ****************************************************************************/
-
-/*
- * Rockbox button functions
- */
-
-#include <stdlib.h>
-#include "config.h"
-#include "cpu.h"
-#include "system.h"
-#include "button.h"
-#include "kernel.h"
-#include "backlight.h"
-#include "serial.h"
-#include "power.h"
-#include "powermgmt.h"
-#if defined(IPOD_NANO2G) || defined(IPOD_6G)
-#include "pmu-target.h"
-#endif
-
-#define WHEEL_FAST_OFF_TIMEOUT   250000 /* timeout for acceleration = 250ms */
-#define WHEEL_REPEAT_TIMEOUT     250000 /* timeout for button repeat = 250ms */
-#define WHEEL_UNTOUCH_TIMEOUT    150000 /* timeout for untouching wheel = 150ms */
-
-#ifdef CPU_PP
-#define CLICKWHEEL_DATA   (*(volatile unsigned long*)(0x7000c140))
-#elif CONFIG_CPU==S5L8701 || CONFIG_CPU==S5L8702
-#define CLICKWHEEL_DATA   WHEELRX
-#else
-#error CPU architecture not supported!
-#endif
-
-#define WHEELCLICKS_PER_ROTATION     96 /* wheelclicks per full rotation */
-
-/* This amount of clicks is needed for at least scrolling 1 item. Choose small values 
- * to have high sensitivity but few precision, choose large values to have less 
- * sensitivity and good precision. */
-#if defined(IPOD_NANO) || defined(IPOD_NANO2G)
-#define WHEEL_SENSITIVITY 6 /* iPod nano has smaller wheel, lower sensitivity needed */
-#else
-#define WHEEL_SENSITIVITY 4 /* default sensitivity */
-#endif
-
-int  old_wheel_value  = -1;
-int  new_wheel_value  = 0;
-int  repeat           = 0;
-int  wheel_delta      = 0;
-bool wheel_is_touched = false;
-unsigned int  accumulated_wheel_delta = 0;
-unsigned int  wheel_repeat            = 0;
-unsigned int  wheel_velocity          = 0;
-unsigned long last_wheel_usec         = 0;
-
-/* Variable to use for setting button status in interrupt handler */
-int int_btn = BUTTON_NONE;
-#ifdef HAVE_WHEEL_POSITION
-    static int wheel_position = -1;
-    static bool send_events = true;
-#endif
-
-#if CONFIG_CPU==S5L8701 || CONFIG_CPU==S5L8702
-static struct semaphore button_init_wakeup;
-#endif
-
-#if CONFIG_CPU==S5L8702
-static long holdswitch_last_read;
-static bool holdswitch_last_value;
-#endif
-
-#ifdef CPU_PP
-static void opto_i2c_init(void)
-{
-    DEV_EN |= DEV_OPTO;
-    DEV_RS |= DEV_OPTO;
-    udelay(5);
-    DEV_RS &= ~DEV_OPTO; /* finish reset */
-    DEV_INIT1 |= INIT_BUTTONS; /* enable buttons (needed for "hold"-detection) */
-
-    outl(0xc00a1f00, 0x7000c100);
-    outl(0x01000000, 0x7000c104);
-}
-#endif
-
-static inline int ipod_4g_button_read(void)
-{
-    int whl = -1;
-    int btn = BUTTON_NONE;
-
-#ifdef CPU_PP    
-    if ((inl(0x7000c104) & 0x04000000) != 0) 
-    {
-#endif
-        unsigned status = CLICKWHEEL_DATA;
-
-        if ((status & 0x800000ff) == 0x8000001a) 
-        {
-            if (status & 0x00000100)
-                btn |= BUTTON_SELECT;
-            if (status & 0x00000200)
-                btn |= BUTTON_RIGHT;
-            if (status & 0x00000400)
-                btn |= BUTTON_LEFT;
-            if (status & 0x00000800)
-                btn |= BUTTON_PLAY;
-            if (status & 0x00001000)
-                btn |= BUTTON_MENU;
-            if (status & 0x40000000) 
-            {
-                unsigned long usec = USEC_TIMER;
-                
-                /* Highest wheel = 0x5F, clockwise increases */
-                new_wheel_value = (status >> 16) & 0x7f;
-                whl = new_wheel_value;
-                
-                /* switch on backlight (again), reset power-off timer */
-                backlight_on();
-                reset_poweroff_timer();
-                
-                /* Check whether the scrollwheel was untouched by accident or by will. */
-                /* This is needed because wheel may be untoched very shortly during rotation */
-                if ( (!wheel_is_touched) && TIME_AFTER(usec, last_wheel_usec + WHEEL_UNTOUCH_TIMEOUT) )
-                {
-                    /* wheel has been really untouched -> reset internal variables */
-                    old_wheel_value         = -1;
-                    wheel_velocity          = 0;
-                    accumulated_wheel_delta = 0;
-                    wheel_repeat            = BUTTON_NONE;
-                }
-                else
-                {
-                    /* wheel was shortly untouched by accident -> leave internal variables */
-                    wheel_is_touched = true;
-                }
-
-                if (old_wheel_value >= 0)
-                {
-                    /* This is for later = BUTTON_SCROLL_TOUCH;*/
-                    wheel_delta = new_wheel_value - old_wheel_value;
-                    unsigned int wheel_keycode = BUTTON_NONE;
-
-                    /* Taking into account wrapping during transition from highest 
-                     * to lowest wheel position and back */
-                    if      (wheel_delta < -WHEELCLICKS_PER_ROTATION/2)
-                        wheel_delta += WHEELCLICKS_PER_ROTATION; /* Forward wrapping case */
-                    else if (wheel_delta >  WHEELCLICKS_PER_ROTATION/2)
-                        wheel_delta -= WHEELCLICKS_PER_ROTATION; /* Backward wrapping case */
-    
-                    /* Getting direction and wheel_keycode from wheel_delta.
-                     * Need at least some clicks to be sure to avoid haptic fuzziness */
-                    if      (wheel_delta >=  WHEEL_SENSITIVITY)
-                        wheel_keycode = BUTTON_SCROLL_FWD;
-                    else if (wheel_delta <= -WHEEL_SENSITIVITY)
-                        wheel_keycode = BUTTON_SCROLL_BACK;
-                    else 
-                        wheel_keycode = BUTTON_NONE;
-
-                    if (wheel_keycode != BUTTON_NONE)
-                    {
-                        long v = (usec - last_wheel_usec) & 0x7fffffff;
-                        
-                        /* undo signedness */
-                        wheel_delta = (wheel_delta>0) ? wheel_delta : -wheel_delta;
-                        
-                        /* add the current wheel_delta */
-                        accumulated_wheel_delta += wheel_delta;
-
-                        v = v ? (1000000 * wheel_delta) / v : 0;  /* clicks/sec = 1000000 * clicks/usec */
-                        v = (v * 360) / WHEELCLICKS_PER_ROTATION; /* conversion to degree/sec */
-                        v = (v<0) ? -v : v;                       /* undo signedness */
-            
-                        /* some velocity filtering to smooth things out */
-                        wheel_velocity = (15 * wheel_velocity + v) / 16;
-                        /* limit to 24 bit */
-                        wheel_velocity = (wheel_velocity>0xffffff) ? 0xffffff : wheel_velocity;
-
-                        /* assume REPEAT = off */
-                        repeat = 0;
-                        
-                        /* direction reversals must nullify acceleration and accumulator */
-                        if (wheel_keycode != wheel_repeat)
-                        {
-                            wheel_repeat            = wheel_keycode;
-                            wheel_velocity          = 0;
-                            accumulated_wheel_delta = 0;
-                        }
-                        /* on same direction REPEAT is assumed when new click is within timeout */
-                        else if (TIME_BEFORE(usec, last_wheel_usec + WHEEL_REPEAT_TIMEOUT))
-                        {
-                            repeat = BUTTON_REPEAT;
-                        }
-                        /* timeout nullifies acceleration and accumulator */
-                        if (TIME_AFTER(usec, last_wheel_usec + WHEEL_FAST_OFF_TIMEOUT))
-                        {
-                            wheel_velocity          = 0;
-                            accumulated_wheel_delta = 0;
-                        }
-
-#ifdef HAVE_WHEEL_POSITION
-                        if (send_events) 
-#endif
-                        /* The queue should have no other events when scrolling */
-                        if (queue_empty(&button_queue))
-                        {
-                            /* each WHEEL_SENSITIVITY clicks = scrolling 1 item */
-                            accumulated_wheel_delta /= WHEEL_SENSITIVITY;
-#ifdef HAVE_SCROLLWHEEL
-                            /* use data-format for HAVE_SCROLLWHEEL */
-                            /* always use acceleration mode (1<<31) */
-                            /* always set message post count to (1<<24) for iPod */
-                            /* this way the scrolling is always calculated from wheel_velocity */
-                            queue_post(&button_queue, wheel_keycode | repeat, 
-                                       (1<<31) | (1 << 24) | wheel_velocity);
-                                       
-#else
-                            queue_post(&button_queue, wheel_keycode | repeat, 
-                                       (accumulated_wheel_delta << 16) | new_wheel_value);
-#endif
-                            accumulated_wheel_delta = 0;
-                        }
-                        last_wheel_usec = usec;
-                        old_wheel_value = new_wheel_value;
-                    }
-                }
-                else
-                {
-                    /* scrollwheel was touched for the first time after finger lifting */
-                    old_wheel_value = new_wheel_value;
-                    wheel_is_touched = true;
-                }
-            }
-            else
-            {
-                /* In this case the finger was lifted from the scrollwheel. */
-                wheel_is_touched = false; 
-            }
-
-        }
-#if CONFIG_CPU==S5L8701 || CONFIG_CPU==S5L8702
-        else if ((status & 0x8000FFFF) == 0x8000023A)
-        {
-            if (status & 0x00010000)
-                btn |= BUTTON_SELECT;
-            if (status & 0x00020000)
-                btn |= BUTTON_RIGHT;
-            if (status & 0x00040000)
-                btn |= BUTTON_LEFT;
-            if (status & 0x00080000)
-                btn |= BUTTON_PLAY;
-            if (status & 0x00100000)
-                btn |= BUTTON_MENU;
-            semaphore_release(&button_init_wakeup);
-        }
-#endif
-
-#ifdef CPU_PP    
-    }
-#endif
-
-#ifdef HAVE_WHEEL_POSITION
-    /* Save the new absolute wheel position */
-    wheel_position = whl;
-#endif
-    return btn;
-}
-
-#ifdef HAVE_WHEEL_POSITION
-int wheel_status(void)
-{
-    return wheel_position;
-}
- 
-void wheel_send_events(bool send)
-{
-    send_events = send;
-}
-#endif
-
-#ifdef CPU_PP
-void ipod_4g_button_int(void)
-{
-    CPU_HI_INT_DIS = I2C_MASK;
-
-    /* The following delay was 250 in the ipodlinux source, but 50 seems to 
-       work fine - tested on Nano, Color/Photo and Video. */
-    udelay(50);
-
-    int_btn = ipod_4g_button_read();
-    
-    outl(inl(0x7000c104) | 0x0c000000, 0x7000c104);
-    outl(0x400a1f00, 0x7000c100);
-
-    CPU_HI_INT_EN = I2C_MASK;
-}
-
-void button_init_device(void)
-{
-    opto_i2c_init();
-    
-    /* hold button - enable as input */
-    GPIOA_ENABLE |= 0x20;
-    GPIOA_OUTPUT_EN &= ~0x20; 
-    
-    /* unmask interrupt */
-    CPU_INT_EN = HI_MASK;
-    CPU_HI_INT_EN = I2C_MASK;
-}
-
-bool button_hold(void)
-{
-    return (GPIOA_INPUT_VAL & 0x20)?false:true;
-}
-
-bool headphones_inserted(void)
-{
-    return (GPIOA_INPUT_VAL & 0x80)?true:false;
-}
-#else
-void INT_WHEEL(void)
-{
-    int clickwheel_events = WHEELINT;
-
-    /* Clear interrupts */
-    if (clickwheel_events & 4) WHEELINT = 4;
-    if (clickwheel_events & 2) WHEELINT = 2;
-    if (clickwheel_events & 1) WHEELINT = 1;
-
-    int_btn = ipod_4g_button_read();
-}
-
-static void s5l_clickwheel_init(void)
-{
-#if CONFIG_CPU==S5L8701
-    PWRCONEXT &= ~1;
-    PCON15 = (PCON15 & ~0xFFFF0000) | 0x22220000;
-    PUNK15 = 0xF0;
-    WHEEL08 = 0x3A980;
-    WHEEL00 = 0x280000;
-    WHEEL10 = 3;
-    PCON10 = (PCON10 & ~0xFF0) | 0x10;
-    PDAT10 |= 2;
-    WHEELTX = 0x8000023A;
-    WHEEL04 |= 1;
-    PDAT10 &= ~2;
-#elif CONFIG_CPU==S5L8702
-    //TODO: Implement
-#endif
-}
-
-void button_init_device(void)
-{
-    semaphore_init(&button_init_wakeup, 1, 0);
-#if CONFIG_CPU==S5L8701
-    INTMSK |= (1<<26);
-#elif CONFIG_CPU==S5L8702
-    holdswitch_last_read = USEC_TIMER;
-    holdswitch_last_value = (pmu_read(0x87) & 2) == 0;
-#endif
-    s5l_clickwheel_init();
-    semaphore_wait(&button_init_wakeup, HZ / 10);
-}
-
-bool button_hold(void)
-{
-#if CONFIG_CPU==S5L8701
-    bool value = (PDAT14 & (1 << 6)) == 0;
-    if (value)
-        PCON15 = PCON15 & ~0xffff0000;
-    else PCON15 = (PCON15 & ~0xffff0000) | 0x22220000;
-    return value;
-#elif CONFIG_CPU==S5L8702
-    if (USEC_TIMER - holdswitch_last_read > 100000)
-    {
-        holdswitch_last_read = USEC_TIMER;
-        holdswitch_last_value = (pmu_read(0x87) & 2) == 0;
-    }
-    if (holdswitch_last_value)
-        PCON(14) = PCON(14) & ~0xffffff00;
-    else PCON(14) = (PCON(14) & ~0xffffff00) | 0x22222200;
-    return holdswitch_last_value;
-#endif
-}
-
-bool headphones_inserted(void)
-{
-#if CONFIG_CPU==S5L8701
-    return ((PDAT14 & (1 << 5)) != 0);
-#elif CONFIG_CPU==S5L8702
-    return ((PDATA & (1 << 6)) != 0);
-    return false;
-#endif
-}
-#endif
-
-/*
- * Get button pressed from hardware
- */
-int button_read_device(void)
-{
-    static bool hold_button = false;
-    bool hold_button_old;
-
-    /* normal buttons */
-    hold_button_old = hold_button;
-    hold_button = button_hold();
-
-    if (hold_button != hold_button_old)
-    {
-#ifndef BOOTLOADER
-        backlight_hold_changed(hold_button);
-#endif
-        
-        if (hold_button)
-        {
-#ifdef CPU_PP
-            /* lock -> disable wheel sensor */
-            DEV_EN &= ~DEV_OPTO;
-#elif CONFIG_CPU==S5L8701
-            pmu_ldo_power_off(1); /* disable clickwheel power supply */
-            WHEEL00 = 0;
-            WHEEL10 = 0;
-            PWRCONEXT |= 1;
-#elif CONFIG_CPU==S5L8702
-            //TODO: Implement
-#endif
-        }
-        else
-        {
-#ifdef CPU_PP
-            /* unlock -> enable wheel sensor */
-            DEV_EN |= DEV_OPTO;
-            opto_i2c_init();
-#elif CONFIG_CPU==S5L8701
-            pmu_ldo_power_on(1); /* enable clickwheel power supply */
-            s5l_clickwheel_init();
-#elif CONFIG_CPU==S5L8702
-            //TODO: Implement
-#endif
-        }
-    }
-
-    /* The int_btn variable is set in the button interrupt handler */
-#ifdef IPOD_ACCESSORY_PROTOCOL
-    return int_btn | remote_control_rx();
-#else
-    return int_btn;
-#endif
-}
diff --git a/firmware/target/arm/ipod/button-mini1g.c b/firmware/target/arm/ipod/button-mini1g.c
deleted file mode 100644
index d4a75c9..0000000
--- a/firmware/target/arm/ipod/button-mini1g.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Daniel Stenberg
- *
- * iPod driver based on code from the ipodlinux project - http://ipodlinux.org
- * Adapted for Rockbox in December 2005
- * Original file: linux/arch/armnommu/mach-ipod/keyboard.c
- * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
- *
- *
- * 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.
- *
- ****************************************************************************/
-
-/*
- * Rockbox button functions
- */
-
-#include <stdlib.h>
-#include "config.h"
-#include "cpu.h"
-#include "system.h"
-#include "button.h"
-#include "kernel.h"
-#include "backlight.h"
-#include "serial.h"
-#include "power.h"
-#include "powermgmt.h"
-
-#define WHEELCLICKS_PER_ROTATION  96
-#define WHEEL_BASE_SENSITIVITY     6 /* Compute every ... clicks */
-#define WHEEL_REPEAT_VELOCITY     45 /* deg/s */
-#define WHEEL_SMOOTHING_VELOCITY 100 /* deg/s */
-
-/* Variable to use for setting button status in interrupt handler */
-int int_btn = BUTTON_NONE;
-
-static void handle_scroll_wheel(int new_scroll)
-{
-    static const signed char scroll_state[4][4] = {
-        {0, 1, -1, 0},
-        {-1, 0, 0, 1},
-        {1, 0, 0, -1},
-        {0, -1, 1, 0}
-    };
-
-    static int prev_scroll = -1;
-    static int direction = 0;
-    static int count = 0;
-    static long next_backlight_on = 0;
-
-    int wheel_keycode = BUTTON_NONE;
-    int scroll;
-
-    static unsigned long wheel_delta = 1ul << 24;
-    static unsigned long wheel_velocity = 0;
-    static unsigned long last_wheel_usec = 0;
-    static int prev_keypost = BUTTON_NONE;
-
-    unsigned long usec;
-    unsigned long v;
-
-    if ( prev_scroll == -1 ) {
-        prev_scroll = new_scroll;
-        return;
-    }
-    
-    scroll = scroll_state[prev_scroll][new_scroll];
-    prev_scroll = new_scroll;
-
-    if (direction != scroll) {
-        /* direction reversal or was hold - reset all */
-        direction = scroll;
-        count = 0;
-        prev_keypost = BUTTON_NONE;
-        wheel_velocity = 0;
-        wheel_delta = 1ul << 24;
-        return;
-    }
-
-   /* poke backlight every 1/4s of activity */
-    if (TIME_AFTER(current_tick, next_backlight_on)) {
-        backlight_on();
-        reset_poweroff_timer();
-        next_backlight_on = current_tick + HZ/4;
-    }
-
-    if (++count < WHEEL_BASE_SENSITIVITY)
-        return;
-
-    count = 0;
-    /* Mini 1st Gen wheel has inverse direction mapping
-     * compared to 1st..3rd Gen wheel. */
-    switch (direction) {
-        case 1:
-            wheel_keycode = BUTTON_SCROLL_FWD;
-            break;
-        case -1:
-            wheel_keycode = BUTTON_SCROLL_BACK;
-            break;
-        default:
-            /* only happens if we get out of sync */
-            break;
-    }
-
-    /* have a keycode */
-
-    usec = USEC_TIMER;
-    v = usec - last_wheel_usec;
-
-    /* calculate deg/s based upon sensitivity-adjusted interrupt period */
-
-    if ((long)v <= 0) {
-        /* timer wrapped (no activity for awhile), skip acceleration */
-        v = 0;
-        wheel_delta = 1ul << 24;
-    }
-    else {
-        if (v > 0xfffffffful/WHEELCLICKS_PER_ROTATION) {
-            v = 0xfffffffful/WHEELCLICKS_PER_ROTATION; /* check overflow below */
-        }
-
-        v = 360000000ul*WHEEL_BASE_SENSITIVITY / (v*WHEELCLICKS_PER_ROTATION);
-
-        if (v > 0xfffffful)
-            v = 0xfffffful; /* limit to 24 bits */
-    }
-
-    if (v < WHEEL_SMOOTHING_VELOCITY) {
-        /* very slow - no smoothing */
-        wheel_velocity = v;
-        /* ensure backlight never gets stuck for an extended period if tick
-         * wrapped such that next poke is very far ahead */
-        next_backlight_on = current_tick - 1;
-    }
-    else {
-        /* some velocity filtering to smooth things out */
-        wheel_velocity = (7*wheel_velocity + v) / 8;
-    }
-
-    if (queue_empty(&button_queue)) {
-        int key = wheel_keycode;
-
-        if (v >= WHEEL_REPEAT_VELOCITY && prev_keypost == key) {
-            /* quick enough and same key is being posted more than once in a
-             * row - generate repeats - use unsmoothed v to guage */
-            key |= BUTTON_REPEAT;
-        }
-
-        prev_keypost = wheel_keycode;
-
-        /* post wheel keycode with wheel data */
-        queue_post(&button_queue, key,
-                   (wheel_velocity >= WHEEL_ACCEL_START ? (1ul << 31) : 0)
-                    | wheel_delta | wheel_velocity);
-        /* message posted - reset delta */
-        wheel_delta = 1ul << 24;
-    }
-    else {
-        /* skipped post - increment delta and limit to 7 bits */
-        wheel_delta += 1ul << 24;
-
-        if (wheel_delta > (0x7ful << 24))
-            wheel_delta = 0x7ful << 24;
-    }
-
-    last_wheel_usec = usec;
-}
-
-/* mini 1 only, mini 2G uses iPod 4G code */
-static int ipod_mini_button_read(void)
-{
-    unsigned char source, wheel_source, state, wheel_state;
-    int btn = BUTTON_NONE;
-
-    /* The ipodlinux source had a udelay(250) here, but testing has shown that
-       it is not needed - tested on mini 1g. */
-    /* udelay(250);*/
-
-    /* get source(s) of interupt */
-    source = GPIOA_INT_STAT & 0x3f;
-    wheel_source = GPIOB_INT_STAT & 0x30;
-
-    if (source == 0 && wheel_source == 0) {
-        return BUTTON_NONE; /* not for us */
-    }
-
-    /* get current keypad & wheel status */
-    state = GPIOA_INPUT_VAL & 0x3f;
-    wheel_state = GPIOB_INPUT_VAL & 0x30;
-
-    /* toggle interrupt level */
-    GPIOA_INT_LEV = ~state;
-    GPIOB_INT_LEV = ~wheel_state;
-
-   /* ack any active interrupts */
-    if (source)
-        GPIOA_INT_CLR = source;
-    if (wheel_source)
-        GPIOB_INT_CLR = wheel_source;
-
-   if (button_hold())
-        return BUTTON_NONE;
-
-    /* hold switch causes all outputs to go low    */
-    /* we shouldn't interpret these as key presses */
-        if (!(state & 0x1))
-            btn |= BUTTON_SELECT;
-        if (!(state & 0x2))
-            btn |= BUTTON_MENU;
-        if (!(state & 0x4))
-            btn |= BUTTON_PLAY;
-        if (!(state & 0x8))
-            btn |= BUTTON_RIGHT;
-        if (!(state & 0x10))
-            btn |= BUTTON_LEFT;
-
-        if (wheel_source & 0x30) {
-            handle_scroll_wheel((wheel_state & 0x30) >> 4);
-        }
-
-    return btn;
-}
-
-void ipod_mini_button_int(void)
-{
-    CPU_HI_INT_DIS = GPIO0_MASK;
-    int_btn = ipod_mini_button_read();
-    //CPU_INT_EN = 0x40000000;
-    CPU_HI_INT_EN = GPIO0_MASK;
-}
-
-void button_init_device(void)
-{
-    /* iPod Mini G1 */
-    /* buttons - enable as input */
-    GPIOA_ENABLE |= 0x3f;
-    GPIOA_OUTPUT_EN &= ~0x3f;
-    /* scroll wheel- enable as input */
-    GPIOB_ENABLE |= 0x30; /* port b 4,5 */
-    GPIOB_OUTPUT_EN &= ~0x30; /* port b 4,5 */
-    /* buttons - set interrupt levels */
-    GPIOA_INT_LEV = ~(GPIOA_INPUT_VAL & 0x3f);
-    GPIOA_INT_CLR = GPIOA_INT_STAT & 0x3f;
-    /* scroll wheel - set interrupt levels */
-    GPIOB_INT_LEV = ~(GPIOB_INPUT_VAL & 0x30);
-    GPIOB_INT_CLR = GPIOB_INT_STAT & 0x30;
-    /* enable interrupts */
-    GPIOA_INT_EN = 0x3f;
-    GPIOB_INT_EN = 0x30;
-    /* unmask interrupt */
-    CPU_INT_EN = 0x40000000;
-    CPU_HI_INT_EN = GPIO0_MASK;
-}
-
-/*
- * Get button pressed from hardware
- */
-int button_read_device(void)
-{
-    static bool hold_button = false;
-    bool hold_button_old;
-
-    /* normal buttons */
-    hold_button_old = hold_button;
-    hold_button = button_hold();
-
-    if (hold_button != hold_button_old)
-        backlight_hold_changed(hold_button);
-
-    /* The int_btn variable is set in the button interrupt handler */
-    return int_btn;
-}
-
-bool button_hold(void)
-{
-    return (GPIOA_INPUT_VAL & 0x20)?false:true;
-}
-
-bool headphones_inserted(void)
-{
-    return (GPIOA_INPUT_VAL & 0x80)?true:false;
-}
diff --git a/firmware/target/arm/ipod/button-target.h b/firmware/target/arm/ipod/button-target.h
deleted file mode 100644
index 67bdc72..0000000
--- a/firmware/target/arm/ipod/button-target.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 _BUTTON_TARGET_H_
-#define _BUTTON_TARGET_H_
-
-#include <stdbool.h>
-#include "config.h"
-
-#define HAS_BUTTON_HOLD
-
-bool button_hold(void);
-void button_init_device(void);
-int button_read_device(void);
-
-void ipod_mini_button_int(void);
-void ipod_3g_button_int(void);
-void ipod_4g_button_int(void);
-
-/* iPod specific button codes */
-
-#define BUTTON_SELECT       0x00000001
-#define BUTTON_MENU         0x00000002
-
-#define BUTTON_LEFT         0x00000004
-#define BUTTON_RIGHT        0x00000008
-#define BUTTON_SCROLL_FWD   0x00000010
-#define BUTTON_SCROLL_BACK  0x00000020
-
-#define BUTTON_PLAY         0x00000040
-
-#define BUTTON_MAIN (BUTTON_SELECT|BUTTON_MENU\
-                |BUTTON_LEFT|BUTTON_RIGHT|BUTTON_SCROLL_FWD\
-                |BUTTON_SCROLL_BACK|BUTTON_PLAY)
-
-    /* Remote control's buttons */
-#ifdef IPOD_ACCESSORY_PROTOCOL
-#define BUTTON_RC_PLAY      0x00100000
-#define BUTTON_RC_STOP      0x00080000
-
-#define BUTTON_RC_LEFT      0x00040000
-#define BUTTON_RC_RIGHT     0x00020000
-#define BUTTON_RC_VOL_UP    0x00010000
-#define BUTTON_RC_VOL_DOWN  0x00008000
-
-#define BUTTON_REMOTE (BUTTON_RC_PLAY|BUTTON_RC_STOP\
-                |BUTTON_RC_LEFT|BUTTON_RC_RIGHT\
-                |BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN)
-#else
-#define BUTTON_REMOTE 0
-#endif
-
-/* This is for later
-#define  BUTTON_SCROLL_TOUCH 0x00000200
-*/
-
-
-#define POWEROFF_BUTTON BUTTON_PLAY
-#define POWEROFF_COUNT 40
-
-#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/ipod/lcd-as-color-nano.S b/firmware/target/arm/ipod/lcd-as-color-nano.S
deleted file mode 100644
index f6f9cc5..0000000
--- a/firmware/target/arm/ipod/lcd-as-color-nano.S
+++ /dev/null
@@ -1,287 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2010-2011 by Andree Buschmann
- *
- * Generic asm helper function used by YUV blitting.
- *
- * 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"
-
-/**************************************************************************** 
- * #define FORCE_FIFO_WAIT
- *
- * This is not needed in YUV blitting when the LCD IF is fast enough. In this
- * case YUV-to-RGB conversion per pixel needs longer than the transfer of a 
- * pixel via the LCD IF.
- ****************************************************************************/
-
-#include "config.h"
-
-/* Set FIFO wait for both iPod Color and iPod nano1G until we know for which
- * devices we can switch this off. */
-#define FORCE_FIFO_WAIT
-
-    .section .icode, "ax", %progbits
-    
-/****************************************************************************
- * extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
- *                                    const unsigned LCD_BASE,
- *                                    int width,
- *                                    int stride);
- *
- *   Conversion from Motion JPEG and MPEG Y'PbPr to RGB is:
- *   |R|   |1.164  0.000  1.596| |Y' -  16|
- *   |G| = |1.164 -0.391 -0.813| |Pb - 128|
- *   |B|   |1.164  2.018  0.000| |Pr - 128|
- *
- *   Scaled, normalized, rounded and tweaked to yield RGB 565:
- *   |R|   |74   0 101| |Y' -  16| >> 9
- *   |G| = |74 -24 -51| |Cb - 128| >> 8
- *   |B|   |74 128   0| |Cr - 128| >> 9
- *
- * Converts two lines from YUV to RGB565 and writes to LCD at once. First loop
- * loads Cb/Cr, calculates the chroma offset and saves them to buffer. Within
- * the second loop these chroma offset are reloaded from buffer. Within each 
- * loop two pixels are calculated and written to LCD. 
- */
-    .align      2
-    .global     lcd_write_yuv420_lines
-    .type       lcd_write_yuv420_lines, %function
-lcd_write_yuv420_lines:
-                                      /* r0 = src = yuv_src */
-                                      /* r1 = dst = LCD_BASE */
-                                      /* r2 = width */
-                                      /* r3 = stride */                
-    stmfd       sp!, { r4-r10, lr }   /* save non-scratch */
-    ldmia       r0, { r9, r10, r12 }  /* r9 = yuv_src[0] = Y'_p */
-                                      /* r10 = yuv_src[1] = Cb_p */
-                                      /* r12 = yuv_src[2] = Cr_p */
-    add         r3, r9, r3            /* r3 = &ysrc[stride] */
-    add         r4, r2, r2, asr #1    /* chroma buffer lenght = width/2 *3 */
-    mov         r4, r4, asl #2        /*   use words for str/ldm possibility */
-    add         r4, r4, #19           /*   plus room for 4 additional words, */
-    bic         r4, r4, #3            /*   rounded up to multiples of 4 byte */
-    sub         sp, sp, r4            /*   and allocate on stack */
-    stmia       sp, {r1-r4}           /* LCD_BASE, width, &ysrc[stride], stack_alloc */
-
-    mov         r7, r2                /* r7 = loop count */
-    add         r8, sp, #16           /* chroma buffer */
-    add         lr, r1, #0x100        /* LCD data port = LCD2_BASE + 0x100 */
-
-    /* 1st loop start */
-10:                                   /* loop start */
-
-    ldrb        r0, [r10], #1         /* r0 = *usrc++ = *Cb_p++ */
-    ldrb        r1, [r12], #1         /* r1 = *vsrc++ = *Cr_p++ */
-
-    sub         r0, r0, #128          /* r0 = Cb-128 */
-    sub         r1, r1, #128          /* r1 = Cr-128 */
-
-    add         r2, r1, r1, asl #1    /* r2 = Cr*51 + Cb*24 */
-    add         r2, r2, r2, asl #4   
-    add         r2, r2, r0, asl #3   
-    add         r2, r2, r0, asl #4   
-
-    add         r4, r1, r1, asl #2    /* r1 = Cr*101 */
-    add         r4, r4, r1, asl #5
-    add         r1, r4, r1, asl #6
-
-    add         r1, r1, #256          /* r1 = rv = (r1 + 256) >> 9 */
-    mov         r1, r1, asr #9
-    rsb         r2, r2, #128          /* r2 = guv = (-r2 + 128) >> 8 */
-    mov         r2, r2, asr #8       
-    add         r0, r0, #2            /* r0 = bu = (Cb*128 + 256) >> 9 */
-    mov         r0, r0, asr #2       
-    stmia       r8!, {r0-r2}          /* store r0, r1 and r2 to chroma buffer */
-
-    /* 1st loop, first pixel */
-    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
-    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
-    add         r3, r5, r5, asl #2
-    add         r5, r3, r5, asl #5
-
-    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
-    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
-    add         r4, r0, r5, asr #8    /* r4 = b = (Y >> 9) + bu */
-
-    orr         r5, r6, r4            /* check if clamping is needed... */
-    orr         r5, r5, r3, asr #1    /* ...at all */
-    cmp         r5, #31                 
-    bls         15f                   /* -> no clamp */
-    cmp         r6, #31               /* clamp r */
-    mvnhi       r6, r6, asr #31         
-    andhi       r6, r6, #31             
-    cmp         r3, #63               /* clamp g */
-    mvnhi       r3, r3, asr #31
-    andhi       r3, r3, #63
-    cmp         r4, #31               /* clamp b */
-    mvnhi       r4, r4, asr #31         
-    andhi       r4, r4, #31          
-15:                                   /* no clamp */
-
-    /* calculate pixel_1 and save to r4 for later pixel packing */
-    orr         r4, r4, r3, lsl #5    /* pixel_1 = r<<11 | g<<5 | b */
-    orr         r4, r4, r6, lsl #11   /* r4 = pixel_1 */
-
-    /* 1st loop, second pixel */
-    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
-    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
-    add         r3, r5, r5, asl #2
-    add         r5, r3, r5, asl #5
-
-    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
-    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
-    add         r5, r0, r5, asr #8    /* r5 = b = (Y >> 9) + bu */   
-
-    orr         r0, r6, r5            /* check if clamping is needed... */
-    orr         r0, r0, r3, asr #1    /* ...at all */
-    cmp         r0, #31                 
-    bls         15f                   /* -> no clamp */
-    cmp         r6, #31               /* clamp r */
-    mvnhi       r6, r6, asr #31         
-    andhi       r6, r6, #31             
-    cmp         r3, #63               /* clamp g */
-    mvnhi       r3, r3, asr #31
-    andhi       r3, r3, #63
-    cmp         r5, #31               /* clamp b */
-    mvnhi       r5, r5, asr #31         
-    andhi       r5, r5, #31          
-15:                                   /* no clamp */
-
-    /* calculate pixel_2 and pack with pixel_1 before writing */
-    orr         r5, r5, r3, lsl #5    /* pixel_2 = r<<11 | g<<5 | b */
-    orr         r5, r5, r6, lsl #11   /* r5 = pixel_2 */
-#ifdef FORCE_FIFO_WAIT
-    /* wait for FIFO half full */
-.fifo_wait1:
-    ldr         r3, [lr, #-0xE0]      /* while !(LCD2_BLOCK_CTRL & 0x1000000); */
-    tst         r3, #0x1000000
-    beq         .fifo_wait1
-#endif
-
-    mov         r3, r4, lsl #8        /* swap pixel_1 */
-    and         r3, r3, #0xff00
-    add         r4, r3, r4, lsr #8
-    
-    orr         r4, r4, r5, lsl #24   /* swap pixel_2 and pack with pixel_1 */
-    mov         r5, r5, lsr #8
-    orr         r4, r4, r5, lsl #16
-
-    str         r4, [lr]              /* write pixel_1 and pixel_2 */
-
-    subs        r7, r7, #2            /* check for loop end */
-    bgt         10b                   /* back to beginning  */
-    /* 1st loop end */
-
-    /* Reload several registers for pointer rewinding for next loop */
-    add         r8, sp, #16           /* chroma buffer */
-    ldmia       sp, { r1, r7, r9}     /* r1  = LCD_BASE */
-                                      /* r7  = loop count */
-                                      /* r9 = &ysrc[stride] */   
-
-    /* 2nd loop start */
-20:                                   /* loop start */
-    /* restore r0 (bu), r1 (rv) and r2 (guv) from chroma buffer */
-    ldmia       r8!, {r0-r2}
-
-    /* 2nd loop, first pixel */
-    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
-    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
-    add         r3, r5, r5, asl #2
-    add         r5, r3, r5, asl #5
-
-    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
-    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
-    add         r4, r0, r5, asr #8    /* r4 = b = (Y >> 9) + bu */
-
-    orr         r5, r6, r4            /* check if clamping is needed... */
-    orr         r5, r5, r3, asr #1    /* ...at all */
-    cmp         r5, #31                 
-    bls         15f                   /* -> no clamp */
-    cmp         r6, #31               /* clamp r */
-    mvnhi       r6, r6, asr #31         
-    andhi       r6, r6, #31             
-    cmp         r3, #63               /* clamp g */
-    mvnhi       r3, r3, asr #31
-    andhi       r3, r3, #63
-    cmp         r4, #31               /* clamp b */
-    mvnhi       r4, r4, asr #31         
-    andhi       r4, r4, #31          
-15:                                   /* no clamp */
-    /* calculate pixel_1 and save to r4 for later pixel packing */
-    orr         r4, r4, r3, lsl #5    /* pixel_1 = r<<11 | g<<5 | b */
-    orr         r4, r4, r6, lsl #11   /* r4 = pixel_1 */
-
-    /* 2nd loop, second pixel */
-    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
-    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
-    add         r3, r5, r5, asl #2
-    add         r5, r3, r5, asl #5
-
-    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
-    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
-    add         r5, r0, r5, asr #8    /* r5 = b = (Y >> 9) + bu */
-
-    orr         r0, r6, r5            /* check if clamping is needed... */
-    orr         r0, r0, r3, asr #1    /* ...at all */
-    cmp         r0, #31                 
-    bls         15f                   /* -> no clamp */
-    cmp         r6, #31               /* clamp r */
-    mvnhi       r6, r6, asr #31         
-    andhi       r6, r6, #31             
-    cmp         r3, #63               /* clamp g */
-    mvnhi       r3, r3, asr #31
-    andhi       r3, r3, #63
-    cmp         r5, #31               /* clamp b */
-    mvnhi       r5, r5, asr #31         
-    andhi       r5, r5, #31          
-15:                                   /* no clamp */
-
-    /* calculate pixel_2 and pack with pixel_1 before writing */
-    orr         r5, r5, r3, lsl #5    /* pixel_2 = r<<11 | g<<5 | b */
-    orr         r5, r5, r6, lsl #11   /* r5 = pixel_2 */
-#ifdef FORCE_FIFO_WAIT
-    /* wait for FIFO half full */
-.fifo_wait2:
-    ldr         r3, [lr, #-0xE0]      /* while !(LCD2_BLOCK_CTRL & 0x1000000); */
-    tst         r3, #0x1000000
-    beq         .fifo_wait2
-#endif
-
-    mov         r3, r4, lsl #8        /* swap pixel_1 */
-    and         r3, r3, #0xff00
-    add         r4, r3, r4, lsr #8
-    
-    orr         r4, r4, r5, lsl #24   /* swap pixel_2 and pack with pixel_1 */
-    mov         r5, r5, lsr #8
-    orr         r4, r4, r5, lsl #16
-    
-    str         r4, [lr]              /* write pixel_1 and pixel_2 */
-
-    subs        r7, r7, #2            /* check for loop end */
-    bgt         20b                   /* back to beginning  */
-    /* 2nd loop end */
-
-    ldr         r3, [sp, #12]
-    add         sp, sp, r3            /* deallocate buffer */
-    ldmpc       regs=r4-r10           /* restore registers */
-
-    .ltorg
-    .size   lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
diff --git a/firmware/target/arm/ipod/lcd-as-gray.S b/firmware/target/arm/ipod/lcd-as-gray.S
deleted file mode 100644
index cfd179a..0000000
--- a/firmware/target/arm/ipod/lcd-as-gray.S
+++ /dev/null
@@ -1,272 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Jens Arnold
- *
- * 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"
-
-#if CONFIG_CPU == PP5002
-    .section    .icode,"ax",%progbits
-#else
-    .text
-#endif
-    .align      2
-
-
-    .global     lcd_write_data
-    .type       lcd_write_data,%function
-
-lcd_write_data:
-    ldr     r12, =LCD1_BASE
-
-.loop:
-    ldrb    r2, [r0], #1
-
-#ifdef IPOD_MINI2G
-    ldrb    r3, [r0], #1
-    orr     r2, r3, r2, lsl #8
-    orr     r2, r2, #0x760000
-1:
-    ldr     r3, [r12]
-    tst     r3, #LCD1_BUSY_MASK
-    bne     1b
-    str     r2, [r12, #0x08]
-#else
-1:
-    ldr     r3, [r12]
-    tst     r3, #LCD1_BUSY_MASK
-    bne     1b
-    str     r2, [r12, #0x10]
-
-    ldrb    r2, [r0], #1
-1:
-    ldr     r3, [r12]
-    tst     r3, #LCD1_BUSY_MASK
-    bne     1b
-    str     r2, [r12, #0x10]
-#endif
-
-    subs    r1, r1, #1
-    bne     .loop
-
-    bx      lr
-    .size   lcd_write_data,.-lcd_write_data
-    
-
-#ifdef IPOD_MINI2G
-
-    .global     lcd_write_data_shifted
-    .type       lcd_write_data_shifted,%function
-    
-lcd_write_data_shifted:
-    stmfd   sp!, {r4, lr}
-    ldr     lr, =LCD1_BASE
-    mov     r12, #0x760000
-    ldrb    r2, [r0], #1
-
-.sloop:
-    ldrb    r3, [r0], #1
-    orr     r2, r3, r2, lsl #8
-    ldrb    r3, [r0], #1
-    orr     r2, r3, r2, lsl #8
-    mov     r4, r2, lsl #12
-    orr     r4, r12, r4, lsr #16
-1:
-    ldr     r3, [lr]
-    tst     r3, #LCD1_BUSY_MASK
-    bne     1b
-    str     r4, [lr, #0x08]
-
-    subs    r1, r1, #1
-    bne     .sloop
-
-    ldmpc   regs=r4
-    .size   lcd_write_data_shifted,.-lcd_write_data_shifted
-    
-#elif defined IPOD_MINI
-
-    .global     lcd_write_data_shifted
-    .type       lcd_write_data_shifted,%function
-    
-lcd_write_data_shifted:
-    str     lr, [sp, #-4]!
-    ldr     lr, =LCD1_BASE
-    ldrb    r2, [r0], #1
-
-.sloop:
-    ldrb    r3, [r0], #1
-    orr     r2, r3, r2, lsl #8
-    mov     r12, r2, lsr #4
-1:
-    ldr     r3, [lr]
-    tst     r3, #LCD1_BUSY_MASK
-    bne     1b
-    str     r12, [lr, #0x10]
-
-    ldrb    r3, [r0], #1
-    orr     r2, r3, r2, lsl #8
-    mov     r12, r2, lsr #4
-1:
-    ldr     r3, [lr]
-    tst     r3, #LCD1_BUSY_MASK
-    bne     1b
-    str     r12, [lr, #0x10]
-
-    subs    r1, r1, #1
-    bne     .sloop
-
-    ldrpc
-    .size   lcd_write_data_shifted,.-lcd_write_data_shifted
-
-#endif
-
-    .global     lcd_mono_data
-    .type       lcd_mono_data,%function
-    
-lcd_mono_data:
-    stmfd   sp!, {r4, lr}
-    ldr     lr, =LCD1_BASE
-    adr     r12, .dibits
-
-.mloop:
-    ldrb    r2, [r0], #1
-    mov     r3, r2, lsr #4
-    ldrb    r4, [r12, r3]
-
-#ifdef IPOD_MINI2G
-    and     r3, r2, #0x0f
-    ldrb    r3, [r12, r3]
-    orr     r4, r3, r4, lsl #8
-    orr     r4, r4, #0x760000
-1:
-    ldr     r3, [lr]
-    tst     r3, #LCD1_BUSY_MASK
-    bne     1b
-    str     r4, [lr, #0x08]
-#else
-1:
-    ldr     r3, [lr]
-    tst     r3, #LCD1_BUSY_MASK
-    bne     1b
-    str     r4, [lr, #0x10]
-
-    and     r3, r2, #0x0f
-    ldrb    r4, [r12, r3]
-1:
-    ldr     r3, [lr]
-    tst     r3, #LCD1_BUSY_MASK
-    bne     1b
-    str     r4, [lr, #0x10]
-#endif
-
-    subs    r1, r1, #1
-    bne     .mloop
-
-    ldmpc   regs=r4
-
-.dibits:
-    .byte   0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F
-    .byte   0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF
-
-    .size   lcd_mono_data,.-lcd_mono_data
-
-
-    .global     lcd_grey_data
-    .type       lcd_grey_data,%function
-
-/* A high performance function to write grey phase data to the display,
- * one or multiple pixels.
- *
- * Arguments:
- *   r0 - pixel value data address
- *   r1 - pixel phase data address
- *   r2 - pixel block count
- *
- * Register usage:
- *   r3/r4 - current block of phases
- *   r5/r6 - lcd data accumulators
- *   r6/r7 - current block of values
- *   r12 - phase signs mask
- *   lr  - lcd bridge address
- */
-
-lcd_grey_data:
-    stmfd   sp!, {r4-r7, lr}
-    mov     r12, #0x80
-    orr     r12, r12, r12, lsl #8
-    orr     r12, r12, r12, lsl #16
-    ldr     lr, =LCD1_BASE
-
-.greyloop:
-    ldmia   r1, {r3-r4}         /* Fetch 8 pixel phases */
-
-    bic     r5, r12, r3         /* r5 = 3.......2.......1.......0....... */
-    orr     r5, r5, r5, lsr #10 /* r5 = 3.......2.3.....1.2.....0.1..... */
-    orr     r5, r5, r5, lsr #10 /* r5 = 3.......2.3.....1.2.3...0.1.2... */
-    orr     r5, r5, r5, lsr #10 /* r5 = 3.......2.3.....1.2.3...0.1.2.3. */
-    orr     r5, r5, r5, lsr #1  /* r5 = 33......2233....112233..00112233 */
-    bic     r3, r3, r12
-
-#ifndef IPOD_MINI2G  /* 8 bit parallel bridge mode */
-1:
-    ldr     r6, [lr]
-    tst     r6, #LCD1_BUSY_MASK
-    bne     1b
-
-    str     r5, [lr, #0x10]
-#endif
-
-    ldmia   r0!, {r6-r7}        /* Fetch 8 pixel values */
-    add     r3, r3, r6
-
-    bic     r6, r12, r4         /* r6 = 7.......6.......5.......4....... */
-    orr     r6, r6, r6, lsr #10 /* r6 = 7.......6.7.....5.6.....4.5..... */
-    orr     r6, r6, r6, lsr #10 /* r6 = 7.......6.7.....5.6.7...4.5.6... */
-    orr     r6, r6, r6, lsr #10 /* r6 = 7.......6.7.....5.6.7...4.5.6.7. */
-    orr     r6, r6, r6, lsr #1  /* r6 = 77......6677....556677..44556677 */
-    bic     r4, r4, r12
-
-    add     r4, r4, r7
-    stmia   r1!, {r3-r4}
-
-#ifdef IPOD_MINI2G   /* 16 bit serial bridge mode */
-    and     r5, r5, #0xff       /* r5 = ........................00112233 */
-    and     r6, r6, #0xff       /* r6 = ........................44556677 */
-    orr     r5, r6, r5, lsl #8  /* r5 = ................0011223344556677 */
-    orr     r5, r5, #0x760000   /* data marker */
-#endif
-
-1:
-    ldr     r7, [lr]
-    tst     r7, #LCD1_BUSY_MASK
-    bne     1b
-
-#ifdef IPOD_MINI2G
-    str     r5, [lr, #0x08]
-#else
-    str     r6, [lr, #0x10]
-#endif
-
-    subs    r2, r2, #1
-    bne     .greyloop
-
-    ldmpc   regs=r4-r7
-    .size   lcd_grey_data,.-lcd_grey_data
-
diff --git a/firmware/target/arm/ipod/lcd-color_nano.c b/firmware/target/arm/ipod/lcd-color_nano.c
deleted file mode 100644
index 589e865..0000000
--- a/firmware/target/arm/ipod/lcd-color_nano.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Rockbox driver for iPod LCDs
- *
- * Based on code from the ipodlinux project - http://ipodlinux.org/
- * Adapted for Rockbox in November 2005
- *
- * Original file: linux/arch/armnommu/mach-ipod/fb.c
- *
- * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
- *
- * 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 "lcd.h"
-#include "kernel.h"
-#include "system.h"
-#include "hwcompat.h"
-#include "backlight-target.h"
-
-/* LCD command codes for HD66789R */
-#define LCD_CNTL_RAM_ADDR_SET           0x21
-#define LCD_CNTL_WRITE_TO_GRAM          0x22
-#define LCD_CNTL_HORIZ_RAM_ADDR_POS     0x44
-#define LCD_CNTL_VERT_RAM_ADDR_POS      0x45
-
-/*** globals ***/
-int lcd_type = 1; /* 0,2 = "old" Color/Photo; 1,3 = similar to HD66789R */
-
-static inline void lcd_wait_write(void)
-{
-    while (LCD2_PORT & LCD2_BUSY_MASK);
-}
-
-static void lcd_cmd_data(unsigned cmd, unsigned data)
-{
-    if ((lcd_type&1) == 0) {  /* 16 bit transfers */
-        lcd_wait_write();
-        LCD2_PORT = LCD2_CMD_MASK | cmd;
-        lcd_wait_write();
-        LCD2_PORT = LCD2_CMD_MASK | data;
-    } else {
-        lcd_wait_write();
-        LCD2_PORT = LCD2_CMD_MASK;
-        LCD2_PORT = LCD2_CMD_MASK | cmd;
-        lcd_wait_write();
-        LCD2_PORT = LCD2_DATA_MASK | (data >> 8);
-        LCD2_PORT = LCD2_DATA_MASK | (data & 0xff);
-    }
-}
-
-/*** hardware configuration ***/
-
-#ifdef HAVE_LCD_CONTRAST
-void lcd_set_contrast(int val)
-{
-  /* TODO: Implement lcd_set_contrast() */
-  (void)val;
-}
-#endif
-
-#ifdef HAVE_LCD_INVERT
-void lcd_set_invert_display(bool yesno)
-{
-#ifdef IPOD_NANO    /* this has only been tested on the ipod nano */
-    lcd_cmd_data(0x07, 0x73 | (yesno ? 0 : (1<<2)));
-#endif
-}
-#endif
-
-#ifdef HAVE_LCD_FLIP
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
-  /* TODO: Implement lcd_set_flip() */
-  (void)yesno;
-}
-#endif
-
-/* LCD init */
-void lcd_init_device(void)
-{  
-#if CONFIG_LCD == LCD_IPODCOLOR
-    if (IPOD_HW_REVISION == 0x60000) {
-        lcd_type = 0;
-    } else {
-        lcd_type = (GPIOA_INPUT_VAL & 0x2) | ((GPIOA_INPUT_VAL & 0x10) >> 4);
-    }
-    if ((lcd_type&1) == 0) {
-        lcd_cmd_data(0xef, 0x0);
-        lcd_cmd_data(0x01, 0x0);
-        lcd_cmd_data(0x80, 0x1);
-        lcd_cmd_data(0x10, 0xc);
-        lcd_cmd_data(0x18, 0x6);
-        lcd_cmd_data(0x7e, 0x4);
-        lcd_cmd_data(0x7e, 0x5);
-        lcd_cmd_data(0x7f, 0x1);
-    }
-#elif CONFIG_LCD == LCD_IPODNANO
-    /* iPodLinux doesn't appear have any LCD init code for the Nano */
-#endif
-}
-
-#ifdef HAVE_LCD_SHUTDOWN
-void lcd_shutdown(void) {
-    /* Immediately switch off the backlight to avoid flashing. */
-#if defined(IPOD_NANO)
-    _backlight_hw_enable(false);
-#elif defined(IPOD_COLOR)
-    _backlight_off();
-#endif
-
-    if ((lcd_type&1) == 0) {
-        /* lcd_type 0 and 2 */
-        lcd_cmd_data(0x00EF, 0x0000);
-        lcd_cmd_data(0x0080, 0x0000); udelay(1000);
-        lcd_cmd_data(0x0001, 0x0001);
-    } else if (lcd_type == 1) {
-        /* lcd_type 1 */
-        lcd_cmd_data(0x0007, 0x0236); sleep( 40*HZ/1000);
-        lcd_cmd_data(0x0007, 0x0226); sleep( 40*HZ/1000);
-        lcd_cmd_data(0x0007, 0x0204);
-        lcd_cmd_data(0x0010, 0x7574); sleep(200*HZ/1000);
-        lcd_cmd_data(0x0010, 0x7504); sleep( 50*HZ/1000);
-        lcd_cmd_data(0x0010, 0x0501);
-    } else {
-        /* lcd_type 3 */
-        lcd_cmd_data(0x0007, 0x4016); sleep( 20*HZ/1000);
-        lcd_cmd_data(0x0059, 0x0011); sleep( 20*HZ/1000);
-        lcd_cmd_data(0x0059, 0x0003); sleep( 20*HZ/1000);
-        lcd_cmd_data(0x0059, 0x0002); sleep( 20*HZ/1000);
-        lcd_cmd_data(0x0010, 0x6360); sleep(200*HZ/1000);
-        lcd_cmd_data(0x0010, 0x6300); sleep( 50*HZ/1000);
-        lcd_cmd_data(0x0010, 0x0300);
-        lcd_cmd_data(0x0059, 0x0000);
-        lcd_cmd_data(0x0007, 0x4004);
-        lcd_cmd_data(0x0010, 0x0301);
-    }
-}
-#endif
-
-/* Helper function to set up drawing region and start drawing */
-static void lcd_setup_drawing_region(int x, int y, int width, int height)
-{
-    int y0, x0, y1, x1;
-    
-    /* calculate the drawing region */
-#if CONFIG_LCD == LCD_IPODNANO
-    y0 = x;                         /* start horiz */
-    y1 = (x + width) - 1;           /* max horiz */
-    x0 = y;                         /* start vert */
-    x1 = (y + height) - 1;          /* max vert */
-#elif CONFIG_LCD == LCD_IPODCOLOR
-    y0 = y;                         /* start vert */
-    y1 = (y + height) - 1;          /* end vert */
-    x1 = (LCD_WIDTH - 1) - x;       /* end horiz */
-    x0 = (x1 - width) + 1;          /* start horiz */
-#endif
-
-    /* setup the drawing region */
-    if ((lcd_type&1) == 0) {
-        /* x0 and x1 need to be swapped until 
-         * proper direction setup is added */
-        lcd_cmd_data(0x12, y0);      /* start vert */
-        lcd_cmd_data(0x13, x1);      /* start horiz */
-        lcd_cmd_data(0x15, y1);      /* end vert */
-        lcd_cmd_data(0x16, x0);      /* end horiz */
-    } else {
-        /* max horiz << 8 | start horiz */
-        lcd_cmd_data(LCD_CNTL_HORIZ_RAM_ADDR_POS, (y1 << 8) | y0);
-        /* max vert << 8 | start vert */
-        lcd_cmd_data(LCD_CNTL_VERT_RAM_ADDR_POS, (x1 << 8) | x0);
-
-        /* start vert = max vert */
-#if CONFIG_LCD == LCD_IPODCOLOR
-        x0 = x1;
-#endif
-
-        /* position cursor (set AD0-AD15) */
-        /* start vert << 8 | start horiz */
-        lcd_cmd_data(LCD_CNTL_RAM_ADDR_SET, ((x0 << 8) | y0));
-
-        /* start drawing */
-        lcd_wait_write();
-        LCD2_PORT = LCD2_CMD_MASK;
-        LCD2_PORT = (LCD2_CMD_MASK|LCD_CNTL_WRITE_TO_GRAM);
-    }
-}
-
-/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
-extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
-                                   const unsigned int lcd_baseadress,
-                                   int width,
-                                   int stride);
-
-/* Performance function to blit a YUV bitmap directly to the LCD */
-void lcd_blit_yuv(unsigned char * const src[3],
-                  int src_x, int src_y, int stride,
-                  int x, int y, int width, int height)
-{
-    int z;
-    unsigned char const * yuv_src[3];
-
-    width  = (width  + 1) & ~1; /* ensure width is even  */
-    height = (height + 1) & ~1; /* ensure height is even */
-
-    lcd_setup_drawing_region(x, y, width, height);
-
-    z = stride * src_y;
-    yuv_src[0] = src[0] + z + src_x;
-    yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
-    yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
-
-    while (height > 0) {
-        int r, h, pixels_to_write;
-
-        pixels_to_write = (width * height) * 2;
-        h = height;
-
-        /* calculate how much we can do in one go */
-        if (pixels_to_write > 0x10000) {
-            h = ((0x10000/2) / width) & ~1; /* ensure h is even */
-            pixels_to_write = (width * h) * 2;
-        }
-        
-        LCD2_BLOCK_CTRL   = 0x10000080;
-        LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
-        LCD2_BLOCK_CTRL   = 0x34000000;
-
-        r = h>>1; /* lcd_write_yuv420_lines writes two lines at once */
-        do {
-            lcd_write_yuv420_lines(yuv_src, LCD2_BASE, width, stride);
-            yuv_src[0] += stride << 1;
-            yuv_src[1] += stride >> 1;
-            yuv_src[2] += stride >> 1;
-        } while (--r > 0);
-        
-        /* transfer of pixels_to_write bytes finished */
-        while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
-        LCD2_BLOCK_CONFIG = 0;
-        
-        height -= h;
-    }
-}
-
-/* Helper function writes 'count' consecutive pixels from src to LCD IF */
-static void lcd_write_line(int count, unsigned long *src)
-{
-    do {
-        while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK)); /* FIFO wait */
-        LCD2_BLOCK_DATA = *src++;                     /* output 2 pixels */
-        count -= 2;
-    } while (count > 0);
-}
-
-/* Update a fraction of the display. */
-void lcd_update_rect(int x, int y, int width, int height)
-{
-    unsigned long *addr;
-
-    /* Ensure both x and width are even to be able to read 32-bit aligned 
-     * data from lcd_framebuffer */
-    x     =  x & ~1;            /* use the smaller even number */
-    width = (width + 1) & ~1;   /* use the bigger even number  */
-
-    lcd_setup_drawing_region(x, y, width, height);
-
-    addr = (unsigned long*)&lcd_framebuffer[y][x];
-
-    while (height > 0) {
-        int r, h, pixels_to_write;
-
-        pixels_to_write = (width * height) * 2;
-        h = height;
-
-        /* calculate how much we can do in one go */
-        if (pixels_to_write > 0x10000) {
-            h = ((0x10000/2) / width) & ~1; /* ensure h is even */
-            pixels_to_write = (width * h) * 2;
-        }
-
-        LCD2_BLOCK_CTRL   = 0x10000080;
-        LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
-        LCD2_BLOCK_CTRL   = 0x34000000;
-
-        if (LCD_WIDTH == width) {
-            /* for each row and column in a single call */
-            lcd_write_line(h*width, addr);
-            addr += LCD_WIDTH/2*h;
-        } else {
-            /* for each row */
-            for (r = 0; r < h; r++) {
-                lcd_write_line(width, addr);
-                addr += LCD_WIDTH/2;
-            }
-        }
-
-        /* transfer of pixels_to_write bytes finished */
-        while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
-        LCD2_BLOCK_CONFIG = 0;
-
-        height -= h;
-    }
-}
-
-/* Update the display.
-   This must be called after all other LCD functions that change the display. */
-void lcd_update(void)
-{
-    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
-}
diff --git a/firmware/target/arm/ipod/lcd-gray.c b/firmware/target/arm/ipod/lcd-gray.c
deleted file mode 100644
index 11d4cba..0000000
--- a/firmware/target/arm/ipod/lcd-gray.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Rockbox driver for iPod LCDs
- *
- * Based on code from the ipodlinux project - http://ipodlinux.org/
- * Adapted for Rockbox in November 2005
- *
- * Original file: linux/arch/armnommu/mach-ipod/fb.c
- *
- * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
- *
- * 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 "lcd.h"
-#include "kernel.h"
-#include "system.h"
-#include "hwcompat.h"
-
-/* LCD command codes for HD66753 */
-
-#define R_START_OSC             0x00
-#define R_DRV_OUTPUT_CONTROL    0x01
-#define R_DRV_WAVEFORM_CONTROL  0x02
-#define R_POWER_CONTROL         0x03
-#define R_CONTRAST_CONTROL      0x04
-#define R_ENTRY_MODE            0x05
-#define R_ROTATION              0x06
-#define R_DISPLAY_CONTROL       0x07
-#define R_CURSOR_CONTROL        0x08
-#define R_HORIZONTAL_CURSOR_POS 0x0b
-#define R_VERTICAL_CURSOR_POS   0x0c
-#define R_1ST_SCR_DRV_POS       0x0d
-#define R_2ND_SCR_DRV_POS       0x0e
-#define R_RAM_WRITE_MASK        0x10
-#define R_RAM_ADDR_SET          0x11
-#define R_RAM_DATA              0x12
-
-#ifdef HAVE_BACKLIGHT_INVERSION
-/* The backlight makes the LCD appear negative on the 1st/2nd gen */
-static bool lcd_inverted = false;
-static bool lcd_backlit = false;
-#if NUM_CORES > 1
-/* invert_display() and the lcd_blit_* functions need to be corelocked */
-static struct corelock cl IBSS_ATTR;
-#endif
-static void invert_display(void);
-#endif
-
-#if defined(IPOD_1G2G) || defined(IPOD_3G)
-#define POWER_REG_H 0x1120   /* 1/7 Bias, 5x step-up @ clk/8 */
-#else
-#define POWER_REG_H 0x1200   /* 1/7 Bias, 6x step-up @ clk/32 */
-#endif
-
-#define CONTRAST_REG_H 0x400
-
-#if defined(IPOD_1G2G)
-#define DEFAULT_CONTRAST 45
-#elif defined(IPOD_3G)
-#define DEFAULT_CONTRAST 50
-#elif defined(IPOD_MINI) || defined(IPOD_MINI2G)
-#define DEFAULT_CONTRAST 42
-#elif defined(IPOD_4G)
-#define DEFAULT_CONTRAST 35
-#endif
-
-/* needed for flip */
-static int addr_offset;
-#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
-static int pix_offset;
-void lcd_write_data_shifted(const fb_data* p_bytes, int count);
-#endif
-
-/* wait for LCD with timeout */
-static inline void lcd_wait_write(void)
-{
-    while (LCD1_CONTROL & LCD1_BUSY_MASK);
-}
-
-/* send LCD command */
-static void lcd_prepare_cmd(unsigned cmd)
-{
-    lcd_wait_write();
-#ifdef IPOD_MINI2G
-    LCD1_CMD = cmd | 0x740000;
-#else
-    LCD1_CMD = 0;
-    lcd_wait_write();
-    LCD1_CMD = cmd;
-#endif
-}
-
-/* send LCD command and data */
-static void lcd_cmd_and_data(unsigned cmd, unsigned data)
-{
-    lcd_wait_write();
-#ifdef IPOD_MINI2G
-    LCD1_CMD = cmd | 0x740000;
-    lcd_wait_write();
-    LCD1_CMD = data | 0x760000;
-#else
-    LCD1_CMD = 0;
-    lcd_wait_write();
-    LCD1_CMD = cmd;
-    lcd_wait_write();
-    LCD1_DATA = data >> 8;
-    lcd_wait_write();
-    LCD1_DATA = data & 0xff;
-#endif
-}
-
-/* LCD init */
-void lcd_init_device(void)
-{
-#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
-    corelock_init(&cl);
-#endif
-#ifdef IPOD_MINI2G /* serial LCD hookup */
-    lcd_wait_write();
-    LCD1_CONTROL = 0x01730084; /* fastest setting */
-#elif defined(IPOD_1G2G) || defined(IPOD_3G)
-    LCD1_CONTROL = (LCD1_CONTROL & 0x0002) | 0x0084; 
-                   /* fastest setting, keep backlight bit */
-#else
-    LCD1_CONTROL = 0x0084; /* fastest setting */
-#endif
-
-    lcd_cmd_and_data(R_DRV_WAVEFORM_CONTROL, 0x48);
-                     /* C waveform, no EOR, 9 lines inversion */
-    lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0xc);
-    lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0019);
-    lcd_set_contrast(DEFAULT_CONTRAST);
-#ifdef HAVE_BACKLIGHT_INVERSION
-    invert_display();
-#endif
-    lcd_set_flip(false);
-    lcd_cmd_and_data(R_ENTRY_MODE, 0x0000);
-}
-
-/*** hardware configuration ***/
-
-int lcd_default_contrast(void)
-{
-    return DEFAULT_CONTRAST;
-}
-
-/* Rockbox stores the contrast as 0..63 - we add 64 to it */
-void lcd_set_contrast(int val)
-{
-    if (val < 0) val = 0;
-    else if (val > 63) val = 63;
-
-    lcd_cmd_and_data(R_CONTRAST_CONTROL, CONTRAST_REG_H | (val + 64));
-}
-
-#ifdef HAVE_BACKLIGHT_INVERSION
-static void invert_display(void)
-{
-    static bool last_invert = false;
-    bool new_invert = lcd_inverted ^ lcd_backlit;
-
-    if (new_invert != last_invert)
-    {
-        int oldlevel = disable_irq_save();
-#if NUM_CORES > 1
-        corelock_lock(&cl);
-        lcd_cmd_and_data(R_DISPLAY_CONTROL, new_invert? 0x0027 : 0x0019);
-        corelock_unlock(&cl);
-#else
-        lcd_cmd_and_data(R_DISPLAY_CONTROL, new_invert? 0x0027 : 0x0019);
-#endif
-        restore_irq(oldlevel);
-        last_invert = new_invert;
-    }
-}
-
-void lcd_set_invert_display(bool yesno)
-{
-    lcd_inverted = yesno;
-    invert_display();
-}
-
-void lcd_set_backlight_inversion(bool yesno)
-{
-    lcd_backlit = yesno;
-    invert_display();
-}
-#else
-void lcd_set_invert_display(bool yesno)
-{
-    lcd_cmd_and_data(R_DISPLAY_CONTROL, yesno ? 0x0027 : 0x0019);
-}
-#endif
-
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
-#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
-    if (yesno) 
-    {    /* 168x112, inverse COM order */
-        lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020d);
-        lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8316);    /* 22..131 */
-        addr_offset = (22 << 5) | (20 - 4);
-        pix_offset = -2;
-    }
-    else 
-    {   /* 168x112,  inverse SEG order */
-        lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010d);
-        lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00);    /* 0..109 */
-        addr_offset = 20;
-        pix_offset = 0;
-    }
-#else
-    if (yesno) 
-    {   /* 168x128, inverse SEG & COM order */
-        lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030f);
-        lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304);    /* 4..131 */
-        addr_offset = (4 << 5) | (20 - 1);
-    } 
-    else 
-    {   /* 168x128 */
-        lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000f);
-        lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00);    /* 0..127 */
-        addr_offset = 20;
-    }
-#endif
-}
-
-#ifdef HAVE_LCD_ENABLE
-void lcd_enable(bool on)
-{
-    if (on)
-    {
-        lcd_cmd_and_data(R_START_OSC, 1);               /* start oscillation */
-        sleep(HZ/10);                                           /* wait 10ms */
-        lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H); /*clear standby mode */
-        lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0xc);
-                                                   /* enable opamp & booster */
-    }
-    else
-    {
-        lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H);
-                                               /* switch off opamp & booster */
-        lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0x1);
-                                                       /* enter standby mode */
-    }
-}
-#endif /* HAVE_LCD_ENABLE */
-
-/*** update functions ***/
-
-/* Helper function. */
-void lcd_mono_data(const unsigned char *data, int count);
-
-/* Performance function that works with an external buffer
-   note that x, bwidtht and stride are in 8-pixel units! */
-void lcd_blit_mono(const unsigned char *data, int bx, int y, int bwidth,
-                   int height, int stride)
-{
-#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
-    corelock_lock(&cl);
-#endif
-    while (height--)
-    {
-        lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx);
-        lcd_prepare_cmd(R_RAM_DATA);
-        lcd_mono_data(data, bwidth);
-        data += stride;
-    }
-#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
-    corelock_unlock(&cl);
-#endif
-}
-
-/* Helper function for lcd_grey_phase_blit(). */
-void lcd_grey_data(unsigned char *values, unsigned char *phases, int count);
-
-/* Performance function that works with an external buffer
-   note that bx and bwidth are in 8-pixel units! */
-void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
-                         int bx, int y, int bwidth, int height, int stride)
-{
-#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
-    corelock_lock(&cl);
-#endif
-    while (height--)
-    {
-        lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx);
-        lcd_prepare_cmd(R_RAM_DATA);
-        lcd_grey_data(values, phases, bwidth);
-        values += stride;
-        phases += stride;
-    }
-#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
-    corelock_unlock(&cl);
-#endif
-}
-
-void lcd_update_rect(int x, int y, int width, int height)
-{
-    int xmax, ymax;
-
-    if (x + width > LCD_WIDTH)
-        width = LCD_WIDTH - x;
-    if (width <= 0)
-        return;
-    
-    ymax = y + height - 1;
-    if (ymax >= LCD_HEIGHT)
-        ymax = LCD_HEIGHT - 1;
-
-#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
-    x += pix_offset;
-#endif
-     /* writing is done in 16-bit units (8 pixels) */
-    xmax = (x + width - 1) >> 3;
-    x >>= 3;
-    width = xmax - x + 1;
-
-    for (; y <= ymax; y++) 
-    {
-        lcd_cmd_and_data(R_RAM_ADDR_SET, (y << 5) + addr_offset - x);
-        lcd_prepare_cmd(R_RAM_DATA);
-
-#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
-        if (pix_offset == -2)
-            lcd_write_data_shifted(&lcd_framebuffer[y][2*x], width);
-        else
-#endif
-            lcd_write_data(&lcd_framebuffer[y][2*x], width);
-    }
-}
-
-/* Update the display. */
-void lcd_update(void)
-{
-    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
-}
-
-#ifdef HAVE_LCD_SHUTDOWN
-/* LCD powerdown */
-void lcd_shutdown(void)
-{
-    lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0x00); /* Turn off op amp power */
-    lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0x02); /* Put LCD driver in standby */
-}
-#endif
diff --git a/firmware/target/arm/ipod/power-ipod.c b/firmware/target/arm/ipod/power-ipod.c
deleted file mode 100644
index ef59417..0000000
--- a/firmware/target/arm/ipod/power-ipod.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- *
- * 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 "kernel.h"
-#include "system.h"
-#include "power.h"
-#include "logf.h"
-#include "pcf50605.h"
-#include "usb.h"
-#include "lcd.h"
-#include "string.h"
-#ifdef HAVE_USB_CHARGING_ENABLE
-#include "usb_core.h"   /* for usb_charging_maxcurrent_change */
-#endif
-
-void power_init(void)
-{
-#if defined(IPOD_1G2G) || defined(IPOD_3G)
-    GPIOC_ENABLE |= 0x40;      /* GPIO C6 is HDD power (low active) */
-    GPIOC_OUTPUT_VAL &= ~0x40; /* on by default */
-    GPIOC_OUTPUT_EN |= 0x40;   /* enable output */
-#endif
-#ifndef IPOD_1G2G
-    pcf50605_init();
-#endif
-}
-
-#if CONFIG_CHARGING
-unsigned int power_input_status(void)
-{
-    unsigned int status = POWER_INPUT_NONE;
-
-#if defined(IPOD_NANO) || defined(IPOD_VIDEO)
-    if ((GPIOL_INPUT_VAL & 0x08) == 0)
-        status = POWER_INPUT_MAIN_CHARGER;
-
-    if ((GPIOL_INPUT_VAL & 0x10) != 0)
-        status |= POWER_INPUT_USB_CHARGER;
-    /* */
-#elif defined(IPOD_4G) || defined(IPOD_COLOR) \
-       || defined(IPOD_MINI) || defined(IPOD_MINI2G)
-    /* C2 is firewire power */
-    if ((GPIOC_INPUT_VAL & 0x04) == 0)
-        status = POWER_INPUT_MAIN_CHARGER;
-
-    if ((GPIOD_INPUT_VAL & 0x08) != 0)
-        status |= POWER_INPUT_USB_CHARGER;
-    /* */
-#elif defined(IPOD_3G)
-    /* firewire power */
-    if ((GPIOC_INPUT_VAL & 0x10) == 0)
-        status = POWER_INPUT_MAIN_CHARGER;
-    /* */
-#else
-    /* This needs filling in for other ipods. */
-#endif
-
-    return status;
-}
-
-/* Returns true if the unit is charging the batteries. */
-bool charging_state(void) {
-#if defined(IPOD_COLOR)
-    /* 0x70000088 appears to be the input value for GPO32 bits.
-       Write a zero to 0x70000088 before reading.
-       To enable input set the corresponding 0x7000008C bit,
-       and clear the corresponding GPO32_ENABLE bit. */
-    outl(0, 0x70000088);
-    return (inl(0x70000088) & 1)?false:true;
-#else
-    return (GPIOB_INPUT_VAL & 0x01)?false:true;
-#endif
-}
-#endif /* CONFIG_CHARGING */
-
-
-void ide_power_enable(bool on)
-{
-#if defined(IPOD_1G2G) || defined(IPOD_3G)
-    if (on)
-        GPIOC_OUTPUT_VAL &= ~0x40;
-    else
-        GPIOC_OUTPUT_VAL |= 0x40;
-#elif defined(IPOD_4G) || defined(IPOD_COLOR) \
-   || defined(IPOD_MINI) || defined(IPOD_MINI2G)
-    if (on)
-    {
-        GPIO_CLEAR_BITWISE(GPIOJ_OUTPUT_VAL, 0x04);
-        DEV_EN |= DEV_IDE0;
-    }
-    else
-    {
-        DEV_EN &= ~DEV_IDE0;
-        GPIO_SET_BITWISE(GPIOJ_OUTPUT_VAL, 0x04);
-    }
-#elif defined(IPOD_VIDEO)
-    if (on)
-    {
-        GPO32_VAL &= ~0x40000000;
-        sleep(1);  /* only need 4 ms */
-        DEV_EN |= DEV_IDE0;
-        GPIOG_ENABLE = 0;
-        GPIOH_ENABLE = 0;
-        GPIO_CLEAR_BITWISE(GPIOI_ENABLE, 0xBF);
-        GPIO_CLEAR_BITWISE(GPIOK_ENABLE, 0x1F);
-        udelay(10);
-    }
-    else
-    {
-        DEV_EN &= ~DEV_IDE0;
-        udelay(10);
-        GPIOG_ENABLE = 0xFF;
-        GPIOH_ENABLE = 0xFF;
-        GPIO_SET_BITWISE(GPIOI_ENABLE, 0xBF);
-        GPIO_SET_BITWISE(GPIOK_ENABLE, 0x1F);
-        GPO32_VAL |= 0x40000000;
-    }
-#else /* Nano */
-    (void)on;  /* Do nothing. */
-#endif
-}
-
-bool ide_powered(void)
-{
-#if defined(IPOD_1G2G) || defined(IPOD_3G)
-    return !(GPIOC_OUTPUT_VAL & 0x40);
-#elif defined(IPOD_4G) || defined(IPOD_COLOR) \
-   || defined(IPOD_MINI) || defined(IPOD_MINI2G)
-    return !(GPIOJ_OUTPUT_VAL & 0x04);
-#elif defined(IPOD_VIDEO)
-    return !(GPO32_VAL & 0x40000000);
-#else /* Nano */
-    return true; /* Pretend we are always powered */
-#endif
-}
-
-void power_off(void)
-{
-#if defined(HAVE_LCD_COLOR) && !defined(HAVE_LCD_SHUTDOWN)
-    /* Clear the screen and backdrop to
-    remove ghosting effect on shutdown */
-    lcd_set_backdrop(NULL);
-    lcd_set_background(LCD_WHITE);
-    lcd_clear_display();
-    lcd_update();
-    sleep(HZ/16);
-#endif
-
-#ifndef BOOTLOADER
-#ifdef IPOD_1G2G
-    /* we cannot turn off the 1st gen/ 2nd gen yet. Need to figure out sleep mode. */
-    system_reboot();
-#else
-    /* We don't turn off the ipod, we put it in a deep sleep */
-    /* Clear latter part of iram (the part used by plugins/codecs) to ensure
-     * that the OF behaves properly on boot. There is some kind of boot
-     * failure flag there which otherwise may not be cleared.
-     */
-#if CONFIG_CPU == PP5022
-    memset((void*)0x4000c000, 0, 0x14000);
-#elif CONFIG_CPU == PP5020
-    memset((void*)0x4000c000, 0, 0xc000);
-#endif
-    pcf50605_standby_mode();
-#endif
-#endif
-}
-
-#ifdef HAVE_USB_CHARGING_ENABLE
-void usb_charging_maxcurrent_change(int maxcurrent)
-{
-    bool suspend_charging = (maxcurrent < 100);
-    bool fast_charging = (maxcurrent >= 500);
-
-    /* This GPIO is connected to the LTC4066's SUSP pin */
-    /* Setting it high prevents any power being drawn over USB */
-    /* which supports USB suspend */
-#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
-    if (suspend_charging)
-        GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 4);
-    else
-        GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_VAL, 4);
-#elif defined(IPOD_MINI2G)
-    if (suspend_charging)
-        GPIO_SET_BITWISE(GPIOJ_OUTPUT_VAL, 2);
-    else
-        GPIO_CLEAR_BITWISE(GPIOJ_OUTPUT_VAL, 2);
-#else /* Color, 4G, Mini G1 */
-    if (suspend_charging)
-        GPO32_VAL |= 0x8000000;
-    else
-        GPO32_VAL &= ~0x8000000;
-#endif
-
-    /* This GPIO is connected to the LTC4066's HPWR pin */
-    /* Setting it low limits current to 100mA, setting it high allows 500mA */
-#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
-    if (fast_charging)
-        GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 4);
-    else
-        GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_VAL, 4);
-#else
-    if (fast_charging)
-        GPO32_VAL |= 0x40;
-    else 
-        GPO32_VAL &= ~0x40;
-#endif
-
-    /* This GPIO is connected to the LTC4066's CLDIS pin */
-    /* Setting it high allows up to 1.5A of current to be drawn */
-    /* This doesn't appear to actually be safe even with an AC charger */
-    /* so for now it is disabled. It's not known (or maybe doesn't exist) */
-    /* on all models. */
-#if 0
-#if defined(IPOD_VIDEO)
-    if (unlimited_charging)
-        GPO32_VAL |= 0x10000000;
-    else 
-        GPO32_VAL &= ~0x10000000;
-#elif defined(IPOD_4G) || defined(IPOD_COLOR)
-    if (unlimited_charging)
-        GPO32_VAL |= 0x200;
-    else 
-        GPO32_VAL &= ~0x200;
-#endif
-    /* This might be GPIOD & 40 on 2G */
-#endif
-}
-#endif /* HAVE_USB_CHARGING_ENABLE */
diff --git a/firmware/target/arm/ipod/powermgmt-ipod-pcf.c b/firmware/target/arm/ipod/powermgmt-ipod-pcf.c
deleted file mode 100644
index 44e908a..0000000
--- a/firmware/target/arm/ipod/powermgmt-ipod-pcf.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
- * Revisions copyright (C) 2005 by Gerald Van Baren
- *
- * 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 "adc.h"
-#include "powermgmt.h"
-#include "pcf5060x.h"
-#include "pcf50605.h"
-#include "audiohw.h"
-
-const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
-{
-#if   defined(IPOD_NANO)
-    3330
-#elif defined(IPOD_VIDEO)
-    3500
-#elif defined(IPOD_COLOR)
-    3300
-#elif defined(IPOD_3G)
-    3700
-#else
-    /* FIXME: calibrate value for other iPods */
-    3300
-#endif
-};
-
-const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
-{
-#if   defined(IPOD_NANO)
-    3230
-#elif defined(IPOD_VIDEO)
-    3300
-#elif defined(IPOD_COLOR)
-    3300
-#elif defined(IPOD_3G)
-    3500
-#else
-    /* FIXME: calibrate value for other iPods */
-    3000
-#endif
-};
-
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
-const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
-{
-#if   defined(IPOD_NANO)
-    /* measured values */
-    { 3230, 3620, 3700, 3730, 3750, 3780, 3830, 3890, 3950, 4030, 4160 },
-#elif defined(IPOD_VIDEO)
-    /* iPod Video 30GB Li-Ion 400mAh */
-    { 3600, 3720, 3750, 3780, 3810, 3840, 3880, 3950, 4020, 4100, 4180 },
-#elif defined(IPOD_COLOR)
-    /* iPod Photo 30GB, see FS#9072 */
-    { 3450, 3660, 3700, 3730, 3750, 3770, 3820, 3870, 3920, 4040, 4170 },
-#elif defined(IPOD_3G)
-    /* iPod 3G 40GB, first approach based upon measurements */
-    { 3720, 3740, 3760, 3780, 3830, 3870, 3910, 3970, 4020, 4060, 4090 },
-#else
-    /* FIXME: calibrate value for other iPods */
-    /* Table is "provisional" from IPOD_COLOR */
-    { 3450, 3660, 3700, 3730, 3750, 3770, 3820, 3870, 3920, 4040, 4170 }
-#endif
-};
-
-#if CONFIG_CHARGING
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
-const unsigned short percent_to_volt_charge[11] =
-{
-#if   defined(IPOD_NANO)
-    /* measured values */
-    3230, 3620, 3700, 3730, 3750, 3780, 3830, 3890, 3950, 4030, 4160
-#elif defined(IPOD_VIDEO)
-    /* iPOD Video 30GB Li-Ion 400mAh */
-    3600, 3720, 3750, 3780, 3810, 3840, 3880, 3950, 4020, 4100, 4180
-#elif defined(IPOD_COLOR)
-    /* iPod Photo 30GB, see FS#9072 */
-    3450, 3660, 3700, 3730, 3750, 3770, 3820, 3870, 3920, 4040, 4170
-#elif defined(IPOD_3G)
-    /* iPod 3G 40GB, first approach based upon measurements */
-    3720, 3740, 3760, 3780, 3830, 3870, 3910, 3970, 4020, 4060, 4090
-#else
-    /* FIXME: calibrate value for other iPods */
-    /* Table is "provisional" from IPOD_COLOR */
-    3450, 3660, 3700, 3730, 3750, 3770, 3820, 3870, 3920, 4040, 4170
-#endif
-};
-#endif /* CONFIG_CHARGING */
-
-#define BATTERY_SCALE_FACTOR 6000
-/* full-scale ADC readout (2^10) in millivolt */
-
-/* Returns battery voltage from ADC [millivolts] */
-unsigned int battery_adc_voltage(void)
-{
-    return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
-}
-
-#ifdef HAVE_ACCESSORY_SUPPLY
-void accessory_supply_set(bool enable)
-{
-    /* Set accessory power supply to 3.3V, otherwise switch it off. */
-    unsigned char value = enable ? 0xf8 : 0x18;
-    
-    /* Write to register. */
-    pcf50605_write(PCF5060X_D2REGC1, value);
-}
-#endif
-
-#ifdef HAVE_LINEOUT_POWEROFF
-void lineout_set(bool enable)
-{
-    /* Call audio hardware driver implementation */
-    audiohw_enable_lineout(enable);
-}
-#endif
diff --git a/firmware/target/arm/ipod/video/battery-video.c b/firmware/target/arm/ipod/video/battery-video.c
deleted file mode 100644
index b4c4602..0000000
--- a/firmware/target/arm/ipod/video/battery-video.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id $
- *
- * Default battery capacity for ipod video
- *
- * Copyright (c) 2011 Frank Gevaerts
- *
- * 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 "system.h"
-
-int battery_default_capacity(void)
-{
-    if(probed_ramsize==64)
-        return BATTERY_CAPACITY_DEFAULT_THICK;
-    else
-        return BATTERY_CAPACITY_DEFAULT_THIN;
-}
diff --git a/firmware/target/arm/ipod/video/lcd-as-video.S b/firmware/target/arm/ipod/video/lcd-as-video.S
deleted file mode 100644
index 47155b8..0000000
--- a/firmware/target/arm/ipod/video/lcd-as-video.S
+++ /dev/null
@@ -1,302 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2007 by Andree Buschmann
- *
- * 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"
-
-    .section .icode, "ax", %progbits
-
-/****************************************************************************
- * void lcd_write_data(const fb_data *addr, 
- *                     int pixelcount);
- * 
- * Writes pixelcount pixels from src-pointer (lcd_framebuffer) to BCM dataport.
- * Use the sequence 2:2:2:2 (2 = read/write 2 regs) for best performance.
- */
-    .align  2
-    .global lcd_write_data
-    .type   lcd_write_data, %function
-                                      /* r0 = addr, must be aligned */
-lcd_write_data:                       /* r1 = pixel count, must be even */
-    stmfd   sp!, {r4, lr}
-    mov     lr, #0x30000000           /* LCD data port */
-
-    subs    r1, r1, #16
-.loop16:
-    ldmgeia r0!, {r2-r3}
-    stmgeia lr,  {r2-r3}
-    ldmgeia r0!, {r2-r3}
-    stmgeia lr,  {r2-r3}
-    ldmgeia r0!, {r2-r3}
-    stmgeia lr,  {r2-r3}
-    ldmgeia r0!, {r2-r3}
-    stmgeia lr,  {r2-r3}
-    subges  r1, r1, #16
-    bge     .loop16
-
-    /* no need to correct the count, we're just checking bits from now */
-    tst     r1, #8
-    ldmneia r0!, {r2-r4, r12}
-    stmneia lr,  {r2-r4, r12}
-    tst     r1, #4
-    ldmneia r0!, {r2-r3}
-    stmneia lr,  {r2-r3}
-    tst     r1, #2
-    ldrne   r3, [r0], #4
-    strne   r3, [lr]
-
-    ldmpc   regs=r4
-
-/****************************************************************************
- * extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
- *                                    unsigned bcmaddr
- *                                    int width,
- *                                    int stride);
- *
- *   Conversion from Motion JPEG and MPEG Y'PbPr to RGB is:
- *   |R|   |1.164  0.000  1.596| |Y' -  16|
- *   |G| = |1.164 -0.391 -0.813| |Pb - 128|
- *   |B|   |1.164  2.018  0.000| |Pr - 128|
- *
- *   Scaled, normalized, rounded and tweaked to yield RGB 565:
- *   |R|   |74   0 101| |Y' -  16| >> 9
- *   |G| = |74 -24 -51| |Cb - 128| >> 8
- *   |B|   |74 128   0| |Cr - 128| >> 9
- *
- * Converts two lines from YUV to RGB565 and writes to BCM at once. First loop
- * loads Cb/Cr, calculates the chroma offset and saves them to buffer. Within
- * the second loop these chroma offset are reloaded from buffer.
- * Within each loop two pixels are calculated and written to BCM. Before each
- * loop the desired destination address is transmitted to BCM.
- */
-    .align      2
-    .global     lcd_write_yuv420_lines
-    .type       lcd_write_yuv420_lines, %function
-lcd_write_yuv420_lines:
-                                      /* r0 = src = yuv_src */
-                                      /* r1 = dst = bcmaddr */
-                                      /* r2 = width */
-                                      /* r3 = stride */                
-    stmfd       sp!, { r4-r10, lr }   /* save non-scratch */
-    ldmia       r0, { r9, r10, r12 }  /* r9 = yuv_src[0] = Y'_p */
-                                      /* r10 = yuv_src[1] = Cb_p */
-                                      /* r12 = yuv_src[2] = Cr_p */
-    add         r3, r9, r3            /* r3 = &ysrc[stride] */
-    add         r4, r2, r2, asr #1    /* chroma buffer lenght = width/2 *3 */
-    mov         r4, r4, asl #2        /*   use words for str/ldm possibility */
-    add         r4, r4, #19           /*   plus room for 4 additional words, */
-    bic         r4, r4, #3            /*   rounded up to multiples of 4 byte */
-    sub         sp, sp, r4            /*   and allocate on stack */
-    stmia       sp, {r1-r4}           /* bcmaddr, width, &ysrc[stride], stack_alloc */
-
-    mov         r7, r2                /* r7 = loop count */
-    add         r8, sp, #16           /* chroma buffer */
-    mov         lr, #0x30000000       /* LCD data port */
-    
-    /* The following writes dest address to BCM and waits for write ready */
-    orr         r2, lr, #0x00010000   /* r2 = BCM_WR_ADDR32 */
-    orr         r6, lr, #0x00030000   /* r6 = BCM_CONTROL */
-    str         r1, [r2]              /* BCM_WR_ADDR32 = bcmaddr */
-.busy_1:
-    ldrh        r1, [r6]              /* while (!(BCM_CONTROL & 0x2)) */
-    tst         r1, #0x2
-    beq         .busy_1      
-
-    /* 1st loop start */
-10:                                   /* loop start */
-
-    ldrb        r0, [r10], #1         /* r0 = *usrc++ = *Cb_p++ */
-    ldrb        r1, [r12], #1         /* r1 = *vsrc++ = *Cr_p++ */
-
-    sub         r0, r0, #128          /* r0 = Cb-128 */
-    sub         r1, r1, #128          /* r1 = Cr-128 */
-
-    add         r2, r1, r1, asl #1    /* r2 = Cr*51 + Cb*24 */
-    add         r2, r2, r2, asl #4   
-    add         r2, r2, r0, asl #3   
-    add         r2, r2, r0, asl #4   
-
-    add         r4, r1, r1, asl #2    /* r1 = Cr*101 */
-    add         r4, r4, r1, asl #5
-    add         r1, r4, r1, asl #6
-
-    add         r1, r1, #256          /* r1 = rv = (r1 + 256) >> 9 */
-    mov         r1, r1, asr #9
-    rsb         r2, r2, #128          /* r2 = guv = (-r2 + 128) >> 8 */
-    mov         r2, r2, asr #8       
-    add         r0, r0, #2            /* r0 = bu = (Cb*128 + 256) >> 9 */
-    mov         r0, r0, asr #2       
-    stmia       r8!, {r0-r2}          /* store r0, r1 and r2 to chroma buffer */
-    
-    /* 1st loop, first pixel */
-    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
-    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
-    add         r3, r5, r5, asl #2
-    add         r5, r3, r5, asl #5
-    
-    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
-    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
-    add         r4, r0, r5, asr #8    /* r4 = b = (Y >> 9) + bu */
- 
-    orr         r5, r6, r4            /* check if clamping is needed... */
-    orr         r5, r5, r3, asr #1    /* ...at all */
-    cmp         r5, #31                 
-    bls         15f                   /* -> no clamp */
-    cmp         r6, #31               /* clamp r */
-    mvnhi       r6, r6, asr #31         
-    andhi       r6, r6, #31             
-    cmp         r3, #63               /* clamp g */
-    mvnhi       r3, r3, asr #31
-    andhi       r3, r3, #63
-    cmp         r4, #31               /* clamp b */
-    mvnhi       r4, r4, asr #31         
-    andhi       r4, r4, #31          
-15:                                   /* no clamp */
-
-    /* calculate pixel_1 and save to r5 for later pixel packing */
-    orr         r4, r4, r3, lsl #5    /* pixel_1 = r<<11 | g<<5 | b */
-    orr         r5, r4, r6, lsl #11   /* r5 = pixel_1 */
-
-    /* 1st loop, second pixel */
-    ldrb        r4, [r9], #1          /* r4 = *ysrc++ = *Y'_p++ */
-    sub         r4, r4, #16           /* r4 = (Y'-16) * 74 */
-    add         r3, r4, r4, asl #2
-    add         r4, r3, r4, asl #5
-    
-    add         r6, r1, r4, asr #8    /* r6 = r = (Y >> 9) + rv */
-    add         r3, r2, r4, asr #7    /* r3 = g = (Y >> 8) + guv */
-    add         r4, r0, r4, asr #8    /* r4 = b = (Y >> 9) + bu */   
-    
-    orr         r0, r6, r4            /* check if clamping is needed... */
-    orr         r0, r0, r3, asr #1    /* ...at all */
-    cmp         r0, #31                 
-    bls         15f                   /* -> no clamp */
-    cmp         r6, #31               /* clamp r */
-    mvnhi       r6, r6, asr #31         
-    andhi       r6, r6, #31             
-    cmp         r3, #63               /* clamp g */
-    mvnhi       r3, r3, asr #31
-    andhi       r3, r3, #63
-    cmp         r4, #31               /* clamp b */
-    mvnhi       r4, r4, asr #31         
-    andhi       r4, r4, #31          
-15:                                   /* no clamp */
-
-    /* calculate pixel_2 and pack with pixel_1 before writing */
-    orr         r4, r4, r3, lsl #5    /* pixel_2 = r<<11 | g<<5 | b */
-    orr         r4, r4, r6, lsl #11   /* r4 = pixel_2 */
-    orr         r4, r5, r4, lsl #16   /* r4 = pixel_2<<16 | pixel_1 */
-    str         r4, [lr]              /* write packed pixels */
-  
-    subs        r7, r7, #2            /* check for loop end */
-    bgt         10b                   /* back to beginning  */
-    /* 1st loop end */
-    
-    /* Reload several registers for pointer rewinding for next loop */
-    add         r8, sp, #16           /* chroma buffer */
-    ldmia       sp, { r1, r7, r9}     /* r1  = bcmaddr */
-                                      /* r7  = loop count */
-                                      /* r9 = &ysrc[stride] */
-    
-    /* The following writes dest address to BCM and waits for write ready */
-    orr         r2, lr, #0x00010000   /* r2 = BCM_WR_ADDR32 */
-    orr         r6, lr, #0x00030000   /* r6 = BCM_CONTROL */
-    add         r1, r1, #640          /* dst += (LCD_WIDTH*2) */
-    str         r1, [r2]              /* BCM_WR_ADDR32 = dst */
-.busy_2:
-    ldrh        r1, [r6]              /* while (!(BCM_CONTROL & 0x2)) */
-    tst         r1, #0x2
-    beq         .busy_2      
-                                      
-
-    /* 2nd loop start */
-20:                                   /* loop start */
-    /* restore r0 (bu), r1 (rv) and r2 (guv) from chroma buffer */
-    ldmia       r8!, {r0-r2}
-  
-    /* 2nd loop, first pixel */
-    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
-    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
-    add         r3, r5, r5, asl #2
-    add         r5, r3, r5, asl #5
-    
-    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
-    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
-    add         r4, r0, r5, asr #8    /* r4 = b = (Y >> 9) + bu */
-   
-    orr         r5, r6, r4            /* check if clamping is needed... */
-    orr         r5, r5, r3, asr #1    /* ...at all */
-    cmp         r5, #31                 
-    bls         15f                   /* -> no clamp */
-    cmp         r6, #31               /* clamp r */
-    mvnhi       r6, r6, asr #31         
-    andhi       r6, r6, #31             
-    cmp         r3, #63               /* clamp g */
-    mvnhi       r3, r3, asr #31
-    andhi       r3, r3, #63
-    cmp         r4, #31               /* clamp b */
-    mvnhi       r4, r4, asr #31         
-    andhi       r4, r4, #31          
-15:                                   /* no clamp */
-    /* calculate pixel_1 and save to r5 for later pixel packing */
-    orr         r4, r4, r3, lsl #5    /* pixel_1 = r<<11 | g<<5 | b */
-    orr         r5, r4, r6, lsl #11   /* r5 = pixel_1 */
-    
-    /* 2nd loop, second pixel */
-    ldrb        r4, [r9], #1          /* r4 = *ysrc++ = *Y'_p++ */
-    sub         r4, r4, #16           /* r4 = (Y'-16) * 74 */
-    add         r3, r4, r4, asl #2
-    add         r4, r3, r4, asl #5
-    
-    add         r6, r1, r4, asr #8    /* r6 = r = (Y >> 9) + rv */
-    add         r3, r2, r4, asr #7    /* r3 = g = (Y >> 8) + guv */
-    add         r4, r0, r4, asr #8    /* r4 = b = (Y >> 9) + bu */
-  
-    orr         r0, r6, r4            /* check if clamping is needed... */
-    orr         r0, r0, r3, asr #1    /* ...at all */
-    cmp         r0, #31                 
-    bls         15f                   /* -> no clamp */
-    cmp         r6, #31               /* clamp r */
-    mvnhi       r6, r6, asr #31         
-    andhi       r6, r6, #31             
-    cmp         r3, #63               /* clamp g */
-    mvnhi       r3, r3, asr #31
-    andhi       r3, r3, #63
-    cmp         r4, #31               /* clamp b */
-    mvnhi       r4, r4, asr #31         
-    andhi       r4, r4, #31          
-15:                                   /* no clamp */
-   
-    /* calculate pixel_2 and pack with pixel_1 before writing */
-    orr         r4, r4, r3, lsl #5    /* pixel_2 = r<<11 | g<<5 | b */
-    orr         r4, r4, r6, lsl #11   /* r4 = pixel_2 */
-    orr         r4, r5, r4, lsl #16   /* r4 = pixel_2<<16 | pixel_1 */
-    str         r4, [lr]              /* write packed pixels */
-    
-    subs        r7, r7, #2            /* check for loop end */
-    bgt         20b                   /* back to beginning  */
-    /* 2nd loop end */
-
-    ldr         r3, [sp, #12]
-    add         sp, sp, r3            /* deallocate buffer */
-    ldmpc       regs=r4-r10           /* restore registers */
-
-    .ltorg
-    .size   lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
diff --git a/firmware/target/arm/ipod/video/lcd-video.c b/firmware/target/arm/ipod/video/lcd-video.c
deleted file mode 100644
index c499e9f..0000000
--- a/firmware/target/arm/ipod/video/lcd-video.c
+++ /dev/null
@@ -1,658 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * LCD driver for iPod Video
- *
- * Based on code from the ipodlinux project - http://ipodlinux.org/
- * Adapted for Rockbox in December 2005
- *
- * Original file: linux/arch/armnommu/mach-ipod/fb.c
- *
- * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
- *
- * 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 <sys/types.h> /* off_t */
-#include "config.h"
-#include "cpu.h"
-#include "lcd.h"
-#include "kernel.h"
-#include "system.h"
-#ifdef HAVE_LCD_SLEEP
-/* Included only for lcd_awake() prototype */
-#include "backlight-target.h"
-#endif
-
-/* The BCM bus width is 16 bits. But since the low address bits aren't decoded
- * by the chip (the 3 BCM address bits are mapped to address bits 16..18 of the
- * PP5022), writing 32 bits (and even more, using 'stmia') at once works. */
-#define BCM_DATA      (*(volatile unsigned short*)(0x30000000))
-#define BCM_DATA32    (*(volatile unsigned long *)(0x30000000))
-#define BCM_WR_ADDR   (*(volatile unsigned short*)(0x30010000))
-#define BCM_WR_ADDR32 (*(volatile unsigned long *)(0x30010000))
-#define BCM_RD_ADDR   (*(volatile unsigned short*)(0x30020000))
-#define BCM_RD_ADDR32 (*(volatile unsigned long *)(0x30020000))
-#define BCM_CONTROL   (*(volatile unsigned short*)(0x30030000))
-
-#define BCM_ALT_DATA      (*(volatile unsigned short*)(0x30040000))
-#define BCM_ALT_DATA32    (*(volatile unsigned long *)(0x30040000))
-#define BCM_ALT_WR_ADDR   (*(volatile unsigned short*)(0x30050000))
-#define BCM_ALT_WR_ADDR32 (*(volatile unsigned long *)(0x30050000))
-#define BCM_ALT_RD_ADDR   (*(volatile unsigned short*)(0x30060000))
-#define BCM_ALT_RD_ADDR32 (*(volatile unsigned long *)(0x30060000))
-#define BCM_ALT_CONTROL   (*(volatile unsigned short*)(0x30070000))
-
-/* Time until the BCM is considered stalled and will be re-kicked.
- * Must be guaranteed to be >~ 20ms. */
-#define BCM_UPDATE_TIMEOUT (HZ/20)
-/* An LCD update command done while the LCD is off needs >~ 200ms */
-#define BCM_LCDINIT_TIMEOUT (HZ/2)
-
-/* Addresses within BCM */
-#define BCMA_SRAM_BASE   0
-#define BCMA_COMMAND     0x1F8
-#define BCMA_STATUS      0x1FC
-#define BCMA_CMDPARAM    0xE0000    /* Parameters/data for commands */
-#define BCMA_SDRAM_BASE  0xC0000000
-#define BCMA_TV_FB       0xC0000000 /* TV out framebuffer */
-#define BCMA_TV_BMPDATA  0xC0200000 /* BMP data for TV out functions */
-
-/* BCM commands.  Write them to BCMA_COMMAND.  Note BCM_CMD encoding. */
-#define BCM_CMD(x) ((~((unsigned long)x) << 16) | ((unsigned long)x))
-#define BCMCMD_LCD_UPDATE     BCM_CMD(0)
-/* Execute "M25 Diagnostics".  Status displayed on LCD.  Takes <40s */
-#define BCMCMD_SELFTEST       BCM_CMD(1)
-#define BCMCMD_TV_PALBMP      BCM_CMD(2)
-#define BCMCMD_TV_NTSCBMP     BCM_CMD(3)
-/* BCM_CMD(4) may be another TV-related command */
-/* The following might do more depending on word at 0xE00000 */
-#define BCMCMD_LCD_UPDATERECT BCM_CMD(5)
-#define BCMCMD_LCD_SLEEP      BCM_CMD(8)
-/* BCM_CMD(12) involved in shutdown */
-/* Macrovision analog copy prevention is on by default on TV output.
-   Execute this command after enabling TV out to turn it off.
- */
-#define BCMCMD_TV_MVOFF       BCM_CMD(14)
-
-enum lcd_status
-{
-    LCD_IDLE,
-    LCD_INITIAL,
-    LCD_NEED_UPDATE,
-    LCD_UPDATING
-};
-
-struct
-{
-    long update_timeout;  /* also used to ensure BCM stays off for >= 50 ms */
-    enum lcd_status state;
-    bool blocked;
-#if NUM_CORES > 1
-    struct corelock cl;   /* inter-core sync */
-#endif
-#ifdef HAVE_LCD_SLEEP
-    bool display_on;
-    bool waking;
-    struct semaphore initwakeup;
-#endif
-} lcd_state IBSS_ATTR;
-
-#ifdef HAVE_LCD_SLEEP
-const fb_data *flash_vmcs_offset;
-unsigned flash_vmcs_length;
-
-#define ROM_BASE        0x20000000
-#define ROM_ID(a,b,c,d) (unsigned int)(  ((unsigned int)(d))        | \
-                                        (((unsigned int)(c)) << 8)  | \
-                                        (((unsigned int)(b)) << 16) | \
-                                        (((unsigned int)(a)) << 24) )
-
-/* Get address and length of iPod flash section.
-   Based on part of FS#6721.  This may belong elsewhere.
-   (BCM initialization uploads the vmcs section to the BCM.)
- */
-static bool flash_get_section(const unsigned int imageid,
-                              void **offset,
-                              unsigned int *length)
-{
-    unsigned long *p = (unsigned long*)(ROM_BASE + 0xffe00);
-    unsigned char *csp, *csend;
-    unsigned long checksum;
-
-    /* Find the image in the directory */
-    while (1)
-    {
-        if (p[0] != ROM_ID('f','l','s','h'))
-            return false;
-        if (p[1] == imageid)
-            break;
-        p += 10;
-    }
-
-    *offset = (void *)(ROM_BASE + p[3]);
-    *length = p[4];
-
-    /* Verify checksum.  Probably unnecessary, but it's fast. */
-    checksum = 0;
-    csend = (unsigned char *)(ROM_BASE + p[3] + p[4]);
-    for(csp = (unsigned char *)(ROM_BASE + p[3]); csp < csend; csp++)
-    {
-        checksum += *csp;
-    }
-
-    return checksum == p[7];
-}
-#endif /* HAVE_LCD_SLEEP */
-
-static inline void bcm_write_addr(unsigned address)
-{
-    BCM_WR_ADDR32 = address;       /* write destination address */
-
-    while (!(BCM_CONTROL & 0x2));  /* wait for it to be write ready */
-}
-
-static inline void bcm_write32(unsigned address, unsigned value)
-{
-
-    bcm_write_addr(address);       /* set destination address */
-
-    BCM_DATA32 = value;            /* write value */
-}
-
-static inline unsigned bcm_read32(unsigned address)
-{
-    while (!(BCM_RD_ADDR & 1));
-
-    BCM_RD_ADDR32 = address;       /* write source address */
-
-    while (!(BCM_CONTROL & 0x10)); /* wait for it to be read ready */
-
-    return BCM_DATA32;             /* read value */
-}
-
-#ifdef HAVE_LCD_SLEEP
-static void continue_lcd_awake(void)
-{
-    lcd_state.waking = false;
-    semaphore_release(&(lcd_state.initwakeup));
-}
-#endif
-
-#ifndef BOOTLOADER
-static void lcd_tick(void)
-{
-    /* No core level interrupt mask - already in interrupt context */
-#if NUM_CORES > 1
-    corelock_lock(&lcd_state.cl);
-#endif
-
-    if (!lcd_state.blocked && lcd_state.state >= LCD_NEED_UPDATE)
-    {
-        unsigned data = bcm_read32(BCMA_COMMAND);
-        bool bcm_is_busy = (data == BCMCMD_LCD_UPDATE || data == 0xFFFF);
-
-        if (((lcd_state.state == LCD_NEED_UPDATE) && !bcm_is_busy)
-            /* Update requested and BCM is no longer busy. */
-         || (TIME_AFTER(current_tick, lcd_state.update_timeout) && bcm_is_busy))
-            /* BCM still busy after timeout, i.e. stalled. */
-        {
-            bcm_write32(BCMA_COMMAND, BCMCMD_LCD_UPDATE);  /* Kick off update */
-            BCM_CONTROL = 0x31;
-            lcd_state.update_timeout = current_tick + BCM_UPDATE_TIMEOUT;
-            lcd_state.state = LCD_UPDATING;
-#ifdef HAVE_LCD_SLEEP
-            if (lcd_state.waking)
-                continue_lcd_awake();
-#endif
-        }
-        else if ((lcd_state.state == LCD_UPDATING) && !bcm_is_busy)
-        {
-            /* Update finished properly and no new update pending. */
-            lcd_state.state = LCD_IDLE;
-#ifdef HAVE_LCD_SLEEP
-            if (lcd_state.waking)
-                continue_lcd_awake();
-#endif
-        }
-    }
-#if NUM_CORES > 1
-    corelock_unlock(&lcd_state.cl);
-#endif
-}
-
-static inline void lcd_block_tick(void)
-{
-    int oldlevel = disable_irq_save();
-
-#if NUM_CORES > 1
-    corelock_lock(&lcd_state.cl);
-    lcd_state.blocked = true;
-    corelock_unlock(&lcd_state.cl);
-#else
-    lcd_state.blocked = true;
-#endif
-    restore_irq(oldlevel);
-}
-
-static void lcd_unblock_and_update(void)
-{
-    unsigned data;
-    bool bcm_is_busy;
-    int oldlevel = disable_irq_save();
-
-#if NUM_CORES > 1
-    corelock_lock(&lcd_state.cl);
-#endif
-    data = bcm_read32(BCMA_COMMAND);
-    bcm_is_busy = (data == BCMCMD_LCD_UPDATE || data == 0xFFFF);
-
-    if (!bcm_is_busy || (lcd_state.state == LCD_INITIAL) ||
-        TIME_AFTER(current_tick, lcd_state.update_timeout))
-    {
-        bcm_write32(BCMA_COMMAND, BCMCMD_LCD_UPDATE);  /* Kick off update */
-        BCM_CONTROL = 0x31;
-        lcd_state.update_timeout = current_tick + BCM_UPDATE_TIMEOUT;
-        lcd_state.state = LCD_UPDATING;
-#ifdef HAVE_LCD_SLEEP
-        if (lcd_state.waking)
-            continue_lcd_awake();
-#endif
-    }
-    else
-    {
-         lcd_state.state = LCD_NEED_UPDATE; /* Post update request */
-    }
-    lcd_state.blocked = false;
-
-#if NUM_CORES > 1
-    corelock_unlock(&lcd_state.cl);
-#endif
-    restore_irq(oldlevel);
-}
-
-#else /* BOOTLOADER */
-
-#define lcd_block_tick()
-
-static void lcd_unblock_and_update(void)
-{
-    unsigned data;
-
-    if (lcd_state.state != LCD_INITIAL)
-    {
-        data = bcm_read32(BCMA_COMMAND);
-        while (data == BCMCMD_LCD_UPDATE || data == 0xFFFF)
-        {
-            yield();
-            data = bcm_read32(BCMA_COMMAND);
-        }
-    }
-    bcm_write32(BCMA_COMMAND, BCMCMD_LCD_UPDATE);  /* Kick off update */
-    BCM_CONTROL = 0x31;
-    lcd_state.state = LCD_IDLE;
-}
-#endif /* BOOTLOADER */
-
-/*** hardware configuration ***/
-
-void lcd_set_contrast(int val)
-{
-  /* TODO: Implement lcd_set_contrast() */
-  (void)val;
-}
-
-void lcd_set_invert_display(bool yesno)
-{
-  /* TODO: Implement lcd_set_invert_display() */
-  (void)yesno;
-}
-
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
-  /* TODO: Implement lcd_set_flip() */
-  (void)yesno;
-}
-
-/* LCD init */
-void lcd_init_device(void)
-{
-    /* These port initializations are supposed to be done when initializing
-       the BCM.  None of it is changed when shutting down the BCM.
-     */
-    GPO32_ENABLE |= 0xC000;
-    GPIO_CLEAR_BITWISE(GPIOC_ENABLE, 0x80);
-    /* This pin is used for BCM interrupts */
-    GPIOC_ENABLE |= 0x40;
-    GPIOC_OUTPUT_EN &= ~0x40;
-    GPO32_ENABLE &= ~1;
-
-    lcd_state.blocked = false;
-    lcd_state.state = LCD_INITIAL;
-#ifndef BOOTLOADER
-#if NUM_CORES > 1
-    corelock_init(&lcd_state.cl);
-#endif
-#ifdef HAVE_LCD_SLEEP
-    if (!flash_get_section(ROM_ID('v', 'm', 'c', 's'),
-                           (void **)(&flash_vmcs_offset), &flash_vmcs_length))
-        /* BCM cannot be shut down because firmware wasn't found */
-        flash_vmcs_length = 0;
-    else
-    {
-        /* lcd_write_data needs an even number of 16 bit values */
-        flash_vmcs_length = ((flash_vmcs_length + 3) >> 1) & ~1;
-    }
-    semaphore_init(&(lcd_state.initwakeup), 1, 0);
-    lcd_state.waking = false;
-
-    if (GPO32_VAL & 0x4000)
-    {
-        /* BCM is powered.  Assume it is initialized. */
-        lcd_state.display_on = true;
-        tick_add_task(&lcd_tick);
-    }
-    else
-    {
-        /* BCM is not powered, so it needs to be initialized.
-           This can only happen when loading Rockbox via ROLO.
-         */
-        lcd_state.update_timeout = current_tick;
-        lcd_state.display_on = false;
-        lcd_awake();
-    }
-#else /* !HAVE_LCD_SLEEP */
-    tick_add_task(&lcd_tick);
-#endif
-#endif /* !BOOTLOADER */
-}
-
-/*** update functions ***/
-
-/* Update a fraction of the display. */
-void lcd_update_rect(int x, int y, int width, int height)
-{
-    const fb_data *addr;
-    unsigned bcmaddr;
-
-#ifdef HAVE_LCD_SLEEP
-    if (!lcd_state.display_on)
-        return;
-#endif
-
-    if (x + width >= LCD_WIDTH)
-        width = LCD_WIDTH - x;
-    if (y + height >= LCD_HEIGHT)
-        height = LCD_HEIGHT - y;
-
-    if ((width <= 0) || (height <= 0))
-        return; /* Nothing left to do. */
-
-    /* Ensure x and width are both even. The BCM doesn't like small unaligned
-     * writes and would just ignore them. */
-    width = (width + (x & 1) + 1) & ~1;
-    x &= ~1;
-
-    /* Prevent the tick from triggering BCM updates while we're writing. */
-    lcd_block_tick();
-
-    addr = &lcd_framebuffer[y][x];
-    bcmaddr = BCMA_CMDPARAM + (LCD_WIDTH*2) * y + (x << 1);
-
-    if (width == LCD_WIDTH)
-    {
-        bcm_write_addr(bcmaddr);
-        lcd_write_data(addr, width * height);
-    }
-    else
-    {
-        do
-        {
-            bcm_write_addr(bcmaddr);
-            bcmaddr += (LCD_WIDTH*2);
-            lcd_write_data(addr, width);
-            addr += LCD_WIDTH;
-        }
-        while (--height > 0);
-    }
-    lcd_unblock_and_update();
-}
-
-/* Update the display.
-   This must be called after all other LCD functions that change the display. */
-void lcd_update(void)
-{
-    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
-}
-
-/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
-extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
-                                   unsigned bcmaddr,
-                                   int width,
-                                   int stride);
-
-/* Performance function to blit a YUV bitmap directly to the LCD */
-void lcd_blit_yuv(unsigned char * const src[3],
-                  int src_x, int src_y, int stride,
-                  int x, int y, int width, int height)
-{
-    unsigned bcmaddr;
-    off_t z;
-    unsigned char const * yuv_src[3];
-
-#ifdef HAVE_LCD_SLEEP
-    if (!lcd_state.display_on)
-        return;
-#endif
-
-    /* Sorry, but width and height must be >= 2 or else */
-    width &= ~1;
-
-    z = stride * src_y;
-    yuv_src[0] = src[0] + z + src_x;
-    yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
-    yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
-
-    /* Prevent the tick from triggering BCM updates while we're writing. */
-    lcd_block_tick();
-
-    bcmaddr = BCMA_CMDPARAM + (LCD_WIDTH*2) * y + (x << 1);
-    height >>= 1;
-
-    do
-    {
-        lcd_write_yuv420_lines(yuv_src, bcmaddr, width, stride);
-        bcmaddr += (LCD_WIDTH*4);  /* Skip up two lines */
-        yuv_src[0] += stride << 1;
-        yuv_src[1] += stride >> 1; /* Skip down one chroma line */
-        yuv_src[2] += stride >> 1;
-    }
-    while (--height > 0);
-
-    lcd_unblock_and_update();
-}
-
-#ifdef HAVE_LCD_SLEEP
-/* Executes a BCM command immediately and waits for it to complete.
-   Other BCM commands (eg. LCD updates or lcd_tick) must not interfere.
- */
-static void bcm_command(unsigned cmd)
-{
-    unsigned status;
-
-    bcm_write32(BCMA_COMMAND,  cmd);
-
-    BCM_CONTROL = 0x31;
-
-    while (1)
-    {
-        status = bcm_read32(BCMA_COMMAND);
-        if (status != cmd && status != 0xFFFF)
-            break;
-        yield();
-    }
-}
-
-static void bcm_powerdown(void)
-{
-    /* Immediately switch off the backlight to avoid flashing. */
-    _backlight_hw_enable(false);
-    
-    /* Not sure what this does. */
-    bcm_write32(0x10001400, bcm_read32(0x10001400) & ~0xF0);
-
-    /* Blanks the LCD and decreases power consumption
-       below what clearing the LCD would achieve.
-       Executing an LCD update command wakes it.
-     */
-    bcm_command(BCMCMD_LCD_SLEEP);
-
-    /* Not sure if this does anything */
-    bcm_command(BCM_CMD(0xC));
-
-    /* Further cuts power use, probably by powering down BCM.
-       After this point, BCM needs to be bootstrapped
-     */
-    GPO32_VAL &= ~0x4000;
-}
-
-/* Data written to BCM_CONTROL and BCM_ALT_CONTROL */
-const unsigned char bcm_bootstrapdata[] =
-{
-    0xA1, 0x81, 0x91, 0x02, 0x12, 0x22, 0x72, 0x62
-};
-
-static void bcm_init(void)
-{
-    int i;
-
-    /* Power up BCM */
-    GPO32_VAL |= 0x4000;
-    sleep(HZ/20);
-
-    /* Bootstrap stage 1 */
-
-    STRAP_OPT_A &= ~0xF00;
-    outl(0x1313, 0x70000040);
-
-    /* Interrupt-related code for future use
-       GPIOC_INT_LEV |= 0x40;
-       GPIOC_INT_EN |= 0x40;
-       CPU_HI_INT_EN |= 0x40000;
-    */
-
-    /* Bootstrap stage 2 */
-
-    while (BCM_ALT_CONTROL & 0x80);
-    while (!(BCM_ALT_CONTROL & 0x40));
-
-    for (i = 0; i < 8; i++)
-    {
-        BCM_CONTROL = bcm_bootstrapdata[i];
-    }
-
-    for (i = 3; i < 8; i++)
-    {
-        BCM_ALT_CONTROL = bcm_bootstrapdata[i];
-    }
-
-    while ((BCM_RD_ADDR & 1) == 0 || (BCM_ALT_RD_ADDR & 1) == 0);
-
-    (void)BCM_WR_ADDR;
-    (void)BCM_ALT_WR_ADDR;
-
-    /* Bootstrap stage 3: upload firmware */
-
-    while (BCM_ALT_CONTROL & 0x80);
-    while (!(BCM_ALT_CONTROL & 0x40));
-
-    /* Upload firmware to BCM SRAM */
-    bcm_write_addr(BCMA_SRAM_BASE);
-    lcd_write_data(flash_vmcs_offset, flash_vmcs_length);
-
-    bcm_write32(BCMA_COMMAND,  0);
-    bcm_write32(0x10000C00, 0xC0000000);
-
-    while (!(bcm_read32(0x10000C00) & 1));
-
-    bcm_write32(0x10000C00, 0);
-    bcm_write32(0x10000400, 0xA5A50002);
-
-    while (bcm_read32(BCMA_COMMAND) == 0)
-        yield();
-
-    /* sleep(HZ/2) apparently unneeded */
-}
-
-void lcd_awake(void)
-{
-    if (!lcd_state.display_on && flash_vmcs_length != 0)
-    {
-        /* Ensure BCM has been off for >= 50 ms */
-        long sleepwait = lcd_state.update_timeout + HZ/20 - current_tick;
-        if (sleepwait > 0 && sleepwait < HZ/20)
-            sleep(sleepwait);
-
-        bcm_init();
-
-        /* Start the first LCD update, which also initializes the LCD */
-        lcd_state.state = LCD_INITIAL;
-        lcd_state.display_on = true;
-        lcd_update();
-        lcd_state.update_timeout = current_tick + BCM_LCDINIT_TIMEOUT;
-
-        /* Wait for end of first LCD update, so LCD isn't white
-           when the backlight turns on.
-         */
-        lcd_state.waking = true;
-        tick_add_task(&lcd_tick);
-        semaphore_wait(&(lcd_state.initwakeup), TIMEOUT_BLOCK);
-
-        send_event(LCD_EVENT_ACTIVATION, NULL);
-    }
-}
-
-void lcd_sleep(void)
-{
-    if (lcd_state.display_on && flash_vmcs_length != 0)
-    {
-        lcd_state.display_on = false;
-
-        /* Wait for BCM to finish work */
-        while (lcd_state.state != LCD_INITIAL && lcd_state.state != LCD_IDLE)
-            yield();
-
-        tick_remove_task(&lcd_tick);
-        bcm_powerdown();
-
-        /* Remember time to ensure BCM stays off for >= 50 ms */
-        lcd_state.update_timeout = current_tick;
-    }
-}
-
-bool lcd_active(void)
-{
-    return lcd_state.display_on;
-}
-
-#ifdef HAVE_LCD_SHUTDOWN
-void lcd_shutdown(void)
-{
-    lcd_sleep();
-}
-#endif /* HAVE_LCD_SHUTDOWN */
-#endif /* HAVE_LCD_SLEEP */
diff --git a/firmware/target/arm/iriver/app.lds b/firmware/target/arm/iriver/app.lds
deleted file mode 100644
index de355c3..0000000
--- a/firmware/target/arm/iriver/app.lds
+++ /dev/null
@@ -1,204 +0,0 @@
-#include "config.h"
-
-ENTRY(start)
-
-OUTPUT_FORMAT(elf32-littlearm)
-OUTPUT_ARCH(arm)
-STARTUP(target/arm/crt0-pp.o)
-
-#define PLUGINSIZE PLUGIN_BUFFER_SIZE
-#define CODECSIZE CODEC_SIZE
-
-#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - CODECSIZE
-
-#define DRAMORIG 0x00000000
-#define IRAMORIG 0x40000000
-#define IRAMSIZE 0xc000
-
-#ifdef CPU_PP502x
-#define NOCACHE_BASE 	0x10000000
-#else
-#define NOCACHE_BASE 	0x28000000
-#endif
-
-#define CACHEALIGN_SIZE 16
-
-/* End of the audio buffer, where the codec buffer starts */
-#define ENDAUDIOADDR  (DRAMORIG + DRAMSIZE)
-
-/* Where the codec buffer ends, and the plugin buffer starts */
-#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
-
-MEMORY
-{
-    DRAM : ORIGIN = DRAMORIG,     LENGTH = DRAMSIZE
-    IRAM : ORIGIN = IRAMORIG,     LENGTH = IRAMSIZE
-}
-
-SECTIONS
-{
-    .text :
-    {
-        loadaddress = .;
-        _loadaddress = .;
-        . = ALIGN(0x200);
-        *(.init.text)
-        *(.text*)
-        *(.glue_7)
-        *(.glue_7t)
-        . = ALIGN(0x4);
-    } > DRAM
-
-    .rodata :
-    {
-        *(.rodata)  /* problems without this, dunno why */
-        *(.rodata*)
-        *(.rodata.str1.1)
-        *(.rodata.str1.4)
-        . = ALIGN(0x4);
-
-        /* Pseudo-allocate the copies of the data sections */
-        _datacopy = .;
-    } > DRAM
-
-    /* TRICK ALERT! For RAM execution, we put the .data section at the
-       same load address as the copy. Thus, we don't waste extra RAM
-       when we don't actually need the copy.  */
-    .data : AT ( _datacopy )
-    {
-        _datastart = .;
-        *(.data*)
-        . = ALIGN(0x4);
-        _dataend  = .;
-    } > DRAM
-
-#if NOCACHE_BASE != 0
-    /* .ncdata section is placed at uncached physical alias address and is
-     * loaded at the proper cached virtual address - no copying is
-     * performed in the init code */
-    .ncdata . + NOCACHE_BASE :
-    {
-        . = ALIGN(CACHEALIGN_SIZE);
-        *(.ncdata*)
-        . = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-#endif
-    
-    /DISCARD/ :
-    {
-        *(.eh_frame)
-    }
-
-    .vectors 0x0 :
-    {
-        _vectorsstart = .;
-        *(.vectors);
-        _vectorsend = .;
-    } AT> DRAM
-
-    _vectorscopy = LOADADDR(.vectors);
-    _noloaddram  = LOADADDR(.vectors);
-
-    .ibss IRAMORIG (NOLOAD) :
-    {
-        _iedata = .;
-        *(.qharray)
-        *(.ibss)
-        . = ALIGN(0x4);
-        _iend = .;
-    } > IRAM
-
-    .iram _iend :
-    {
-        _iramstart = .;
-        *(.icode)
-        *(.irodata)
-        *(.idata)
-        . = ALIGN(0x4);
-        _iramend = .;
-    } > IRAM AT> DRAM
-
-    _iramcopy = LOADADDR(.iram);
-
-
-    .init ENDAUDIOADDR : 
-    {
-        . = ALIGN(4);
-        _initstart = .;
-        *(.init)
-        _initend = .;
-    } AT> DRAM
-
-    _initcopy = LOADADDR(.init);
-
-    .idle_stacks (NOLOAD) :
-    {
-       *(.idle_stacks)
-#if NUM_CORES > 1
-       cpu_idlestackbegin = .;
-       . += IDLE_STACK_SIZE;
-       cpu_idlestackend = .;
-#endif
-       cop_idlestackbegin = .;
-       . += IDLE_STACK_SIZE;
-       cop_idlestackend = .;
-    } > IRAM
-
-    .stack (NOLOAD) :
-    {
-       *(.stack)
-       stackbegin = .;
-       . += 0x2000;
-       stackend = .;
-    } > IRAM
-    
-    /* .bss and .ncbss are treated as a single section to use one init loop to
-     * zero it - note "_edata" and "_end" */
-    .bss _noloaddram (NOLOAD) :
-    {
-       _edata = .;
-        *(.bss*)
-        *(COMMON)
-        . = ALIGN(0x4);
-    } > DRAM
-
-#if NOCACHE_BASE != 0
-    .ncbss . + NOCACHE_BASE (NOLOAD):
-    {
-    	. = ALIGN(CACHEALIGN_SIZE);
-        *(.ncbss*)
-    	. = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-#endif
-
-    /* This will be aligned by preceding alignments */
-    .endaddr . - NOCACHE_BASE (NOLOAD) :
-    {
-        _end = .;
-    } > DRAM
-
-    .audiobuf (NOLOAD) :
-    {
-        _audiobuffer = .;
-        . = ALIGN(0x4);
-        audiobuffer = .;
-    } > DRAM
-    
-    .audiobufend ENDAUDIOADDR (NOLOAD) :
-    {
-        audiobufend = .;
-        _audiobufend = .;
-    } > DRAM
-
-    .codec ENDAUDIOADDR (NOLOAD) :
-    {
-        codecbuf = .;
-        _codecbuf = .;
-    }
-
-    .plugin ENDADDR (NOLOAD) :
-    {
-        _pluginbuf = .;
-        pluginbuf = .;
-    }
-}
diff --git a/firmware/target/arm/iriver/backlight-target.h b/firmware/target/arm/iriver/backlight-target.h
deleted file mode 100644
index a27b489..0000000
--- a/firmware/target/arm/iriver/backlight-target.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 BACKLIGHT_TARGET_H
-#define BACKLIGHT_TARGET_H
-
-#define _backlight_init() true
-void _backlight_on(void);
-void _backlight_off(void);
-
-#endif
diff --git a/firmware/target/arm/iriver/boot.lds b/firmware/target/arm/iriver/boot.lds
deleted file mode 100644
index ed4fc35..0000000
--- a/firmware/target/arm/iriver/boot.lds
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "config.h"
-#include "../boot-pp502x-bl-usb.lds"
diff --git a/firmware/target/arm/iriver/h10/adc-target.h b/firmware/target/arm/iriver/h10/adc-target.h
deleted file mode 100644
index ba3e98d..0000000
--- a/firmware/target/arm/iriver/h10/adc-target.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 _ADC_TARGET_H_
-#define _ADC_TARGET_H_
-
-#define NUM_ADC_CHANNELS 4
-
-#define ADC_BATTERY     0
-#define ADC_UNKNOWN_1   1
-#define ADC_REMOTE      2
-#define ADC_SCROLLPAD   3
-#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
-
-/* Force a scan now */
-unsigned short adc_scan(int channel);
-
-#endif
diff --git a/firmware/target/arm/iriver/h10/backlight-h10.c b/firmware/target/arm/iriver/h10/backlight-h10.c
deleted file mode 100644
index db10f39..0000000
--- a/firmware/target/arm/iriver/h10/backlight-h10.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 "system.h"
-#include "backlight.h"
-#include "backlight-target.h"
-#include "lcd.h"
-
-void _backlight_on(void)
-{
-#ifdef HAVE_LCD_ENABLE
-    lcd_enable(true); /* power on lcd + visible display */
-#endif
-    GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 0x20);
-}
-
-void _backlight_off(void)
-{
-    GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_VAL, 0x20);
-#ifdef HAVE_LCD_ENABLE
-    lcd_enable(false); /* power off visible display */
-#endif
-}
diff --git a/firmware/target/arm/iriver/h10/button-h10.c b/firmware/target/arm/iriver/h10/button-h10.c
deleted file mode 100644
index 6710f39..0000000
--- a/firmware/target/arm/iriver/h10/button-h10.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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.
- *
- ****************************************************************************/
-
-/* Custom written for the H10 based on analysis of the GPIO data */
-
-
-#include <stdlib.h>
-#include "config.h"
-#include "cpu.h"
-#include "system.h"
-#include "button.h"
-#include "kernel.h"
-#include "backlight.h"
-#include "adc.h"
-
-
-void button_init_device(void)
-{
-    /* Enable REW, FF, Play, Left, Right, Hold buttons */
-    GPIO_SET_BITWISE(GPIOA_ENABLE, 0xfc);
-    
-    /* Enable POWER button */
-    GPIO_SET_BITWISE(GPIOB_ENABLE, 0x01);
-    
-    /* We need to output to pin 6 of GPIOD when reading the scroll pad value */
-    GPIO_SET_BITWISE(GPIOD_ENABLE, 0x40);
-    GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x40);
-    GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x40);
-}
-
-bool button_hold(void)
-{
-    return (GPIOA_INPUT_VAL & 0x4)?false:true;
-}
-
-bool remote_button_hold(void)
-{
-    return adc_scan(ADC_REMOTE) < 0x2B;
-}
-
-/*
- * Get button pressed from hardware
- */
-int button_read_device(void)
-{
-    int btn = BUTTON_NONE;
-    int data;
-    unsigned char state;
-    static bool hold_button = false;
-    static bool remote_hold_button = false;
-    bool hold_button_old;
-    bool remote_hold_button_old;
-
-    /* Hold */
-    hold_button_old = hold_button;
-    hold_button = button_hold();
-
-#ifndef BOOTLOADER
-    /* light handling */
-    if (hold_button != hold_button_old)
-    {
-        backlight_hold_changed(hold_button);
-    }
-#endif
-
-    /* device buttons */
-    if (!hold_button)
-    {
-        /* Read normal buttons */
-        state = GPIOA_INPUT_VAL & 0xf8;
-        if ((state & 0x8) == 0) btn |= BUTTON_FF;
-        if ((state & 0x10) == 0) btn |= BUTTON_PLAY;
-        if ((state & 0x20) == 0) btn |= BUTTON_REW;
-        if ((state & 0x40) == 0) btn |= BUTTON_RIGHT;
-        if ((state & 0x80) == 0) btn |= BUTTON_LEFT;
-        
-        /* Read power button */
-        if (GPIOB_INPUT_VAL & 0x1) btn |= BUTTON_POWER;
-        
-        /* Read scroller */
-        if ( GPIOD_INPUT_VAL & 0x20 )
-        {
-            GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x40);
-            udelay(250);
-            data = adc_scan(ADC_SCROLLPAD);
-            GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x40);
-            
-            if(data < 0x224)
-            {
-                btn |= BUTTON_SCROLL_DOWN;
-            } else {
-                btn |= BUTTON_SCROLL_UP;
-            }
-        }
-    }
-    
-    /* remote buttons */
-    remote_hold_button_old = remote_hold_button;
-
-    data = adc_scan(ADC_REMOTE);
-    remote_hold_button = data < 0x2B;
-
-#ifndef BOOTLOADER
-    if (remote_hold_button != remote_hold_button_old)
-        backlight_hold_changed(remote_hold_button);
-#endif
-
-    if(!remote_hold_button)
-    {
-        if (data < 0x3FF)
-        {
-            if(data < 0x204)
-                if(data < 0x155)
-                    btn |= BUTTON_RC_FF;
-                else
-                    btn |= BUTTON_RC_REW;
-            else
-                if(data < 0x2D0)
-                   btn |= BUTTON_RC_VOL_DOWN;
-                else
-                    btn |= BUTTON_RC_VOL_UP;
-        }
-    }
-
-    /* remote play button should be dead if hold */
-    if (!remote_hold_button && !(GPIOA_INPUT_VAL & 0x1))
-        btn |= BUTTON_RC_PLAY;
-    
-    return btn;
-}
diff --git a/firmware/target/arm/iriver/h10/button-target.h b/firmware/target/arm/iriver/h10/button-target.h
deleted file mode 100644
index c2d7165..0000000
--- a/firmware/target/arm/iriver/h10/button-target.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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.
- *
- ****************************************************************************/
-
-/* Custom written for the H10 */
-
-#ifndef _BUTTON_TARGET_H_
-#define _BUTTON_TARGET_H_
-
-#include <stdbool.h>
-#include "config.h"
-
-#define HAS_BUTTON_HOLD
-#define HAS_REMOTE_BUTTON_HOLD
-
-bool button_hold(void);
-bool remote_button_hold(void);
-void button_init_device(void);
-int button_read_device(void);
-
-/* iriver H10 specific button codes */
-
-    /* Main unit's buttons */
-#define BUTTON_POWER        0x00000001
-
-#define BUTTON_LEFT         0x00000002
-#define BUTTON_RIGHT        0x00000004
-
-#define BUTTON_REW          0x00000008
-#define BUTTON_PLAY         0x00000010
-#define BUTTON_FF           0x00000020
-
-#define BUTTON_SCROLL_UP    0x00000040
-#define BUTTON_SCROLL_DOWN  0x00000080
-
-#define BUTTON_MAIN (BUTTON_POWER|BUTTON_LEFT|BUTTON_RIGHT|BUTTON_REW\
-                |BUTTON_PLAY|BUTTON_FF|BUTTON_SCROLL_UP|BUTTON_SCROLL_DOWN)
-
-    /* Remote control's buttons */
-#define BUTTON_RC_REW       0x00080000
-#define BUTTON_RC_PLAY      0x00100000
-#define BUTTON_RC_FF        0x00200000
-#define BUTTON_RC_VOL_UP    0x00400000
-#define BUTTON_RC_VOL_DOWN  0x00800000
-
-#define BUTTON_REMOTE (BUTTON_RC_PLAY|BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN\
-                |BUTTON_RC_REW|BUTTON_RC_FF)
-
-#define POWEROFF_BUTTON     BUTTON_POWER
-#define RC_POWEROFF_BUTTON  BUTTON_RC_PLAY
-#define POWEROFF_COUNT 10
-
-#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/iriver/h10/fmradio_i2c-h10.c b/firmware/target/arm/iriver/h10/fmradio_i2c-h10.c
deleted file mode 100644
index bee1c6e..0000000
--- a/firmware/target/arm/iriver/h10/fmradio_i2c-h10.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- * Physical interface of the Philips TEA5767 in iriver H10 series
- *
- * Copyright (C) 2002 by Linus Nielsen Feltzing
- *
- * 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 "logf.h"
-#include "system.h"
-#include "fmradio_i2c.h"
-
-/* cute little functions, atomic read-modify-write */
-
-#define SDA_OUTINIT GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x08)
-#define SDA_HI_IN   GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x08)
-#define SDA_LO_OUT  GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x08)
-#define SDA         (GPIOD_INPUT_VAL & 0x08)
-
-#define SCL_INPUT   GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x10)
-#define SCL_OUTPUT  GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x10)
-#define SCL_LO      GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x10)
-#define SCL_HI      GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL,0x10)
-#define SCL         (GPIOD_INPUT_VAL & 0x10)
-
-#define DELAY   udelay(2)
-
-static void fmradio_i2c_start(void)
-{
-    SCL_HI;
-    SCL_OUTPUT;
-    SDA_HI_IN;
-    SDA_OUTINIT;
-    DELAY;
-    SDA_LO_OUT;
-    DELAY;
-    SCL_LO;
-}
-
-static void fmradio_i2c_stop(void)
-{
-   SDA_LO_OUT;
-   DELAY;
-   SCL_HI;
-   DELAY;
-   SDA_HI_IN;
-}
-
-/* Generate ACK or NACK */
-static void fmradio_i2c_ack(bool nack)
-{
-    /* Here's the deal. The slave is slow, and sometimes needs to wait
-       before it can receive the acknowledge. Therefore it forces the clock
-       low until it is ready. We need to poll the clock line until it goes
-       high before we release the ack.
-
-       In their infinite wisdom, iriver didn't pull up the SCL line, so
-       we have to drive the SCL high repeatedly to simulate a pullup. */
-    
-    if (nack)
-        SDA_HI_IN;
-    else
-        SDA_LO_OUT;
-    DELAY;
-
-    SCL_HI;
-    do
-    {
-        SCL_OUTPUT;  /* Set the clock to output */
-        SCL_INPUT;   /* Set the clock to input */
-        DELAY;
-    }
-    while(!SCL);  /* and wait for the slave to release it */
-
-    SCL_OUTPUT;
-    SCL_LO;
-}
-
-static int fmradio_i2c_getack(void)
-{
-    int ret = 1;
-
-    /* Here's the deal. The slave is slow, and sometimes needs to wait
-       before it can send the acknowledge. Therefore it forces the clock
-       low until it is ready. We need to poll the clock line until it goes
-       high before we read the ack.
-
-       In their infinite wisdom, iriver didn't pull up the SCL line, so
-       we have to drive the SCL high repeatedly to simulate a pullup. */
-
-    SDA_HI_IN;
-    DELAY;
-
-    SCL_HI;          /* set clock to high */
-    do
-    {
-        SCL_OUTPUT;  /* Set the clock to output */
-        SCL_INPUT;   /* Set the clock to input */
-        DELAY;
-    }
-    while(!SCL);     /* and wait for the slave to release it */
-
-    if (SDA)
-        ret = 0;    /* ack failed */
-    
-    SCL_OUTPUT;
-    SCL_LO;
-
-    return ret;
-}
-
-static void fmradio_i2c_outb(unsigned char byte)
-{
-   int i;
-
-   /* clock out each bit, MSB first */
-   for ( i=0x80; i; i>>=1 ) {
-      if ( i & byte )
-         SDA_HI_IN;
-      else
-         SDA_LO_OUT;
-      DELAY;
-      SCL_HI;
-      DELAY;
-      SCL_LO;
-
-      DELAY;
-   }
-}
-
-static unsigned char fmradio_i2c_inb(void)
-{
-   int i;
-   unsigned char byte = 0;
-
-   SDA_HI_IN;
-   /* clock in each bit, MSB first */
-   for ( i=0x80; i; i>>=1 ) {
-       DELAY;
-       SCL_HI;
-       DELAY;
-       if ( SDA )
-           byte |= i;
-       SCL_LO;
-   }
-
-   return byte;
-}
-
-int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count)
-{
-    int i,x=0;
-
-    fmradio_i2c_start();
-    fmradio_i2c_outb(address & 0xfe);
-    if (fmradio_i2c_getack())
-    {
-        for (i=0; i<count; i++)
-        {
-            fmradio_i2c_outb(buf[i]);
-            if (!fmradio_i2c_getack())
-            {
-                x=-2;
-                break;
-            }
-        }
-    }
-    else
-    {
-        logf("fmradio_i2c_write() - no ack\n");
-        x=-1;
-    }
-    fmradio_i2c_stop();
-    return x;
-}
-
-int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
-{
-    int i,x=0;
-    
-    fmradio_i2c_start();
-    fmradio_i2c_outb(address | 1);
-
-    if (fmradio_i2c_getack())
-    {
-        for (i=count; i>0; i--)
-        {
-            *buf++ = fmradio_i2c_inb();
-            fmradio_i2c_ack(i == 1);
-        }
-    }
-    else
-        x=-1;
-    fmradio_i2c_stop();
-    return x;
-}
diff --git a/firmware/target/arm/iriver/h10/lcd-as-h10.S b/firmware/target/arm/iriver/h10/lcd-as-h10.S
deleted file mode 100644
index 8e851d8..0000000
--- a/firmware/target/arm/iriver/h10/lcd-as-h10.S
+++ /dev/null
@@ -1,538 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2007-2008 by Michael Sevakis
- *
- * H10 20GB LCD assembly routines
- *
- * 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"
-
-/****************************************************************************
- * void lcd_write_yuv_420_lines(unsigned char const * const src[3],
- *                              int width,
- *                              int stride);
- *
- *   |R|   |1.000000 -0.000001  1.402000| |Y'|
- *   |G| = |1.000000 -0.334136 -0.714136| |Pb|
- *   |B|   |1.000000  1.772000  0.000000| |Pr|
- *   Scaled, normalized, rounded and tweaked to yield RGB 565:
- *   |R|   |74   0 101| |Y' -  16| >> 9
- *   |G| = |74 -24 -51| |Cb - 128| >> 8
- *   |B|   |74 128   0| |Cr - 128| >> 9
- *
- * Write four RGB565 pixels in the following order on each loop:
- * 1 3 + > down
- * 2 4 \/ left
- */
-    .section    .icode, "ax", %progbits
-    .align      2
-    .global     lcd_write_yuv420_lines
-    .type       lcd_write_yuv420_lines, %function
-lcd_write_yuv420_lines:
-                                        @ r0 = yuv_src
-                                        @ r1 = width
-                                        @ r2 = stride
-    stmfd       sp!, { r4-r11, lr }     @ save non-scratch
-    ldmia       r0, { r4, r5, r6 }      @ r4 = yuv_src[0] = Y'_p
-                                        @ r5 = yuv_src[1] = Cb_p
-                                        @ r6 = yuv_src[2] = Cr_p
-                                        @
-    mov         r0, #0x7000000c         @ r0 = &LCD2_PORT = 0x70008a0c
-    add         r0, r0, #0x8a00         @
-    mov         r14, #LCD2_DATA_MASK    @
-                                        @
-    sub         r2, r2, #1              @ Adjust stride because of increment
-10: @ loop line                         @
-    ldrb        r7, [r4], #1            @ r7 = *Y'_p++;
-    ldrb        r8, [r5], #1            @ r8 = *Cb_p++;
-    ldrb        r9, [r6], #1            @ r9 = *Cr_p++;
-                                        @
-    sub         r7, r7, #16             @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @ actually (Y' - 16)*37 and shift right
-    add         r7, r12, r7, asl #5     @ by one less when adding - same for all
-                                        @
-    sub         r8, r8, #128            @ Cb -= 128
-    sub         r9, r9, #128            @ Cr -= 128
-                                        @
-    add         r10, r9, r9, asl #1     @ r10 = Cr*51 + Cb*24
-    add         r10, r10, r10, asl #4   @
-    add         r10, r10, r8, asl #3    @
-    add         r10, r10, r8, asl #4    @
-                                        @
-    add         r11, r9, r9, asl #2     @ r9 = Cr*101
-    add         r11, r11, r9, asl #5    @
-    add         r9, r11, r9, asl #6     @
-                                        @
-    add         r8, r8, #2              @ r8 = bu = (Cb*128 + 128) >> 8
-    mov         r8, r8, asr #2          @
-    add         r9, r9, #256            @ r9 = rv = (r8 + 256) >> 9
-    mov         r9, r9, asr #9          @
-    rsb         r10, r10, #128          @ r10 = guv = (-r9 + 128) >> 8
-    mov         r10, r10, asr #8        @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3 = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
-    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
-                                        @
-    orr         r7, r14, r3, lsr #8     @ store pixel
-    orr         r11, r14, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4], #1           @ r12 = Y' = *(Y'_p++)
-                                        @
-    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
-    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
-                                        @
-    orr         r7, r14, r3, lsr #8     @ store pixel
-    orr         r11, r14, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    orr         r3, r3, r7, lsl #5      @ r3 = b | (g << 5)
-    orr         r3, r3, r11, lsl #11    @ r3 |= (r << 11)
-                                        @
-    orr         r7, r14, r3, lsr #8     @ store pixel
-    orr         r11, r14, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
-    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
-                                        @
-    orr         r7, r14, r3, lsr #8     @ store pixel
-    orr         r11, r14, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-    str         r11, [r0]               @
-                                        @
-    subs        r1, r1, #2              @ subtract block from width
-    bgt         10b @ loop line         @
-                                        @
-    ldmpc       regs=r4-r11             @ restore registers and return
-    .ltorg                              @ dump constant pool
-    .size   lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
-
-
-/****************************************************************************
- * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
- *                                      int width,
- *                                      int stride,
- *                                      int x_screen,
- *                                      int y_screen);
- *
- *   |R|   |1.000000 -0.000001  1.402000| |Y'|
- *   |G| = |1.000000 -0.334136 -0.714136| |Pb|
- *   |B|   |1.000000  1.772000  0.000000| |Pr|
- *   Red scaled at twice g & b but at same precision to place it in correct
- *   bit position after multiply and leave instruction count lower.
- *   |R|   |258   0  408| |Y' -  16|
- *   |G| = |149 -49 -104| |Cb - 128|
- *   |B|   |149 258    0| |Cr - 128|
- *
- * Write four RGB565 pixels in the following order on each loop:
- * 1 3 + > down
- * 2 4 \/ left
- *
- * Kernel pattern (raw|use order):
- * 5 3 4 2     row0    row2         > down
- * 1 7 0 6 | 5 1 3 7 4 0 2 6 col0     left
- * 4 2 5 3 | 4 0 2 6 5 1 3 7 col2  \/
- * 0 6 1 7
- */
-    .section    .icode, "ax", %progbits
-    .align      2
-    .global     lcd_write_yuv420_lines_odither
-    .type       lcd_write_yuv420_lines_odither, %function
-lcd_write_yuv420_lines_odither:
-                                        @ r0   = yuv_src
-                                        @ r1   = width
-                                        @ r2   = stride
-                                        @ r3   = x_screen
-                                        @ [sp] = y_screen
-    stmfd       sp!, { r4-r11, lr }     @ save non-scratch
-    ldmia       r0, { r4, r5, r6 }      @ r4 = yuv_src[0] = Y'_p
-                                        @ r5 = yuv_src[1] = Cb_p
-                                        @ r6 = yuv_src[2] = Cr_p
-                                        @
-    ldr         r0, [sp, #36]           @ Line up pattern and kernel quadrant
-    eor         r14, r3, r0             @
-    and         r14, r14, #0x2          @
-    mov         r14, r14, lsl #6        @ 0x00 or 0x80
-                                        @
-    mov         r0, #0x7000000c         @ r0 = &LCD2_PORT = 0x70008a0c
-    add         r0, r0, #0x8a00         @
-                                        @
-    sub         r2, r2, #1              @ Adjust stride because of increment
-10: @ loop line                         @
-                                        @
-    ldrb        r7, [r4], #1            @ r7 = *Y'_p++;
-    ldrb        r8, [r5], #1            @ r8 = *Cb_p++;
-    ldrb        r9, [r6], #1            @ r9 = *Cr_p++;
-                                        @
-    eor         r14, r14, #0x80         @ flip pattern quadrant
-                                        @
-    sub         r7, r7, #16             @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @    
-    sub         r8, r8, #128            @ Cb -= 128
-    sub         r9, r9, #128            @ Cr -= 128
-                                        @
-    add         r10, r8, r8, asl #4     @ r10 = guv = Cr*104 + Cb*49
-    add         r10, r10, r8, asl #5    @
-    add         r10, r10, r9, asl #3    @
-    add         r10, r10, r9, asl #5    @
-    add         r10, r10, r9, asl #6    @
-                                        @
-    mov         r8, r8, asl #1          @ r8 = bu = Cb*258
-    add         r8, r8, r8, asl #7      @
-                                        @
-    add         r9, r9, r9, asl #1      @ r9 = rv = Cr*408
-    add         r9, r9, r9, asl #4      @
-    mov         r9, r9, asl #3          @
-                                        @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-                                        @ r8 = bu, r9 = rv, r10 = guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3 = 31/32*b + b/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r + r/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7 = 63/64*g + g/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    add         r12, r14, #0x200        @
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    mov         r11, #LCD2_DATA_MASK    @ store pixel
-    orr         r7, r11, r3, lsr #8     @
-    orr         r11, r11, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3  = 31/32*b' + b'/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r' + r'/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7  = 63/64*g' + g'/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    @ This element is zero - use r14    @
-                                        @
-    add         r3, r3, r14             @ b = r3 + delta
-    add         r11, r11, r14, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r14, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4], #1           @ r12 = Y' = *(Y'_p++)
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    mov         r11, #LCD2_DATA_MASK    @ store pixel
-    orr         r7, r11, r3, lsr #8     @
-    orr         r11, r11, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-                                        @ r8 = bu, r9 = rv, r10 = guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3  = 31/32*b' + b'/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r' + r'/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7  = 63/64*g' + g'/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    add         r12, r14, #0x100        @
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)    
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    mov         r11, #LCD2_DATA_MASK    @ store pixel
-    orr         r7, r11, r3, lsr #8     @
-    orr         r11, r11, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3 = 31/32*b + b/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r + r/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7 = 63/64*g + g/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    add         r12, r14, #0x300        @
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    mov         r11, #LCD2_DATA_MASK    @ store pixel
-    orr         r7, r11, r3, lsr #8     @
-    orr         r11, r11, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-    str         r11, [r0]               @
-                                        @
-    subs        r1, r1, #2              @ subtract block from width
-    bgt         10b @ loop line         @
-                                        @
-    ldmpc       regs=r4-r11             @ restore registers and return
-    .ltorg                              @ dump constant pool
-    .size   lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
diff --git a/firmware/target/arm/iriver/h10/lcd-h10_20gb.c b/firmware/target/arm/iriver/h10/lcd-h10_20gb.c
deleted file mode 100644
index 596276a..0000000
--- a/firmware/target/arm/iriver/h10/lcd-h10_20gb.c
+++ /dev/null
@@ -1,551 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 "lcd.h"
-#include "kernel.h"
-#include "system.h"
-
-/** Initialized in lcd_init_device() **/
-/* Is the power turned on? */
-static bool power_on;
-/* Is the display turned on? */
-static bool display_on;
-/* Amount of vertical offset. Used for flip offset correction/detection. */
-static int y_offset;
-/* Reverse flag. Must be remembered when display is turned off. */
-static unsigned short disp_control_rev;
-/* Contrast setting << 8 */
-static int lcd_contrast;
-
-static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
-
-/* Forward declarations */
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-static void lcd_display_off(void);
-#endif
-
-/* register defines for the Renesas HD66773R */
-#define R_START_OSC             0x00
-#define R_DEVICE_CODE_READ      0x00
-#define R_DRV_OUTPUT_CONTROL    0x01
-#define R_DRV_AC_CONTROL        0x02
-#define R_POWER_CONTROL1        0x03
-#define R_POWER_CONTROL2        0x04
-#define R_ENTRY_MODE            0x05
-#define R_COMPARE_REG           0x06
-#define R_DISP_CONTROL          0x07
-#define R_FRAME_CYCLE_CONTROL   0x0b
-#define R_POWER_CONTROL3        0x0c
-#define R_POWER_CONTROL4        0x0d
-#define R_POWER_CONTROL5        0x0e
-#define R_GATE_SCAN_START_POS   0x0f
-#define R_VERT_SCROLL_CONTROL   0x11
-#define R_1ST_SCR_DRV_POS       0x14
-#define R_2ND_SCR_DRV_POS       0x15
-#define R_HORIZ_RAM_ADDR_POS    0x16
-#define R_VERT_RAM_ADDR_POS     0x17
-#define R_RAM_WRITE_DATA_MASK   0x20
-#define R_RAM_ADDR_SET          0x21
-#define R_WRITE_DATA_2_GRAM     0x22
-#define R_RAM_READ_DATA         0x22
-#define R_GAMMA_FINE_ADJ_POS1   0x30
-#define R_GAMMA_FINE_ADJ_POS2   0x31
-#define R_GAMMA_FINE_ADJ_POS3   0x32
-#define R_GAMMA_GRAD_ADJ_POS    0x33
-#define R_GAMMA_FINE_ADJ_NEG1   0x34
-#define R_GAMMA_FINE_ADJ_NEG2   0x35
-#define R_GAMMA_FINE_ADJ_NEG3   0x36
-#define R_GAMMA_GRAD_ADJ_NEG    0x37
-#define R_GAMMA_AMP_ADJ_POS     0x3a
-#define R_GAMMA_AMP_ADJ_NEG     0x3b
-
-static inline void lcd_wait_write(void)
-{
-    while (LCD2_PORT & LCD2_BUSY_MASK);
-}
-
-/* Send command */
-static inline void lcd_send_cmd(unsigned v)
-{
-    lcd_wait_write();
-    LCD2_PORT = LCD2_CMD_MASK;
-    LCD2_PORT = LCD2_CMD_MASK | v;
-}
-
-/* Send 16-bit data */
-static inline void lcd_send_data(unsigned v)
-{
-    lcd_wait_write();
-    LCD2_PORT = LCD2_DATA_MASK | (v >> 8);    /* Send MSB first */
-    LCD2_PORT = LCD2_DATA_MASK | (v & 0xff);
-}
-
-/* Send 16-bit data byte-swapped. Only needed until we can use block transfer. */
-static inline void lcd_send_data_swapped(unsigned v)
-{
-    lcd_wait_write();
-    LCD2_PORT = LCD2_DATA_MASK | (v & 0xff);  /* Send LSB first */
-    LCD2_PORT = LCD2_DATA_MASK | (v >> 8);    
-}
-
-/* Write value to register */
-static void lcd_write_reg(int reg, int val)
-{
-    lcd_send_cmd(reg);
-    lcd_send_data(val);
-}
-
-/*** hardware configuration ***/
-
-int lcd_default_contrast(void)
-{
-    return DEFAULT_CONTRAST_SETTING;
-}
-
-void lcd_set_contrast(int val)
-{
-    /* Clamp val in range 0-14, 16-30 */
-    if (val < 1)
-        val = 0;
-    else if (val <= 15)
-        --val;
-    else if (val > 30)
-        val = 30;
-
-    lcd_contrast = val << 8;
-
-    if (!power_on)
-             return;
-
-    /* VCOMG=1, VDV4-0=xxxxx, VCM4-0=11000 */
-    lcd_write_reg(R_POWER_CONTROL5, 0x2018 | lcd_contrast);
-}
-
-void lcd_set_invert_display(bool yesno)
-{
-    if (yesno == (disp_control_rev == 0x0000))
-        return;
-
-    disp_control_rev = yesno ? 0x0000 : 0x0004;
-
-    if (!display_on)
-        return;
-
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=11 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0033 | disp_control_rev);
-}
-
-
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
-    if (yesno == (y_offset != 0))
-        return;
-
-    /* The LCD controller is 132x160 while the LCD itself is 128x160, so we need
-     * to shift the origin by 4 when we flip the LCD */
-    y_offset = yesno ? 4 : 0;
-
-    if (!power_on)
-        return;
-
-    /* SCN4-0=000x0 (G1/G160) */
-    lcd_write_reg(R_GATE_SCAN_START_POS, yesno ? 0x0002 : 0x0000);
-    /* SM=0, GS=x, SS=x, NL4-0=10011 (G1-G160) */
-    lcd_write_reg(R_DRV_OUTPUT_CONTROL, yesno ? 0x0213 : 0x0113);
-}
-
-/* LCD init */
-void lcd_init_device(void)
-{  
-#ifndef BOOTLOADER
-    /* The OF won't boot if this is done in the bootloader - ideally we should 
-       tweak the lcd controller speed settings but this will do for now */
-    CLCD_CLOCK_SRC |= 0xc0000000; /* Set LCD interface clock to PLL */
-#endif
-    power_on = true;
-    display_on = true;
-    y_offset = 0;
-    disp_control_rev = 0x0004;
-    lcd_contrast     = DEFAULT_CONTRAST_SETTING << 8;
-}
-
-#ifdef HAVE_LCD_SLEEP
-static void lcd_power_on(void)
-{
-    /* Be sure standby bit is clear. */
-    /* BT2-0=000, DC2-0=000, AP2-0=000, SLP=0, STB=0 */
-    lcd_write_reg(R_POWER_CONTROL1, 0x0000);
-
-    /** Power ON Sequence **/
-    /* Per datasheet Rev.1.10, Jun.21.2003, p. 99 */
-
-    lcd_write_reg(R_START_OSC, 0x0001); /* Start Oscillation */
-    /* 10ms or more for oscillation circuit to stabilize */
-    sleep(HZ/50);
-    /* Instruction (1) for power setting; VC2-0, VRH3-0, CAD,
-       VRL3-0, VCM4-0, VDV4-0 */
-    /* VC2-0=001 */
-    lcd_write_reg(R_POWER_CONTROL3, 0x0001);
-    /* VRL3-0=0100, PON=0, VRH3-0=0001 */
-    lcd_write_reg(R_POWER_CONTROL4, 0x0401);
-    /* CAD=1 */
-    lcd_write_reg(R_POWER_CONTROL2, 0x8000);
-    /* VCOMG=0, VDV4-0=xxxxx (19), VCM4-0=11000 */
-    lcd_write_reg(R_POWER_CONTROL5, 0x0018 | lcd_contrast);
-    /* Instruction (2) for power setting; BT2-0, DC2-0, AP2-0 */
-    /* BT2-0=000, DC2-0=001, AP2-0=011, SLP=0, STB=0 */
-    lcd_write_reg(R_POWER_CONTROL1, 0x002c);
-    /* Instruction (3) for power setting; VCOMG = "1" */
-    /* VCOMG=1, VDV4-0=xxxxx (19), VCM4-0=11000 */
-    lcd_write_reg(R_POWER_CONTROL5, 0x2018 | lcd_contrast);
-
-    /* 40ms or more; time for step-up circuits 1,2 to stabilize */
-    sleep(HZ/25);
-
-    /* Instruction (4) for power setting; PON = "1" */
-    /* VRL3-0=0100, PON=1, VRH3-0=0001 */
-    lcd_write_reg(R_POWER_CONTROL4, 0x0411);
-
-    /* 40ms or more; time for step-up circuit 4 to stabilize */
-    sleep(HZ/25);
-
-    /* Instructions for other mode settings (in register order). */
-    /* SM=0, GS=x, SS=0, NL4-0=10011 (G1-G160)*/
-    lcd_write_reg(R_DRV_OUTPUT_CONTROL, y_offset ? 0x0013 : 0x0113); /* different to X5 */
-    /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */
-    lcd_write_reg(R_DRV_AC_CONTROL, 0x0700);
-    /* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=1, LG2-0=000 */
-    lcd_write_reg(R_ENTRY_MODE, 0x1028); /* different to X5 */
-    /* CP15-0=0000000000000000 */
-    lcd_write_reg(R_COMPARE_REG, 0x0000);
-    /* NO1-0=01, SDT1-0=00, EQ1-0=00, DIV1-0=00, RTN3-00000 */
-    lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x4000);
-    /* SCN4-0=000x0 (G1/G160) */
-/*    lcd_write_reg(R_GATE_SCAN_START_POS, y_offset ? 0x0000 : 0x0002); */
-    /* VL7-0=0x00 */
-    lcd_write_reg(R_VERT_SCROLL_CONTROL, 0x0000);
-    /* SE17-10(End)=0x9f (159), SS17-10(Start)=0x00 */
-    lcd_write_reg(R_1ST_SCR_DRV_POS, 0x9f00);
-    /* SE27-20(End)=0x5c (92), SS27-20(Start)=0x00 */
-    lcd_write_reg(R_2ND_SCR_DRV_POS, 0x5c00);
-    /* HEA7-0=7f, HSA7-0=00 */
-    lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 0x7f00);
-    /* PKP12-10=0x0, PKP02-00=0x0 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x0003);
-    /* PKP32-30=0x4, PKP22-20=0x0 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0400);
-    /* PKP52-50=0x4, PKP42-40=0x7 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0407);
-    /* PRP12-10=0x3, PRP02-00=0x5 */
-    lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x0305);
-    /* PKN12-10=0x0, PKN02-00=0x3 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0003);
-    /* PKN32-30=0x7, PKN22-20=0x4 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 0x0704);
-    /* PKN52-50=0x4, PRN42-40=0x7 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0407);
-    /* PRN12-10=0x5, PRN02-00=0x3 */
-    lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 0x0503);
-    /* VRP14-10=0x14, VRP03-00=0x09 */
-    lcd_write_reg(R_GAMMA_AMP_ADJ_POS, 0x1409);
-    /* VRN14-00=0x06, VRN03-00=0x02 */
-    lcd_write_reg(R_GAMMA_AMP_ADJ_NEG, 0x0602);
-
-    /* 100ms or more; time for step-up circuits to stabilize */
-    sleep(HZ/10);
-
-    power_on = true;
-}
-
-static void lcd_power_off(void)
-{
-    /* Display must be off first */
-    if (display_on)
-        lcd_display_off();
-
-    power_on = false;
-
-    /** Power OFF sequence **/
-    /* Per datasheet Rev.1.10, Jun.21.2003, p. 99 */
-
-    /* Step-up1 halt setting bit */
-    /* BT2-0=110, DC2-0=001, AP2-0=011, SLP=0, STB=0 */
-    lcd_write_reg(R_POWER_CONTROL1, 0x062c);
-    /* Step-up3,4 halt setting bit */
-    /* VRL3-0=0100, PON=0, VRH3-0=0001 */
-    lcd_write_reg(R_POWER_CONTROL4, 0x0401);
-    /* VCOMG=0, VDV4-0=10011, VCM4-0=11000 */
-    lcd_write_reg(R_POWER_CONTROL5, 0x0018 | lcd_contrast);
-
-    /* Wait 100ms or more */
-    sleep(HZ/10);
-
-    /* Step-up2,amp halt setting bit */
-    /* BT2-0=000, DC2-0=000, AP2-0=000, SLP=0, STB=0 */
-    lcd_write_reg(R_POWER_CONTROL1, 0x0000);
-}
-
-void lcd_sleep(void)
-{
-    if (power_on)
-        lcd_power_off();
-
-    /* Set standby mode */
-    /* BT2-0=000, DC2-0=000, AP2-0=000, SLP=0, STB=1 */
-    lcd_write_reg(R_POWER_CONTROL1, 0x0001);
-}
-#endif
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-static void lcd_display_off(void)
-{
-    display_on = false;
-
-    /** Display OFF sequence **/
-    /* Per datasheet Rev.1.10, Jun.21.2003, p. 97 */
-
-    /* EQ1-0=00 already */
-
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=10 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0032 | disp_control_rev);
-
-    sleep(HZ/25); /* Wait 2 frames or more */
-
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=0, REV=x, D1-0=10 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0022 | disp_control_rev);
-
-    sleep(HZ/25); /* Wait 2 frames or more */
-
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=0, DTE=0, REV=0, D1-0=00 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0000);
-}
-#endif
-
-#if defined(HAVE_LCD_ENABLE)
-static void lcd_display_on(void)
-{
-    /* Be sure power is on first */
-    if (!power_on)
-        lcd_power_on();
-
-    /** Display ON Sequence **/
-    /* Per datasheet Rev.1.10, Jun.21.2003, p. 97 */
-
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=0, DTE=0, REV=0, D1-0=01 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0001);
-
-    sleep(HZ/25); /* Wait 2 frames or more */
-
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=0, REV=x, D1-0=01 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0021 | disp_control_rev);
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=0, REV=x, D1-0=11 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0023 | disp_control_rev);
-
-    sleep(HZ/25); /* Wait 2 frames or more */
-
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=11 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0033 | disp_control_rev);
-
-    display_on = true;
-}
-
-void lcd_enable(bool on)
-{
-    if (on == display_on)
-        return;
-
-    if (on)
-    {
-        lcd_display_on();
-        /* Probably out of sync and we don't wanna pepper the code with
-           lcd_update() calls for this. */
-        lcd_update();
-        send_event(LCD_EVENT_ACTIVATION, NULL);
-    }
-    else
-    {
-        lcd_display_off();
-    }
-}
-#endif
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-bool lcd_active(void)
-{
-    return display_on;
-}
-#endif
-
-/*** update functions ***/
-
-void lcd_yuv_set_options(unsigned options)
-{
-    lcd_yuv_options = options;
-}
-
-/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
-extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
-                                   int width,
-                                   int stride);
-extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
-                                           int width,
-                                           int stride,
-                                           int x_screen, /* To align dither pattern */
-                                           int y_screen);
-
-/* Performance function to blit a YUV bitmap directly to the LCD */
-void lcd_blit_yuv(unsigned char * const src[3],
-                  int src_x, int src_y, int stride,
-                  int x, int y, int width, int height)
-{
-    const unsigned char *yuv_src[3];
-    const unsigned char *ysrc_max;
-    int y0;
-    int options;
-
-    if (!display_on)
-        return;
-
-    width &= ~1;
-    height &= ~1;
-
-    /* calculate the drawing region */
-
-    /* The 20GB LCD is actually 128x160 but rotated 90 degrees so the origin
-     * is actually the bottom left and horizontal and vertical are swapped. 
-     * Rockbox expects the origin to be the top left so we need to use 
-     * 127 - y instead of just y */
-    
-    /* max vert << 8 | start vert */
-    lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
-
-    y0 = LCD_HEIGHT - 1 - y + y_offset;
-
-    /* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=0, LG2-0=000 */
-    lcd_write_reg(R_ENTRY_MODE, 0x1020);
-
-    yuv_src[0] = src[0] + src_y * stride + src_x;
-    yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1);
-    yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
-    ysrc_max = yuv_src[0] + height * stride;
-
-    options = lcd_yuv_options;
-
-    do
-    {
-        /* max horiz << 8 | start horiz */
-        lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y0 << 8) | (y0 - 1));
-
-        /* position cursor (set AD0-AD15) */
-        /* start vert << 8 | start horiz */
-        lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | y0);
-
-        /* start drawing */
-        lcd_send_cmd(R_WRITE_DATA_2_GRAM);
-
-        if (options & LCD_YUV_DITHER)
-        {
-            lcd_write_yuv420_lines_odither(yuv_src, width, stride,
-                                           x, y);
-            y -= 2;
-        }
-        else
-        {
-            lcd_write_yuv420_lines(yuv_src, width, stride);
-        }
-
-        y0 -= 2;
-        yuv_src[0] += stride << 1;
-        yuv_src[1] += stride >> 1;
-        yuv_src[2] += stride >> 1;
-    }
-    while (yuv_src[0] < ysrc_max);
-
-    /* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=1, LG2-0=000 */
-    lcd_write_reg(R_ENTRY_MODE, 0x1028);
-}
-
-
-/* Update a fraction of the display. */
-void lcd_update_rect(int x0, int y0, int width, int height)
-{
-    int x1, y1;
-    unsigned short *addr;
-
-    if (!display_on)
-        return;
-
-    /* calculate the drawing region */
-    y1 = (y0 + height) - 1;     /* max vert */
-    x1 = (x0 + width) - 1;      /* max horiz */
-
-    if(x1 >= LCD_WIDTH)
-        x1 = LCD_WIDTH - 1;
-    if (x1 <= 0)
-        return; /* nothing left to do, 0 is harmful to lcd_write_data() */
-    if(y1 >= LCD_HEIGHT)
-        y1 = LCD_HEIGHT-1;
-        
-    /* The 20GB LCD is actually 128x160 but rotated 90 degrees so the origin
-     * is actually the bottom left and horizontal and vertical are swapped. 
-     * Rockbox expects the origin to be the top left so we need to use 
-     * 127 - y instead of just y */
-    
-    /* max horiz << 8 | start horiz */
-    lcd_send_cmd(R_HORIZ_RAM_ADDR_POS);
-    lcd_send_data( (((LCD_HEIGHT-1)-y0+y_offset) << 8) | ((LCD_HEIGHT-1)-y1+y_offset) );
-    
-    /* max vert << 8 | start vert */
-    lcd_send_cmd(R_VERT_RAM_ADDR_POS);
-    lcd_send_data((x1 << 8) | x0);
-
-    /* position cursor (set AD0-AD15) */
-    /* start vert << 8 | start horiz */
-    lcd_send_cmd(R_RAM_ADDR_SET);
-    lcd_send_data( (x0 << 8) | ((LCD_HEIGHT-1)-y0+y_offset) );
-
-    /* start drawing */
-    lcd_send_cmd(R_WRITE_DATA_2_GRAM);
-
-    addr = (unsigned short*)&lcd_framebuffer[y0][x0];
-
-    int c, r;
-
-    /* for each row */
-    for (r = 0; r < height; r++) {
-        /* for each column */
-        for (c = 0; c < width; c++) {
-            /* output 1 pixel */
-            lcd_send_data_swapped(*addr++);
-        }
-
-        addr += LCD_WIDTH - width;
-    }
-}
-
-/* Update the display.
-   This must be called after all other LCD functions that change the display. */
-void lcd_update(void)
-{
-    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
-}
diff --git a/firmware/target/arm/iriver/h10/lcd-h10_5gb.c b/firmware/target/arm/iriver/h10/lcd-h10_5gb.c
deleted file mode 100644
index ce57af1..0000000
--- a/firmware/target/arm/iriver/h10/lcd-h10_5gb.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 "lcd.h"
-#include "kernel.h"
-#include "system.h"
-
-/* register defines for TL1771 */
-#define R_START_OSC             0x00
-#define R_DEVICE_CODE_READ      0x00
-#define R_DRV_OUTPUT_CONTROL    0x01
-#define R_DRV_AC_CONTROL        0x02
-#define R_ENTRY_MODE            0x03
-#define R_DISP_CONTROL1         0x07
-#define R_DISP_CONTROL2         0x08
-#define R_FRAME_CYCLE_CONTROL   0x0b
-#define R_POWER_CONTROL1        0x10
-#define R_POWER_CONTROL2        0x11
-#define R_POWER_CONTROL3        0x12
-#define R_POWER_CONTROL4        0x13
-#define R_POWER_CONTROL5        0x14
-#define R_RAM_ADDR_SET          0x21
-#define R_WRITE_DATA_2_GRAM     0x22
-#define R_GAMMA_FINE_ADJ_POS1   0x30
-#define R_GAMMA_FINE_ADJ_POS2   0x31
-#define R_GAMMA_FINE_ADJ_POS3   0x32
-#define R_GAMMA_GRAD_ADJ_POS    0x33
-#define R_GAMMA_FINE_ADJ_NEG1   0x34
-#define R_GAMMA_FINE_ADJ_NEG2   0x35
-#define R_GAMMA_FINE_ADJ_NEG3   0x36
-#define R_GAMMA_GRAD_ADJ_NEG    0x37
-#define R_POWER_CONTROL6        0x38
-#define R_GATE_SCAN_START_POS   0x40
-#define R_1ST_SCR_DRV_POS       0x42
-#define R_2ND_SCR_DRV_POS       0x43
-#define R_HORIZ_RAM_ADDR_POS    0x44
-#define R_VERT_RAM_ADDR_POS     0x45
-
-static inline void lcd_wait_write(void)
-{
-    while (LCD2_PORT & LCD2_BUSY_MASK);
-}
-
-/* Send command */
-static inline void lcd_send_cmd(unsigned v)
-{
-    lcd_wait_write();
-    LCD2_PORT = LCD2_CMD_MASK;
-    LCD2_PORT = LCD2_CMD_MASK | v;
-}
-
-/* Send 16-bit data */
-static inline void lcd_send_data(unsigned v)
-{
-    lcd_wait_write();
-    LCD2_PORT = LCD2_DATA_MASK | (v >> 8);    /* Send MSB first */
-    LCD2_PORT = LCD2_DATA_MASK | (v & 0xff);
-}
-
-/* Write value to register */
-static void lcd_write_reg(int reg, int val)
-{
-    lcd_send_cmd(reg);
-    lcd_send_data(val);
-}
-
-
-/*** hardware configuration ***/
-
-void lcd_set_contrast(int val)
-{
-  /* TODO: Implement lcd_set_contrast() */
-  (void)val;
-}
-
-void lcd_set_invert_display(bool yesno)
-{
-  /* TODO: Implement lcd_set_invert_display() */
-  (void)yesno;
-}
-
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
-  /* TODO: Implement lcd_set_flip() */
-  (void)yesno;
-}
-
-/* LCD init */
-void lcd_init_device(void)
-{  
-#ifndef BOOTLOADER
-    /* The OF won't boot if this is done in the bootloader - ideally we should 
-       tweak the lcd controller speed settings but this will do for now */
-    CLCD_CLOCK_SRC |= 0xc0000000; /* Set LCD interface clock to PLL */
-#endif
-    /* H10 LCD is initialised by the bootloader */
-}
-
-/*** update functions ***/
-
-#define CSUB_X 2
-#define CSUB_Y 2
-
-#define RYFAC (31*257)
-#define GYFAC (31*257)
-#define BYFAC (31*257)
-#define RVFAC 11170     /* 31 * 257 *  1.402    */
-#define GVFAC (-5690)  /* 31 * 257 * -0.714136 */
-#define GUFAC (-2742)   /* 31 * 257 * -0.344136 */
-#define BUFAC 14118     /* 31 * 257 *  1.772    */
-
-#define ROUNDOFFS (127*257)
-#define ROUNDOFFSG (63*257)
-
-/* Performance function to blit a YUV bitmap directly to the LCD */
-void lcd_blit_yuv(unsigned char * const src[3],
-                  int src_x, int src_y, int stride,
-                  int x, int y, int width, int height)
-{
-    int y0, x0, y1, x1;
-    int ymax;
-
-    width = (width + 1) & ~1;
-
-    /* calculate the drawing region */
-    x0 = x;
-    x1 = x + width - 1;
-    y0 = y;
-    y1 = y + height - 1;
-
-    /* max horiz << 8 | start horiz */
-    lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (x1 << 8) | x0);
-
-    /* max vert << 8 | start vert */
-    lcd_write_reg(R_VERT_RAM_ADDR_POS, (y1 << 8) | y0);
-
-    /* start vert << 8 | start horiz */
-    lcd_write_reg(R_RAM_ADDR_SET, (y0 << 8) | x0);
-
-    /* start drawing */
-    lcd_send_cmd(R_WRITE_DATA_2_GRAM);
-
-    ymax = y + height - 1 ;
-
-    const int stride_div_csub_x = stride/CSUB_X;
-
-    for (; y <= ymax ; y++)
-    {
-        /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
-        const unsigned char *ysrc = src[0] + stride * src_y + src_x;
-
-        const int uvoffset = stride_div_csub_x * (src_y/CSUB_Y) +
-                             (src_x/CSUB_X);
-
-        const unsigned char *usrc = src[1] + uvoffset;
-        const unsigned char *vsrc = src[2] + uvoffset;
-        const unsigned char *row_end = ysrc + width;
-
-        int y, u, v;
-        int red1, green1, blue1;
-        int red2, green2, blue2;
-        unsigned rbits, gbits, bbits;
-
-        int rc, gc, bc;
-
-        do
-        {
-            u = *usrc++ - 128;
-            v = *vsrc++ - 128;
-            rc = RVFAC * v + ROUNDOFFS;
-            gc = GVFAC * v + GUFAC * u + ROUNDOFFSG;
-            bc = BUFAC * u + ROUNDOFFS;
-
-            /* Pixel 1 */
-            y = *ysrc++;
-
-            red1   = RYFAC * y + rc;
-            green1 = GYFAC * y + gc;
-            blue1  = BYFAC * y + bc;
-
-            /* Pixel 2 */
-            y = *ysrc++;
-            red2   = RYFAC * y + rc;
-            green2 = GYFAC * y + gc;
-            blue2  = BYFAC * y + bc;
-
-            /* Since out of bounds errors are relatively rare, we check two
-               pixels at once to see if any components are out of bounds, and
-               then fix whichever is broken. This works due to high values and
-               negative values both becoming larger than the cutoff when
-               casted to unsigned.  And ORing them together checks all of them
-               simultaneously.  */
-            if (((unsigned)(red1 | green1 | blue1 |
-                     red2 | green2 | blue2)) > (RYFAC*255+ROUNDOFFS)) {
-                if (((unsigned)(red1 | green1 | blue1)) > 
-                    (RYFAC*255+ROUNDOFFS)) {
-                    if ((unsigned)red1 > (RYFAC*255+ROUNDOFFS))
-                    {
-                        if (red1 < 0)
-                            red1 = 0;
-                        else
-                            red1 = (RYFAC*255+ROUNDOFFS);
-                    }
-                    if ((unsigned)green1 > (GYFAC*255+ROUNDOFFSG))
-                    {
-                        if (green1 < 0)
-                            green1 = 0;
-                        else
-                            green1 = (GYFAC*255+ROUNDOFFSG);
-                    }
-                    if ((unsigned)blue1 > (BYFAC*255+ROUNDOFFS))
-                    {
-                        if (blue1 < 0)
-                            blue1 = 0;
-                        else
-                            blue1 = (BYFAC*255+ROUNDOFFS);
-                    }
-                }
-
-                if (((unsigned)(red2 | green2 | blue2)) > 
-                    (RYFAC*255+ROUNDOFFS)) {
-                    if ((unsigned)red2 > (RYFAC*255+ROUNDOFFS))
-                    {
-                        if (red2 < 0)
-                            red2 = 0;
-                        else
-                            red2 = (RYFAC*255+ROUNDOFFS);
-                    }
-                    if ((unsigned)green2 > (GYFAC*255+ROUNDOFFSG))
-                    {
-                        if (green2 < 0)
-                            green2 = 0;
-                        else
-                            green2 = (GYFAC*255+ROUNDOFFSG);
-                    }
-                    if ((unsigned)blue2 > (BYFAC*255+ROUNDOFFS))
-                    {
-                        if (blue2 < 0)
-                            blue2 = 0;
-                        else
-                            blue2 = (BYFAC*255+ROUNDOFFS);
-                    }
-                }
-            }
-                
-            rbits = red1 >> 16 ;
-            gbits = green1 >> 15 ;
-            bbits = blue1 >> 16 ;
-            lcd_send_data((rbits << 11) | (gbits << 5) | bbits);
-
-            rbits = red2 >> 16 ;
-            gbits = green2 >> 15 ;
-            bbits = blue2 >> 16 ;
-            lcd_send_data((rbits << 11) | (gbits << 5) | bbits);
-        }
-        while (ysrc < row_end);
-
-        src_y++;
-    }
-}
-
-
-/* Update a fraction of the display. */
-void lcd_update_rect(int x0, int y0, int width, int height)
-{
-    int x1, y1;
-    int newx,newwidth;
-    unsigned long *addr;
-
-    /* Ensure x and width are both even - so we can read 32-bit aligned 
-       data from lcd_framebuffer */
-    newx=x0&~1;
-    newwidth=width&~1;
-    if (newx+newwidth < x0+width) { newwidth+=2; }
-    x0=newx; width=newwidth;
-
-    /* calculate the drawing region */
-    y1 = (y0 + height) - 1;           /* max vert */
-    x1 = (x0 + width) - 1;          /* max horiz */
-
-
-    /* swap max horiz < start horiz */
-    if (y1 < y0) {
-        int t;
-        t = y0;
-        y0 = y1;
-        y1 = t;
-    }
-
-    /* swap max vert < start vert */
-    if (x1 < x0) {
-        int t;
-        t = x0;
-        x0 = x1;
-        x1 = t;
-    }
-
-    /* max horiz << 8 | start horiz */
-    lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (x1 << 8) | x0);
-
-    /* max vert << 8 | start vert */
-    lcd_write_reg(R_VERT_RAM_ADDR_POS, (y1 << 8) | y0);
-
-    /* start vert << 8 | start horiz */
-    lcd_write_reg(R_RAM_ADDR_SET, (y0 << 8) | x0);
-
-    /* start drawing */
-    lcd_send_cmd(R_WRITE_DATA_2_GRAM);
-
-    addr = (unsigned long*)&lcd_framebuffer[y0][x0];
-
-    while (height > 0) {
-        int c, r;
-        int h, pixels_to_write;
-
-        pixels_to_write = (width * height) * 2;
-        h = height;
-
-        /* calculate how much we can do in one go */
-        if (pixels_to_write > 0x10000) {
-            h = (0x10000/2) / width;
-            pixels_to_write = (width * h) * 2;
-        }
-
-        LCD2_BLOCK_CTRL = 0x10000080;
-        LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
-        LCD2_BLOCK_CTRL = 0x34000000;
-
-        /* for each row */
-        for (r = 0; r < h; r++) {
-            /* for each column */
-            for (c = 0; c < width; c += 2) {
-                while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK));
-
-                /* output 2 pixels */
-                LCD2_BLOCK_DATA = *addr++;
-            }
-            addr += (LCD_WIDTH - width)/2;
-        }
-
-        while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
-        LCD2_BLOCK_CONFIG = 0;
-
-        height -= h;
-    }
-}
-
-/* Update the display.
-   This must be called after all other LCD functions that change the display. */
-void lcd_update(void)
-{
-    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
-}
diff --git a/firmware/target/arm/iriver/h10/power-h10.c b/firmware/target/arm/iriver/h10/power-h10.c
deleted file mode 100644
index 26b8975..0000000
--- a/firmware/target/arm/iriver/h10/power-h10.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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.
- *
- ****************************************************************************/
-
-/* Created from power.c using some iPod code, and some custom stuff based on 
-   GPIO analysis 
-*/
-
-#include "config.h"
-#include "cpu.h"
-#include <stdbool.h>
-#include "kernel.h"
-#include "system.h"
-#include "power.h"
-#include "logf.h"
-#include "usb.h"
-
-#if CONFIG_TUNER
-
-bool tuner_power(bool status)
-{
-    (void)status;
-    /* TODO: tuner power control */
-    return true;
-}
-
-#endif /* #if CONFIG_TUNER */
-
-void power_init(void)
-{
-}
-
-unsigned int power_input_status(void)
-{
-    unsigned int status = POWER_INPUT_NONE;
-
-    if (GPIOF_INPUT_VAL & 0x08)
-        status = POWER_INPUT_MAIN_CHARGER;
-
-    if (GPIOL_INPUT_VAL & 0x04)
-        status |= POWER_INPUT_USB_CHARGER;
-
-    return status;
-}
-
-void ide_power_enable(bool on)
-{
-    if(on){
-        GPIO_CLEAR_BITWISE(GPIOF_OUTPUT_VAL, 0x01);
-        DEV_EN |= DEV_IDE0;
-    } else {
-        DEV_EN &= ~DEV_IDE0;
-        GPIO_SET_BITWISE(GPIOF_OUTPUT_VAL, 0x01);
-    }
-}
-
-
-bool ide_powered(void)
-{
-    return ((GPIOF_INPUT_VAL & 0x1) == 0);
-}
-
-void power_off(void)
-{
-    GPIOF_OUTPUT_VAL &=~ 0x20;
-    while(1);
-}
diff --git a/firmware/target/arm/iriver/h10/powermgmt-h10.c b/firmware/target/arm/iriver/h10/powermgmt-h10.c
deleted file mode 100644
index 9970c29..0000000
--- a/firmware/target/arm/iriver/h10/powermgmt-h10.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
- * Revisions copyright (C) 2005 by Gerald Van Baren
- *
- * 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 "adc.h"
-#include "powermgmt.h"
-
-const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
-{
-#if   defined(IRIVER_H10)
-    3733
-#elif defined(IRIVER_H10_5GB)
-    3700
-#endif
-};
-
-const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
-{
-#if   defined(IRIVER_H10)
-    3627
-#elif defined(IRIVER_H10_5GB)
-    3600
-#endif
-};
-
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
-const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
-{
-#if   defined(IRIVER_H10)
-    { 3733, 3772, 3821, 3840, 3869, 3917, 3985, 4034, 4072, 4140, 4198 }
-#elif defined(IRIVER_H10_5GB)
-    { 3700, 3800, 3850, 3880, 3910, 3960, 4000, 4070, 4120, 4210, 4280 }
-#endif
-};
-
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
-const unsigned short percent_to_volt_charge[11] =
-{
-#if   defined(IRIVER_H10)
-    3956, 3995, 4024, 4043, 4063, 4082, 4111, 4140, 4179, 4218, 4266
-#elif defined(IRIVER_H10_5GB)
-    /* TODO: Not yet calibrated */
-    3700, 3800, 3850, 3880, 3910, 3960, 4000, 4070, 4120, 4210, 4280
-#endif
-};
-
-#define BATTERY_SCALE_FACTOR 4650
-/* full-scale ADC readout (2^10) in millivolt */
-
-/* Returns battery voltage from ADC [millivolts] */
-unsigned int battery_adc_voltage(void)
-{
-    return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
-}
diff --git a/firmware/target/arm/iriver/usb-target.h b/firmware/target/arm/iriver/usb-target.h
deleted file mode 100644
index 034b012..0000000
--- a/firmware/target/arm/iriver/usb-target.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardelll
- *
- * 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.
- *
- ****************************************************************************/
-
-/* Based off x5 version */
-
-#ifndef USB_TARGET_H
-#define USB_TARGET_H
-
-#ifdef HAVE_BOOTLOADER_USB_MODE
-#define USB_DRIVER_CLOSE
-#endif
-
-bool usb_init_device(void);
-void usb_pin_init(void); /* Init the GPIO input only */
-bool usb_plugged(void); /* Returns instantaneous state - always */
-
-#endif
diff --git a/firmware/target/arm/kernel-pp.c b/firmware/target/arm/kernel-pp.c
deleted file mode 100644
index 2a00254..0000000
--- a/firmware/target/arm/kernel-pp.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Björn Stenberg
- *
- * 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 "system.h"
-#include "kernel.h"
-
-#if !defined(BOOTLOADER) || defined(HAVE_BOOTLOADER_USB_MODE)
-void TIMER1(void)
-{
-    /* Run through the list of tick tasks (using main core) */
-    TIMER1_VAL; /* Read value to ack IRQ */
-
-    /* Run through the list of tick tasks using main CPU core - 
-       wake up the COP through its control interface to provide pulse */
-    call_tick_tasks();
-
-#if NUM_CORES > 1
-    /* Pulse the COP */
-    core_wake(COP);
-#endif /* NUM_CORES */
-}
-#endif
-
-/* Must be last function called init kernel/thread initialization */
-void tick_start(unsigned int interval_in_ms)
-{
-#if !defined(BOOTLOADER) || defined(HAVE_BOOTLOADER_USB_MODE)
-    TIMER1_CFG = 0x0;
-    TIMER1_VAL;
-    /* enable timer */
-    TIMER1_CFG = 0xc0000000 | (interval_in_ms*1000 - 1);
-    /* unmask interrupt source */
-    CPU_INT_EN = TIMER1_MASK;
-#else
-    /* We don't enable interrupts in the bootloader */
-    (void)interval_in_ms;
-#endif
-}
-
-#ifdef HAVE_BOOTLOADER_USB_MODE
-void tick_stop(void)
-{
-    CPU_INT_DIS = TIMER1_MASK;
-    TIMER1_CFG = 0;
-}
-#endif
diff --git a/firmware/target/arm/olympus/app.lds b/firmware/target/arm/olympus/app.lds
deleted file mode 100644
index de355c3..0000000
--- a/firmware/target/arm/olympus/app.lds
+++ /dev/null
@@ -1,204 +0,0 @@
-#include "config.h"
-
-ENTRY(start)
-
-OUTPUT_FORMAT(elf32-littlearm)
-OUTPUT_ARCH(arm)
-STARTUP(target/arm/crt0-pp.o)
-
-#define PLUGINSIZE PLUGIN_BUFFER_SIZE
-#define CODECSIZE CODEC_SIZE
-
-#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - CODECSIZE
-
-#define DRAMORIG 0x00000000
-#define IRAMORIG 0x40000000
-#define IRAMSIZE 0xc000
-
-#ifdef CPU_PP502x
-#define NOCACHE_BASE 	0x10000000
-#else
-#define NOCACHE_BASE 	0x28000000
-#endif
-
-#define CACHEALIGN_SIZE 16
-
-/* End of the audio buffer, where the codec buffer starts */
-#define ENDAUDIOADDR  (DRAMORIG + DRAMSIZE)
-
-/* Where the codec buffer ends, and the plugin buffer starts */
-#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
-
-MEMORY
-{
-    DRAM : ORIGIN = DRAMORIG,     LENGTH = DRAMSIZE
-    IRAM : ORIGIN = IRAMORIG,     LENGTH = IRAMSIZE
-}
-
-SECTIONS
-{
-    .text :
-    {
-        loadaddress = .;
-        _loadaddress = .;
-        . = ALIGN(0x200);
-        *(.init.text)
-        *(.text*)
-        *(.glue_7)
-        *(.glue_7t)
-        . = ALIGN(0x4);
-    } > DRAM
-
-    .rodata :
-    {
-        *(.rodata)  /* problems without this, dunno why */
-        *(.rodata*)
-        *(.rodata.str1.1)
-        *(.rodata.str1.4)
-        . = ALIGN(0x4);
-
-        /* Pseudo-allocate the copies of the data sections */
-        _datacopy = .;
-    } > DRAM
-
-    /* TRICK ALERT! For RAM execution, we put the .data section at the
-       same load address as the copy. Thus, we don't waste extra RAM
-       when we don't actually need the copy.  */
-    .data : AT ( _datacopy )
-    {
-        _datastart = .;
-        *(.data*)
-        . = ALIGN(0x4);
-        _dataend  = .;
-    } > DRAM
-
-#if NOCACHE_BASE != 0
-    /* .ncdata section is placed at uncached physical alias address and is
-     * loaded at the proper cached virtual address - no copying is
-     * performed in the init code */
-    .ncdata . + NOCACHE_BASE :
-    {
-        . = ALIGN(CACHEALIGN_SIZE);
-        *(.ncdata*)
-        . = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-#endif
-    
-    /DISCARD/ :
-    {
-        *(.eh_frame)
-    }
-
-    .vectors 0x0 :
-    {
-        _vectorsstart = .;
-        *(.vectors);
-        _vectorsend = .;
-    } AT> DRAM
-
-    _vectorscopy = LOADADDR(.vectors);
-    _noloaddram  = LOADADDR(.vectors);
-
-    .ibss IRAMORIG (NOLOAD) :
-    {
-        _iedata = .;
-        *(.qharray)
-        *(.ibss)
-        . = ALIGN(0x4);
-        _iend = .;
-    } > IRAM
-
-    .iram _iend :
-    {
-        _iramstart = .;
-        *(.icode)
-        *(.irodata)
-        *(.idata)
-        . = ALIGN(0x4);
-        _iramend = .;
-    } > IRAM AT> DRAM
-
-    _iramcopy = LOADADDR(.iram);
-
-
-    .init ENDAUDIOADDR : 
-    {
-        . = ALIGN(4);
-        _initstart = .;
-        *(.init)
-        _initend = .;
-    } AT> DRAM
-
-    _initcopy = LOADADDR(.init);
-
-    .idle_stacks (NOLOAD) :
-    {
-       *(.idle_stacks)
-#if NUM_CORES > 1
-       cpu_idlestackbegin = .;
-       . += IDLE_STACK_SIZE;
-       cpu_idlestackend = .;
-#endif
-       cop_idlestackbegin = .;
-       . += IDLE_STACK_SIZE;
-       cop_idlestackend = .;
-    } > IRAM
-
-    .stack (NOLOAD) :
-    {
-       *(.stack)
-       stackbegin = .;
-       . += 0x2000;
-       stackend = .;
-    } > IRAM
-    
-    /* .bss and .ncbss are treated as a single section to use one init loop to
-     * zero it - note "_edata" and "_end" */
-    .bss _noloaddram (NOLOAD) :
-    {
-       _edata = .;
-        *(.bss*)
-        *(COMMON)
-        . = ALIGN(0x4);
-    } > DRAM
-
-#if NOCACHE_BASE != 0
-    .ncbss . + NOCACHE_BASE (NOLOAD):
-    {
-    	. = ALIGN(CACHEALIGN_SIZE);
-        *(.ncbss*)
-    	. = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-#endif
-
-    /* This will be aligned by preceding alignments */
-    .endaddr . - NOCACHE_BASE (NOLOAD) :
-    {
-        _end = .;
-    } > DRAM
-
-    .audiobuf (NOLOAD) :
-    {
-        _audiobuffer = .;
-        . = ALIGN(0x4);
-        audiobuffer = .;
-    } > DRAM
-    
-    .audiobufend ENDAUDIOADDR (NOLOAD) :
-    {
-        audiobufend = .;
-        _audiobufend = .;
-    } > DRAM
-
-    .codec ENDAUDIOADDR (NOLOAD) :
-    {
-        codecbuf = .;
-        _codecbuf = .;
-    }
-
-    .plugin ENDADDR (NOLOAD) :
-    {
-        _pluginbuf = .;
-        pluginbuf = .;
-    }
-}
diff --git a/firmware/target/arm/olympus/boot.lds b/firmware/target/arm/olympus/boot.lds
deleted file mode 100644
index e8d1ff3..0000000
--- a/firmware/target/arm/olympus/boot.lds
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "config.h"
-
-ENTRY(start)
-OUTPUT_FORMAT(elf32-littlearm)
-OUTPUT_ARCH(arm)
-STARTUP(target/arm/crt0-pp-bl.o)
-
-#define DRAMSIZE (MEMORYSIZE * 0x100000)
-
-#define DRAMORIG 0x10000000
-#define IRAMORIG 0x40000000
-#define IRAMSIZE 0x18000
-#define FLASHORIG 0x001f0000
-#define FLASHSIZE 2M
-
-MEMORY
-{
-    DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
-    IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
-}
-
-SECTIONS
-{
-  . = IRAMORIG;
-
-  .text : {
-    *(.init.text)
-    *(.text*)
-    *(.glue_7)
-    *(.glue_7t)
-  } > IRAM
-
-  .data : {
-    *(.icode)
-    *(.irodata)
-    *(.idata)
-    *(.data*)
-    *(.ncdata*)
-    *(.rodata*)
-    _dataend = . ;
-   } > IRAM
-
-  .stack (NOLOAD) : {
-     *(.stack)
-     _stackbegin = .;
-     stackbegin = .;
-     . += 0x2000;
-     _stackend = .;
-     stackend = .;
-  } > IRAM
-
-  /* The bss section is too large for IRAM - we just move it 16MB into the
-     DRAM */
-
-  . = DRAMORIG;
-  .bss . + (16*1024*1024) (NOLOAD) : {
-     _edata = .;
-     *(.bss*);
-     *(.ibss);
-     *(COMMON)
-     *(.ncbss*);
-     _end = .;
-   } > DRAM
-}
diff --git a/firmware/target/arm/olympus/mrobe-100/adc-target.h b/firmware/target/arm/olympus/mrobe-100/adc-target.h
deleted file mode 100644
index ee9e294..0000000
--- a/firmware/target/arm/olympus/mrobe-100/adc-target.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 _ADC_TARGET_H_
-#define _ADC_TARGET_H_
-
-#define NUM_ADC_CHANNELS 4
-
-#define ADC_BATTERY     0
-#define ADC_UNKNOWN_1   1
-#define ADC_UNKNOWN_2   2
-#define ADC_UNKNOWN_3   3
-#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
-
-/* Force a scan now */
-unsigned short adc_scan(int channel);
-
-#endif
diff --git a/firmware/target/arm/olympus/mrobe-100/backlight-mr100.c b/firmware/target/arm/olympus/mrobe-100/backlight-mr100.c
deleted file mode 100644
index 7dd8094..0000000
--- a/firmware/target/arm/olympus/mrobe-100/backlight-mr100.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 "system.h"
-#include "backlight-target.h"
-#include "lcd-remote-target.h"
-
-#define MIN_BRIGHTNESS 0x80ff08ff
-
-static const int log_brightness[12] = {0,4,8,12,20,28,40,60,88,124,176,255};
-
-/* Returns the current state of the backlight (true=ON, false=OFF). */
-bool _backlight_init(void)
-{
-    return (GPO32_ENABLE & 0x1000000) ? true : false;
-}
-
-void _backlight_hw_on(void)
-{
-    GPO32_ENABLE |= 0x1000000;
-}
-
-void _backlight_hw_off(void)
-{
-    GPO32_ENABLE &= ~0x1000000;
-}
-
-void _buttonlight_set_brightness(int brightness)
-{
-    /* clamp the brightness value */
-    brightness = MAX(0, MIN(15, brightness));
-
-    outl(MIN_BRIGHTNESS-(log_brightness[brightness - 1] << 16), 0x7000a010);
-}
-
-void _buttonlight_on(void)
-{
-    /* turn on all touchpad leds */
-    GPIOA_OUTPUT_VAL |= BUTTONLIGHT_ALL;
-}
-
-void _buttonlight_off(void)
-{
-    /* turn off all touchpad leds */
-    GPIOA_OUTPUT_VAL &= ~BUTTONLIGHT_ALL;
-}
-
-#ifdef HAVE_REMOTE_LCD
-void _remote_backlight_on(void)
-{
-    lcd_remote_backlight(true);
-}
-
-void _remote_backlight_off(void)
-{
-    lcd_remote_backlight(false);
-}
-#endif
diff --git a/firmware/target/arm/olympus/mrobe-100/backlight-target.h b/firmware/target/arm/olympus/mrobe-100/backlight-target.h
deleted file mode 100644
index df25106..0000000
--- a/firmware/target/arm/olympus/mrobe-100/backlight-target.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 BACKLIGHT_TARGET_H
-#define BACKLIGHT_TARGET_H
-
-bool _backlight_init(void); /* Returns backlight current state (true=ON). */
-void _backlight_hw_on(void);
-void _backlight_hw_off(void);
-
-#ifdef HAVE_REMOTE_LCD
-void _remote_backlight_on(void);
-void _remote_backlight_off(void);
-#endif
-
-#ifdef BOOTLOADER
-#define _backlight_on() _backlight_hw_on()
-#define _backlight_off() _backlight_hw_off()
-#else
-#define _backlight_on_isr() _backlight_hw_on()
-#define _backlight_off_isr() _backlight_hw_off()
-#define _backlight_on_normal() _backlight_hw_on()
-#define _backlight_off_normal() _backlight_hw_off()
-#define _BACKLIGHT_FADE_BOOST
-#endif
-
-/* Button lights are controlled by GPIOA_OUTPUT_VAL */
-#define BUTTONLIGHT_PLAY     0x01
-#define BUTTONLIGHT_MENU     0x02
-#define BUTTONLIGHT_DISPLAY  0x04
-#define BUTTONLIGHT_LEFT     0x08
-#define BUTTONLIGHT_RIGHT    0x10
-#define BUTTONLIGHT_SCROLL   0x20
-#define BUTTONLIGHT_ALL      (BUTTONLIGHT_PLAY    | BUTTONLIGHT_MENU  | \
-                              BUTTONLIGHT_DISPLAY | BUTTONLIGHT_LEFT  | \
-                              BUTTONLIGHT_RIGHT   | BUTTONLIGHT_SCROLL)
-
-void _buttonlight_set_brightness(int brightness);
-void _buttonlight_on(void);
-void _buttonlight_off(void);
-
-#endif
diff --git a/firmware/target/arm/olympus/mrobe-100/button-mr100.c b/firmware/target/arm/olympus/mrobe-100/button-mr100.c
deleted file mode 100644
index 4a17f4d..0000000
--- a/firmware/target/arm/olympus/mrobe-100/button-mr100.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 "system.h"
-#include "button.h"
-#include "backlight.h"
-#include "backlight-target.h"
-#include "synaptics-mep.h"
-
-#ifdef HAVE_REMOTE_LCD
-#include "lcd-remote-target.h"
-static bool remote_hold = false;
-static bool headphones_status = true;
-#endif
-
-/*#define LOGF_ENABLE*/
-#include "logf.h"
-
-static int int_btn = BUTTON_NONE;
-
-#ifndef BOOTLOADER
-void button_init_device(void)
-{
-    /* enable touchpad leds */
-    GPIOA_ENABLE     |= BUTTONLIGHT_ALL;
-    GPIOA_OUTPUT_EN  |= BUTTONLIGHT_ALL;
-    
-    /* enable touchpad */
-    GPO32_ENABLE     |=  0x40000000;
-    GPO32_VAL        &= ~0x40000000;
-
-    /* enable ACK, CLK, DATA lines */
-    GPIOD_ENABLE     |=  (0x1 | 0x2 | 0x4);
-
-    GPIOD_OUTPUT_EN  |=  0x1; /* ACK  */
-    GPIOD_OUTPUT_VAL |=  0x1; /* high */
-
-    GPIOD_OUTPUT_EN  &= ~0x2; /* CLK  */
-    
-    GPIOD_OUTPUT_EN  |=  0x4; /* DATA */
-    GPIOD_OUTPUT_VAL |=  0x4; /* high */
-
-    if (!touchpad_init())
-    {
-        logf("touchpad not ready");
-    }
-
-    /* headphone detection bit */
-    GPIOD_OUTPUT_EN &= ~0x80;
-    GPIOD_ENABLE |= 0x80;
-
-    /* remote detection (via headphone state) */
-    headphones_int();
-}
-
-/*
- * Button interrupt handler
- */
-void button_int(void)
-{
-    char data[4];
-    int val;
-
-    int_btn = BUTTON_NONE;
-
-    val = touchpad_read_device(data, 4);
-
-    if (val == MEP_BUTTON_HEADER)
-    {
-        /* Buttons packet - touched one of the 5 "buttons" */
-        if (data[1] & 0x1) int_btn |= BUTTON_PLAY;
-        if (data[1] & 0x2) int_btn |= BUTTON_MENU;
-        if (data[1] & 0x4) int_btn |= BUTTON_LEFT;
-        if (data[1] & 0x8) int_btn |= BUTTON_DISPLAY;
-        if (data[2] & 0x1) int_btn |= BUTTON_RIGHT;
-    }
-    else if (val == MEP_ABSOLUTE_HEADER)
-    {
-        /* Absolute packet - the finger is on the vertical strip.
-           Position ranges from 1-4095, with 1 at the bottom. */
-        val = ((data[1] >> 4) << 8) | data[2]; /* position */
-
-        if ((val > 0) && (val <= 1365))
-            int_btn |= BUTTON_DOWN;
-        else if ((val > 1365) && (val <= 2730))
-            int_btn |= BUTTON_SELECT;
-        else if ((val > 2730) && (val <= 4095))
-            int_btn |= BUTTON_UP;
-    }
-}
-#else
-void button_init_device(void){}
-#endif /* bootloader */
-
-/*
- * Get button pressed from hardware
- */
-int button_read_device(void)
-{
-    int btn = BUTTON_NONE;
-
-#ifdef HAVE_REMOTE_LCD
-    unsigned char data[5];
-
-    if (lcd_remote_read_device(data))
-    {
-        remote_hold = (data[2] & 0x80) ? true : false;
-        if (!remote_hold)
-        {
-            if (data[1] & 0x1)  btn |= BUTTON_RC_PLAY;
-            if (data[1] & 0x2)  btn |= BUTTON_RC_DOWN;
-            if (data[1] & 0x4)  btn |= BUTTON_RC_FF;
-            if (data[1] & 0x8)  btn |= BUTTON_RC_REW;
-            if (data[1] & 0x10) btn |= BUTTON_RC_VOL_UP;
-            if (data[1] & 0x20) btn |= BUTTON_RC_VOL_DOWN;
-            if (data[1] & 0x40) btn |= BUTTON_RC_MODE;
-            if (data[1] & 0x80) btn |= BUTTON_RC_HEART;
-        }
-    }
-#endif
-
-    if(!button_hold())
-    {
-        btn |= int_btn;
-
-        if (~GPIOA_INPUT_VAL & 0x40)
-            btn |= BUTTON_POWER;
-    }
-
-    return btn;
-}
-
-bool button_hold(void)
-{
-    return (GPIOD_INPUT_VAL & 0x10) ? false : true;
-}
-
-#ifdef HAVE_REMOTE_LCD
-bool remote_button_hold(void)
-{
-    return remote_hold;
-}
-
-bool headphones_inserted(void)
-{
-    return headphones_status;
-}
-
-void headphones_int(void)
-{
-    int state = 0x80 & ~GPIOD_INPUT_VAL;
-    headphones_status = (state) ? true : false;
-
-    GPIO_CLEAR_BITWISE(GPIOD_INT_EN, 0x80);
-    GPIO_WRITE_BITWISE(GPIOD_INT_LEV, state, 0x80);
-    GPIO_WRITE_BITWISE(GPIOD_INT_CLR, 0x80, 0x80);
-    GPIO_SET_BITWISE(GPIOD_INT_EN, 0x80);
-
-    lcd_remote_on();
-}
-#else
-bool headphones_inserted(void)
-{
-    return (GPIOD_INPUT_VAL & 0x80) ? false : true;
-}
-#endif
diff --git a/firmware/target/arm/olympus/mrobe-100/button-target.h b/firmware/target/arm/olympus/mrobe-100/button-target.h
deleted file mode 100644
index 93d42d6..0000000
--- a/firmware/target/arm/olympus/mrobe-100/button-target.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 _BUTTON_TARGET_H_
-#define _BUTTON_TARGET_H_
-
-#include <stdbool.h>
-#include "config.h"
-
-#define MEP_BUTTON_HEADER   0x1a
-#define MEP_BUTTON_ID       0x09
-#define MEP_ABSOLUTE_HEADER 0x0b
-
-bool button_hold(void);
-void button_init_device(void);
-int  button_read_device(void);
-
-#ifndef BOOTLOADER
-void button_int(void);
-#endif
-
-/* Main unit's buttons */
-#define BUTTON_PLAY         0x00000001
-#define BUTTON_MENU         0x00000002
-#define BUTTON_LEFT         0x00000004
-#define BUTTON_DISPLAY      0x00000008
-#define BUTTON_RIGHT        0x00000010
-#define BUTTON_SELECT       0x00000020
-#define BUTTON_UP           0x00000040
-#define BUTTON_SLIDE_UP     0x00000080
-#define BUTTON_DOWN         0x00000100
-#define BUTTON_SLIDE_DOWN   0x00000200
-#define BUTTON_POWER        0x00000400
-#define BUTTON_MAIN         (BUTTON_PLAY|BUTTON_MENU|BUTTON_LEFT|BUTTON_DISPLAY\
-                            |BUTTON_RIGHT|BUTTON_SELECT|BUTTON_UP|BUTTON_SLIDE_UP\
-                            |BUTTON_DOWN|BUTTON_SLIDE_DOWN|BUTTON_POWER)
-
-#define HAS_BUTTON_HOLD
-
-#define POWEROFF_BUTTON     BUTTON_POWER
-#define POWEROFF_COUNT      10
-
-#ifdef HAVE_REMOTE_LCD
-void headphones_int(void);
-bool remote_button_hold(void);
-
-/* Remote control's buttons */
-#define BUTTON_RC_PLAY      0x00010000
-#define BUTTON_RC_REW       0x00020000
-#define BUTTON_RC_FF        0x00040000
-#define BUTTON_RC_DOWN      0x00080000
-#define BUTTON_RC_HEART     0x00100000
-#define BUTTON_RC_MODE      0x00200000
-#define BUTTON_RC_VOL_UP    0x00400000
-#define BUTTON_RC_VOL_DOWN  0x00800000
-#define BUTTON_REMOTE       (BUTTON_RC_PLAY|BUTTON_RC_REW|BUTTON_RC_FF\
-                            |BUTTON_RC_DOWN|BUTTON_RC_HEART|BUTTON_RC_MODE\
-                            |BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN)
-
-#define HAS_REMOTE_BUTTON_HOLD
-#define RC_POWEROFF_BUTTON  BUTTON_RC_PLAY
-#else
-#define BUTTON_REMOTE 0
-#endif /* HAVE_REMOTE_LCD */
-
-#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/olympus/mrobe-100/lcd-as-mr100.S b/firmware/target/arm/olympus/mrobe-100/lcd-as-mr100.S
deleted file mode 100644
index 0977801..0000000
--- a/firmware/target/arm/olympus/mrobe-100/lcd-as-mr100.S
+++ /dev/null
@@ -1,104 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Jens Arnold
- *
- * 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"
-
-    .text
-    .align      2
-
-
-    .global     lcd_write_data
-    .type       lcd_write_data,%function
-
-lcd_write_data:
-    ldr     r12, =LCD1_BASE
-
-.loop:
-    ldrb    r2, [r0], #1
-1:
-    ldr     r3, [r12]
-    tst     r3, #LCD1_BUSY_MASK
-    bne     1b
-    str     r2, [r12, #0x10]
-
-    subs    r1, r1, #1
-    bne     .loop
-
-    bx      lr
-    .size   lcd_write_data,.-lcd_write_data
-
-
-    .global     lcd_grey_data
-    .type       lcd_grey_data,%function
-
-/* A high performance function to write grey phase data to the display,
- * one or multiple pixels.
- *
- * Arguments:
- *   r0 - pixel value data address
- *   r1 - pixel phase data address
- *   r2 - pixel block count
- *
- * Register usage:
- *   r3/r4 - current block of phases
- *   r5/r6 - current block of values
- *   r7  - lcd data accumulator
- *   r12 - phase signs mask
- *   lr  - lcd bridge address
- */
- 
-lcd_grey_data:
-    stmfd   sp!, {r4-r7, lr}
-    mov     r12, #0x80
-    orr     r12, r12, r12, lsl #8
-    orr     r12, r12, r12, lsl #16
-    ldr     lr, =LCD1_BASE
-
-.greyloop:
-    ldmia   r1, {r3-r4}
-    
-    and     r5, r12, r3         /* r5 = 3.......2.......1.......0....... */
-    and     r6, r12, r4         /* r6 = 7.......6.......5.......4....... */
-    orr     r5, r5, r6, lsr #4  /* r5 = 3...7...2...6...1...5...0...4... */
-    orr     r5, r5, r5, lsr #9  /* r5 = 3...7...23..67..12..56..01..45.. */
-    orr     r5, r5, r5, lsr #9  /* r5 = 3...7...23..67..123.567.012.456. */
-    orr     r5, r5, r5, lsr #9  /* r5 = 3...7...23..67..123.567.01234567 */
-    
-    ldmia   r0!, {r6-r7}
-    bic     r3, r3, r12
-    add     r3, r3, r6
-    bic     r4, r4, r12
-    add     r4, r4, r7
-    stmia   r1!, {r3-r4}
-
-1:
-    ldr     r6, [lr]
-    tst     r6, #LCD1_BUSY_MASK
-    bne     1b
-    str     r5, [lr, #0x10]
-
-    subs    r2, r2, #1
-    bne     .greyloop
-
-    ldmpc   regs=r4-r7
-    .size   lcd_grey_data,.-lcd_grey_data
-
diff --git a/firmware/target/arm/olympus/mrobe-100/lcd-mr100.c b/firmware/target/arm/olympus/mrobe-100/lcd-mr100.c
deleted file mode 100644
index a0ea2a6..0000000
--- a/firmware/target/arm/olympus/mrobe-100/lcd-mr100.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 "lcd.h"
-#include "kernel.h"
-#include "system.h"
-
-/* The m:robe 100 display has a register set that is very similar to the
-   Solomon SSD1815 */
-
-/*** definitions ***/
-
-#define LCD_SET_LOWER_COLUMN_ADDRESS              ((char)0x00)
-#define LCD_SET_HIGHER_COLUMN_ADDRESS             ((char)0x10)
-#define LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO ((char)0x20)
-#define LCD_SET_POWER_CONTROL_REGISTER            ((char)0x28)
-#define LCD_SET_DISPLAY_START_LINE                ((char)0x40)
-#define LCD_SET_CONTRAST_CONTROL_REGISTER         ((char)0x81)
-#define LCD_SET_SEGMENT_REMAP                     ((char)0xA0)
-#define LCD_SET_LCD_BIAS                          ((char)0xA2)
-#define LCD_SET_ENTIRE_DISPLAY_OFF                ((char)0xA4)
-#define LCD_SET_ENTIRE_DISPLAY_ON                 ((char)0xA5)
-#define LCD_SET_NORMAL_DISPLAY                    ((char)0xA6)
-#define LCD_SET_REVERSE_DISPLAY                   ((char)0xA7)
-#define LCD_SET_MULTIPLEX_RATIO                   ((char)0xA8)
-#define LCD_SET_BIAS_TC_OSC                       ((char)0xA9)
-#define LCD_SET_1OVER4_BIAS_RATIO                 ((char)0xAA)
-#define LCD_SET_INDICATOR_OFF                     ((char)0xAC)
-#define LCD_SET_INDICATOR_ON                      ((char)0xAD)
-#define LCD_SET_DISPLAY_OFF                       ((char)0xAE)
-#define LCD_SET_DISPLAY_ON                        ((char)0xAF)
-#define LCD_SET_PAGE_ADDRESS                      ((char)0xB0)
-#define LCD_SET_COM_OUTPUT_SCAN_DIRECTION         ((char)0xC0)
-#define LCD_SET_TOTAL_FRAME_PHASES                ((char)0xD2)
-#define LCD_SET_DISPLAY_OFFSET                    ((char)0xD3)
-#define LCD_SET_READ_MODIFY_WRITE_MODE            ((char)0xE0)
-#define LCD_SOFTWARE_RESET                        ((char)0xE2)
-#define LCD_NOP                                   ((char)0xE3)
-#define LCD_SET_END_OF_READ_MODIFY_WRITE_MODE     ((char)0xEE)
-
-/* LCD command codes */
-
-#define LCD_CNTL_RESET          0xe2    /* Software reset */
-#define LCD_CNTL_POWER          0x2f    /* Power control */
-#define LCD_CNTL_CONTRAST       0x81    /* Contrast */
-#define LCD_CNTL_OUTSCAN        0xc8    /* Output scan direction */
-#define LCD_CNTL_SEGREMAP       0xa1    /* Segment remap */
-#define LCD_CNTL_DISPON         0xaf    /* Display on */
-
-#define LCD_CNTL_PAGE           0xb0    /* Page address */
-#define LCD_CNTL_HIGHCOL        0x10    /* Upper column address */
-#define LCD_CNTL_LOWCOL         0x00    /* Lower column address */
-
-/* send LCD command */
-
-void lcd_write_command(int byte)
-{
-    while (LCD1_CONTROL & LCD1_BUSY_MASK); /* wait for LCD */
-    LCD1_CMD = byte;
-}
-
-static int xoffset; /* needed for flip */
-
-/*** hardware configuration ***/
-
-int lcd_default_contrast(void)
-{
-    return DEFAULT_CONTRAST_SETTING;
-}
-
-void lcd_set_contrast(int val)
-{
-    lcd_write_command(LCD_CNTL_CONTRAST);
-    lcd_write_command(val);
-}
-
-void lcd_set_invert_display(bool yesno)
-{
-    if (yesno) 
-        lcd_write_command(LCD_SET_REVERSE_DISPLAY);
-    else
-        lcd_write_command(LCD_SET_NORMAL_DISPLAY);
-}
-
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
-    if (!yesno)
-    {
-        /* normal */
-        lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0xc);
-        xoffset = 240 - LCD_WIDTH; /* 240 colums minus the 160 we have */
-    }
-    else
-    {
-        /* upside-down */
-        lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION);
-        xoffset = 0;
-    }
-}
-
-/* LCD init */
-void lcd_init_device(void)
-{
-    int i;
-
-    DEV_INIT1 &= ~0xfc000000;
-
-    i = DEV_INIT1;
-    DEV_INIT1 = i;
-
-    DEV_INIT2 &= ~0x400;
-    udelay(10000);
-
-    LCD1_CONTROL &= ~0x4;
-    udelay(15);
-
-    LCD1_CONTROL |= 0x4;
-    udelay(10);
-
-    LCD1_CONTROL = 0x0094;
-
-    /* OF just reads these */
-    LCD1_CONTROL;
-    inl(0x70003004);
-    LCD1_CMD;
-    inl(0x7000300c);
-
-    LCD1_CONTROL |= 0x1;
-    udelay(15000);
-
-    lcd_write_command(LCD_SOFTWARE_RESET);                   /* 0xE2 */
-    lcd_write_command(LCD_SET_POWER_CONTROL_REGISTER + 7);   /* 0x2F */
-               /* power control register: op-amp=1, regulator=1, booster=1 */
-    lcd_write_command(LCD_SET_INTERNAL_REGULATOR_RESISTOR_RATIO + 6); /* 0x26 */ 
-
-    lcd_set_flip(false);                                    /* 0xCC */
-
-    lcd_write_command(0xe8);
-
-    lcd_set_contrast(lcd_default_contrast());               /* 0x80, 0x00 */
-
-    lcd_write_command(LCD_SET_DISPLAY_START_LINE + 0);       /* 0x40 */
-    lcd_write_command(LCD_SET_NORMAL_DISPLAY);               /* 0xA6 */
-
-    lcd_write_command(0x88);
-
-    lcd_write_command(LCD_SET_PAGE_ADDRESS);                 /* 0xB0 */
-    lcd_write_command(LCD_SET_HIGHER_COLUMN_ADDRESS + 0);    /* 0x10 */
-    lcd_write_command(LCD_SET_LOWER_COLUMN_ADDRESS + 0);     /* 0x00 */
-
-    lcd_write_command(LCD_SET_DISPLAY_ON);                   /* 0xAF */
-}
-
-/*** update functions ***/
-
-/* Performance function that works with an external buffer
-   note that by and bheight are in 8-pixel units! */
-void lcd_blit_mono(const unsigned char* data, int x, int by, int width,
-              int bheight, int stride)
-{
-    int cmd1, cmd2;
-
-    cmd1 = LCD_CNTL_HIGHCOL | (((x + xoffset) >> 4) & 0xf);
-    cmd2 = LCD_CNTL_LOWCOL | ((x + xoffset) & 0xf);
-
-    /* Copy display bitmap to hardware */
-    while (bheight--)
-    {
-        lcd_write_command(LCD_CNTL_PAGE | (by++ & 0xff));
-        lcd_write_command(cmd1);
-        lcd_write_command(cmd2);
-
-        lcd_write_data(data, width);
-
-        data += stride;
-    }
-}
-
-/* Helper function for lcd_grey_phase_blit(). */
-void lcd_grey_data(unsigned char *values, unsigned char *phases, int count);
-
-/* Performance function that works with an external buffer
-   note that by and bheight are in 8-pixel units! */
-void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
-                         int x, int by, int width, int bheight, int stride)
-{
-    int cmd1, cmd2;
-
-    stride <<= 3;  /* 8 pixels per block */
-    cmd1 = LCD_CNTL_HIGHCOL | (((x + xoffset) >> 4) & 0xf);
-    cmd2 = LCD_CNTL_LOWCOL | ((x + xoffset) & 0xf);
-
-    while (bheight--)
-    {
-        lcd_write_command(LCD_CNTL_PAGE | (by++ & 0xff));
-        lcd_write_command(cmd1);
-        lcd_write_command(cmd2);
-
-        lcd_grey_data(values, phases, width);
-        values += stride;
-        phases += stride;
-    }
-}
- 
-/* Update the display.
-   This must be called after all other LCD functions that change the display. */
-void lcd_update(void) ICODE_ATTR;
-void lcd_update(void)
-{
-    int y, cmd1, cmd2;
-
-    cmd1 = LCD_CNTL_HIGHCOL | (((xoffset) >> 4) & 0xf);
-    cmd2 = LCD_CNTL_LOWCOL | ((xoffset) & 0xf);
-
-    /* Copy display bitmap to hardware */
-    for (y = 0; y < LCD_FBHEIGHT; y++)
-    {
-        lcd_write_command (LCD_CNTL_PAGE | (y & 0xf));
-        lcd_write_command(cmd1);
-        lcd_write_command(cmd2);
-
-        lcd_write_data (lcd_framebuffer[y], LCD_WIDTH);
-    }
-}
-
-/* Update a fraction of the display. */
-void lcd_update_rect(int, int, int, int) ICODE_ATTR;
-void lcd_update_rect(int x, int y, int width, int height)
-{
-    int ymax, cmd1, cmd2;
-
-    /* The Y coordinates have to work on even 8 pixel rows */
-    ymax = (y + height - 1) >> 3;
-    y >>= 3;
-
-    if(x + width > LCD_WIDTH)
-        width = LCD_WIDTH - x;
-    if (width <= 0)
-        return; /* nothing left to do, 0 is harmful to lcd_write_data() */
-    if(ymax >= LCD_FBHEIGHT)
-        ymax = LCD_FBHEIGHT-1;
-
-
-    cmd1 = LCD_CNTL_HIGHCOL | (((x + xoffset) >> 4) & 0xf);
-    cmd2 = LCD_CNTL_LOWCOL | ((x + xoffset) & 0xf);
-
-    /* Copy specified rectange bitmap to hardware */
-    for (; y <= ymax; y++)
-    {
-        lcd_write_command(LCD_CNTL_PAGE | (y & 0xf));
-        lcd_write_command(cmd1);
-        lcd_write_command(cmd2);
-
-        lcd_write_data (&lcd_framebuffer[y][x], width);
-    }
-}
diff --git a/firmware/target/arm/olympus/mrobe-100/lcd-remote-mr100.c b/firmware/target/arm/olympus/mrobe-100/lcd-remote-mr100.c
deleted file mode 100644
index d1e1c82..0000000
--- a/firmware/target/arm/olympus/mrobe-100/lcd-remote-mr100.c
+++ /dev/null
@@ -1,562 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2009 Mark Arigo
- *
- * 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 "cpu.h"
-#include "kernel.h"
-#include "thread.h"
-#include "system.h"
-#include "lcd-remote.h"
-#include "button.h"
-#include "button-target.h"
-
-/* Temporary defines until we sort out why the gui stuff doesn't like this size
-   (I believe the status bar isn't doing sanity checks and is writing outside
-   the frame buffer size). */
-#define RC_WIDTH                79
-#define RC_HEIGHT               16
-
-#define RC_CONTRAST_MASK        0x000000ff
-#define RC_SCREEN_ON            0x00000100
-#define RC_BACKLIGHT_ON         0x00000200
-
-#define RC_DEV_INIT             0x00001000
-#define RC_DETECTED             0x00002000
-#define RC_AWAKE                0x00004000
-#define RC_POWER_OFF            0x00008000
-
-#define RC_UPDATE_LCD           0x00010000
-#define RC_UPDATE_CONTROLLER    0x00020000
-#define RC_UPDATE_ICONS         0x00040000
-#define RC_UPDATE_MASK          (RC_UPDATE_LCD|RC_UPDATE_CONTROLLER|RC_UPDATE_ICONS)
-
-#define RC_TX_ERROR             0x00100000
-#define RC_RX_ERROR             0x00200000
-#define RC_TIMEOUT_ERROR        0x00400000
-#define RC_ERROR_MASK           (RC_TX_ERROR|RC_RX_ERROR|RC_TIMEOUT_ERROR)
-
-#define RC_FORCE_DETECT         0x80000000
-
-#define RX_READY                0x01
-#define TX_READY                0x20
-
-#define POLL_TIMEOUT            50000
-
-bool remote_initialized = false;
-unsigned int rc_status = 0;
-unsigned char rc_buf[5];
-
-/* ================================================== */
-/* Remote thread functions                            */
-/*   These functions are private to the remote thread */
-/* ================================================== */
-static struct semaphore rc_thread_wakeup;
-static unsigned int remote_thread_id;
-static int remote_stack[256/sizeof(int)];
-static const char * const remote_thread_name = "remote";
-
-static bool remote_wait_ready(int ready_mask)
-{
-    unsigned long current;
-    unsigned long start = USEC_TIMER;
-    unsigned long timeout = start + POLL_TIMEOUT;
-
-    rc_status &= ~RC_TIMEOUT_ERROR;
-
-    if (start <= timeout)
-    {
-        do
-        {
-            if (SER1_LSR & ready_mask)
-                return true;
-
-            //~ sleep(1);
-
-            current = USEC_TIMER;
-        } while (current < timeout);
-    }
-    else
-    {
-        do
-        {
-            if (SER1_LSR & ready_mask)
-                return true;
-
-            //~ sleep(1);
-
-            current = USEC_TIMER - POLL_TIMEOUT;
-        } while (current < start);
-    }
-
-    rc_status |= RC_TIMEOUT_ERROR;
-    return false;
-}
-
-static bool remote_rx(void)
-{
-    int i;
-    unsigned char chksum[2];
-
-    rc_status &= ~RC_RX_ERROR;
-
-    for (i = 0; i < 5; i++)
-    {
-        if (!remote_wait_ready(RX_READY))
-        {
-            rc_status |= RC_RX_ERROR;
-            return false;
-        }
-
-        rc_buf[i] = SER1_RBR;
-    }
-
-    /* check opcode */
-    if ((rc_buf[0] & 0xf0) != 0xf0)
-    {
-        rc_status |= RC_RX_ERROR;
-        return false;
-    }
-
-    /* verify the checksums */
-    chksum[0] = chksum[1] = 0;
-    for (i = 0; i < 3; i++)
-    {
-        chksum[0] ^= rc_buf[i];
-        chksum[1] += rc_buf[i];
-    }
-
-    if ((chksum[0] != rc_buf[3]) && (chksum[1] != rc_buf[4]))
-    {
-        rc_status |= RC_RX_ERROR;
-        return false;
-    }
-
-    /* reception error */
-    if ((rc_buf[0] & 0x1) || (rc_buf[0] & 0x2) || (rc_buf[0] & 0x4))
-    {
-        rc_status |= RC_RX_ERROR;
-        return false;
-    }
-
-    return true;
-}
-
-static bool remote_tx(unsigned char *data, int len)
-{
-    int i;
-    unsigned char chksum[2];
-
-    rc_status &= ~RC_TX_ERROR;
-    
-    chksum[0] = chksum[1] = 0;
-
-    for (i = 0; i < len; i++)
-    {
-        if (!remote_wait_ready(TX_READY))
-        {
-            rc_status |= RC_TX_ERROR;
-            return false;
-        }
-
-        SER1_THR = data[i];
-        chksum[0] ^= data[i];
-        chksum[1] += data[i];
-    }
-
-    for (i = 0; i < 2; i++)
-    {
-        if (!remote_wait_ready(TX_READY))
-        {
-            rc_status |= RC_TX_ERROR;
-            return false;
-        }
-
-        SER1_THR = chksum[i];
-    }
-
-    return remote_rx();
-}
-
-static void remote_dev_enable(bool enable)
-{
-    if (enable)
-    {
-        outl(inl(0x70000018) | 0xaa000, 0x70000018);
-        DEV_INIT2 &= ~0x800;
-
-        GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_VAL, 0x80);
-        GPIO_SET_BITWISE(GPIOL_OUTPUT_EN, 0x80);
-
-        DEV_EN |= DEV_SER1;
-
-        SER1_RBR;
-        SER1_LCR = 0x80;
-        SER1_DLL = 0x50;
-        SER1_DLM = 0x00;
-        SER1_LCR = 0x03;
-        SER1_FCR = 0x07;
-
-        rc_status |= RC_DEV_INIT;
-    }
-    else
-    {
-        outl(inl(0x70000018) & ~0xaa000, 0x70000018);
-        DEV_INIT2 &= ~0x800;
-
-        GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 0x80);
-        GPIO_SET_BITWISE(GPIOL_OUTPUT_EN, 0x80);
-
-        DEV_RS |= DEV_SER1;
-        nop;
-        DEV_RS &= ~DEV_SER1;
-
-        DEV_EN &= ~DEV_SER1;
-
-        rc_status &= ~RC_DEV_INIT;
-    }
-}
-
-void remote_update_lcd(void)
-{
-    int x, y, draw_now;
-    unsigned char data[RC_WIDTH + 7];
-
-    /* If the draw_now bit is set, the draw occurs directly on the LCD.
-       Otherwise, the data is stored in an off-screen buffer and displayed
-       the next time a draw operation is executed with this flag set. */
-    draw_now = 0;
-
-    for (y = 0; y < 2; y++)
-    {
-        data[0] = 0x51;
-        data[1] = draw_now << 7;
-        data[2] = RC_WIDTH;         /* width */
-        data[3] = 0;                /* x1    */
-        data[4] = y << 3;           /* y1    */
-        data[5] = RC_WIDTH;         /* x2    */
-        data[6] = (y + 1) << 3;     /* y2    */
-
-        for (x = 0; x < RC_WIDTH; x++)
-            data[x + 7] = lcd_remote_framebuffer[y][x];
-
-        remote_tx(data, RC_WIDTH + 7);
-
-        draw_now = 1;
-    }
-}
-
-static void remote_update_controller(void)
-{
-    unsigned char data[3];
-
-    data[0] = 0x31;
-    data[1] = 0x00;
-    if (rc_status & RC_SCREEN_ON)
-        data[1] |= 0x80;
-    if (rc_status & RC_BACKLIGHT_ON)
-        data[1] |= 0x40;
-    data[2] = (unsigned char)(rc_status & RC_CONTRAST_MASK);
-    remote_tx(data, 3);
-}
-
-#if 0
-static void remote_update_icons(unsigned char symbols)
-{
-    unsigned char data[2];
-
-    if (!(rc_status & RC_AWAKE) && !(rc_status & RC_SCREEN_ON))
-        return;
-
-    data[0] = 0x41;
-    data[1] = symbols;
-    remote_tx(data, 2);
-}
-#endif
-
-static bool remote_nop(void)
-{
-    unsigned char val[2];
-
-    val[0] = 0x11;
-    val[1] = 0x30;
-    return remote_tx(val, 2);
-}
-
-static void remote_wake(void)
-{
-    if (remote_nop())
-    {
-        rc_status |= RC_AWAKE;
-        return;
-    }
-
-    rc_status &= ~RC_AWAKE;
-    return;
-}
-
-static void remote_sleep(void)
-{
-    unsigned char data[2];
-
-    if (rc_status & RC_AWAKE)
-    {
-        data[0] = 0x71;
-        data[1] = 0x30;
-        remote_tx(data, 2);
-
-        udelay(25000);
-    }
-
-    rc_status &= ~RC_AWAKE;
-}
-
-static void remote_off(void)
-{
-    if (rc_status & RC_AWAKE)
-        remote_sleep();
-
-    if (rc_status & RC_DEV_INIT)
-        remote_dev_enable(false);
-
-    rc_status &= ~(RC_DETECTED | RC_ERROR_MASK | RC_UPDATE_MASK);
-    remote_initialized = false;
-}
-
-static void remote_on(void)
-{
-    if (!(rc_status & RC_DEV_INIT))
-        remote_dev_enable(true);
-
-    remote_wake();
-
-    if (rc_status & RC_AWAKE)
-    {
-        rc_status |= RC_DETECTED;
-        remote_initialized = true;
-
-        rc_status |= (RC_UPDATE_MASK | RC_SCREEN_ON | RC_BACKLIGHT_ON);
-        //~ remote_update_icons(0xf0); /* show battery */
-    }
-    else
-    {
-        rc_status &= ~RC_DETECTED;
-        remote_initialized = false;
-    }
-}
-
-static void remote_thread(void)
-{
-    int rc_thread_sleep_count = 10;
-    int rc_thread_wait_timeout = TIMEOUT_BLOCK;
-
-    while (1)
-    {
-        semaphore_wait(&rc_thread_wakeup, rc_thread_wait_timeout);
-
-        /* Error handling (most likely due to remote not present) */
-        if (rc_status & RC_ERROR_MASK)
-        {
-            if (--rc_thread_sleep_count == 0)
-                rc_status |= RC_POWER_OFF;
-        }
-
-        /* Power-off (thread sleeps) */
-        if (rc_status & RC_POWER_OFF)
-        {
-            remote_off();
-
-            rc_thread_sleep_count = 10;
-            rc_thread_wait_timeout = TIMEOUT_BLOCK;
-
-            continue;
-        }
-
-        /* Detection */
-        if (!(rc_status & RC_DETECTED))
-        {
-            rc_thread_wait_timeout = HZ;
-
-            if (headphones_inserted())
-            {
-                remote_on();
-
-                if (rc_status & RC_AWAKE)
-                {
-                    rc_thread_sleep_count = 10;
-                    rc_thread_wait_timeout = HZ/20; /* ~50ms for updates */
-                }
-            }
-            else
-            {
-                if (--rc_thread_sleep_count == 0)
-                    rc_status &= ~RC_POWER_OFF;
-            }
-
-            continue;
-        }
-
-        /* Update the remote (one per wakeup cycle) */
-        if (headphones_inserted() && (rc_status & RC_AWAKE))
-        {
-            if (rc_status & RC_SCREEN_ON)
-            {
-                /* In order of importance */
-                if (rc_status & RC_UPDATE_CONTROLLER)
-                {
-                    remote_update_controller();
-                    rc_status &= ~RC_UPDATE_CONTROLLER;
-                }
-                else if (rc_status & RC_UPDATE_LCD)
-                {
-                    remote_update_lcd();
-                    rc_status &= ~RC_UPDATE_LCD;
-                }
-                else
-                {
-                    remote_nop();
-                }
-            }
-            else
-            {
-                remote_nop();
-            }
-        }
-    }
-}
-
-/* ============================================= */
-/* Public functions                              */
-/*   These should only set the update flags that */
-/*   will be executed in the remote thread.      */
-/* ============================================= */
-bool lcd_remote_read_device(unsigned char *data)
-{
-    if (!(rc_status & RC_AWAKE) || (rc_status & RC_ERROR_MASK))
-        return false;
-
-    /* Return the most recent data. While the remote is plugged,
-       this is updated ~50ms */
-    data[0] = rc_buf[0];
-    data[1] = rc_buf[1];
-    data[2] = rc_buf[2];
-    data[3] = rc_buf[3];
-    data[4] = rc_buf[4];
-
-    return true;
-}
-
-void lcd_remote_set_invert_display(bool yesno)
-{
-    /* dummy function...need to introduce HAVE_LCD_REMOTE_INVERT */
-    (void)yesno;
-}
-
-/* turn the display upside down (call lcd_remote_update() afterwards) */
-void lcd_remote_set_flip(bool yesno)
-{
-    /* dummy function...need to introduce HAVE_LCD_REMOTE_FLIP */
-    (void)yesno;
-}
-
-int lcd_remote_default_contrast(void)
-{
-    return DEFAULT_REMOTE_CONTRAST_SETTING;
-}
-
-void lcd_remote_set_contrast(int val)
-{
-    rc_status = (rc_status & ~RC_CONTRAST_MASK) | (val & RC_CONTRAST_MASK);
-    rc_status |= RC_UPDATE_CONTROLLER;
-}
-
-void lcd_remote_backlight(bool on)
-{
-    if (on)
-        rc_status |= RC_BACKLIGHT_ON;
-    else
-        rc_status &= ~RC_BACKLIGHT_ON;
-
-    rc_status |= RC_UPDATE_CONTROLLER;
-}
-
-void lcd_remote_off(void)
-{
-    /* should only be used to power off at shutdown */
-    rc_status |= RC_POWER_OFF;
-    semaphore_release(&rc_thread_wakeup);
-
-    /* wait until the things are powered off */
-    while (rc_status & RC_DEV_INIT)
-        sleep(HZ/10);
-}
-
-void lcd_remote_on(void)
-{
-    /* Only wake the remote thread if it's in the blocked state. */
-    struct thread_entry *rc_thread = thread_id_entry(remote_thread_id);
-    if (rc_thread->state == STATE_BLOCKED || (rc_status & RC_FORCE_DETECT))
-    {
-        rc_status &= ~RC_FORCE_DETECT;
-        rc_status &= ~RC_POWER_OFF;
-        semaphore_release(&rc_thread_wakeup);
-    }
-}
-
-bool remote_detect(void)
-{
-    return (rc_status & RC_DETECTED);
-}
-
-void lcd_remote_init_device(void)
-{
-    /* reset */
-    remote_dev_enable(false);
-    rc_status |= RC_FORCE_DETECT; /* force detection at startup */
-
-    /* unknown */
-    GPIO_SET_BITWISE(GPIOL_ENABLE, 0x80);
-    GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_VAL, 0x80);
-    GPIO_SET_BITWISE(GPIOL_OUTPUT_EN, 0x80);
-
-    /* a thread is required to poll & update the remote */
-    semaphore_init(&rc_thread_wakeup, 1, 0);
-    remote_thread_id = create_thread(remote_thread, remote_stack,
-                            sizeof(remote_stack), 0, remote_thread_name
-                            IF_PRIO(, PRIORITY_SYSTEM)
-                            IF_COP(, CPU));
-}
-
-/* Update the display.
-   This must be called after all other LCD functions that change the display. */
-void lcd_remote_update(void)
-{
-    rc_status |= RC_UPDATE_LCD;
-}
-
-/* Update a fraction of the display. */
-void lcd_remote_update_rect(int x, int y, int width, int height)
-{
-    (void)x;
-    (void)y;
-    (void)width;
-    (void)height;
-
-    rc_status |= RC_UPDATE_LCD;
-}
diff --git a/firmware/target/arm/olympus/mrobe-100/lcd-remote-target.h b/firmware/target/arm/olympus/mrobe-100/lcd-remote-target.h
deleted file mode 100644
index b5a5010..0000000
--- a/firmware/target/arm/olympus/mrobe-100/lcd-remote-target.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id: lcd-remote-target.h 11967 2007-01-09 23:29:07Z linus $
- *
- * Copyright (C) 2007 by Jens Arnold
- *
- * 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 LCD_REMOTE_TARGET_H
-#define LCD_REMOTE_TARGET_H
-
-bool remote_detect(void);    /* returns detection status */
-
-void lcd_remote_set_invert_display(bool yesno);
-void lcd_remote_set_flip(bool yesno);
-void lcd_remote_backlight(bool on);
-
-void lcd_remote_init_device(void);
-void lcd_remote_on(void);
-void lcd_remote_off(void);
-void lcd_remote_update(void);
-void lcd_remote_update_rect(int, int, int, int);
-bool lcd_remote_read_device(unsigned char *data);
-
-extern bool remote_initialized;
-extern unsigned int rc_status;
-extern unsigned char rc_buf[5];
-#endif
diff --git a/firmware/target/arm/olympus/mrobe-100/power-mr100.c b/firmware/target/arm/olympus/mrobe-100/power-mr100.c
deleted file mode 100644
index 6f6ee2b..0000000
--- a/firmware/target/arm/olympus/mrobe-100/power-mr100.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 "kernel.h"
-#include "system.h"
-#include "power.h"
-#include "logf.h"
-#include "usb.h"
-#include "lcd-remote-target.h"
-
-void power_init(void)
-{
-    /* Enable power-off bit */
-    GPIOB_ENABLE     |=  0x80;
-    GPIOB_OUTPUT_VAL &= ~0x80;
-    GPIOB_OUTPUT_EN  |=  0x80;
-
-    /* IDE power */
-    GPIOC_ENABLE     |=  0x8;
-    GPIOC_OUTPUT_VAL &= ~0x8;
-    GPIOC_OUTPUT_EN  |=  0x8;
-}
-
-unsigned int power_input_status(void)
-{
-    return (GPIOL_INPUT_VAL & 0x24) ?
-        POWER_INPUT_MAIN_CHARGER : POWER_INPUT_NONE;
-}
-
-void ide_power_enable(bool on)
-{
-    if(on)
-    {
-        GPIO_CLEAR_BITWISE(GPIOC_OUTPUT_VAL, 0x08);
-        DEV_EN |= DEV_IDE0;
-    }
-    else
-    {
-        DEV_EN &= ~DEV_IDE0;
-        GPIO_SET_BITWISE(GPIOC_OUTPUT_VAL, 0x08);
-    }
-}
-
-
-bool ide_powered(void)
-{
-    return ((GPIOC_INPUT_VAL & 0x8) == 0);
-}
-
-void power_off(void)
-{
-#ifdef HAVE_REMOTE_LCD
-    lcd_remote_off();
-#endif
-
-    /* Disable interrupts on this core */
-    disable_interrupt(IRQ_FIQ_STATUS);
-
-    /* Mask them on both cores */
-    CPU_INT_DIS = -1;
-    COP_INT_DIS = -1;
-
-    while (1)
-        GPIOB_OUTPUT_VAL |= 0x80;
-}
diff --git a/firmware/target/arm/olympus/mrobe-100/powermgmt-mr100.c b/firmware/target/arm/olympus/mrobe-100/powermgmt-mr100.c
deleted file mode 100644
index c8d5584..0000000
--- a/firmware/target/arm/olympus/mrobe-100/powermgmt-mr100.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
- * Revisions copyright (C) 2005 by Gerald Van Baren
- *
- * 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 "adc.h"
-#include "powermgmt.h"
-
-const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
-{
-    3450 
-};
-
-const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
-{
-    3400
-};
-
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
-const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
-{
-    { 3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 },
-};
-
-#if CONFIG_CHARGING
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
-const unsigned short percent_to_volt_charge[11] =
-{
-    3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 
-};
-#endif /* CONFIG_CHARGING */
-
-#define BATTERY_SCALE_FACTOR 6003
-/* full-scale ADC readout (2^10) in millivolt */
-
-/* adc readout
- * max with charger connected: 690
- * max fully charged:          682
- * min just before shutdown:   570
- */
-
-/* Returns battery voltage from ADC [millivolts] */
-unsigned int battery_adc_voltage(void)
-{
-    return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
-}
diff --git a/firmware/target/arm/pbell/app.lds b/firmware/target/arm/pbell/app.lds
deleted file mode 100644
index de355c3..0000000
--- a/firmware/target/arm/pbell/app.lds
+++ /dev/null
@@ -1,204 +0,0 @@
-#include "config.h"
-
-ENTRY(start)
-
-OUTPUT_FORMAT(elf32-littlearm)
-OUTPUT_ARCH(arm)
-STARTUP(target/arm/crt0-pp.o)
-
-#define PLUGINSIZE PLUGIN_BUFFER_SIZE
-#define CODECSIZE CODEC_SIZE
-
-#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - CODECSIZE
-
-#define DRAMORIG 0x00000000
-#define IRAMORIG 0x40000000
-#define IRAMSIZE 0xc000
-
-#ifdef CPU_PP502x
-#define NOCACHE_BASE 	0x10000000
-#else
-#define NOCACHE_BASE 	0x28000000
-#endif
-
-#define CACHEALIGN_SIZE 16
-
-/* End of the audio buffer, where the codec buffer starts */
-#define ENDAUDIOADDR  (DRAMORIG + DRAMSIZE)
-
-/* Where the codec buffer ends, and the plugin buffer starts */
-#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
-
-MEMORY
-{
-    DRAM : ORIGIN = DRAMORIG,     LENGTH = DRAMSIZE
-    IRAM : ORIGIN = IRAMORIG,     LENGTH = IRAMSIZE
-}
-
-SECTIONS
-{
-    .text :
-    {
-        loadaddress = .;
-        _loadaddress = .;
-        . = ALIGN(0x200);
-        *(.init.text)
-        *(.text*)
-        *(.glue_7)
-        *(.glue_7t)
-        . = ALIGN(0x4);
-    } > DRAM
-
-    .rodata :
-    {
-        *(.rodata)  /* problems without this, dunno why */
-        *(.rodata*)
-        *(.rodata.str1.1)
-        *(.rodata.str1.4)
-        . = ALIGN(0x4);
-
-        /* Pseudo-allocate the copies of the data sections */
-        _datacopy = .;
-    } > DRAM
-
-    /* TRICK ALERT! For RAM execution, we put the .data section at the
-       same load address as the copy. Thus, we don't waste extra RAM
-       when we don't actually need the copy.  */
-    .data : AT ( _datacopy )
-    {
-        _datastart = .;
-        *(.data*)
-        . = ALIGN(0x4);
-        _dataend  = .;
-    } > DRAM
-
-#if NOCACHE_BASE != 0
-    /* .ncdata section is placed at uncached physical alias address and is
-     * loaded at the proper cached virtual address - no copying is
-     * performed in the init code */
-    .ncdata . + NOCACHE_BASE :
-    {
-        . = ALIGN(CACHEALIGN_SIZE);
-        *(.ncdata*)
-        . = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-#endif
-    
-    /DISCARD/ :
-    {
-        *(.eh_frame)
-    }
-
-    .vectors 0x0 :
-    {
-        _vectorsstart = .;
-        *(.vectors);
-        _vectorsend = .;
-    } AT> DRAM
-
-    _vectorscopy = LOADADDR(.vectors);
-    _noloaddram  = LOADADDR(.vectors);
-
-    .ibss IRAMORIG (NOLOAD) :
-    {
-        _iedata = .;
-        *(.qharray)
-        *(.ibss)
-        . = ALIGN(0x4);
-        _iend = .;
-    } > IRAM
-
-    .iram _iend :
-    {
-        _iramstart = .;
-        *(.icode)
-        *(.irodata)
-        *(.idata)
-        . = ALIGN(0x4);
-        _iramend = .;
-    } > IRAM AT> DRAM
-
-    _iramcopy = LOADADDR(.iram);
-
-
-    .init ENDAUDIOADDR : 
-    {
-        . = ALIGN(4);
-        _initstart = .;
-        *(.init)
-        _initend = .;
-    } AT> DRAM
-
-    _initcopy = LOADADDR(.init);
-
-    .idle_stacks (NOLOAD) :
-    {
-       *(.idle_stacks)
-#if NUM_CORES > 1
-       cpu_idlestackbegin = .;
-       . += IDLE_STACK_SIZE;
-       cpu_idlestackend = .;
-#endif
-       cop_idlestackbegin = .;
-       . += IDLE_STACK_SIZE;
-       cop_idlestackend = .;
-    } > IRAM
-
-    .stack (NOLOAD) :
-    {
-       *(.stack)
-       stackbegin = .;
-       . += 0x2000;
-       stackend = .;
-    } > IRAM
-    
-    /* .bss and .ncbss are treated as a single section to use one init loop to
-     * zero it - note "_edata" and "_end" */
-    .bss _noloaddram (NOLOAD) :
-    {
-       _edata = .;
-        *(.bss*)
-        *(COMMON)
-        . = ALIGN(0x4);
-    } > DRAM
-
-#if NOCACHE_BASE != 0
-    .ncbss . + NOCACHE_BASE (NOLOAD):
-    {
-    	. = ALIGN(CACHEALIGN_SIZE);
-        *(.ncbss*)
-    	. = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-#endif
-
-    /* This will be aligned by preceding alignments */
-    .endaddr . - NOCACHE_BASE (NOLOAD) :
-    {
-        _end = .;
-    } > DRAM
-
-    .audiobuf (NOLOAD) :
-    {
-        _audiobuffer = .;
-        . = ALIGN(0x4);
-        audiobuffer = .;
-    } > DRAM
-    
-    .audiobufend ENDAUDIOADDR (NOLOAD) :
-    {
-        audiobufend = .;
-        _audiobufend = .;
-    } > DRAM
-
-    .codec ENDAUDIOADDR (NOLOAD) :
-    {
-        codecbuf = .;
-        _codecbuf = .;
-    }
-
-    .plugin ENDADDR (NOLOAD) :
-    {
-        _pluginbuf = .;
-        pluginbuf = .;
-    }
-}
diff --git a/firmware/target/arm/pbell/boot.lds b/firmware/target/arm/pbell/boot.lds
deleted file mode 100644
index 10bde4e..0000000
--- a/firmware/target/arm/pbell/boot.lds
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "config.h"
-
-ENTRY(start)
-OUTPUT_FORMAT(elf32-littlearm)
-OUTPUT_ARCH(arm)
-STARTUP(target/arm/crt0-pp-bl.o)
-
-#define DRAMSIZE (MEMORYSIZE * 0x100000)
-
-#define DRAMORIG 0x10000000
-#define IRAMORIG 0x40000000
-#define IRAMSIZE 0x18000
-#define FLASHORIG 0x001f0000
-#define FLASHSIZE 2M
-
-MEMORY
-{
-    DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
-    IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
-}
-
-SECTIONS
-{
-  . = IRAMORIG;
-
-  .text : {
-    *(.init.text)
-    *(.text*)
-    *(.glue_7)
-    *(.glue_7t)
-  } > IRAM
-
-  .data : {
-    *(.icode)
-    *(.irodata)
-    *(.idata)
-    *(.data*)
-    *(.ncdata*)
-    *(.rodata*)
-    _dataend = . ;
-  } > IRAM
-
-  .stack (NOLOAD) : {
-     *(.stack)
-     _stackbegin = .;
-     stackbegin = .;
-     . += 0x2000;
-     _stackend = .;
-     stackend = .;
-  } > IRAM
-
-  /* The bss section is too large for IRAM - we just move it 16MB into the
-     DRAM */
-
-  . = DRAMORIG;
-  .bss . + (16*1024*1024) (NOLOAD) : {
-     _edata = .;
-     *(.bss*);
-     *(.ibss);
-     *(COMMON)
-     *(.ncbss*);
-     _end = .;
-  } > DRAM
-}
diff --git a/firmware/target/arm/pbell/vibe500/adc-target.h b/firmware/target/arm/pbell/vibe500/adc-target.h
deleted file mode 100644
index 79a3f2d..0000000
--- a/firmware/target/arm/pbell/vibe500/adc-target.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2009 by Szymon Dziok
- *
- * 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 _ADC_TARGET_H_
-#define _ADC_TARGET_H_
-
-#define NUM_ADC_CHANNELS 1
-
-#define ADC_BATTERY     0
-#define ADC_UNKNOWN_1   1
-#define ADC_UNKNOWN_2   2
-#define ADC_UNKNOWN_3   3
-#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
-
-/* Force a scan now */
-unsigned short adc_scan(int channel);
-
-#endif
diff --git a/firmware/target/arm/pbell/vibe500/backlight-target.h b/firmware/target/arm/pbell/vibe500/backlight-target.h
deleted file mode 100644
index 7fd6d87..0000000
--- a/firmware/target/arm/pbell/vibe500/backlight-target.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2009 by Szymon Dziok
- *
- * 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 BACKLIGHT_TARGET_H
-#define BACKLIGHT_TARGET_H
-
-#define _backlight_init() true
-void _backlight_on(void);
-void _backlight_off(void);
-
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
-void _backlight_set_brightness(int brightness);
-#endif
-
-#ifdef HAVE_BUTTON_LIGHT
-void _buttonlight_on(void);
-void _buttonlight_off(void);
-void _buttonlight_set_brightness(int brightness);
-#endif
-
-#endif /* BACKLIGHT_TARGET.H */
diff --git a/firmware/target/arm/pbell/vibe500/backlight-vibe500.c b/firmware/target/arm/pbell/vibe500/backlight-vibe500.c
deleted file mode 100644
index ab71012..0000000
--- a/firmware/target/arm/pbell/vibe500/backlight-vibe500.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2009 by Szymon Dziok
- * Based on the Iriver H10 and the Philips HD1630 code.
- *
- * 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 "system.h"
-#include "backlight.h"
-#include "backlight-target.h"
-#include "lcd.h"
-#include "synaptics-mep.h"
-
-void _backlight_on(void)
-{
-#ifdef HAVE_LCD_ENABLE
-    lcd_enable(true); /* power on lcd + visible display */
-#endif
-    GPIO_SET_BITWISE(GPIOJ_OUTPUT_VAL, 0x01);
-}
-
-void _backlight_off(void)
-{
-    GPIO_CLEAR_BITWISE(GPIOJ_OUTPUT_VAL, 0x01);
-#ifdef HAVE_LCD_ENABLE
-    lcd_enable(false); /* power off visible display */
-#endif
-}
-
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
-static const int brightness_vals[16] =
-                {255,237,219,201,183,165,147,130,112,94,76,58,40,22,5,0};
-
-void _backlight_set_brightness(int brightness)
-{
-    /* From PB Vibe Bootloader and OF */
-    DEV_INIT1&=0xFFFF3F3F;
-    DEV_INIT1+=0x4000;
-    DEV_EN |= 0x20000;
-    outl(0x80000000 | (brightness_vals[brightness-1] << 16), 0x7000a010);
-}
-#endif
-
-#ifdef HAVE_BUTTON_LIGHT
-static unsigned short buttonlight_status = 0;
-
-void _buttonlight_on(void)
-{
-    if (!buttonlight_status)
-    {
-        touchpad_set_parameter(0, 0x22, 0x000f); /* 0x22 - GPO_ENABLE */
-        buttonlight_status = 1;
-    }
-}
-
-void _buttonlight_off(void)
-{
-    if (buttonlight_status)
-    {
-        touchpad_set_parameter(0, 0x22, 0x0000); /* 0x22 - GPO_ENABLE */
-        buttonlight_status = 0;
-    }
-}
-
-void _buttonlight_set_brightness(int brightness)
-{
-    /* no brightness control, but lights stays on - for compatibility */
-    (void)brightness;
-    touchpad_set_parameter(0, 0x22, 0x000f); /* 0x22 - GPO_ENABLE */
-    buttonlight_status = 1;
-}
-#endif
diff --git a/firmware/target/arm/pbell/vibe500/button-target.h b/firmware/target/arm/pbell/vibe500/button-target.h
deleted file mode 100644
index fa29c27..0000000
--- a/firmware/target/arm/pbell/vibe500/button-target.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2009 by Szymon Dziok
- *
- * 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 _BUTTON_TARGET_H_
-#define _BUTTON_TARGET_H_
-
-#include <stdbool.h>
-#include "config.h"
-
-#define MEP_BUTTON_HEADER   0x19
-#define MEP_BUTTON_ID       0x09
-#define MEP_ABSOLUTE_HEADER 0x0b
-#define MEP_FINGER          0x01
-
-#define HAS_BUTTON_HOLD
-
-bool button_hold(void);
-void button_init_device(void);
-int button_read_device(void);
-
-#ifndef BOOTLOADER
-void button_int(void);
-#endif
-
-
-#define BUTTON_POWER        0x00000001
-#define BUTTON_MENU         0x00000002
-#define BUTTON_PLAY         0x00000004
-#define BUTTON_PREV         0x00000008
-#define BUTTON_NEXT         0x00000010
-#define BUTTON_REC          0x00000020 /* RECORD */
-#define BUTTON_UP           0x00000040 /* Scrollstrip up move */
-#define BUTTON_DOWN         0x00000080 /* Scrollstrip down move */
-#define BUTTON_OK           0x00000100
-#define BUTTON_CANCEL       0x00000200
-
-/* there are no LEFT/RIGHT buttons, but other parts of the code expect them */
-#define BUTTON_LEFT         0x00000400
-#define BUTTON_RIGHT        0x00000800
-
-#define BUTTON_MAIN         0x00000fff
-
-#define BUTTON_REMOTE       0
-
-#define POWEROFF_BUTTON BUTTON_POWER
-#define POWEROFF_COUNT 10
-
-#endif /* _BUTTON_TARGET_H_ */
-
diff --git a/firmware/target/arm/pbell/vibe500/button-vibe500.c b/firmware/target/arm/pbell/vibe500/button-vibe500.c
deleted file mode 100644
index 54b4d2d..0000000
--- a/firmware/target/arm/pbell/vibe500/button-vibe500.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2009 Szymon Dziok
- * Based on the Iriver H10 and the Philips HD1630 code
- *
- * 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 "system.h"
-#include "button.h"
-#include "backlight.h"
-#include "powermgmt.h"
-#include "synaptics-mep.h"
-
-static int int_btn = BUTTON_NONE;
-static int old_pos = -1;
-
-static int scroll_repeat = BUTTON_NONE;
-static int repeat = 0;
-
-void button_init_device(void)
-{
-}
-
-/*
- * Button interrupt handler
- */
-void button_int(void)
-{
-    char data[4];
-    int val;
-
-    int_btn = BUTTON_NONE;
-
-    val = touchpad_read_device(data, 4);
-
-    if (data[0] == MEP_BUTTON_HEADER)
-    {
-        /* Buttons packet */
-        if (data[1] & 0x1)
-            int_btn |= BUTTON_MENU;
-        if (data[1] & 0x2)
-            int_btn |= BUTTON_PLAY;
-        if (data[1] & 0x4)
-            int_btn |= BUTTON_NEXT;
-        if (data[1] & 0x8)
-            int_btn |= BUTTON_PREV;
-    }
-    else if (data[0] == MEP_ABSOLUTE_HEADER)
-    {
-        if (data[1] & MEP_FINGER)
-        {
-            /* Absolute packet - the finger is on the vertical strip.
-               Position ranges from 1-4095, with 1 at the bottom. */
-            val = ((data[1] >> 4) << 8) | data[2]; /* position */
-
-            int scr_pos = val >> 8; /* split the scrollstrip into 16 regions */
-            if ((old_pos<scr_pos)&&(old_pos!=-1)) int_btn = BUTTON_DOWN;
-            if ((old_pos>scr_pos)&&(old_pos!=-1)) int_btn = BUTTON_UP;
-
-            old_pos = scr_pos;
-
-            /* repeat button */
-            repeat = 0;
-            if (int_btn!=BUTTON_NONE)
-            {
-                if (int_btn!=scroll_repeat)
-                scroll_repeat = int_btn;
-                else repeat = BUTTON_REPEAT;
-            }
-        }
-        else
-        {
-            old_pos = -1; 
-            scroll_repeat = BUTTON_NONE; 
-        }
-    }
-}
-
-int button_read_device(void)
-{
-    int buttons = int_btn;
-    unsigned char state;
-    static bool hold_button = false;
-    bool hold_button_old;
-
-    hold_button_old = hold_button;
-    hold_button = button_hold();
-
-#ifndef BOOTLOADER
-    if (hold_button != hold_button_old)
-    {
-        backlight_hold_changed(hold_button);
-    }
-#endif
-
-    /* device buttons */
-    if (!hold_button)
-    {
-        /* Read Record, OK, C */
-        state = GPIOA_INPUT_VAL;
-        if ((state & 0x01)==0) buttons|=BUTTON_REC;
-        if ((state & 0x40)==0) buttons|=BUTTON_OK;
-        if ((state & 0x08)==0) buttons|=BUTTON_CANCEL;
-
-        /* Read POWER button */
-        if ((GPIOD_INPUT_VAL & 0x40)==0) buttons|=BUTTON_POWER;
-
-        /* Scrollstrip direct button post - much better response */
-        if ((buttons==BUTTON_UP) || (buttons==BUTTON_DOWN))
-        {
-            queue_post(&button_queue,buttons|repeat,0);
-            backlight_on();
-            buttonlight_on();
-            reset_poweroff_timer();
-            buttons = BUTTON_NONE;
-            int_btn = BUTTON_NONE;
-            repeat = BUTTON_NONE;
-        }
-    }
-    else return BUTTON_NONE;
-    return buttons;
-}
-
-bool button_hold(void)
-{
-    /* GPIOK 01000000B - HOLD when bit not set */
-    return (GPIOK_INPUT_VAL & 0x40)?false:true;
-}
diff --git a/firmware/target/arm/pbell/vibe500/lcd-as-vibe500.S b/firmware/target/arm/pbell/vibe500/lcd-as-vibe500.S
deleted file mode 100644
index 9079be6..0000000
--- a/firmware/target/arm/pbell/vibe500/lcd-as-vibe500.S
+++ /dev/null
@@ -1,556 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2007-2008 by Michael Sevakis
- * Adapted for the Packard Bell Vibe 500 by Szymon Dziok
- * 
- * Packard Bell Vibe 500 LCD assembly routines
- *
- * 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"
-
-/****************************************************************************
- * void lcd_write_yuv_420_lines(unsigned char const * const src[3],
- *                              int width,
- *                              int stride);
- *
- *   |R|   |1.000000 -0.000001  1.402000| |Y'|
- *   |G| = |1.000000 -0.334136 -0.714136| |Pb|
- *   |B|   |1.000000  1.772000  0.000000| |Pr|
- *   Scaled, normalized, rounded and tweaked to yield RGB 565:
- *   |R|   |74   0 101| |Y' -  16| >> 9
- *   |G| = |74 -24 -51| |Cb - 128| >> 8
- *   |B|   |74 128   0| |Cr - 128| >> 9
- *
- * Write four RGB565 pixels in the following order on each loop:
- * 1 3 + > down
- * 2 4 \/ left
- */
-    .section    .icode, "ax", %progbits
-    .align      2
-    .global     lcd_write_yuv420_lines
-    .type       lcd_write_yuv420_lines, %function
-lcd_write_yuv420_lines:
-                                        @ r0 = yuv_src
-                                        @ r1 = width
-                                        @ r2 = stride
-    stmfd       sp!, { r4-r11, lr }     @ save non-scratch
-    ldmia       r0, { r4, r5, r6 }      @ r4 = yuv_src[0] = Y'_p
-                                        @ r5 = yuv_src[1] = Cb_p
-                                        @ r6 = yuv_src[2] = Cr_p
-                                        @
-    ldr         r0, =LCD1_BASE          @
-                                        @
-    sub         r2, r2, #1              @ Adjust stride because of increment
-10: @ loop line                         @
-    ldrb        r7, [r4], #1            @ r7 = *Y'_p++;
-    ldrb        r8, [r5], #1            @ r8 = *Cb_p++;
-    ldrb        r9, [r6], #1            @ r9 = *Cr_p++;
-                                        @
-    sub         r7, r7, #16             @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @ actually (Y' - 16)*37 and shift right
-    add         r7, r12, r7, asl #5     @ by one less when adding - same for all
-                                        @
-    sub         r8, r8, #128            @ Cb -= 128
-    sub         r9, r9, #128            @ Cr -= 128
-                                        @
-    add         r10, r9, r9, asl #1     @ r10 = Cr*51 + Cb*24
-    add         r10, r10, r10, asl #4   @
-    add         r10, r10, r8, asl #3    @
-    add         r10, r10, r8, asl #4    @
-                                        @
-    add         r11, r9, r9, asl #2     @ r9 = Cr*101
-    add         r11, r11, r9, asl #5    @
-    add         r9, r11, r9, asl #6     @
-                                        @
-    add         r8, r8, #2              @ r8 = bu = (Cb*128 + 128) >> 8
-    mov         r8, r8, asr #2          @
-    add         r9, r9, #256            @ r9 = rv = (r8 + 256) >> 9
-    mov         r9, r9, asr #9          @
-    rsb         r10, r10, #128          @ r10 = guv = (-r9 + 128) >> 8
-    mov         r10, r10, asr #8        @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3 = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
-    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
-                                        @
-    movs         r7, r3, lsr #8         @ store pixel
-20:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         20b                     @
-    str         r7, [r0, #0x10]         @
-25:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         25b                     @
-    str         r3, [r0, #0x10]         @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4], #1           @ r12 = Y' = *(Y'_p++)
-                                        @
-    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
-    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
-                                        @
-    movs         r7, r3, lsr #8         @ store pixel
-20:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         20b                     @
-    str         r7, [r0, #0x10]         @
-25:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         25b                     @
-    str         r3, [r0, #0x10]         @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    orr         r3, r3, r7, lsl #5      @ r3 = b | (g << 5)
-    orr         r3, r3, r11, lsl #11    @ r3 |= (r << 11)
-                                        @
-    movs         r7, r3, lsr #8         @ store pixel
-20:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         20b                     @
-    str         r7, [r0, #0x10]         @
-25:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         25b                     @
-    str         r3, [r0, #0x10]         @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
-    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
-                                        @
-    movs         r7, r3, lsr #8         @ store pixel
-20:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         20b                     @
-    str         r7, [r0, #0x10]         @
-25:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         25b                     @
-    str         r3, [r0, #0x10]         @
-                                        @
-    subs        r1, r1, #2              @ subtract block from width
-    bgt         10b @ loop line         @
-                                        @
-    ldmpc       regs=r4-r11             @ restore registers and return
-    .ltorg                              @ dump constant pool
-    .size   lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
-
-
-/****************************************************************************
- * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
- *                                      int width,
- *                                      int stride,
- *                                      int x_screen,
- *                                      int y_screen);
- *
- *   |R|   |1.000000 -0.000001  1.402000| |Y'|
- *   |G| = |1.000000 -0.334136 -0.714136| |Pb|
- *   |B|   |1.000000  1.772000  0.000000| |Pr|
- *   Red scaled at twice g & b but at same precision to place it in correct
- *   bit position after multiply and leave instruction count lower.
- *   |R|   |258   0  408| |Y' -  16|
- *   |G| = |149 -49 -104| |Cb - 128|
- *   |B|   |149 258    0| |Cr - 128|
- *
- * Write four RGB565 pixels in the following order on each loop:
- * 1 3 + > down
- * 2 4 \/ left
- *
- * Kernel pattern (raw|use order):
- * 5 3 4 2     row0    row2         > down
- * 1 7 0 6 | 5 1 3 7 4 0 2 6 col0     left
- * 4 2 5 3 | 4 0 2 6 5 1 3 7 col2  \/
- * 0 6 1 7
- */
-    .section    .icode, "ax", %progbits
-    .align      2
-    .global     lcd_write_yuv420_lines_odither
-    .type       lcd_write_yuv420_lines_odither, %function
-lcd_write_yuv420_lines_odither:
-                                        @ r0   = yuv_src
-                                        @ r1   = width
-                                        @ r2   = stride
-                                        @ r3   = x_screen
-                                        @ [sp] = y_screen
-    stmfd       sp!, { r4-r11, lr }     @ save non-scratch
-    ldmia       r0, { r4, r5, r6 }      @ r4 = yuv_src[0] = Y'_p
-                                        @ r5 = yuv_src[1] = Cb_p
-                                        @ r6 = yuv_src[2] = Cr_p
-                                        @
-    ldr         r0, [sp, #36]           @ Line up pattern and kernel quadrant
-    eor         r14, r3, r0             @
-    and         r14, r14, #0x2          @
-    mov         r14, r14, lsl #6        @ 0x00 or 0x80
-                                        @
-    ldr         r0, =LCD1_BASE          @
-                                        @
-    sub         r2, r2, #1              @ Adjust stride because of increment
-10: @ loop line                         @
-                                        @
-    ldrb        r7, [r4], #1            @ r7 = *Y'_p++;
-    ldrb        r8, [r5], #1            @ r8 = *Cb_p++;
-    ldrb        r9, [r6], #1            @ r9 = *Cr_p++;
-                                        @
-    eor         r14, r14, #0x80         @ flip pattern quadrant
-                                        @
-    sub         r7, r7, #16             @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @    
-    sub         r8, r8, #128            @ Cb -= 128
-    sub         r9, r9, #128            @ Cr -= 128
-                                        @
-    add         r10, r8, r8, asl #4     @ r10 = guv = Cr*104 + Cb*49
-    add         r10, r10, r8, asl #5    @
-    add         r10, r10, r9, asl #3    @
-    add         r10, r10, r9, asl #5    @
-    add         r10, r10, r9, asl #6    @
-                                        @
-    mov         r8, r8, asl #1          @ r8 = bu = Cb*258
-    add         r8, r8, r8, asl #7      @
-                                        @
-    add         r9, r9, r9, asl #1      @ r9 = rv = Cr*408
-    add         r9, r9, r9, asl #4      @
-    mov         r9, r9, asl #3          @
-                                        @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-                                        @ r8 = bu, r9 = rv, r10 = guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3 = 31/32*b + b/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r + r/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7 = 63/64*g + g/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    add         r12, r14, #0x200        @
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    movs         r7, r3, lsr #8         @ store pixel
-20:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         20b                     @
-    str         r7, [r0, #0x10]         @
-25:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         25b                     @
-    str         r3, [r0, #0x10]         @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3  = 31/32*b' + b'/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r' + r'/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7  = 63/64*g' + g'/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    @ This element is zero - use r14    @
-                                        @
-    add         r3, r3, r14             @ b = r3 + delta
-    add         r11, r11, r14, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r14, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4], #1           @ r12 = Y' = *(Y'_p++)
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    movs         r7, r3, lsr #8         @ store pixel
-20:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         20b                     @
-    str         r7, [r0, #0x10]         @
-25:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         25b                     @
-    str         r3, [r0, #0x10]         @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-                                        @ r8 = bu, r9 = rv, r10 = guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3  = 31/32*b' + b'/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r' + r'/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7  = 63/64*g' + g'/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    add         r12, r14, #0x100        @
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)    
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    movs         r7, r3, lsr #8         @ store pixel
-20:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         20b                     @
-    str         r7, [r0, #0x10]         @
-25:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         25b                     @
-    str         r3, [r0, #0x10]         @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3 = 31/32*b + b/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r + r/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7 = 63/64*g + g/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    add         r12, r14, #0x300        @
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    movs         r7, r3, lsr #8         @ store pixel
-20:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         20b                     @
-    str         r7, [r0, #0x10]         @
-25:                                     @
-    ldr         r11, [r0]               @
-    tst         r11, #LCD1_BUSY_MASK    @
-    bne         25b                     @
-    str         r3, [r0, #0x10]         @
-                                        @
-    subs        r1, r1, #2              @ subtract block from width
-    bgt         10b @ loop line         @
-                                        @
-    ldmpc       regs=r4-r11             @ restore registers and return
-    .ltorg                              @ dump constant pool
-    .size   lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
diff --git a/firmware/target/arm/pbell/vibe500/lcd-vibe500.c b/firmware/target/arm/pbell/vibe500/lcd-vibe500.c
deleted file mode 100644
index 4cb073d..0000000
--- a/firmware/target/arm/pbell/vibe500/lcd-vibe500.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2009 by Szymon Dziok
- * Based on the Iriver H10 code by Barry Wardell
- *
- * 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 "lcd.h"
-#include "kernel.h"
-#include "system.h"
-
-/** Initialized in lcd_init_device() **/
-/* Is the power turned on? */
-static bool power_on;
-/* Is the display turned on? */
-static bool display_on;
-/* Reverse flag. Must be remembered when display is turned off. */
-static unsigned short disp_control_rev;
-/* Contrast setting << 8 */
-static int lcd_contrast;
-
-static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
-
-/* Forward declarations */
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-static void lcd_display_off(void);
-#endif
-
-/* register defines for the Renesas HD66773R */
-/*
-   In Packard Bell from the OF - it seems to be
-   HD66774(gate) with HD66772(source) - registers
-   are very similar but not all the same
-*/
-#define R_START_OSC             0x00
-#define R_DEVICE_CODE_READ      0x00
-#define R_DRV_OUTPUT_CONTROL    0x01
-#define R_DRV_AC_CONTROL        0x02
-#define R_POWER_CONTROL1        0x03
-#define R_POWER_CONTROL2        0x04
-#define R_ENTRY_MODE            0x05
-#define R_COMPARE_REG           0x06
-#define R_DISP_CONTROL          0x07
-#define R_FRAME_CYCLE_CONTROL   0x0b
-#define R_POWER_CONTROL3        0x0c
-#define R_POWER_CONTROL4        0x0d
-#define R_POWER_CONTROL5        0x0e
-#define R_GATE_SCAN_START_POS   0x0f
-#define R_VERT_SCROLL_CONTROL   0x11
-#define R_1ST_SCR_DRV_POS       0x14
-#define R_2ND_SCR_DRV_POS       0x15
-#define R_HORIZ_RAM_ADDR_POS    0x16
-#define R_VERT_RAM_ADDR_POS     0x17
-#define R_RAM_WRITE_DATA_MASK   0x20
-#define R_RAM_ADDR_SET          0x21
-#define R_WRITE_DATA_2_GRAM     0x22
-#define R_RAM_READ_DATA         0x22
-#define R_GAMMA_FINE_ADJ_POS1   0x30
-#define R_GAMMA_FINE_ADJ_POS2   0x31
-#define R_GAMMA_FINE_ADJ_POS3   0x32
-#define R_GAMMA_GRAD_ADJ_POS    0x33
-#define R_GAMMA_FINE_ADJ_NEG1   0x34
-#define R_GAMMA_FINE_ADJ_NEG2   0x35
-#define R_GAMMA_FINE_ADJ_NEG3   0x36
-#define R_GAMMA_GRAD_ADJ_NEG    0x37
-#define R_GAMMA_AMP_ADJ_POS     0x3a
-#define R_GAMMA_AMP_ADJ_NEG     0x3b
-
-static inline void lcd_wait_write(void)
-{
-    while (LCD1_CONTROL & LCD1_BUSY_MASK);
-}
-
-/* Send command */
-static inline void lcd_send_cmd(unsigned v)
-{
-    lcd_wait_write();
-    LCD1_CMD = (v >> 8);
-    lcd_wait_write();
-    LCD1_CMD = (v & 0xff);
-}
-
-/* Send 16-bit data */
-static inline void lcd_send_data(unsigned v)
-{
-    lcd_wait_write();
-    LCD1_DATA = (v >> 8);
-    lcd_wait_write();
-    LCD1_DATA = (v & 0xff);
-}
-
-/* Send 16-bit data byte-swapped.  */
-static inline void lcd_send_data_swapped(unsigned v)
-{
-    lcd_wait_write();
-    LCD1_DATA = (v & 0xff);
-    lcd_wait_write();
-    LCD1_DATA = (v >> 8);
-}
-
-/* Write value to register */
-static void lcd_write_reg(int reg, int val)
-{
-    lcd_send_cmd(reg);
-    lcd_send_data(val);
-}
-
-/*** hardware configuration ***/
-
-int lcd_default_contrast(void)
-{
-    return DEFAULT_CONTRAST_SETTING;
-}
-
-void lcd_set_contrast(int val)
-{
-    lcd_contrast = (val&0x1f) << 8;
-    if (!power_on) return;
-
-    /* VCOMG=1, VDV4-0=xxxxx, VCM4-0=11000 */
-    lcd_write_reg(R_POWER_CONTROL5, 0x2018 | lcd_contrast);
-}
-
-void lcd_set_invert_display(bool yesno)
-{
-    if (yesno == (disp_control_rev == 0x0000))
-        return;
-
-    disp_control_rev = yesno ? 0x0000 : 0x0004;
-
-    if (!display_on)
-        return;
-
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=11 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0033 | disp_control_rev);
-}
-
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
-    if (!power_on)
-        return;
-
-    /* SM=0, GS=x, SS=x, NL4-0=10011 (G1-G160) */
-    lcd_write_reg(R_DRV_OUTPUT_CONTROL, yesno ? 0x0313 : 0x0013);
-}
-
-/* LCD init */
-void lcd_init_device(void)
-{
-    power_on = true;
-    display_on = true;
-    disp_control_rev = 0x0004;
-    lcd_contrast     = DEFAULT_CONTRAST_SETTING << 8;
-}
-
-#ifdef HAVE_LCD_SLEEP
-static void lcd_power_on(void)
-{
-    /* from the OF */
-    lcd_write_reg(R_START_OSC,0x01); /* START_OSC */
-    sleep(HZ/40); /* 25ms */
-    /* set 396x160 dots, SM=0, GS=x, SS=0, NL4-0=10011 G1-G160)*/
-    lcd_write_reg(R_DRV_OUTPUT_CONTROL,0x13);
-    /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */
-    lcd_write_reg(R_DRV_AC_CONTROL,7 << 8);
-    /* DIT=0, BGR=1, HWM=0, I/D1-0=0 - decrement AC, AM=1, LG2-0=000 */
-    lcd_write_reg(R_ENTRY_MODE,0x1008);
-    lcd_write_reg(0x25,0x0000); /* - ?? */
-    lcd_write_reg(0x26,0x0202); /* - ?? */
-    lcd_write_reg(0x0A,0x0000); /* - ?? */
-    lcd_write_reg(R_FRAME_CYCLE_CONTROL,0x0000);
-    lcd_write_reg(R_POWER_CONTROL4,0x0000);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL5,0x0000);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL3,0x0000);
-    lcd_write_reg(0x09,0x0008); /* - ?? */
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL4,0x0003);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL5,0x1019);
-    sleep(HZ/20); /* 50ms */
-    lcd_write_reg(R_POWER_CONTROL4,0x0013);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL1,0x0010);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(0x09,0x0000); /* - ?? */
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL1,0x0010);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL5,0x3019);
-    sleep(HZ*10/66);/* /6.6 = 150ms */
-    lcd_write_reg(0x09,0x0002); /* - ?? */
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL4,0x0018);
-    sleep(HZ/20); /* 50ms */
-    /* RAM Address set (0x0000) */
-    lcd_write_reg(R_RAM_ADDR_SET,0x0000);
-    /* Gamma settings */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_POS1,0x0004);
-    lcd_write_reg(R_GAMMA_FINE_ADJ_POS2,0x0606);
-    lcd_write_reg(R_GAMMA_FINE_ADJ_POS3,0x0505);
-    lcd_write_reg(R_GAMMA_GRAD_ADJ_POS,0x0206);
-    lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1,0x0505);
-    lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2,0x0707);
-    lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3,0x0105);
-    lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG,0x0301);
-    lcd_write_reg(R_GAMMA_AMP_ADJ_POS,0x1A00);
-    lcd_write_reg(R_GAMMA_AMP_ADJ_NEG,0x010E);
-
-    lcd_write_reg(R_GATE_SCAN_START_POS,0x0000);
-    /* Horizontal ram address start/end position (0,127); */
-    lcd_write_reg(R_HORIZ_RAM_ADDR_POS,0x7F00);
-    /* Vertical ram address start/end position (0,159); */
-    lcd_write_reg(R_VERT_RAM_ADDR_POS,0x9F00);
-
-    lcd_write_reg(R_DISP_CONTROL,0x0005);
-    sleep(HZ/25); /* 40ms */
-    lcd_write_reg(R_DISP_CONTROL,0x0025);
-    lcd_write_reg(R_DISP_CONTROL,0x0027);
-    sleep(HZ/25); /* 40ms */
-    lcd_write_reg(R_DISP_CONTROL,0x0033 | disp_control_rev);
-    sleep(HZ/100); /* 10ms */
-    lcd_write_reg(R_POWER_CONTROL1,0x0110);
-    lcd_write_reg(R_FRAME_CYCLE_CONTROL,0x0000);
-    lcd_write_reg(R_POWER_CONTROL4,0x0013);
-    lcd_write_reg(R_POWER_CONTROL5,0x2018 | lcd_contrast);
-    sleep(HZ/20); /* 50ms */
-
-    power_on = true;
-}
-
-static void lcd_power_off(void)
-{
-    /* Display must be off first */
-    if (display_on)
-        lcd_display_off();
-
-    /* power_on = false; */
-
-    /** Power OFF sequence **/
-    /* The method is unknown */
-}
-
-void lcd_sleep(void)
-{
-    if (power_on)
-        lcd_power_off();
-
-    /* Set standby mode */
-    /* Because we dont know how to power off display
-       we cannot set standby */
-    /* BT2-0=000, DC2-0=000, AP2-0=000, SLP=0, STB=1 */
-    /* lcd_write_reg(R_POWER_CONTROL1, 0x0001); */
-}
-#endif
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-static void lcd_display_off(void)
-{
-    display_on = false;
-
-    /** Display OFF sequence **/
-    /* In the OF it is called "EnterStandby" */
-
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=10 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0032 | disp_control_rev);
-    sleep(HZ/22); /* 45ms */
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=0, REV=x, D1-0=10 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0022 | disp_control_rev);
-    sleep(HZ/22); /* 45ms */
-    /* PT1-0=00, VLE2-1=00, SPT=0, GON=0, DTE=0, REV=0, D1-0=00 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0000);
-
-    lcd_write_reg(R_POWER_CONTROL1, 0x0000);
-    lcd_write_reg(0x09, 0x0000); /* -?? */
-    lcd_write_reg(R_POWER_CONTROL4, 0x0000);
-
-    sleep(HZ/22); /* 45ms */
-}
-#endif
-
-#if defined(HAVE_LCD_ENABLE)
-static void lcd_display_on(void)
-{
-    /* Be sure power is on first */
-    if (!power_on)
-        lcd_power_on();
-
-    /** Display ON Sequence **/
-    /* In the OF it is called "ExitStandby" */
-
-    lcd_write_reg(R_START_OSC,1);
-    sleep(HZ/40); /* 25ms */
-    lcd_write_reg(R_POWER_CONTROL4,0);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL5,0);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_DISP_CONTROL,0);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL3,0);
-    lcd_write_reg(0x09,8); /* -?? */
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL4,3);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL5,0x1019);
-    sleep(HZ/20); /* 50ms */
-    lcd_write_reg(R_POWER_CONTROL4,0x13);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL1,0x10);
-    sleep(HZ/20); /* 50ms */
-    lcd_write_reg(0x09,0); /* -?? */
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL1,0x10);
-    sleep(HZ/67); /* 15ms */
-    lcd_write_reg(R_POWER_CONTROL5,0x3019);
-    sleep(HZ*10/66);/* /6.6 = 150ms */
-    lcd_write_reg(0x09,2); /* -?? */
-    sleep(HZ/20); /* 50ms */
-    lcd_write_reg(R_DISP_CONTROL,5);
-    sleep(HZ/22); /* 45ms */
-    lcd_write_reg(R_DISP_CONTROL,0x25);
-    sleep(HZ/22); /* 45ms */
-    lcd_write_reg(R_DISP_CONTROL,0x27);
-    sleep(HZ/25); /* 40ms */
-    lcd_write_reg(R_DISP_CONTROL,0x33 | disp_control_rev);
-    sleep(HZ/22); /* 45ms */
-    /* fix contrast */
-    lcd_write_reg(R_POWER_CONTROL5, 0x2018 | lcd_contrast);
-
-    display_on = true;
-}
-
-void lcd_enable(bool on)
-{
-    if (on == display_on)
-        return;
-
-    if (on)
-    {
-        lcd_display_on();
-        /* Probably out of sync and we don't wanna pepper the code with
-           lcd_update() calls for this. */
-        lcd_update();
-        send_event(LCD_EVENT_ACTIVATION, NULL);
-    }
-    else
-    {
-        lcd_display_off();
-    }
-}
-#endif
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-bool lcd_active(void)
-{
-    return display_on;
-}
-#endif
-
-/*** update functions ***/
-
-void lcd_yuv_set_options(unsigned options)
-{
-    lcd_yuv_options = options;
-}
-
-/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
-
-extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
-                                   int width,
-                                   int stride);
-extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
-                                           int width,
-                                           int stride,
-                                           int x_screen, /* To align dither pattern */
-                                           int y_screen);
-
-/* Performance function to blit a YUV bitmap directly to the LCD */
-void lcd_blit_yuv(unsigned char * const src[3],
-                  int src_x, int src_y, int stride,
-                  int x, int y, int width, int height)
-{
-    const unsigned char *yuv_src[3];
-    const unsigned char *ysrc_max;
-    int y0;
-    int options;
-
-    if (!display_on)
-        return;
-
-    width &= ~1;
-    height &= ~1;
-
-    lcd_write_reg(R_VERT_RAM_ADDR_POS, ((LCD_WIDTH - 1 - x) << 8) |
-    ((LCD_WIDTH-1) - (x + width - 1)));
-
-    y0 = LCD_HEIGHT - 1 - y;
-
-    lcd_write_reg(R_ENTRY_MODE,0x1000);
-
-    yuv_src[0] = src[0] + src_y * stride + src_x;
-    yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1);
-    yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
-    ysrc_max = yuv_src[0] + height * stride;
-
-    options = lcd_yuv_options;
-
-    do
-    {
-        lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y0 << 8) | (y0 - 1));
-        lcd_write_reg(R_RAM_ADDR_SET, ((LCD_WIDTH - 1 - x) << 8) | y0);
-
-        /* start drawing */
-        lcd_send_cmd(R_WRITE_DATA_2_GRAM);
-
-        if (options & LCD_YUV_DITHER)
-        {
-            lcd_write_yuv420_lines_odither(yuv_src, width, stride,x, y);
-            y -= 2;
-        }
-        else
-        {
-            lcd_write_yuv420_lines(yuv_src, width, stride);
-        }
-
-        y0 -= 2;
-        yuv_src[0] += stride << 1;
-        yuv_src[1] += stride >> 1;
-        yuv_src[2] += stride >> 1;
-    }
-    while (yuv_src[0] < ysrc_max);
-    lcd_write_reg(R_ENTRY_MODE,0x1008);
-}
-
-/* Update a fraction of the display. */
-void lcd_update_rect(int x0, int y0, int width, int height)
-{
-    const fb_data *addr;
-    int x1, y1;
-
-    if (!display_on)
-       return;
-
-    if ((width<=0)||(height<=0))
-       return;
-
-    if ((x0 + width)>=LCD_WIDTH)
-       width = LCD_WIDTH - x0;
-    if ((y0 + height)>=LCD_HEIGHT)
-       height = LCD_HEIGHT - y0;
-
-    y1 = (y0 + height) - 1;
-    x1 = (x0 + width) - 1;
-
-    /* In the PB Vibe LCD is flipped and the RAM addresses are decremented */
-    lcd_send_cmd(R_HORIZ_RAM_ADDR_POS);
-    lcd_send_data( (((LCD_HEIGHT-1)-y0) << 8) | ((LCD_HEIGHT-1)-y1));
-
-    lcd_send_cmd(R_VERT_RAM_ADDR_POS);
-    lcd_send_data( (((LCD_WIDTH -1)-x0) << 8) | ((LCD_WIDTH -1)-x1));
-
-    lcd_send_cmd(R_RAM_ADDR_SET);
-    lcd_send_data( (((LCD_WIDTH -1)-x0) << 8) | ((LCD_HEIGHT-1)-y0));
-
-    /* start drawing */
-    lcd_send_cmd(R_WRITE_DATA_2_GRAM);
-
-    addr = &lcd_framebuffer[y0][x0];
-
-    int c, r;
-    for (r = 0; r < height; r++)
-    {
-        for (c = 0; c < width; c++)
-        lcd_send_data_swapped(*addr++);
-        addr += LCD_WIDTH - width;
-    }
-}
-
-/* Update the display.
-   This must be called after all other LCD 
-   functions that change the display. */
-void lcd_update(void)
-{
-    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
-}
diff --git a/firmware/target/arm/pbell/vibe500/power-vibe500.c b/firmware/target/arm/pbell/vibe500/power-vibe500.c
deleted file mode 100644
index a5660d7..0000000
--- a/firmware/target/arm/pbell/vibe500/power-vibe500.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2009 by Szymon Dziok
- *
- * 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 "kernel.h"
-#include "system.h"
-#include "power.h"
-#include "logf.h"
-#include "usb.h"
-#include "synaptics-mep.h"
-
-void power_init(void)
-{
-    GPIOD_ENABLE |= 0x80;          /* enable ACK */
-    GPIOA_ENABLE |= (0x10 | 0x20); /* enable DATA, CLK */
-
-    GPIOD_OUTPUT_EN  |=  0x80; /* set ACK */
-    GPIOD_OUTPUT_VAL |=  0x80; /*    high */
-
-    GPIOA_OUTPUT_EN  &= ~0x20; /* CLK */
-
-    GPIOA_OUTPUT_EN  |=  0x10; /* set DATA */
-    GPIOA_OUTPUT_VAL |=  0x10; /*     high */
-
-    if (!touchpad_init())
-    {
-        logf("touchpad not ready");
-    }
-    /* Max touch sensivity = 0x77, Rate=80/s,NoFilter=0,
-       KeyMatrix=0,Buttons=1,Relative=0,Absolute=1.
-       MEP parameter 0x20 - Report Modes */
-    touchpad_set_parameter(0,0x20,0x7785);
-    /* MinAbsReporting=0, NotAllCapButtons=0,SingleCapButton=0,
-       50msDebounce=0,MotionReporting=1 (reduce transmission overhead),
-       ClipZifnoFinger=0,DisableDeceleration=0,Dribble=0.
-       MEP parameter 0x21 - Enhanced Operating Configuration */
-    touchpad_set_parameter(0,0x21,0x0008);
-    /* Set the GPO_LEVELS = 0 - for the button lights */
-    touchpad_set_parameter(0,0x23,0x0000);
-
-    /* Sound unmute (on) */
-    GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_VAL, 0x10);
-}
-
-unsigned int power_input_status(void)
-{
-    unsigned int status = POWER_INPUT_NONE;
-    /* GPIOL - external charger connected  */
-    if (GPIOL_INPUT_VAL & 0x20)
-    status = POWER_INPUT_MAIN_CHARGER;
-    /* GPIOL - usb connected */
-    if (GPIOL_INPUT_VAL & 0x04)
-    status |= POWER_INPUT_USB_CHARGER;
-
-    return status;
-}
-
-void ide_power_enable(bool on)
-{
-    if(on){
-        GPIO_SET_BITWISE(GPIOC_OUTPUT_VAL, 0x08);
-        DEV_EN |= DEV_IDE0;
-    } else
-    {
-        DEV_EN &= ~DEV_IDE0;
-        GPIO_CLEAR_BITWISE(GPIOC_OUTPUT_VAL, 0x08);
-    }
-}
-
-bool ide_powered(void)
-{
-    return ((GPIOC_INPUT_VAL & 0x08) == 1);
-}
-
-void power_off(void)
-{
-    /* Sound mute (off) */
-    DEV_INIT2 |= DEV_I2S;
-    GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 0x10);
-    /* shutdown bit */
-    GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x80);
-    /* button lights off */
-    touchpad_set_parameter(0,0x22,0x0000);
-    /* ATA power off */
-    ide_power_enable(false);
-    /* ? - in the OF */
-    GPO32_VAL |= 0x40000000;
-    GPO32_ENABLE |= 0x40000000;
-    /* lcd controller off ? - makes lcd white until power on */
-    GPIO_CLEAR_BITWISE(GPIOJ_OUTPUT_VAL, 0x04);
-    /* a way to poweroff while charging = system_reset */
-    if (power_input_status())
-    system_reboot();
-}
diff --git a/firmware/target/arm/pbell/vibe500/powermgmt-vibe500.c b/firmware/target/arm/pbell/vibe500/powermgmt-vibe500.c
deleted file mode 100644
index d84881c..0000000
--- a/firmware/target/arm/pbell/vibe500/powermgmt-vibe500.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
- * Revisions copyright (C) 2005 by Gerald Van Baren
- * Copyright (C) 2009 by Szymon Dziok
- *
- * 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 "adc.h"
-#include "powermgmt.h"
-
-const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
-{
-    3515
-};
-
-const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
-{
-    3486
-};
-
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
-const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
-{
-    { 3474, 3515, 3556, 3597, 3638, 3679, 3720, 3761, 3802, 3843, 3884 }
-};
-
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
-const unsigned short percent_to_volt_charge[11] =
-{
-    3474, 3515, 3556, 3597, 3638, 3679, 3720, 3761, 3802, 3843, 3884
-};
-
-#define BATTERY_SCALE_FACTOR 4200
-/* full-scale ADC readout (2^10) in millivolt */
-
-/* Returns battery voltage from ADC [millivolts] */
-unsigned int battery_adc_voltage(void)
-{
-    return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
-}
diff --git a/firmware/target/arm/pbell/vibe500/usb-target.h b/firmware/target/arm/pbell/vibe500/usb-target.h
deleted file mode 100644
index fb51b99..0000000
--- a/firmware/target/arm/pbell/vibe500/usb-target.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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.
- *
- ****************************************************************************/
-
-/* Based off x5 version */
-
-#ifndef USB_TARGET_H
-#define USB_TARGET_H
-
-bool usb_init_device(void);
-void usb_pin_init(void); /* Init the GPIO input only */
-
-#endif
diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c
deleted file mode 100644
index 695bc71..0000000
--- a/firmware/target/arm/pcm-pp.c
+++ /dev/null
@@ -1,734 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Michael Sevakis
- *
- * 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 <stdlib.h>
-#include "system.h"
-#include "kernel.h"
-#include "logf.h"
-#include "audio.h"
-#include "sound.h"
-#include "pcm.h"
-#include "pcm_sampr.h"
-#include "pcm-internal.h"
-
-/** DMA **/
-
-#ifdef CPU_PP502x
-/* 16-bit, L-R packed into 32 bits with left in the least significant halfword */
-#define SAMPLE_SIZE   16
-/* DMA Requests from IIS, Memory to peripheral, single transfer,
-   wait for DMA request, interrupt on complete */
-#define DMA_PLAY_CONFIG ((DMA_REQ_IIS << DMA_CMD_REQ_ID_POS) | \
-                          DMA_CMD_RAM_TO_PER | DMA_CMD_SINGLE | \
-                          DMA_CMD_WAIT_REQ | DMA_CMD_INTR)
-/* DMA status cannot be viewed from outside code in control because that can
- * clear the interrupt from outside the handler and prevent the handler from
- * from being called. Split up transfers to a reasonable size that is good as
- * a timer, obtaining a keyclick position and peaking yet still keeps the
- * FIQ count low.
- */
-#define MAX_DMA_CHUNK_SIZE (pcm_curr_sampr >> 6) /* ~1/256 seconds */
-#else
-/* 32-bit, one left 32-bit sample followed by one right 32-bit sample */
-#define SAMPLE_SIZE   32
-#endif
-
-struct dma_data
-{
-/* NOTE: The order of size and p is important if you use assembler
-   optimised fiq handler, so don't change it. */
-    union
-    {
-        unsigned long addr;
-        uint32_t *p16;  /* For packed 16-16 stereo pairs */
-        uint16_t *p32;  /* For individual samples converted to 32-bit */
-    };
-    size_t size;
-#if NUM_CORES > 1
-    unsigned core;
-#endif
-    int locked;
-    int state;
-};
-
-extern void *fiq_function;
-
-/* Dispatch to the proper handler and leave the main vector table alone */
-void fiq_handler(void) ICODE_ATTR __attribute__((naked));
-void fiq_handler(void)
-{
-    asm volatile (
-        "ldr pc, [pc, #-4]  \n"
-    "fiq_function:          \n"
-        ".word 0            \n"
-    );
-}
-
-#ifdef HAVE_PCM_DMA_ADDRESS
-void * pcm_dma_addr(void *addr)
-{
-    if (addr != NULL && (unsigned long)addr < UNCACHED_BASE_ADDR)
-        addr = UNCACHED_ADDR(addr);
-    return addr;
-}
-#endif
-
-/* TODO: Get simultaneous recording and playback to work. Just needs some tweaking */
-
-/****************************************************************************
- ** Playback DMA transfer
- **/
-static struct dma_data dma_play_data IBSS_ATTR =
-{
-    /* Initialize to a locked, stopped state */
-    { .addr = 0 },
-    .size = 0,
-#if NUM_CORES > 1
-    .core = 0x00,
-#endif
-    .locked = 0,
-    .state = 0
-};
-
-void pcm_dma_apply_settings(void)
-{
-    audiohw_set_frequency(pcm_fsel);
-}
-
-#if defined(CPU_PP502x)
-/* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */
-void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void)
-{
-    bool new_buffer = false;
-    register size_t size;
-
-    DMA0_STATUS; /* Clear any pending interrupt */
-
-    size = (DMA0_CMD & 0xffff) + 4; /* Get size of trasfer that caused this
-                                       interrupt */
-    dma_play_data.addr += size;
-    dma_play_data.size -= size;
-
-    while (1)
-    {
-        if (dma_play_data.size > 0) {
-            size = MAX_DMA_CHUNK_SIZE;
-            /* Not at least MAX_DMA_CHUNK_SIZE left or there would be less
-             * than a FIFO's worth of data after this transfer? */
-            if (size + 16*4 > dma_play_data.size)
-                size = dma_play_data.size;
-
-            /* Set the new DMA values and activate channel */
-            DMA0_RAM_ADDR = dma_play_data.addr;
-            DMA0_CMD = DMA_PLAY_CONFIG | (size - 4) | DMA_CMD_START;
-
-            if (new_buffer)
-                pcm_play_dma_started_callback();
-            return;
-        }
-
-        new_buffer = true;
-
-        /* Buffer empty.  Try to get more. */
-        pcm_play_get_more_callback((void **)&dma_play_data.addr,
-                                   &dma_play_data.size);
-
-        if (dma_play_data.size == 0) {
-            /* No more data */
-            return;
-        }
-
-        if (dma_play_data.addr < UNCACHED_BASE_ADDR) {
-            /* Flush any pending cache writes */
-            dma_play_data.addr = UNCACHED_ADDR(dma_play_data.addr);
-            cpucache_flush();
-        }
-    }
-}
-#else
-/* ASM optimised FIQ handler. Checks for the minimum allowed loop cycles by
- * evalutation of free IISFIFO-slots against available source buffer words.
- * Through this it is possible to move the check for IIS_TX_FREE_COUNT outside
- * the loop and do some further optimization. Right after the loops (source
- * buffer -> IISFIFO) are done we need to check whether we have to exit FIQ
- * handler (this must be done, if all free FIFO slots were filled) or we will
- * have to get some new source data. Important information kept from former
- * ASM implementation (not used anymore): GCC fails to make use of the fact
- * that FIQ mode has registers r8-r14 banked, and so does not need to be saved.
- * This routine uses only these registers, and so will never touch the stack
- * unless it actually needs to do so when calling pcm_callback_for_more.
- * C version is still included below for reference and testing.
- */
-#if 1
-void fiq_playback(void) ICODE_ATTR __attribute__((naked));
-void fiq_playback(void)
-{
-    /* r10 contains IISCONFIG address (set in crt0.S to minimise code in actual
-     * FIQ handler. r11 contains address of p (also set in crt0.S). Most other
-     * addresses we need are generated by using offsets with these two.
-     * r10 + 0x40 is IISFIFO_WR, and r10 + 0x0c is IISFIFO_CFG.
-     * r8 and r9 contains local copies of p and size respectively.
-     * r0-r3 and r12 is a working register.
-     */
-    asm volatile (
-        "stmfd   sp!, { r0-r4, lr }  \n" /* stack scratch regs and lr */
-
-        "mov     r4, #0              \n" /* Was the callback called? */
-#if CONFIG_CPU == PP5002
-        "ldr     r12, =0xcf001040    \n" /* Some magic from iPodLinux */
-        "ldr     r12, [r12]          \n"
-#endif
-        "ldmia   r11, { r8-r9 }      \n" /* r8 = p, r9 = size */
-        "cmp     r9, #0              \n" /* is size 0? */
-        "beq     .more_data          \n" /* if so, ask pcmbuf for more data */
-
-#if SAMPLE_SIZE == 16
-    ".check_fifo:                    \n"   
-        "ldr     r0, [r10, %[cfg]]   \n" /* read IISFIFO_CFG to check FIFO status */
-        "and     r0, r0, %[mask]     \n" /* r0 = IIS_TX_FREE_COUNT << 16 (PP502x) */
-
-        "mov     r1, r0, lsr #16     \n" /* number of free FIFO slots */
-        "cmp     r1, r9, lsr #2      \n" /* number of words from source */
-        "movgt   r1, r9, lsr #2      \n" /* r1 = amount of allowed loops */
-        "sub     r9, r9, r1, lsl #2  \n" /* r1 words will be written in following loop */
-
-        "subs    r1, r1, #2          \n"
-    ".fifo_loop_2:                   \n"
-        "ldmgeia r8!, {r2, r12}      \n" /* load four samples */
-        "strge   r2 , [r10, %[wr]]   \n" /* write sample 0-1 to IISFIFO_WR */
-        "strge   r12, [r10, %[wr]]   \n" /* write sample 2-3 to IISFIFO_WR */
-        "subges  r1, r1, #2          \n" /* one more loop? */
-        "bge     .fifo_loop_2        \n" /* yes, continue */
-
-        "tst     r1, #1              \n" /* two samples (one word) left? */
-        "ldrne   r12, [r8], #4       \n" /* load two samples */
-        "strne   r12, [r10, %[wr]]   \n" /* write sample 0-1 to IISFIFO_WR */
-#elif SAMPLE_SIZE == 32
-    ".check_fifo:                    \n"
-        "ldr     r0, [r10, %[cfg]]   \n" /* read IISFIFO_CFG to check FIFO status */
-        "and     r0, r0, %[mask]     \n" /* r0 = IIS_TX_FREE_COUNT << 23 (PP5002) */
-
-        "movs    r1, r0, lsr #24     \n" /* number of free pairs of FIFO slots */
-        "beq     .fifo_fill_complete \n" /* no complete pair? -> exit */
-        "cmp     r1, r9, lsr #2      \n" /* number of words from source */
-        "movgt   r1, r9, lsr #2      \n" /* r1 = amount of allowed loops */
-        "sub     r9, r9, r1, lsl #2  \n" /* r1 words will be written in following loop */
-
-    ".fifo_loop:                     \n"
-        "ldr     r12, [r8], #4       \n" /* load two samples */
-        "mov     r2 , r12, lsl #16   \n" /* put left sample at the top bits */
-        "str     r2 , [r10, %[wr]]   \n" /* write top sample to IISFIFO_WR */
-        "str     r12, [r10, %[wr]]   \n" /* write low sample to IISFIFO_WR*/
-        "subs    r1, r1, #1          \n" /* one more loop? */
-        "bgt     .fifo_loop          \n" /* yes, continue */
-
-    ".fifo_fill_complete:            \n"
-#endif
-        "cmp     r4, #0              \n" /* If fill came after get_more... */
-        "beq     .still_old_buffer   \n"
-        "mov     r4, #0              \n"
-        "ldr     r2, =pcm_play_dma_started \n"
-        "ldrne   r2, [r2]            \n"
-        "cmp     r2, #0              \n"
-        "movne   lr, pc              \n"
-        "bxne    r2                  \n"
-
-    ".still_old_buffer:              \n"
-        "cmp     r9, #0              \n" /* either FIFO is full or source buffer is empty */
-        "bgt     .exit               \n" /* if source buffer is not empty, FIFO must be full */
-
-    ".more_data:                     \n"
-        "mov     r4, #1              \n" /* Remember we did this */
-        "ldr     r2, =pcm_play_get_more_callback \n"
-        "mov     r0, r11             \n" /* r0 = &p */
-        "add     r1, r11, #4         \n" /* r1 = &size */
-        "mov     lr, pc              \n" /* call pcm_play_get_more_callback */
-        "bx      r2                  \n"
-        "ldmia   r11, { r8-r9 }      \n" /* load new p and size */
-        "cmp     r9, #0              \n"
-        "bne     .check_fifo         \n" /* size != 0? refill */
-
-    ".exit:                          \n" /* (r9=0 if stopping, look above) */
-        "stmia   r11, { r8-r9 }      \n" /* save p and size */
-        "ldmfd   sp!, { r0-r4, lr }  \n"
-        "subs    pc, lr, #4          \n" /* FIQ specific return sequence */
-        ".ltorg                      \n"
-        : /* These must only be integers! No regs */
-        : [mask]"i"(IIS_TX_FREE_MASK),
-          [cfg]"i"((int)&IISFIFO_CFG - (int)&IISCONFIG),
-          [wr]"i"((int)&IISFIFO_WR - (int)&IISCONFIG)
-    );
-}
-#else /* C version for reference */
-void fiq_playback(void) __attribute__((interrupt ("FIQ"))) ICODE_ATTR;
-/* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */
-void fiq_playback(void)
-{
-    bool new_buffer = false;
-
-#if CONFIG_CPU == PP5002
-    inl(0xcf001040);
-#endif
-
-    do {
-        while (dma_play_data.size > 0) {
-            if (IIS_TX_FREE_COUNT < 2) {
-                if (new_buffer) {
-                    new_buffer = false;
-                    pcm_play_dma_started_callback();
-                }
-                return;
-            }
-#if SAMPLE_SIZE == 16
-            IISFIFO_WR = *dma_play_data.p16++;
-#elif SAMPLE_SIZE == 32
-            IISFIFO_WR = *dma_play_data.p32++ << 16;
-            IISFIFO_WR = *dma_play_data.p32++ << 16;
-#endif
-            dma_play_data.size -= 4;
-        }
-
-        if (new_buffer) {
-            new_buffer = false;
-            pcm_play_dma_started_callback();
-        }
-
-        /* p is empty, get some more data */
-        pcm_play_get_more_callback((void **)&dma_play_data.addr,
-                                   &dma_play_data.size);
-        new_buffer = true;
-    } while (dma_play_data.size);
-
-    /* No more data  */
-}
-#endif /* ASM / C selection */
-#endif /* CPU_PP502x */
-
-/* For the locks, FIQ must be disabled because the handler manipulates
-   IISCONFIG and the operation is not atomic - dual core support
-   will require other measures */
-void pcm_play_lock(void)
-{
-    int status = disable_fiq_save();
-
-    if (++dma_play_data.locked == 1) {
-#ifdef CPU_PP502x
-        CPU_INT_DIS = DMA_MASK;
-#else
-        IIS_IRQTX_REG &= ~IIS_IRQTX;
-#endif
-    }
-
-    restore_fiq(status);
-}
-
-void pcm_play_unlock(void)
-{
-   int status = disable_fiq_save();
-
-    if (--dma_play_data.locked == 0 && dma_play_data.state != 0) {
-#ifdef CPU_PP502x
-        CPU_INT_EN = DMA_MASK;
-#else
-        IIS_IRQTX_REG |= IIS_IRQTX;
-#endif
-    }
-
-   restore_fiq(status);
-}
-
-static void play_start_pcm(void)
-{
-    fiq_function = fiq_playback;
-
-#ifdef CPU_PP502x
-    /* Not at least MAX_DMA_CHUNK_SIZE left or there would be less than a
-     * FIFO's worth of data after this transfer? */
-    size_t size = MAX_DMA_CHUNK_SIZE;
-    if (size + 16*4 > dma_play_data.size)
-        size = dma_play_data.size;
-
-    DMA0_RAM_ADDR = dma_play_data.addr;
-    DMA0_CMD = DMA_PLAY_CONFIG | (size - 4) | DMA_CMD_START;
-    dma_play_data.state = 1;
-#else
-    IISCONFIG &= ~IIS_TXFIFOEN;  /* Stop transmitting */
-
-    /* Fill the FIFO or start when data is used up */
-    while (1) {
-        if (IIS_TX_FREE_COUNT < 2 || dma_play_data.size == 0) {
-            IISCONFIG |= IIS_TXFIFOEN; /* Start transmitting */
-            dma_play_data.state = 1;
-            return;
-        }
-
-#if SAMPLE_SIZE == 16
-        IISFIFO_WR = *dma_play_data.p16++;
-#elif SAMPLE_SIZE == 32
-        IISFIFO_WR = *dma_play_data.p32++ << 16;
-        IISFIFO_WR = *dma_play_data.p32++ << 16;
-#endif
-        dma_play_data.size -= 4;
-    }
-#endif
-}
-
-static void play_stop_pcm(void)
-{
-#ifdef CPU_PP502x
-    unsigned long status = DMA0_STATUS; /* Snapshot- resume from this point */
-    unsigned long cmd = DMA0_CMD;
-    size_t size = 0;
-
-    /* Stop transfer */
-    DMA0_CMD = cmd & ~(DMA_CMD_START | DMA_CMD_INTR);
-
-    /* Wait for not busy + clear int */
-    while (DMA0_STATUS & (DMA_STATUS_BUSY | DMA_STATUS_INTR));
-
-    if (status & DMA_STATUS_BUSY) {
-        /* Transfer was interrupted - leave what's left */
-        size = (cmd & 0xfffc) - (status & 0xfffc);
-    }
-    else if (status & DMA_STATUS_INTR) {
-        /* Transfer was finished - DMA0_STATUS will have been reloaded
-         * automatically with size in DMA0_CMD. Setup to restart on next
-         * segment. */
-        size = (cmd & 0xfffc) + 4;
-    }
-    /* else not an active state - size = 0 */
-
-    dma_play_data.addr += size;
-    dma_play_data.size -= size;
-
-    if (dma_play_data.size == 0)
-        dma_play_data.addr = 0; /* Entire buffer has completed. */
-#else
-    /* Disable TX interrupt */
-    IIS_IRQTX_REG &= ~IIS_IRQTX;
-#endif
-
-    /* Wait for FIFO to empty */
-    while (!IIS_TX_IS_EMPTY);
-
-    dma_play_data.state = 0;
-}
-
-void pcm_play_dma_start(const void *addr, size_t size)
-{
-#if NUM_CORES > 1
-    /* This will become more important later - and different ! */
-    dma_play_data.core = processor_id(); /* save initiating core */
-#endif
-
-    pcm_play_dma_stop();
-
-#ifdef CPU_PP502x
-    if ((unsigned long)addr < UNCACHED_BASE_ADDR) {
-        /* Flush any pending cache writes */
-        addr = UNCACHED_ADDR(addr);
-        cpucache_flush();
-    }
-
-    dma_play_data.addr = (unsigned long)addr;
-    dma_play_data.size = size;
-    DMA0_PER_ADDR = (unsigned long)&IISFIFO_WR;
-    DMA0_FLAGS = DMA_FLAGS_UNK26;
-    DMA0_INCR = DMA_INCR_RANGE_FIXED | DMA_INCR_WIDTH_32BIT;
-#else
-    dma_play_data.addr = (unsigned long)addr;
-    dma_play_data.size = size;
-#endif
-
-    play_start_pcm();
-}
-
-/* Stops the DMA transfer and interrupt */
-void pcm_play_dma_stop(void)
-{
-    play_stop_pcm();
-    dma_play_data.addr = 0;
-    dma_play_data.size = 0;
-#if NUM_CORES > 1
-    dma_play_data.core = 0; /* no core in control */
-#endif
-}
-
-void pcm_play_dma_pause(bool pause)
-{
-    if (pause) {
-        play_stop_pcm();
-    } else {
-        play_start_pcm();
-    }
-}
-
-size_t pcm_get_bytes_waiting(void)
-{
-    return dma_play_data.size & ~3;
-}
-
-void pcm_play_dma_init(void)
-{
-    /* Initialize default register values. */
-    audiohw_init();
-
-#ifdef CPU_PP502x
-    /* Enable DMA controller */
-    DMA_MASTER_CONTROL |= DMA_MASTER_CONTROL_EN;
-    /* FIQ priority for DMA */
-    CPU_INT_PRIORITY |= DMA_MASK;
-    /* Enable request?? Not setting or clearing everything doesn't seem to
-     * prevent it operating. Perhaps important for reliability (how requests
-     * are handled). */
-    DMA_REQ_STATUS |= 1ul << DMA_REQ_IIS;
-    DMA0_STATUS;
-#else
-    /* Set up banked registers for FIQ mode */
-
-    /* Use non-banked registers for scratch. */
-    register volatile void *iiscfg asm("r0") = &IISCONFIG;
-    register volatile void *dmapd asm("r1") = &dma_play_data;
-
-    asm volatile (
-        "mrs    r2, cpsr            \n" /* Save mode and interrupt status */
-        "msr    cpsr_c, #0xd1       \n" /* Switch to FIQ mode */
-        "mov    r8, #0              \n"
-        "mov    r9, #0              \n"
-        "mov    r10, %[iiscfg]      \n"
-        "mov    r11, %[dmapd]       \n"
-        "msr    cpsr_c, r2          \n"
-        :
-        : [iiscfg]"r"(iiscfg), [dmapd]"r"(dmapd)
-        : "r2");
-
-    /* FIQ priority for I2S */
-    CPU_INT_PRIORITY |= IIS_MASK;
-    CPU_INT_EN = IIS_MASK;
-#endif
-
-    IISCONFIG |= IIS_TXFIFOEN;
-}
-
-void pcm_play_dma_postinit(void)
-{
-    audiohw_postinit();
-}
-
-const void * pcm_play_dma_get_peak_buffer(int *count)
-{
-    unsigned long addr, size;
-
-    int status = disable_fiq_save();
-    addr = dma_play_data.addr;
-    size = dma_play_data.size;
-    restore_fiq(status);
-
-    *count = size >> 2;
-    return (void *)((addr + 2) & ~3);
-}
-
-/****************************************************************************
- ** Recording DMA transfer
- **/
-#ifdef HAVE_RECORDING
-/* PCM recording interrupt routine lockout */
-static struct dma_data dma_rec_data IBSS_ATTR =
-{
-    /* Initialize to a locked, stopped state */
-    { .addr = 0 },
-    .size = 0,
-#if NUM_CORES > 1
-    .core = 0x00,
-#endif
-    .locked = 0,
-    .state  = 0
-};
-
-/* For the locks, FIQ must be disabled because the handler manipulates
-   IISCONFIG and the operation is not atomic - dual core support
-   will require other measures */
-void pcm_rec_lock(void)
-{
-    int status = disable_fiq_save();
-
-    if (++dma_rec_data.locked == 1)
-        IIS_IRQRX_REG &= ~IIS_IRQRX;
-
-    restore_fiq(status);
-}
-
-void pcm_rec_unlock(void)
-{
-    int status = disable_fiq_save();
-
-    if (--dma_rec_data.locked == 0 && dma_rec_data.state != 0)
-        IIS_IRQRX_REG |= IIS_IRQRX;
-
-    restore_fiq(status);
-}
-
-/* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */
-void fiq_record(void) ICODE_ATTR __attribute__((interrupt ("FIQ")));
-
-#if defined(SANSA_C200) || defined(SANSA_E200)
-void fiq_record(void)
-{
-    register int32_t value;
-
-    if (audio_channels == 2) {
-        /* RX is stereo */
-        while (dma_rec_data.size > 0) {
-            if (IIS_RX_FULL_COUNT < 2) {
-                return;
-            }
-
-            /* Discard every other sample since ADC clock is 1/2 LRCK */
-            value = IISFIFO_RD;
-            IISFIFO_RD;
-
-            *dma_rec_data.p16++ = value;
-            dma_rec_data.size -= 4;
-
-            /* TODO: Figure out how to do IIS loopback */
-            if (audio_output_source != AUDIO_SRC_PLAYBACK) {
-                if (IIS_TX_FREE_COUNT >= 16) {
-                    /* Resync the output FIFO - it ran dry */
-                    IISFIFO_WR = 0;
-                    IISFIFO_WR = 0;
-                }
-                IISFIFO_WR = value;
-                IISFIFO_WR = value;
-            }
-        }
-    }
-    else {
-        /* RX is left channel mono */
-        while (dma_rec_data.size > 0) {
-            if (IIS_RX_FULL_COUNT < 2) {
-                return;
-            }
-
-            /* Discard every other sample since ADC clock is 1/2 LRCK */
-            value = IISFIFO_RD;
-            IISFIFO_RD;
-
-            value = (uint16_t)value | (value << 16);
-
-            *dma_rec_data.p16++ = value;
-            dma_rec_data.size -= 4;
-
-            if (audio_output_source != AUDIO_SRC_PLAYBACK) {
-                if (IIS_TX_FREE_COUNT >= 16) {
-                    /* Resync the output FIFO - it ran dry */
-                    IISFIFO_WR = 0;
-                    IISFIFO_WR = 0;
-                }
-
-                value = *((int32_t *)dma_rec_data.p16 - 1);
-                IISFIFO_WR = value;
-                IISFIFO_WR = value;
-            }
-        }
-    }
-
-    pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr,
-                                &dma_rec_data.size);
-}
-
-#else
-void fiq_record(void)
-{
-    while (dma_rec_data.size > 0) {
-        if (IIS_RX_FULL_COUNT < 2) {
-            return;
-        }
-
-#if SAMPLE_SIZE == 16
-        *dma_rec_data.p16++ = IISFIFO_RD;
-#elif SAMPLE_SIZE == 32
-        *dma_rec_data.p32++ = IISFIFO_RD >> 16;
-        *dma_rec_data.p32++ = IISFIFO_RD >> 16;
-#endif
-        dma_rec_data.size -= 4;
-    }
-
-    pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr,
-                                &dma_rec_data.size);
-}
-
-#endif /* SANSA_E200 */
-
-void pcm_rec_dma_stop(void)
-{
-    /* disable interrupt */
-    IIS_IRQRX_REG &= ~IIS_IRQRX;
-
-    dma_rec_data.state = 0;
-    dma_rec_data.size = 0;
-#if NUM_CORES > 1
-    dma_rec_data.core = 0x00;
-#endif
-
-    /* disable fifo */
-    IISCONFIG &= ~IIS_RXFIFOEN;
-    IISFIFO_CFG |= IIS_RXCLR;
-}
-
-void pcm_rec_dma_start(void *addr, size_t size)
-{
-    pcm_rec_dma_stop();
-
-    dma_rec_data.addr = (unsigned long)addr;
-    dma_rec_data.size = size;
-#if NUM_CORES > 1
-    /* This will become more important later - and different ! */
-    dma_rec_data.core = processor_id(); /* save initiating core */
-#endif
-    /* setup FIQ handler */
-    fiq_function = fiq_record;
-
-    /* interrupt on full fifo, enable record fifo interrupt */
-    dma_rec_data.state = 1;
-
-    /* enable RX FIFO */
-    IISCONFIG |= IIS_RXFIFOEN;
-
-    /* enable IIS interrupt as FIQ */
-    CPU_INT_PRIORITY |= IIS_MASK;
-    CPU_INT_EN = IIS_MASK;
-}
-
-void pcm_rec_dma_close(void)
-{
-    pcm_rec_dma_stop();
-} /* pcm_close_recording */
-
-void pcm_rec_dma_init(void)
-{
-    pcm_rec_dma_stop();
-} /* pcm_init */
-
-const void * pcm_rec_dma_get_peak_buffer(void)
-{
-    return (void *)((unsigned long)dma_rec_data.addr & ~3);
-} /* pcm_rec_dma_get_peak_buffer */
-
-#endif /* HAVE_RECORDING */
diff --git a/firmware/target/arm/philips/app.lds b/firmware/target/arm/philips/app.lds
deleted file mode 100644
index de355c3..0000000
--- a/firmware/target/arm/philips/app.lds
+++ /dev/null
@@ -1,204 +0,0 @@
-#include "config.h"
-
-ENTRY(start)
-
-OUTPUT_FORMAT(elf32-littlearm)
-OUTPUT_ARCH(arm)
-STARTUP(target/arm/crt0-pp.o)
-
-#define PLUGINSIZE PLUGIN_BUFFER_SIZE
-#define CODECSIZE CODEC_SIZE
-
-#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - CODECSIZE
-
-#define DRAMORIG 0x00000000
-#define IRAMORIG 0x40000000
-#define IRAMSIZE 0xc000
-
-#ifdef CPU_PP502x
-#define NOCACHE_BASE 	0x10000000
-#else
-#define NOCACHE_BASE 	0x28000000
-#endif
-
-#define CACHEALIGN_SIZE 16
-
-/* End of the audio buffer, where the codec buffer starts */
-#define ENDAUDIOADDR  (DRAMORIG + DRAMSIZE)
-
-/* Where the codec buffer ends, and the plugin buffer starts */
-#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
-
-MEMORY
-{
-    DRAM : ORIGIN = DRAMORIG,     LENGTH = DRAMSIZE
-    IRAM : ORIGIN = IRAMORIG,     LENGTH = IRAMSIZE
-}
-
-SECTIONS
-{
-    .text :
-    {
-        loadaddress = .;
-        _loadaddress = .;
-        . = ALIGN(0x200);
-        *(.init.text)
-        *(.text*)
-        *(.glue_7)
-        *(.glue_7t)
-        . = ALIGN(0x4);
-    } > DRAM
-
-    .rodata :
-    {
-        *(.rodata)  /* problems without this, dunno why */
-        *(.rodata*)
-        *(.rodata.str1.1)
-        *(.rodata.str1.4)
-        . = ALIGN(0x4);
-
-        /* Pseudo-allocate the copies of the data sections */
-        _datacopy = .;
-    } > DRAM
-
-    /* TRICK ALERT! For RAM execution, we put the .data section at the
-       same load address as the copy. Thus, we don't waste extra RAM
-       when we don't actually need the copy.  */
-    .data : AT ( _datacopy )
-    {
-        _datastart = .;
-        *(.data*)
-        . = ALIGN(0x4);
-        _dataend  = .;
-    } > DRAM
-
-#if NOCACHE_BASE != 0
-    /* .ncdata section is placed at uncached physical alias address and is
-     * loaded at the proper cached virtual address - no copying is
-     * performed in the init code */
-    .ncdata . + NOCACHE_BASE :
-    {
-        . = ALIGN(CACHEALIGN_SIZE);
-        *(.ncdata*)
-        . = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-#endif
-    
-    /DISCARD/ :
-    {
-        *(.eh_frame)
-    }
-
-    .vectors 0x0 :
-    {
-        _vectorsstart = .;
-        *(.vectors);
-        _vectorsend = .;
-    } AT> DRAM
-
-    _vectorscopy = LOADADDR(.vectors);
-    _noloaddram  = LOADADDR(.vectors);
-
-    .ibss IRAMORIG (NOLOAD) :
-    {
-        _iedata = .;
-        *(.qharray)
-        *(.ibss)
-        . = ALIGN(0x4);
-        _iend = .;
-    } > IRAM
-
-    .iram _iend :
-    {
-        _iramstart = .;
-        *(.icode)
-        *(.irodata)
-        *(.idata)
-        . = ALIGN(0x4);
-        _iramend = .;
-    } > IRAM AT> DRAM
-
-    _iramcopy = LOADADDR(.iram);
-
-
-    .init ENDAUDIOADDR : 
-    {
-        . = ALIGN(4);
-        _initstart = .;
-        *(.init)
-        _initend = .;
-    } AT> DRAM
-
-    _initcopy = LOADADDR(.init);
-
-    .idle_stacks (NOLOAD) :
-    {
-       *(.idle_stacks)
-#if NUM_CORES > 1
-       cpu_idlestackbegin = .;
-       . += IDLE_STACK_SIZE;
-       cpu_idlestackend = .;
-#endif
-       cop_idlestackbegin = .;
-       . += IDLE_STACK_SIZE;
-       cop_idlestackend = .;
-    } > IRAM
-
-    .stack (NOLOAD) :
-    {
-       *(.stack)
-       stackbegin = .;
-       . += 0x2000;
-       stackend = .;
-    } > IRAM
-    
-    /* .bss and .ncbss are treated as a single section to use one init loop to
-     * zero it - note "_edata" and "_end" */
-    .bss _noloaddram (NOLOAD) :
-    {
-       _edata = .;
-        *(.bss*)
-        *(COMMON)
-        . = ALIGN(0x4);
-    } > DRAM
-
-#if NOCACHE_BASE != 0
-    .ncbss . + NOCACHE_BASE (NOLOAD):
-    {
-    	. = ALIGN(CACHEALIGN_SIZE);
-        *(.ncbss*)
-    	. = ALIGN(CACHEALIGN_SIZE);
-    } AT> DRAM
-#endif
-
-    /* This will be aligned by preceding alignments */
-    .endaddr . - NOCACHE_BASE (NOLOAD) :
-    {
-        _end = .;
-    } > DRAM
-
-    .audiobuf (NOLOAD) :
-    {
-        _audiobuffer = .;
-        . = ALIGN(0x4);
-        audiobuffer = .;
-    } > DRAM
-    
-    .audiobufend ENDAUDIOADDR (NOLOAD) :
-    {
-        audiobufend = .;
-        _audiobufend = .;
-    } > DRAM
-
-    .codec ENDAUDIOADDR (NOLOAD) :
-    {
-        codecbuf = .;
-        _codecbuf = .;
-    }
-
-    .plugin ENDADDR (NOLOAD) :
-    {
-        _pluginbuf = .;
-        pluginbuf = .;
-    }
-}
diff --git a/firmware/target/arm/philips/boot.lds b/firmware/target/arm/philips/boot.lds
deleted file mode 100644
index 5d63cad..0000000
--- a/firmware/target/arm/philips/boot.lds
+++ /dev/null
@@ -1,71 +0,0 @@
-#include "config.h"
-
-/* Can't link all Philips ARM devices the same way at this time */
-#ifdef HAVE_BOOTLOADER_USB_MODE
-#include "../boot-pp502x-bl-usb.lds"
-#else /* !HAVE_BOOTLOADER_USB_MODE */
-ENTRY(start)
-OUTPUT_FORMAT(elf32-littlearm)
-OUTPUT_ARCH(arm)
-STARTUP(target/arm/crt0-pp-bl.o)
-
-#define DRAMSIZE (MEMORYSIZE * 0x100000)
-
-#define DRAMORIG 0x10000000
-#ifndef IRAMORIG
-#define IRAMORIG 0x40000000
-#endif
-#define IRAMSIZE 0x20000
-#define FLASHORIG 0x001f0000
-#define FLASHSIZE 2M
-
-MEMORY
-{
-    DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
-    IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
-}
-
-SECTIONS
-{
-  . = IRAMORIG;
-
-  .text : {
-    *(.init.text)
-    *(.text*)
-    *(.glue_7)
-    *(.glue_7t)
-  } > IRAM
-
-  .data : {
-    *(.icode)
-    *(.irodata)
-    *(.idata)
-    *(.data*)
-    *(.ncdata*)
-    *(.rodata*)
-    _dataend = . ;
-  } > IRAM
-
-  .stack (NOLOAD) : {
-     *(.stack)
-     _stackbegin = .;
-     stackbegin = .;
-     . += 0x2000;
-     _stackend = .;
-     stackend = .;
-  } > IRAM
-
-  /* The bss section is too large for IRAM - we just move it 16MB into the
-     DRAM */
-
-  . = DRAMORIG;
-  .bss . + (16*1024*1024) (NOLOAD) : {
-     _edata = .;
-     *(.bss*);
-     *(.ibss);
-     *(COMMON)
-     *(.ncbss*);
-     _end = .;
-  } > DRAM
-}
-#endif /* HAVE_BOOTLOADER_USB_MODE */
diff --git a/firmware/target/arm/philips/fmradio_i2c-hdd.c b/firmware/target/arm/philips/fmradio_i2c-hdd.c
deleted file mode 100644
index 98fe5f6..0000000
--- a/firmware/target/arm/philips/fmradio_i2c-hdd.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2009 by Mark Arigo
- *
- * 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"
-
-#if (CONFIG_TUNER & TEA5767)
-#include "i2c-pp.h"
-#include "fmradio_i2c.h"
-
-/* The TEA5767 uses 5 bytes, but the pp-i2c will only read/write 4 bytes
-   at a time. The tuner doesn't like it when the i2c resets to send the 5th
-   byte. So, we can only read/write the first 4 bytes. Luckily, on read,
-   the 5th byte is reserved and on write we only use that for the deemphasis
-   bit (which we'll have to ignore). This is what the OF appears to do too. */
-
-int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count)
-{
-    (void)count;
-    return i2c_sendbytes(address, 4, buf);
-}
-
-int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
-{
-    (void)count;
-    return i2c_readbytes(address, -1, 4, buf);
-}
-#endif
diff --git a/firmware/target/arm/philips/hdd1630/adc-target.h b/firmware/target/arm/philips/hdd1630/adc-target.h
deleted file mode 100644
index bf97081..0000000
--- a/firmware/target/arm/philips/hdd1630/adc-target.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 _ADC_TARGET_H_
-#define _ADC_TARGET_H_
-
-#define NUM_ADC_CHANNELS 2
-
-#define ADC_BATTERY     0
-#define ADC_UNKNOWN_1   1
-#define ADC_UNKNOWN_2   2
-#define ADC_UNKNOWN_3   3
-#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
-
-/* Force a scan now */
-unsigned short adc_scan(int channel);
-
-#endif
diff --git a/firmware/target/arm/philips/hdd1630/backlight-hdd1630.c b/firmware/target/arm/philips/hdd1630/backlight-hdd1630.c
deleted file mode 100644
index 47a5d1c..0000000
--- a/firmware/target/arm/philips/hdd1630/backlight-hdd1630.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id: backlight-hdd.c 28307 2010-10-18 19:54:18Z b0hoon $
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 "backlight-target.h"
-#include "system.h"
-#include "backlight.h"
-#include "synaptics-mep.h"
-
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
-static const int brightness_vals[16] =
-                {255,237,219,201,183,165,147,130,112,94,76,58,40,22,5,0};
-
-void _backlight_set_brightness(int brightness)
-{
-    outl(0x80000000 | (brightness_vals[brightness-1] << 16), 0x7000a000);
-}
-#endif
-
-void _backlight_on(void)
-{
-    GPO32_VAL    &= ~0x1000000;
-    GPO32_ENABLE &= ~0x1000000;
-}
-
-void _backlight_off(void)
-{
-    GPO32_VAL    |= 0x1000000;
-    GPO32_ENABLE |= 0x1000000;
-}
-
-#ifdef HAVE_BUTTON_LIGHT
-#define BUTTONLIGHT_MASK 0x7f
-static unsigned short buttonight_brightness = DEFAULT_BRIGHTNESS_SETTING - 1;
-static unsigned short buttonlight_status = 0;
-
-void _buttonlight_on(void)
-{
-    if (!buttonlight_status)
-    {
-        touchpad_set_buttonlights(BUTTONLIGHT_MASK, buttonight_brightness);
-        buttonlight_status = 1;
-    }
-}
- 
-void _buttonlight_off(void)
-{
-    if (buttonlight_status)
-    {
-        touchpad_set_buttonlights(BUTTONLIGHT_MASK, 0);
-        buttonlight_status = 0;
-    }
-}
-
-void _buttonlight_set_brightness(int brightness)
-{
-    buttonight_brightness = brightness - 1;
-    touchpad_set_buttonlights(BUTTONLIGHT_MASK, buttonight_brightness);
-    buttonlight_status = 1;
-}
-#endif
diff --git a/firmware/target/arm/philips/hdd1630/backlight-target.h b/firmware/target/arm/philips/hdd1630/backlight-target.h
deleted file mode 100644
index 63f3f5a..0000000
--- a/firmware/target/arm/philips/hdd1630/backlight-target.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id: backlight-target.h 24112 2009-12-25 04:05:01Z lowlight $
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 BACKLIGHT_TARGET_H
-#define BACKLIGHT_TARGET_H
-
-#define _backlight_init() true
-void _backlight_on(void);
-void _backlight_off(void);
-
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
-void _backlight_set_brightness(int brightness);
-#endif
-
-#ifdef HAVE_BUTTON_LIGHT
-void _buttonlight_on(void);
-void _buttonlight_off(void);
-void _buttonlight_set_brightness(int brightness);
-#endif
-
-#endif
diff --git a/firmware/target/arm/philips/hdd1630/button-hdd1630.c b/firmware/target/arm/philips/hdd1630/button-hdd1630.c
deleted file mode 100644
index ab06c0c..0000000
--- a/firmware/target/arm/philips/hdd1630/button-hdd1630.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 "system.h"
-#include "button.h"
-#include "backlight.h"
-#include "synaptics-mep.h"
-
-/*#define LOGF_ENABLE*/
-#include "logf.h"
-
-static int int_btn = BUTTON_NONE;
-
-/*
- * Generate a click sound from the player (not in headphones yet)
- * TODO: integrate this with the "key click" option
- */
-void button_click(void)
-{
-    GPO32_ENABLE |= 0x2000;
-    GPO32_VAL |= 0x2000;
-    udelay(1000);
-    GPO32_VAL &= ~0x2000;
-}
-
-#ifndef BOOTLOADER
-void button_init_device(void)
-{
-    /* The touchpad is powered on and initialized in power-hdd1630.c
-       since it needs to be ready for both buttons and button lights. */
-}
-
-/*
- * Button interrupt handler
- */
-void button_int(void)
-{
-    char data[4];
-    int val;
-
-    int_btn = BUTTON_NONE;
-
-    val = touchpad_read_device(data, 4);
-    
-    if (val == MEP_BUTTON_HEADER)
-    {
-        /* Buttons packet */
-        if (data[1] & 0x1)
-            int_btn |= BUTTON_LEFT;
-        if (data[1] & 0x2)
-            int_btn |= BUTTON_RIGHT;
-    }
-    else if (val == MEP_ABSOLUTE_HEADER)
-    {
-        /* Absolute packet - the finger is on the vertical strip.
-           Position ranges from 1-4095, with 1 at the bottom. */
-        val = ((data[1] >> 4) << 8) | data[2]; /* position */
-
-        if ((val > 0) && (val <= 1365))
-            int_btn |= BUTTON_DOWN;
-        else if ((val > 1365) && (val <= 2730))
-            int_btn |= BUTTON_SELECT;
-        else if ((val > 2730) && (val <= 4095))
-            int_btn |= BUTTON_UP;
-    }
-}
-#else
-void button_init_device(void){}
-#endif /* bootloader */
-
-bool button_hold(void)
-{
-    return !(GPIOJ_INPUT_VAL & 0x8);
-}
-
-/*
- * Get button pressed from hardware
- */
-int button_read_device(void)
-{
-    static int btn_old = BUTTON_NONE;
-    int btn = int_btn;
-
-    /* Hold */
-    if(button_hold())
-        return BUTTON_NONE;
-
-    /* Device buttons */
-    if (!(GPIOA_INPUT_VAL & 0x01)) btn |= BUTTON_MENU;
-    if (!(GPIOA_INPUT_VAL & 0x02)) btn |= BUTTON_VOL_UP;
-    if (!(GPIOA_INPUT_VAL & 0x04)) btn |= BUTTON_VOL_DOWN;
-    if (!(GPIOA_INPUT_VAL & 0x08)) btn |= BUTTON_VIEW;
-    if (!(GPIOD_INPUT_VAL & 0x20)) btn |= BUTTON_PLAYLIST;
-    if (!(GPIOD_INPUT_VAL & 0x40)) btn |= BUTTON_POWER;
-
-    if ((btn != btn_old) && (btn != BUTTON_NONE))
-        button_click();
-
-    btn_old = btn;
-
-    return btn;
-}
-
-bool headphones_inserted(void)
-{
-    return (GPIOE_INPUT_VAL & 0x80) ? true : false;
-}
diff --git a/firmware/target/arm/philips/hdd1630/button-target.h b/firmware/target/arm/philips/hdd1630/button-target.h
deleted file mode 100644
index b7fc21a..0000000
--- a/firmware/target/arm/philips/hdd1630/button-target.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 _BUTTON_TARGET_H_
-#define _BUTTON_TARGET_H_
-
-#include <stdbool.h>
-#include "config.h"
-
-#define MEP_BUTTON_HEADER   0x19
-#define MEP_BUTTON_ID       0x9
-#define MEP_ABSOLUTE_HEADER 0x0b
-
-#define HAS_BUTTON_HOLD
-
-bool button_hold(void);
-void button_init_device(void);
-int button_read_device(void);
-
-#ifndef BOOTLOADER
-void button_int(void);
-#endif
-
-/* Main unit's buttons */
-#define BUTTON_POWER        0x00000001
-#define BUTTON_PLAYLIST     0x00000002
-#define BUTTON_MENU         0x00000004
-#define BUTTON_VIEW         0x00000008
-#define BUTTON_VOL_UP       0x00000010
-#define BUTTON_VOL_DOWN     0x00000020
-#define BUTTON_SELECT       0x00000040
-#define BUTTON_LEFT         0x00000080
-#define BUTTON_RIGHT        0x00000100
-#define BUTTON_UP           0x00000200
-#define BUTTON_DOWN         0x00000400
-
-#define BUTTON_MAIN         0x00000fff
-
-/* No Remote control */
-#define BUTTON_REMOTE 0
-
-#define POWEROFF_BUTTON BUTTON_POWER
-#define POWEROFF_COUNT 10
-
-#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/philips/hdd1630/lcd-as-hdd1630.S b/firmware/target/arm/philips/hdd1630/lcd-as-hdd1630.S
deleted file mode 100644
index 7be807a..0000000
--- a/firmware/target/arm/philips/hdd1630/lcd-as-hdd1630.S
+++ /dev/null
@@ -1,570 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2007-2008 by Michael Sevakis
- *
- * H10 20GB LCD assembly routines
- *
- * 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"
-
-/****************************************************************************
- * void lcd_write_yuv_420_lines(unsigned char const * const src[3],
- *                              int width,
- *                              int stride);
- *
- *   |R|   |1.000000 -0.000001  1.402000| |Y'|
- *   |G| = |1.000000 -0.334136 -0.714136| |Pb|
- *   |B|   |1.000000  1.772000  0.000000| |Pr|
- *   Scaled, normalized, rounded and tweaked to yield RGB 565:
- *   |R|   |74   0 101| |Y' -  16| >> 9
- *   |G| = |74 -24 -51| |Cb - 128| >> 8
- *   |B|   |74 128   0| |Cr - 128| >> 9
- *
- * Write four RGB565 pixels in the following order on each loop:
- * 1 3 + > down
- * 2 4 \/ left
- */
-    .section    .icode, "ax", %progbits
-    .align      2
-    .global     lcd_write_yuv420_lines
-    .type       lcd_write_yuv420_lines, %function
-lcd_write_yuv420_lines:
-                                        @ r0 = yuv_src
-                                        @ r1 = width
-                                        @ r2 = stride
-    stmfd       sp!, { r4-r11, lr }     @ save non-scratch
-    ldmia       r0, { r4, r5, r6 }      @ r4 = yuv_src[0] = Y'_p
-                                        @ r5 = yuv_src[1] = Cb_p
-                                        @ r6 = yuv_src[2] = Cr_p
-                                        @
-    mov         r0, #0x7000000c         @ r0 = &LCD2_PORT = 0x70008a0c
-    add         r0, r0, #0x8a00         @
-    mov         r14, #LCD2_DATA_MASK    @
-                                        @
-    sub         r2, r2, #1              @ Adjust stride because of increment
-10: @ loop line                         @
-    ldrb        r7, [r4], #1            @ r7 = *Y'_p++;
-    ldrb        r8, [r5], #1            @ r8 = *Cb_p++;
-    ldrb        r9, [r6], #1            @ r9 = *Cr_p++;
-                                        @
-    sub         r7, r7, #16             @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @ actually (Y' - 16)*37 and shift right
-    add         r7, r12, r7, asl #5     @ by one less when adding - same for all
-                                        @
-    sub         r8, r8, #128            @ Cb -= 128
-    sub         r9, r9, #128            @ Cr -= 128
-                                        @
-    add         r10, r9, r9, asl #1     @ r10 = Cr*51 + Cb*24
-    add         r10, r10, r10, asl #4   @
-    add         r10, r10, r8, asl #3    @
-    add         r10, r10, r8, asl #4    @
-                                        @
-    add         r11, r9, r9, asl #2     @ r9 = Cr*101
-    add         r11, r11, r9, asl #5    @
-    add         r9, r11, r9, asl #6     @
-                                        @
-    add         r8, r8, #2              @ r8 = bu = (Cb*128 + 128) >> 8
-    mov         r8, r8, asr #2          @
-    add         r9, r9, #256            @ r9 = rv = (r8 + 256) >> 9
-    mov         r9, r9, asr #9          @
-    rsb         r10, r10, #128          @ r10 = guv = (-r9 + 128) >> 8
-    mov         r10, r10, asr #8        @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3 = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
-    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
-                                        @
-    orr         r7, r14, r3, lsr #8     @ store pixel
-    orr         r11, r14, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4], #1           @ r12 = Y' = *(Y'_p++)
-                                        @
-    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
-    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
-                                        @
-    orr         r7, r14, r3, lsr #8     @ store pixel
-    orr         r11, r14, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    orr         r3, r3, r7, lsl #5      @ r3 = b | (g << 5)
-    orr         r3, r3, r11, lsl #11    @ r3 |= (r << 11)
-                                        @
-    orr         r7, r14, r3, lsr #8     @ store pixel
-    orr         r11, r14, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r11            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r11, #31                @ clamp r
-    mvnhi       r11, r11, asr #31       @
-    andhi       r11, r11, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
-    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
-                                        @
-    orr         r7, r14, r3, lsr #8     @ store pixel
-    orr         r11, r14, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r11, [r0]               @
-                                        @
-    subs        r1, r1, #2              @ subtract block from width
-    bgt         10b @ loop line         @
-                                        @
-    ldmpc       regs=r4-r11             @ restore registers and return
-    .ltorg                              @ dump constant pool
-    .size   lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
-
-
-/****************************************************************************
- * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
- *                                      int width,
- *                                      int stride,
- *                                      int x_screen,
- *                                      int y_screen);
- *
- *   |R|   |1.000000 -0.000001  1.402000| |Y'|
- *   |G| = |1.000000 -0.334136 -0.714136| |Pb|
- *   |B|   |1.000000  1.772000  0.000000| |Pr|
- *   Red scaled at twice g & b but at same precision to place it in correct
- *   bit position after multiply and leave instruction count lower.
- *   |R|   |258   0  408| |Y' -  16|
- *   |G| = |149 -49 -104| |Cb - 128|
- *   |B|   |149 258    0| |Cr - 128|
- *
- * Write four RGB565 pixels in the following order on each loop:
- * 1 3 + > down
- * 2 4 \/ left
- *
- * Kernel pattern (raw|use order):
- * 5 3 4 2     row0    row2         > down
- * 1 7 0 6 | 5 1 3 7 4 0 2 6 col0     left
- * 4 2 5 3 | 4 0 2 6 5 1 3 7 col2  \/
- * 0 6 1 7
- */
-    .section    .icode, "ax", %progbits
-    .align      2
-    .global     lcd_write_yuv420_lines_odither
-    .type       lcd_write_yuv420_lines_odither, %function
-lcd_write_yuv420_lines_odither:
-                                        @ r0   = yuv_src
-                                        @ r1   = width
-                                        @ r2   = stride
-                                        @ r3   = x_screen
-                                        @ [sp] = y_screen
-    stmfd       sp!, { r4-r11, lr }     @ save non-scratch
-    ldmia       r0, { r4, r5, r6 }      @ r4 = yuv_src[0] = Y'_p
-                                        @ r5 = yuv_src[1] = Cb_p
-                                        @ r6 = yuv_src[2] = Cr_p
-                                        @
-    ldr         r0, [sp, #36]           @ Line up pattern and kernel quadrant
-    eor         r14, r3, r0             @
-    and         r14, r14, #0x2          @
-    mov         r14, r14, lsl #6        @ 0x00 or 0x80
-                                        @
-    mov         r0, #0x7000000c         @ r0 = &LCD2_PORT = 0x70008a0c
-    add         r0, r0, #0x8a00         @
-                                        @
-    sub         r2, r2, #1              @ Adjust stride because of increment
-10: @ loop line                         @
-                                        @
-    ldrb        r7, [r4], #1            @ r7 = *Y'_p++;
-    ldrb        r8, [r5], #1            @ r8 = *Cb_p++;
-    ldrb        r9, [r6], #1            @ r9 = *Cr_p++;
-                                        @
-    eor         r14, r14, #0x80         @ flip pattern quadrant
-                                        @
-    sub         r7, r7, #16             @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @    
-    sub         r8, r8, #128            @ Cb -= 128
-    sub         r9, r9, #128            @ Cr -= 128
-                                        @
-    add         r10, r8, r8, asl #4     @ r10 = guv = Cr*104 + Cb*49
-    add         r10, r10, r8, asl #5    @
-    add         r10, r10, r9, asl #3    @
-    add         r10, r10, r9, asl #5    @
-    add         r10, r10, r9, asl #6    @
-                                        @
-    mov         r8, r8, asl #1          @ r8 = bu = Cb*258
-    add         r8, r8, r8, asl #7      @
-                                        @
-    add         r9, r9, r9, asl #1      @ r9 = rv = Cr*408
-    add         r9, r9, r9, asl #4      @
-    mov         r9, r9, asl #3          @
-                                        @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-                                        @ r8 = bu, r9 = rv, r10 = guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3 = 31/32*b + b/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r + r/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7 = 63/64*g + g/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    add         r12, r14, #0x200        @
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    mov         r11, #LCD2_DATA_MASK    @ store pixel
-    orr         r7, r11, r3, lsr #8     @
-    orr         r11, r11, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3  = 31/32*b' + b'/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r' + r'/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7  = 63/64*g' + g'/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    @ This element is zero - use r14    @
-                                        @
-    add         r3, r3, r14             @ b = r3 + delta
-    add         r11, r11, r14, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r14, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4], #1           @ r12 = Y' = *(Y'_p++)
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    mov         r11, #LCD2_DATA_MASK    @ store pixel
-    orr         r7, r11, r3, lsr #8     @
-    orr         r11, r11, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-                                        @ r8 = bu, r9 = rv, r10 = guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3  = 31/32*b' + b'/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r' + r'/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7  = 63/64*g' + g'/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    add         r12, r14, #0x100        @
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)    
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    mov         r11, #LCD2_DATA_MASK    @ store pixel
-    orr         r7, r11, r3, lsr #8     @
-    orr         r11, r11, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r11, [r0]               @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3 = 31/32*b + b/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r + r/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7 = 63/64*g + g/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-    add         r12, r14, #0x300        @
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    and         r11, r11, #0xf800       @ pack pixel
-    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
-    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
-    orr         r3, r11, r3, lsr #10    @              (b >> 10)
-                                        @
-    mov         r11, #LCD2_DATA_MASK    @ store pixel
-    orr         r7, r11, r3, lsr #8     @
-    orr         r11, r11, r3            @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r7, [r0]                @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD2_BUSY_MASK     @
-    bne         20b                     @
-    str         r11, [r0]               @
-                                        @
-    subs        r1, r1, #2              @ subtract block from width
-    bgt         10b @ loop line         @
-                                        @
-    ldmpc       regs=r4-r11             @ restore registers and return
-    .ltorg                              @ dump constant pool
-    .size   lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
diff --git a/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c b/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c
deleted file mode 100644
index 500120a..0000000
--- a/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 <sys/types.h>
-
-#include "config.h"
-#include "cpu.h"
-#include "lcd.h"
-#include "kernel.h"
-#include "system.h"
-
-/* The LCD registers appear to match controllers from Leadis Technology,
-   either the LDS176 (132x132 4k) or the LDS186 (128x160 65k).
-   These defines are from the LDS176 (I couldn't find the LDS186 datasheet. */
-#define NOP     0x00
-#define SWRESET 0x01
-#define BSTROFF 0x02
-#define BSTRON  0x03
-#define RDDID   0x04
-#define RDDST   0x09
-#define SLPIN   0x10
-#define SLPOUT  0x11
-#define PTLON   0x12
-#define NORON   0x13
-#define INVOFF  0x20
-#define INVON   0x21
-#define APOFF   0x22
-#define APON    0x23
-#define WRCNTR  0x25
-#define DISPOFF 0x28
-#define DISPON  0x29
-#define CASET   0x2a
-#define RASET   0x2b
-#define RAMWR   0x2c
-#define RAMRD   0x2e
-#define RGBSET  0x2d
-#define PTLAR   0x30
-#define SCRLAR  0x33
-#define TEOFF   0x34
-#define TEON    0x35
-#define MADCTR  0x36
-#define VSCSAD  0x37
-#define IDMOFF  0x38
-#define IDMON   0x39
-#define COLMOD  0x3a
-#define RDID1   0xda
-#define RDID2   0xdb
-#define RDID3   0xdc
-#define CLKINT  0xb0
-#define CLKEXT  0xb1
-#define FRMSEL  0xb4
-#define FRM8SEL 0xb5
-#define TMPRNG  0xb6
-#define TMPHIS  0xb7
-#define TMPREAD 0xb8
-#define DISCTR  0xba
-#define EPVOL   0xbb
-#define EPWRIN  0xd1
-#define EPWROUT 0xd0
-#define RDEV    0xd4
-#define RDRR    0xd5
-
-/* Display status */
-static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
-static unsigned mad_ctrl = 0;
-
-/* wait for LCD */
-static inline void lcd_wait_write(void)
-{
-    int i = 0;
-    while (LCD2_PORT & LCD2_BUSY_MASK)
-    {
-        if (i < 2000)
-            i++;
-        else
-            LCD2_PORT &= ~LCD2_BUSY_MASK;
-    }
-}
-
-/* send LCD data */
-static void lcd_send_data(unsigned data)
-{
-    lcd_wait_write();
-    LCD2_PORT = LCD2_DATA_MASK | (data & 0xff);
-}
-
-/* send LCD command */
-static void lcd_send_cmd(unsigned cmd)
-{
-    lcd_wait_write();
-    LCD2_PORT = LCD2_CMD_MASK | (cmd & 0xff);
-    lcd_wait_write();
-}
-
-static inline void lcd_send_pixel(unsigned pixel)
-{
-    lcd_send_data(pixel >> 8);
-    lcd_send_data(pixel);
-}
-
-void lcd_init_device(void)
-{
-#if 0
-    /* this sequence from the OF bootloader */
-
-    DEV_EN2 |= 0x2000;
-    outl(inl(0x70000014) & ~0xf000000, 0x70000014);
-    outl(inl(0x70000014) | 0xa000000, 0x70000014);
-    DEV_INIT1 &= 0xc000;
-    DEV_INIT1 |= 0x8000;
-    MLCD_SCLK_DIV &= ~0x800;
-    CLCD_CLOCK_SRC |= 0xc0000000;
-    DEV_INIT2 &= ~0x400;
-    outl(inl(0x7000002c) | ((1<<4)<<24), 0x7000002c);
-    DEV_INIT2 &= ~((1<<4)<<24);
-    udelay(10000);
-
-    DEV_INIT2 |= ((1<<4)<<24);
-    outl(0x220, 0x70008a00);
-    outl(0x1f00, 0x70008a04);
-    LCD2_BLOCK_CTRL = 0x10008080;
-    LCD2_BLOCK_CONFIG = 0xF00000;
-
-    /* lcd power */
-    GPIOJ_ENABLE     |= 0x4;
-    GPIOJ_OUTPUT_VAL |= 0x4;
-    GPIOJ_OUTPUT_EN  |= 0x4;
-    
-    lcd_send_cmd(SWRESET);
-    udelay(10000);
-    
-    lcd_send_cmd(WRCNTR);
-    lcd_send_data(0x3f);
-    
-    lcd_send_cmd(SLPOUT);
-    udelay(120000);
-    
-    lcd_send_cmd(INVOFF);
-    lcd_send_cmd(IDMOFF);
-    lcd_send_cmd(NORON);
-    
-    lcd_send_cmd(FRMSEL);
-    lcd_send_data(0x2);
-    lcd_send_data(0x6);
-    lcd_send_data(0x8);
-    lcd_send_data(0xd);
-
-    lcd_send_cmd(FRM8SEL);
-    lcd_send_data(0x2);
-    lcd_send_data(0x6);
-    lcd_send_data(0x8);
-    lcd_send_data(0xd);
-
-    lcd_send_cmd(TMPRNG);
-    lcd_send_data(0x19);
-    lcd_send_data(0x23);
-    lcd_send_data(0x2d);
-
-    lcd_send_cmd(TMPHIS);
-    lcd_send_data(0x5);
-
-    lcd_send_cmd(DISCTR);
-    lcd_send_data(0x7);
-    lcd_send_data(0x18);
-
-    lcd_send_cmd(MADCTR);
-    lcd_send_data(0);
-    mad_ctrl = 0;
-
-    lcd_send_cmd(COLMOD);
-    lcd_send_data(0x5);
-    
-    lcd_send_cmd(RGBSET);
-    lcd_send_data(0x1);
-    lcd_send_data(0x2);
-    lcd_send_data(0x3);
-    lcd_send_data(0x4);
-    lcd_send_data(0x5);
-    lcd_send_data(0x6);
-    lcd_send_data(0x7);
-    lcd_send_data(0x8);
-    lcd_send_data(0x9);
-    lcd_send_data(0xa);
-    lcd_send_data(0xb);
-    lcd_send_data(0xc);
-    lcd_send_data(0xd);
-    lcd_send_data(0xe);
-    lcd_send_data(0xf);
-    lcd_send_data(0x10);
-    lcd_send_data(0x11);
-    lcd_send_data(0x12);
-    lcd_send_data(0x13);
-    lcd_send_data(0x14);
-    lcd_send_data(0x15);
-    lcd_send_data(0x16);
-    lcd_send_data(0x17);
-    lcd_send_data(0x18);
-    lcd_send_data(0x19);
-    lcd_send_data(0x1a);
-    lcd_send_data(0x1b);
-    lcd_send_data(0x1c);
-    lcd_send_data(0x1d);
-    lcd_send_data(0x1e);
-    lcd_send_data(0x1f);
-    lcd_send_data(0x20);
-    lcd_send_data(0x21);
-    lcd_send_data(0x22);
-    lcd_send_data(0x23);
-    lcd_send_data(0x24);
-    lcd_send_data(0x25);
-    lcd_send_data(0x26);
-    lcd_send_data(0x27);
-    lcd_send_data(0x28);
-    lcd_send_data(0x29);
-    lcd_send_data(0x2a);
-    lcd_send_data(0x2b);
-    lcd_send_data(0x2c);
-    lcd_send_data(0x2d);
-    lcd_send_data(0x2e);
-    lcd_send_data(0x2f);
-    lcd_send_data(0x30);
-
-    lcd_send_cmd(DISPON);
-#endif
-}
-
-/*** hardware configuration ***/
-int lcd_default_contrast(void)
-{
-    return DEFAULT_CONTRAST_SETTING;
-}
-
-void lcd_set_contrast(int val)
-{
-    lcd_send_cmd(WRCNTR);
-    lcd_send_data(val);
-}
-
-void lcd_set_invert_display(bool yesno)
-{
-    if (yesno) 
-        lcd_send_cmd(INVON);
-    else
-        lcd_send_cmd(INVOFF);
-}
-
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
-    if (yesno)
-        mad_ctrl |= ((1<<7) | (1<<6));  /* flip */
-    else
-        mad_ctrl &= ~((1<<7) | (1<<6)); /* normal */
-    
-    lcd_send_cmd(MADCTR);
-    lcd_send_data(mad_ctrl);
-}
-
-void lcd_yuv_set_options(unsigned options)
-{
-    lcd_yuv_options = options;
-}
-
-/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
-extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
-                                   int width, int stride);
-
-extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
-                                           int width, int stride,
-                                           int x_screen,  int y_screen);
-
-/* Performance function to blit a YUV bitmap directly to the LCD */
-void lcd_blit_yuv(unsigned char * const src[3],
-                  int src_x, int src_y, int stride,
-                  int x, int y, int width, int height)
-{
-    unsigned char const * yuv_src[3];
-    off_t z;
-
-    /* Sorry, but width and height must be >= 2 or else */
-    width &= ~1;
-    height >>= 1;
-    
-    z = stride*src_y;
-    yuv_src[0] = src[0] + z + src_x;
-    yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
-    yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
-
-    /* Set vertical address mode */
-    lcd_send_cmd(MADCTR);
-    lcd_send_data(mad_ctrl | (1<<5));
-
-    lcd_send_cmd(RASET);
-    lcd_send_data(x);
-    lcd_send_data(x + width - 1);
-
-    if (lcd_yuv_options & LCD_YUV_DITHER)
-    {
-        do
-        {
-            lcd_send_cmd(CASET);
-            lcd_send_data(y);
-            lcd_send_data(y + 1);
-
-            lcd_send_cmd(RAMWR);
-
-            lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y);
-            yuv_src[0] += stride << 1; /* Skip down two luma lines */
-            yuv_src[1] += stride >> 1; /* Skip down one chroma line */
-            yuv_src[2] += stride >> 1;
-            y += 2;
-        }
-        while (--height > 0);
-    }
-    else
-    {
-        do
-        {
-            lcd_send_cmd(CASET);
-            lcd_send_data(y);
-            lcd_send_data(y + 1);
-
-            lcd_send_cmd(RAMWR);
-
-            lcd_write_yuv420_lines(yuv_src, width, stride);
-            yuv_src[0] += stride << 1; /* Skip down two luma lines */
-            yuv_src[1] += stride >> 1; /* Skip down one chroma line */
-            yuv_src[2] += stride >> 1;
-            y += 2;
-        }
-        while (--height > 0);
-    }
-
-    /* Restore the address mode */
-    lcd_send_cmd(MADCTR);
-    lcd_send_data(mad_ctrl);
-}
-
-/* Update the display.
-   This must be called after all other LCD functions that change the display. */
-void lcd_update(void)
-{
-    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
-}
-
-/* Update a fraction of the display. */
-void lcd_update_rect(int x, int y, int width, int height)
-{
-    const fb_data *addr;
-    
-    if (x + width >= LCD_WIDTH)
-        width = LCD_WIDTH - x;
-    if (y + height >= LCD_HEIGHT)
-        height = LCD_HEIGHT - y;
-        
-    if ((width <= 0) || (height <= 0))
-        return; /* Nothing left to do. */
-
-    addr = &lcd_framebuffer[y][x];
-
-    lcd_send_cmd(CASET);
-    lcd_send_data(x);
-    lcd_send_data(x + width - 1);
-
-    lcd_send_cmd(RASET);
-    lcd_send_data(y);
-    lcd_send_data(y + height - 1);
-
-    lcd_send_cmd(RAMWR);
-    do {
-        int w = width;
-        do {
-            lcd_send_pixel(*addr++);
-        } while (--w > 0);
-        addr += LCD_WIDTH - width;
-    } while (--height > 0);
-}
diff --git a/firmware/target/arm/philips/hdd1630/powermgmt-hdd1630.c b/firmware/target/arm/philips/hdd1630/powermgmt-hdd1630.c
deleted file mode 100644
index 8090c62..0000000
--- a/firmware/target/arm/philips/hdd1630/powermgmt-hdd1630.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
- * Revisions copyright (C) 2005 by Gerald Van Baren
- *
- * 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 "adc.h"
-#include "powermgmt.h"
-
-#define SMLAL(lo, hi, x, y)              \
-    asm volatile ("smlal %0, %1, %2, %3" \
-     : "+r" (lo), "+r" (hi)              \
-     : "%r" (x), "r" (y))
-
-const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
-{
-    3550
-};
-
-const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
-{
-    3500
-};
-
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
-const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
-{
-    { 3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 },
-};
-
-#if CONFIG_CHARGING
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
-const unsigned short percent_to_volt_charge[11] =
-{
-    3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990
-};
-#endif /* CONFIG_CHARGING */
-
-#define BATTERY_SCALE_FACTOR 4200
-/* full-scale ADC readout (2^10) in millivolt */
-
-/* Returns battery voltage from ADC [millivolts] */
-unsigned int battery_adc_voltage(void)
-{
-    /* return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; */
-
-    /* This may be overly complicated (pulled from the OF) */
-    int lo = 0;
-    int val = adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR;
-
-    SMLAL(lo, val, 0x8a42f871, val);
-    val>>= 9;
-    val -= (val >> 31);
-    return val;
-}
diff --git a/firmware/target/arm/philips/hdd6330/adc-target.h b/firmware/target/arm/philips/hdd6330/adc-target.h
deleted file mode 100644
index bf97081..0000000
--- a/firmware/target/arm/philips/hdd6330/adc-target.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 _ADC_TARGET_H_
-#define _ADC_TARGET_H_
-
-#define NUM_ADC_CHANNELS 2
-
-#define ADC_BATTERY     0
-#define ADC_UNKNOWN_1   1
-#define ADC_UNKNOWN_2   2
-#define ADC_UNKNOWN_3   3
-#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
-
-/* Force a scan now */
-unsigned short adc_scan(int channel);
-
-#endif
diff --git a/firmware/target/arm/philips/hdd6330/backlight-hdd6330.c b/firmware/target/arm/philips/hdd6330/backlight-hdd6330.c
deleted file mode 100644
index 46c03e7..0000000
--- a/firmware/target/arm/philips/hdd6330/backlight-hdd6330.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id: backlight-hdd.c 28307 2010-10-18 19:54:18Z b0hoon $
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 "backlight-target.h"
-#include "system.h"
-#include "backlight.h"
-#include "lcd.h"
-#include "synaptics-mep.h"
-
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
-static const int brightness_vals[16] =
-                {255,237,219,201,183,165,147,130,112,94,76,58,40,22,5,0};
-
-void _backlight_set_brightness(int brightness)
-{
-    outl(0x80000000 | (brightness_vals[brightness-1] << 16), 0x7000a000);
-}
-#endif
-
-void _backlight_on(void)
-{
-#ifdef HAVE_LCD_ENABLE
-    lcd_enable(true);
-#endif
-
-    GPO32_ENABLE |= 0x400;
-    GPO32_VAL    |= 0x400;
-}
-
-void _backlight_off(void)
-{
-    GPO32_ENABLE |= 0x400;
-    GPO32_VAL    &= ~0x400;
-
-#ifdef HAVE_LCD_ENABLE
-    lcd_enable(false);
-#endif
-}
-
-#ifdef HAVE_BUTTON_LIGHT
-#define BUTTONLIGHT_MASK 0x64
-static unsigned short buttonight_brightness = DEFAULT_BRIGHTNESS_SETTING - 1;
-static unsigned short buttonlight_status = 0;
-
-void _buttonlight_on(void)
-{
-    if (!buttonlight_status)
-    {
-        /* enable 1 led (from 2) for MENU - GPO, module 1 */
-        /* no need to enable led for the hidden button */
-        touchpad_set_parameter(0x01,0x21,0x01);
-        /* enable 3 leds (from 5) for PREV, PLAY and NEXT, */
-        /* skip 2 leds because their light does not pass */
-        /* through the panel anyway - on GPOs, module 0 */
-        touchpad_set_parameter(0x00,0x22,0x15);
-        /* left, right and the scrollstrip (1 led from 5) */
-        touchpad_set_buttonlights(BUTTONLIGHT_MASK, buttonight_brightness);
-        buttonlight_status = 1;
-    }
-}
-
-void _buttonlight_off(void)
-{
-    if (buttonlight_status)
-    {
-        /* disable all leds on GPOs for module 0 and 1 */
-        touchpad_set_parameter(0x01,0x21,0x00);
-        touchpad_set_parameter(0x00,0x22,0x00);
-        touchpad_set_buttonlights(BUTTONLIGHT_MASK, 0);
-        buttonlight_status = 0;
-    }
-}
-
-void _buttonlight_set_brightness(int brightness)
-{
-    touchpad_set_parameter(0x01,0x21,0x01);
-    touchpad_set_parameter(0x00,0x22,0x15);
-    buttonight_brightness = brightness - 1;
-    touchpad_set_buttonlights(BUTTONLIGHT_MASK, buttonight_brightness);
-    buttonlight_status = 1;
-}
-#endif
diff --git a/firmware/target/arm/philips/hdd6330/backlight-target.h b/firmware/target/arm/philips/hdd6330/backlight-target.h
deleted file mode 100644
index 63f3f5a..0000000
--- a/firmware/target/arm/philips/hdd6330/backlight-target.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id: backlight-target.h 24112 2009-12-25 04:05:01Z lowlight $
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 BACKLIGHT_TARGET_H
-#define BACKLIGHT_TARGET_H
-
-#define _backlight_init() true
-void _backlight_on(void);
-void _backlight_off(void);
-
-#ifdef HAVE_BACKLIGHT_BRIGHTNESS
-void _backlight_set_brightness(int brightness);
-#endif
-
-#ifdef HAVE_BUTTON_LIGHT
-void _buttonlight_on(void);
-void _buttonlight_off(void);
-void _buttonlight_set_brightness(int brightness);
-#endif
-
-#endif
diff --git a/firmware/target/arm/philips/hdd6330/button-hdd6330.c b/firmware/target/arm/philips/hdd6330/button-hdd6330.c
deleted file mode 100644
index fc171c7..0000000
--- a/firmware/target/arm/philips/hdd6330/button-hdd6330.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 "system.h"
-#include "button.h"
-#include "backlight.h"
-#include "powermgmt.h"
-#include "synaptics-mep.h"
-
-/*#define LOGF_ENABLE*/
-#include "logf.h"
-
-static int int_btn = BUTTON_NONE;
-#ifndef BOOTLOADER
-static int old_pos = -1;
-static int scroll_repeat = BUTTON_NONE;
-#endif
-static int repeat = 0;
-
-/*
- * Generate a click sound from the player (not in headphones yet)
- * TODO: integrate this with the "key click" option
- */
-void button_click(void)
-{
-    GPO32_ENABLE |= 0x2000;
-    GPO32_VAL |= 0x2000;
-    udelay(1000);
-    GPO32_VAL &= ~0x2000;
-}
-
-#ifndef BOOTLOADER
-void button_init_device(void)
-{
-    /* The touchpad is powered on and initialized in power-hdd1630.c
-       since it needs to be ready for both buttons and button lights. */
-}
-
-/*
- * Button interrupt handler
- */
-void button_int(void)
-{
-    char data[4];
-    int val;
-
-    int_btn = BUTTON_NONE;
-
-    val = touchpad_read_device(data, 4);
-
-    if (data[0] == MEP_BUTTON_HEADER)
-    {
-        /* Buttons packet */
-        if (data[1] & 0x1)
-            int_btn |= BUTTON_LEFT;
-        if (data[1] & 0x2)
-            int_btn |= BUTTON_MENU;
-        if (data[1] & 0x4)
-            int_btn |= BUTTON_RIGHT;
-        if (data[1] & 0x8)
-            int_btn |= BUTTON_VIEW;
-    }
-    else if ((data[0] == MEP_ABSOLUTE_HEADER))
-    {
-        if (data[1] & MEP_FINGER)
-        {
-            /* Absolute packet - the finger is on the horizontal strip.
-                Position ranges from 1-4095, with 1 at the bottom. */
-            val = ((data[1] >> 4) << 8) | data[2]; /* position */
-
-            /* The HDD63x0 actually has 2 scrollbars. One vertical and one horizontal 
-            (where the prev, play, and next buttons are). Because of that, we need to know
-            which sensor is reporting data. */
-            if ((data[3] >> 6) == 1) /* index = 1 */
-            {
-                if ((val > 0) && (val <= 1365))
-                    int_btn |= BUTTON_PREV;
-                else if ((val > 1365) && (val <= 2730))
-                    int_btn |= BUTTON_PLAY;
-                else if ((val > 2730) && (val <= 4095))
-                    int_btn |= BUTTON_NEXT;
-            } else
-            {
-                int scr_pos = val >> 8; /* split the scrollstrip into 16 regions */
-                if ((old_pos<scr_pos)&&(old_pos!=-1)) int_btn = BUTTON_UP;
-                if ((old_pos>scr_pos)&&(old_pos!=-1)) int_btn = BUTTON_DOWN;
-
-                old_pos = scr_pos;
-
-                /* repeat button */
-                repeat = 0;
-                if (int_btn != BUTTON_NONE)
-                {
-                    if (int_btn != scroll_repeat)
-                        scroll_repeat = int_btn;
-                    else repeat = BUTTON_REPEAT;
-                }
-            }
-        }
-        else
-        {
-            old_pos = -1;
-            scroll_repeat = BUTTON_NONE;
-        }
-    }
-}
-#else
-void button_init_device(void){}
-#endif /* bootloader */
-
-bool button_hold(void)
-{
-    return !(GPIOJ_INPUT_VAL & 0x8);
-}
-
-/*
- * Get button pressed from hardware
- */
-int button_read_device(void)
-{
-    static int btn_old = BUTTON_NONE;
-    int btn = int_btn;
-
-    /* Hold */
-    if(button_hold())
-        return BUTTON_NONE;
-
-    /* Device buttons */
-    if (!(GPIOA_INPUT_VAL & 0x02)) btn |= BUTTON_VOL_UP;
-    if (!(GPIOA_INPUT_VAL & 0x04)) btn |= BUTTON_VOL_DOWN;
-    if (!(GPIOD_INPUT_VAL & 0x40)) btn |= BUTTON_POWER;
-
-    /* Scrollstrip direct button post - much better response */
-    if ((btn == BUTTON_UP) || (btn == BUTTON_DOWN))
-    {
-        queue_post(&button_queue,btn|repeat,0);
-        backlight_on();
-        buttonlight_on();
-        reset_poweroff_timer();
-
-        int_btn = BUTTON_NONE;
-        repeat = BUTTON_NONE;
-        btn = BUTTON_NONE;
-    }
-
-    if ((btn != btn_old) && (btn != BUTTON_NONE))
-        button_click();
-
-    btn_old = btn;
-
-    return btn;
-}
-
-bool headphones_inserted(void)
-{
-    return (GPIOE_INPUT_VAL & 0x80) ? true : false;
-}
diff --git a/firmware/target/arm/philips/hdd6330/button-target.h b/firmware/target/arm/philips/hdd6330/button-target.h
deleted file mode 100644
index 492a501..0000000
--- a/firmware/target/arm/philips/hdd6330/button-target.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 _BUTTON_TARGET_H_
-#define _BUTTON_TARGET_H_
-
-#include <stdbool.h>
-#include "config.h"
-
-#define MEP_BUTTON_HEADER   0x19
-#define MEP_BUTTON_ID       0x9
-#define MEP_ABSOLUTE_HEADER 0x0b
-#define MEP_FINGER          0x01
-
-#define HAS_BUTTON_HOLD
-
-bool button_hold(void);
-void button_init_device(void);
-int button_read_device(void);
-
-#ifndef BOOTLOADER
-void button_int(void);
-#endif
-
-/* Main unit's buttons */
-#define BUTTON_POWER        0x00000001
-#define BUTTON_MENU         0x00000002
-#define BUTTON_VIEW         0x00000004
-#define BUTTON_VOL_UP       0x00000008
-#define BUTTON_VOL_DOWN     0x00000010
-#define BUTTON_LEFT         0x00000020
-#define BUTTON_RIGHT        0x00000040
-#define BUTTON_UP           0x00000080
-#define BUTTON_DOWN         0x00000100
-#define BUTTON_NEXT         0x00000200
-#define BUTTON_PREV         0x00000400
-#define BUTTON_PLAY         0x00000800
-#define BUTTON_MAIN         0x00000fff
-
-/* No Remote control */
-#define BUTTON_REMOTE 0
-
-#define POWEROFF_BUTTON BUTTON_POWER
-#define POWEROFF_COUNT 10
-
-#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/philips/hdd6330/lcd-as-hdd6330.S b/firmware/target/arm/philips/hdd6330/lcd-as-hdd6330.S
deleted file mode 100644
index c3a7992..0000000
--- a/firmware/target/arm/philips/hdd6330/lcd-as-hdd6330.S
+++ /dev/null
@@ -1,140 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2010 by Szymon Dziok
- *
- * Philips Gogear HDD6330 LCD assembly routine
- *
- * 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"
-
-/****************************************************************************
-   void lcd_yuv_write_inner_loop(unsigned char const * const ysrc,
-                                 unsigned char const * const usrc,
-                                 unsigned char const * const vsrc,
-                                 int width);
-*/
-    .section    .icode, "ax", %progbits
-    .align      2
-    .global     lcd_yuv_write_inner_loop
-    .type       lcd_yuv_write_inner_loop, %function
-lcd_yuv_write_inner_loop:
-                                        @ r0 = ysrc
-                                        @ r1 = usrc
-                                        @ r2 = vsrc
-                                        @ r3 = width
-    stmfd sp!, { r4-r11, lr }           @ save regs
-    mov r4, #0x70000000                 @ r4 = LCD2_BLOCK_CTRL - 0x20
-    add r4, r4, #0x8a00                 @
-    add r5, r4, #0x100                  @ r5 = LCD2_BLOCK_DATA
-10:                                     @ loop
-
-    ldrb r7, [r1], #1                   @ *usrc++
-    ldrb r8, [r2], #1                   @ *vsrc++
-
-    sub r7, r7, #128                    @ Cb -= 128
-    sub r8, r8, #128                    @ Cr -= 128
-
-    add r10, r8, r8, asl #2             @ Cr*101
-    add r10, r10, r8, asl #5
-    add r10, r10, r8, asl #6
-
-    add r11, r8, r8, asl #1             @ Cr*51 + Cb*24
-    add r11, r11, r11, asl #4
-    add r11, r11, r7, asl #3
-    add r11, r11, r7, asl #4
-
-    add r12, r7, #2                     @ r12 = bu = (Cb*128 + 256) >> 9
-    mov r12, r12, asr #2
-    add r10, r10, #256                  @ r10 = rv = (Cr*101 + 256) >> 9
-    mov r10, r10, asr #9
-    rsb r11, r11, #128                  @ r11 = guv = (-r11 + 128) >> 8
-    mov r11, r11, asr #8
-
-@ pixel_1
-    ldrb r7, [r0], #1                   @ *ysrc++
-    sub r7, r7, #16                     @ Y = (Y' - 16) * 37
-    add r8, r7, r7, asl #2
-    add r7, r8, r7, asl #5
-
-    add r9, r10, r7, asr #8             @ R = (Y >> 8) + rv
-    add r8, r11, r7, asr #7             @ G = (Y >> 7) + guv
-    add r7, r12, r7, asr #8             @ B = (Y >> 8) + bu
-
-    cmp r9, #31                         @ clamp R
-    mvnhi r9, r9, asr #31
-    andhi r9, r9, #31
-
-    cmp r8, #63                         @ clamp G
-    mvnhi r8, r8, asr #31
-    andhi r8, r8, #63
-
-    cmp r7, #31                         @ clamp B
-    mvnhi r7, r7, asr #31
-    andhi r7, r7, #31
-
-    orr r6, r7, r8, lsl #5              @ pack pixel
-    orr r6, r6, r9, lsl #11
-
-    mov r7, r6, lsl #8                  @ swap bytes
-    and r7, r7, #0xff00
-    add r6, r7, r6, lsr #8
-
-@ pixel_2
-    ldrb r7, [r0], #1                   @ *ysrc++
-    sub r7, r7, #16                     @ Y = (Y' - 16) * 37
-    add r8, r7, r7, asl #2
-    add r7, r8, r7, asl #5
-
-    add r9, r10, r7, asr #8             @ R = (Y >> 8) + rv
-    add r8, r11, r7, asr #7             @ G = (Y >> 7) + guv
-    add r7, r12, r7, asr #8             @ B = (Y >> 8) + bu
-
-    cmp r9, #31                         @ clamp R
-    mvnhi r9, r9, asr #31
-    andhi r9, r9, #31
-
-    cmp r8, #63                         @ clamp G
-    mvnhi r8, r8, asr #31
-    andhi r8, r8, #63
-
-    cmp r7, #31                         @ clamp B
-    mvnhi r7, r7, asr #31
-    andhi r7, r7, #31
-
-    orr r7, r7, r8, lsl #5              @ pack pixel
-    orr r7, r7, r9, lsl #11
-
-    orr r6, r6, r7, lsl #24             @ swap bytes and add pixels simultaneously
-    mov r7, r7, lsr #8
-    orr r6, r6, r7, lsl #16
-
-11:                                     @ while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK));
-    ldr r11, [r4, #0x20]                @
-    tst r11, #0x1000000                 @
-    beq 11b                             @
-
-    str r6, [r5]                        @ send two pixels
-
-    subs r3, r3, #2                     @ decrease width
-    bgt 10b                             @ loop
-
-    ldmpc regs=r4-r11                   @ restore regs
-    .ltorg                              @ dump constant pool
-    .size   lcd_yuv_write_inner_loop, .-lcd_yuv_write_inner_loop
diff --git a/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c b/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c
deleted file mode 100644
index 328c270..0000000
--- a/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2009 by Mark Arigo
- *
- * 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 "lcd.h"
-#include "kernel.h"
-#include "system.h"
-
-/* register defines for Philips LCD 220x176x16 - model: LPH9165-2 */
-#define LCD_REG_UNKNOWN_00        0x00
-#define LCD_REG_UNKNOWN_01        0x01
-#define LCD_REG_UNKNOWN_05        0x05
-#define LCD_REG_WRITE_DATA_2_GRAM 0x06
-#define LCD_REG_HORIZ_ADDR_START  0x08
-#define LCD_REG_HORIZ_ADDR_END    0x09
-#define LCD_REG_VERT_ADDR_START   0x0a
-#define LCD_REG_VERT_ADDR_END     0x0b
-
-/* whether the lcd is currently enabled or not */
-static bool lcd_enabled;
-
-/* Display status */
-static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
-
-/* Value used for flipping. Must be remembered when display is turned off. */
-static unsigned short flip;
-
-/* Used for flip offset correction */
-static int x_offset;
-
-/* Inverse value. Must be remembered when display is turned off. */
-static unsigned short invert;
-
-/* wait for LCD */
-static inline void lcd_wait_write(void)
-{
-    while (LCD2_PORT & LCD2_BUSY_MASK);
-}
-
-/* send LCD data */
-static void lcd_send_data(unsigned data)
-{
-    lcd_wait_write();
-    LCD2_PORT = LCD2_DATA_MASK | (data & 0xff);
-}
-
-/* send LCD command */
-static void lcd_send_reg(unsigned reg)
-{
-    lcd_wait_write();
-    LCD2_PORT = LCD2_CMD_MASK | (reg & 0xff);
-    lcd_wait_write();
-}
-
-void lcd_init_device(void)
-{
-    x_offset = 16;
-    invert = 0x00;
-    flip   = 0x40;
-
-    lcd_enabled = true;
-}
-
-#ifdef HAVE_LCD_ENABLE
-/* enable / disable lcd */
-void lcd_enable(bool on)
-{
-    if (on == lcd_enabled)
-        return;
-
-    if (on) /* lcd_display_on() */
-    {
-        lcd_send_reg(LCD_REG_UNKNOWN_00);
-        lcd_send_data(0x00 | invert);
-        lcd_send_reg(LCD_REG_UNKNOWN_01);
-        lcd_send_data(0x08 | flip);
-        lcd_send_reg(LCD_REG_UNKNOWN_05);
-        lcd_send_data(0x0f);
-        sleep(HZ/10); /* 100ms */
-
-        /* Probably out of sync and we don't wanna pepper the code with
-           lcd_update() calls for this. */
-        lcd_update();
-        send_event(LCD_EVENT_ACTIVATION, NULL);
-
-        lcd_enabled = true;
-    }
-    else /* lcd_display_off() */
-    {
-        lcd_send_reg(LCD_REG_UNKNOWN_00);
-        lcd_send_data(0x08);
-
-        lcd_enabled = false;
-    }
-}
-
-
-bool lcd_active(void)
-{
-    return lcd_enabled;
-}
-#endif /* HAVE_LCD_ENABLE */
-
-
-/*** hardware configuration ***/
-int lcd_default_contrast(void)
-{
-    return DEFAULT_CONTRAST_SETTING;
-}
-
-void lcd_set_contrast(int val)
-{
-    (void)val;
-}
-
-void lcd_set_invert_display(bool yesno)
-{
-    invert = (yesno) ? 0x40 : 0x00;
-    lcd_send_reg(LCD_REG_UNKNOWN_00);
-    lcd_send_data(invert);
-}
-
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
-    flip = (yesno) ? 0x80 : 0x40;
-    x_offset = (yesno) ? 4 : 16;
-    lcd_send_reg(LCD_REG_UNKNOWN_01);
-    lcd_send_data(0x08 | flip);
-}
-
-void lcd_yuv_set_options(unsigned options)
-{
-    lcd_yuv_options = options;
-}
-
-#define CSUB_X 2
-#define CSUB_Y 2
-
-/*   YUV- > RGB565 conversion
- *   |R|   |1.000000 -0.000001  1.402000| |Y'|
- *   |G| = |1.000000 -0.334136 -0.714136| |Pb|
- *   |B|   |1.000000  1.772000  0.000000| |Pr|
- *   Scaled, normalized, rounded and tweaked to yield RGB 565:
- *   |R|   |74   0 101| |Y' -  16| >> 9
- *   |G| = |74 -24 -51| |Cb - 128| >> 8
- *   |B|   |74 128   0| |Cr - 128| >> 9
-*/
-
-extern void lcd_yuv_write_inner_loop(unsigned char const * const ysrc,
-                                     unsigned char const * const usrc,
-                                     unsigned char const * const vsrc,
-                                     int width);
-
-/* Performance function to blit a YUV bitmap directly to the LCD */
-void lcd_blit_yuv(unsigned char * const src[3],
-                  int src_x, int src_y, int stride,
-                  int x, int y, int width, int height)
-{
-    int h;
-
-    width = (width + 1) & ~1;
-
-    lcd_send_reg(LCD_REG_HORIZ_ADDR_START);
-    lcd_send_data(y);
-
-    lcd_send_reg(LCD_REG_HORIZ_ADDR_END);
-    lcd_send_data(y + height - 1);
-
-    lcd_send_reg(LCD_REG_VERT_ADDR_START);
-    lcd_send_data(x + x_offset);
-
-    lcd_send_reg(LCD_REG_VERT_ADDR_END);
-    lcd_send_data(x + width - 1 + x_offset);
-
-    lcd_send_reg(LCD_REG_WRITE_DATA_2_GRAM);
-
-    const int stride_div_csub_x = stride/CSUB_X;
-
-    h=0;
-    while (1)
-    {
-        /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
-        const unsigned char *ysrc = src[0] + stride * src_y + src_x;
-
-        const int uvoffset = stride_div_csub_x * (src_y/CSUB_Y) +
-                             (src_x/CSUB_X);
-
-        const unsigned char *usrc = src[1] + uvoffset;
-        const unsigned char *vsrc = src[2] + uvoffset;
-
-        int pixels_to_write;
-
-        if (h==0)
-        {
-            while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
-            LCD2_BLOCK_CONFIG = 0;
-
-            if (height == 0) break;
-
-            pixels_to_write = (width * height) * 2;
-            h = height;
-
-            /* calculate how much we can do in one go */
-            if (pixels_to_write > 0x10000)
-            {
-                h = (0x10000/2) / width;
-                pixels_to_write = (width * h) * 2;
-            }
-
-            height -= h;
-            LCD2_BLOCK_CTRL = 0x10000080;
-            LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
-            LCD2_BLOCK_CTRL = 0x34000000;
-        }
-
-        lcd_yuv_write_inner_loop(ysrc,usrc,vsrc,width);
-
-        src_y++;
-        h--;
-    }
-
-    while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
-    LCD2_BLOCK_CONFIG = 0;
-}
-
-/* Update the display.
-   This must be called after all other LCD functions that change the display. */
-void lcd_update(void)
-{
-    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
-}
-
-/* Update a fraction of the display. */
-void lcd_update_rect(int x, int y, int width, int height)
-{
-    unsigned long *addr;
-    int new_x, new_width;
-
-    /* Ensure x and width are both even - so we can read 32-bit aligned
-       data from lcd_framebuffer */
-    new_x = x&~1;
-    new_width = width&~1;
-    if (new_x+new_width < x+width) new_width += 2;
-    x = new_x;
-    width = new_width;
-
-    if (x + width >= LCD_WIDTH)
-        width = LCD_WIDTH - x;
-    if (y + height >= LCD_HEIGHT)
-        height = LCD_HEIGHT - y;
-
-    if ((width <= 0) || (height <= 0))
-        return; /* Nothing left to do. */
-
-    lcd_send_reg(LCD_REG_HORIZ_ADDR_START);
-    lcd_send_data(y);
-
-    lcd_send_reg(LCD_REG_HORIZ_ADDR_END);
-    lcd_send_data(y + height - 1);
-
-    lcd_send_reg(LCD_REG_VERT_ADDR_START);
-    lcd_send_data(x + x_offset);
-
-    lcd_send_reg(LCD_REG_VERT_ADDR_END);
-    lcd_send_data(x + width - 1 + x_offset);
-
-    lcd_send_reg(LCD_REG_WRITE_DATA_2_GRAM);
-
-    addr = (unsigned long*)&lcd_framebuffer[y][x];
-
-    while (height > 0)
-    {
-        int c, r;
-        int h, pixels_to_write;
-
-        pixels_to_write = (width * height) * 2;
-        h = height;
-
-        /* calculate how much we can do in one go */
-        if (pixels_to_write > 0x10000)
-        {
-            h = (0x10000/2) / width;
-            pixels_to_write = (width * h) * 2;
-        }
-
-        LCD2_BLOCK_CTRL = 0x10000080;
-        LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
-        LCD2_BLOCK_CTRL = 0x34000000;
-
-        /* for each row */
-        for (r = 0; r < h; r++)
-        {
-            /* for each column */
-            for (c = 0; c < width; c += 2)
-            {
-                while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK));
-
-                /* output 2 pixels */
-                LCD2_BLOCK_DATA = *addr++;
-            }
-            addr += (LCD_WIDTH - width)/2;
-        }
-
-        while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
-        LCD2_BLOCK_CONFIG = 0;
-
-        height -= h;
-    }
-}
diff --git a/firmware/target/arm/philips/hdd6330/powermgmt-hdd6330.c b/firmware/target/arm/philips/hdd6330/powermgmt-hdd6330.c
deleted file mode 100644
index 8090c62..0000000
--- a/firmware/target/arm/philips/hdd6330/powermgmt-hdd6330.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
- * Revisions copyright (C) 2005 by Gerald Van Baren
- *
- * 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 "adc.h"
-#include "powermgmt.h"
-
-#define SMLAL(lo, hi, x, y)              \
-    asm volatile ("smlal %0, %1, %2, %3" \
-     : "+r" (lo), "+r" (hi)              \
-     : "%r" (x), "r" (y))
-
-const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
-{
-    3550
-};
-
-const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
-{
-    3500
-};
-
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
-const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
-{
-    { 3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 },
-};
-
-#if CONFIG_CHARGING
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
-const unsigned short percent_to_volt_charge[11] =
-{
-    3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990
-};
-#endif /* CONFIG_CHARGING */
-
-#define BATTERY_SCALE_FACTOR 4200
-/* full-scale ADC readout (2^10) in millivolt */
-
-/* Returns battery voltage from ADC [millivolts] */
-unsigned int battery_adc_voltage(void)
-{
-    /* return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; */
-
-    /* This may be overly complicated (pulled from the OF) */
-    int lo = 0;
-    int val = adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR;
-
-    SMLAL(lo, val, 0x8a42f871, val);
-    val>>= 9;
-    val -= (val >> 31);
-    return val;
-}
diff --git a/firmware/target/arm/philips/power-hdd.c b/firmware/target/arm/philips/power-hdd.c
deleted file mode 100644
index a7f1302..0000000
--- a/firmware/target/arm/philips/power-hdd.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 "kernel.h"
-#include "system.h"
-#include "power.h"
-#include "logf.h"
-#include "usb.h"
-#include "backlight-target.h"
-#include "synaptics-mep.h"
-
-void power_init(void)
-{
-    /* power off bit */
-    GPIOB_ENABLE |= 0x80;
-    GPIOB_OUTPUT_VAL |= 0x80;
-    GPIOB_OUTPUT_EN |= 0x80;
-
-    /* charger inserted bit */
-    GPIOE_ENABLE |= 0x20;
-    GPIOE_INPUT_VAL |= 0x20;
-
-#if CONFIG_TUNER
-    /* fm antenna? */
-    GPIOE_ENABLE |= 0x40;
-    GPIOE_OUTPUT_EN |= 0x40;
-    GPIOE_OUTPUT_VAL &= ~0x40; /* off */
-#endif
-
-#ifndef BOOTLOADER
-    /* enable touchpad here because we need it for
-       both buttons and button lights */
-    GPO32_ENABLE     |=  0x80;
-    GPO32_VAL        &= ~0x80;
-    udelay(1000);
-
-    GPIOD_ENABLE |= 0x80;          /* enable ACK */
-    GPIOA_ENABLE |= (0x10 | 0x20); /* enable DATA, CLK */
-
-    GPIOD_OUTPUT_EN  |=  0x80; /* set ACK */
-    GPIOD_OUTPUT_VAL |=  0x80; /*    high */
-
-    GPIOA_OUTPUT_EN  &= ~0x20; /* CLK */
-
-    GPIOA_OUTPUT_EN  |=  0x10; /* set DATA */
-    GPIOA_OUTPUT_VAL |=  0x10; /*     high */
-
-    if (!touchpad_init())
-    {
-        logf("touchpad not ready");
-    }
-#if defined(PHILIPS_HDD6330)
-    /* reduce transmission overhead */
-    touchpad_set_parameter(0,0x21,0x0008);
-    /* set GPO_LEVELS = 0 - for the buttonlights */
-    touchpad_set_parameter(0,0x23,0x0000);
-    touchpad_set_parameter(1,0x22,0x0000);
-#endif
-
-#endif
-}
-
-unsigned int power_input_status(void)
-{
-    unsigned int status = POWER_INPUT_NONE;
-
-    /* AC charger */
-    if (GPIOE_INPUT_VAL & 0x20)
-        status |= POWER_INPUT_MAIN_CHARGER;
-
-    /* Do nothing with USB for now
-    if (GPIOE_INPUT_VAL & 0x4)
-        status |= POWER_INPUT_USB_CHARGER;
-    */
-
-    return status;
-}
-
-void ide_power_enable(bool on)
-{
-    (void)on;
-    /* We do nothing */
-}
-
-bool ide_powered(void)
-{
-    /* pretend we are always powered - we don't turn it off */
-    return true;
-}
-
-void power_off(void)
-{
-    _backlight_off();
-    sleep(HZ/10);
-
-    /* power off bit */
-    GPIOB_ENABLE |= 0x80;
-    GPIOB_OUTPUT_VAL &= ~0x80;
-    GPIOB_OUTPUT_EN |= 0x80;
-}
-
-#if CONFIG_TUNER
-bool tuner_power(bool status)
-{
-    if (status)
-        GPIOE_OUTPUT_VAL |= 0x40;
-    else
-        GPIOE_OUTPUT_VAL &= ~0x40;
-
-    return status;
-}
-#endif
diff --git a/firmware/target/arm/philips/sa9200/adc-target.h b/firmware/target/arm/philips/sa9200/adc-target.h
deleted file mode 100644
index 007a11a..0000000
--- a/firmware/target/arm/philips/sa9200/adc-target.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 _ADC_TARGET_H_
-#define _ADC_TARGET_H_
-
-/* The ADC sources and channels are common to all targets with AS3514 */
-#include "as3514.h"
-
-#endif
diff --git a/firmware/target/arm/philips/sa9200/backlight-sa9200.c b/firmware/target/arm/philips/sa9200/backlight-sa9200.c
deleted file mode 100644
index 0de4c05..0000000
--- a/firmware/target/arm/philips/sa9200/backlight-sa9200.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 "backlight-target.h"
-#include "system.h"
-#include "backlight.h"
-#include "ascodec.h"
-#include "as3514.h"
-#include "synaptics-mep.h"
-#include "lcd.h"
-
-void _backlight_set_brightness(int brightness)
-{
-    ascodec_write(AS3514_DCDC15, brightness);
-}
-
-void _backlight_on(void)
-{
-#ifdef HAVE_LCD_ENABLE
-    lcd_enable(true); /* power on lcd + visible display */
-#endif
-#if (CONFIG_BACKLIGHT_FADING != BACKLIGHT_FADING_SW_SETTING) /* in bootloader/sim */
-    /* if we set the brightness to the settings value, then fading up
-     * is glitchy */
-    _backlight_set_brightness(backlight_brightness);
-#endif
-}
-
-void _backlight_off(void)
-{
-    _backlight_set_brightness(0);
-#ifdef HAVE_LCD_ENABLE
-    lcd_enable(false); /* power off visible display */
-#endif
-}
-
-#ifdef HAVE_BUTTON_LIGHT
-
-#define BUTTONLIGHT_MASK 0x7f
-#define BUTTONLIGHT_MAX  0x0f
-static unsigned short buttonlight_status = 0;
-
-void _buttonlight_on(void)
-{
-    if (!buttonlight_status)
-    {
-        touchpad_set_buttonlights(BUTTONLIGHT_MASK, BUTTONLIGHT_MAX);
-        GPIOD_OUTPUT_VAL &= ~(0x40 | 0x20 | 0x04); /* REW/FFWD/MENU */
-        buttonlight_status = 1;
-    }
-}
-
-void _buttonlight_off(void)
-{
-    if (buttonlight_status)
-    {
-        touchpad_set_buttonlights(BUTTONLIGHT_MASK, 0);
-        GPIOD_OUTPUT_VAL |= (0x40 | 0x20 | 0x04); /* REW/FFWD/MENU */
-        buttonlight_status = 0;
-    }
-}
-#endif
diff --git a/firmware/target/arm/philips/sa9200/backlight-target.h b/firmware/target/arm/philips/sa9200/backlight-target.h
deleted file mode 100644
index 9d695e5..0000000
--- a/firmware/target/arm/philips/sa9200/backlight-target.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Barry Wardell
- *
- * 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 BACKLIGHT_TARGET_H
-#define BACKLIGHT_TARGET_H
-
-#define _backlight_init() true
-void _backlight_on(void);
-void _backlight_off(void);
-void _backlight_set_brightness(int brightness);
-int  __backlight_is_on(void);
-
-#ifdef HAVE_BUTTON_LIGHT
-void _buttonlight_on(void);
-void _buttonlight_off(void);
-#endif
-
-#endif
diff --git a/firmware/target/arm/philips/sa9200/button-sa9200.c b/firmware/target/arm/philips/sa9200/button-sa9200.c
deleted file mode 100644
index bef5be7..0000000
--- a/firmware/target/arm/philips/sa9200/button-sa9200.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 "system.h"
-#include "button.h"
-#include "backlight.h"
-#include "synaptics-mep.h"
-
-/*#define LOGF_ENABLE*/
-#include "logf.h"
-
-static int int_btn = BUTTON_NONE;
-
-#ifndef BOOTLOADER
-static bool hold_button_old = false;
-
-/* Capacitive buttons - lowest setting is still very sensitive */
-static const signed char button_sensitivity = -8; /* -8 to 7 */
-
-/* Strip - decent amount of contact needed */
-static const signed char strip_sensitivity = 0; /* -8 to 7 */
-static const unsigned char strip_pressure = 25; /* 0 to 255 */
-
-void button_init_device(void)
-{
-    /* The touchpad is powered on and initialized in power-sa9200.c
-       since it needs to be ready for both buttons and button lights. */
-
-    /* perform button-specific inits here */
-
-    /* Besides $00, only common parameters $20 and $21 are supported */
-
-    /* Report modes:
-     * [15:12] cap btn sens : xxxx,
-     * [11: 8] pos sen sens : xxxx,
-     * [ 7: 6] rate: 10 (40 rps),
-     * [    5] no filter: 0,
-     * [    4] reserved: 0,
-     * [    3] en scr: 0,
-     * [    2] en btns: 1,
-     * [    1] en rel: 0,
-     * [    0] en abs: 1 */
-    touchpad_set_parameter(0, 0x20,
-        ((button_sensitivity & 0xf) << 12) |
-        ((strip_sensitivity & 0xf) << 8) |
-        (0x2 << 6) |
-        (0x1 << 2) |
-        (0x1 << 0));
-
-    /* Enhanced operating configuration:
-     * [15: 9] reserved : 0000000
-     * [    8] Min abs reporting : 0
-     * [    7] reserved : 0
-     * [    6] not all cap btns : 1
-     * [    5] single cap btn : 0
-     * [    4] en 50ms debounce : 1
-     * [    3] motion reporting : 0
-     * [    2] clip z if no finger : 0
-     * [    1] disable decel : 0
-     * [    0] enable dribble : 0 */
-    touchpad_set_parameter(0, 0x21,
-        (0x1 << 6) | (0x1 << 4));
-}
-
-/*
- * Button interrupt handler
- */
-void button_int(void)
-{
-    unsigned char data[4];
-    int val;
-
-    int_btn = BUTTON_NONE;
-
-    val = touchpad_read_device(data, 4);
-
-    if (val == MEP_BUTTON_HEADER)
-    {
-        /* Buttons packet */
-        if (data[1] & 0x1) int_btn |= BUTTON_RIGHT;
-        if (data[1] & 0x2) int_btn |= BUTTON_NEXT;
-        if (data[1] & 0x4) int_btn |= BUTTON_PREV;
-        if (data[1] & 0x8) int_btn |= BUTTON_LEFT;
-        if (data[2] & 0x1) int_btn |= BUTTON_MENU;
-    }
-    else if (val == MEP_ABSOLUTE_HEADER && data[3] >= strip_pressure)
-    {
-        /* Absolute packet - the finger is on the vertical strip.
-           Position ranges from 1-4095, with 1 at the bottom. */
-        val = ((data[1] >> 4) << 8) | data[2]; /* position */
-
-        if ((val > 0) && (val <= 1365))
-            int_btn |= BUTTON_DOWN;
-        else if ((val > 1365) && (val <= 2730))
-            int_btn |= BUTTON_PLAY;
-        else if ((val > 2730) && (val <= 4095))
-            int_btn |= BUTTON_UP;
-    }
-}
-#else
-void button_init_device(void)
-{
-}
-
-void button_int(void)
-{
-}
-#endif /* BOOTLOADER */
-
-bool button_hold(void)
-{
-    return !(GPIOL_INPUT_VAL & 0x40);
-}
-
-/*
- * Get button pressed from hardware
- */
-int button_read_device(void)
-{
-    int btn = int_btn;
-    bool hold = !(GPIOL_INPUT_VAL & 0x40);
-
-#ifndef BOOTLOADER
-    /* Backlight hold handling */
-    if (hold != hold_button_old)
-    {
-        hold_button_old = hold;
-        backlight_hold_changed(hold);
-    }
-#endif
-
-    if (hold)
-        return BUTTON_NONE;
-
-    if (!(GPIOB_INPUT_VAL & 0x20)) btn |= BUTTON_POWER;
-    if (!(GPIOF_INPUT_VAL & 0x10)) btn |= BUTTON_VOL_UP;
-    if (!(GPIOF_INPUT_VAL & 0x04)) btn |= BUTTON_VOL_DOWN;
-
-    return btn;
-}
-
-bool headphones_inserted(void)
-{
-    return (GPIOB_INPUT_VAL & 0x10) ? false : true;
-}
diff --git a/firmware/target/arm/philips/sa9200/button-target.h b/firmware/target/arm/philips/sa9200/button-target.h
deleted file mode 100644
index 7d06015..0000000
--- a/firmware/target/arm/philips/sa9200/button-target.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id:$
- *
- * Copyright (C) 2007 by Mark Arigo
- *
- * 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 _BUTTON_TARGET_H_
-#define _BUTTON_TARGET_H_
-
-#include <stdbool.h>
-#include "config.h"
-
-#define MEP_BUTTON_HEADER   0x1a
-#define MEP_BUTTON_ID       0x09
-#define MEP_ABSOLUTE_HEADER 0x0b
-
-#define HAS_BUTTON_HOLD
-
-bool button_hold(void);
-void button_init_device(void);
-int button_read_device(void);
-void button_int(void);
-
-/* Main unit's buttons */
-#define BUTTON_POWER        0x00000001
-#define BUTTON_PLAY         0x00000002
-#define BUTTON_MENU         0x00000004
-#define BUTTON_PREV         0x00000008
-#define BUTTON_NEXT         0x00000010
-#define BUTTON_LEFT         0x00000020
-#define BUTTON_RIGHT        0x00000040
-#define BUTTON_UP           0x00000080
-#define BUTTON_DOWN         0x00000100
-#define BUTTON_VOL_UP       0x00000200
-#define BUTTON_VOL_DOWN     0x00000400
-
-#define BUTTON_MAIN         0x00000fff
-
-/* No Remote control */
-#define BUTTON_REMOTE 0
-
-#define POWEROFF_BUTTON BUTTON_POWER
-#define POWEROFF_COUNT 10
-
-#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/philips/sa9200/lcd-as-sa9200.S b/firmware/target/arm/philips/sa9200/lcd-as-sa9200.S
deleted file mode 100644
index d99222b..0000000
--- a/firmware/target/arm/philips/sa9200/lcd-as-sa9200.S
+++ /dev/null
@@ -1,590 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2007-2011 by Michael Sevakis
- *
- * Philips GoGear SA9200 LCD assembly routines
- *
- * 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.
- *
- ****************************************************************************/
- 
- /* This code should work in general for a Renesas type LCD interface
-  * connected to the "mono" bridge. TODO: Share it where possible.
-  *
-  * Dither is already prepared to be built for upright and rotated
-  * orientations. */
-
-#include "config.h"
-#include "cpu.h"
-
-/****************************************************************************
- * void lcd_write_yuv420_lines(unsigned char const * const src[3],
- *                             int width,
- *                             int stride);
- *
- *   |R|   |1.000000 -0.000001  1.402000| |Y'|
- *   |G| = |1.000000 -0.334136 -0.714136| |Pb|
- *   |B|   |1.000000  1.772000  0.000000| |Pr|
- *   Scaled, normalized, rounded and tweaked to yield RGB 565:
- *   |R|   |74   0 101| |Y' -  16| >> 9
- *   |G| = |74 -24 -51| |Cb - 128| >> 8
- *   |B|   |74 128   0| |Cr - 128| >> 9
- *
- * Write four RGB565 pixels in the following order on each loop:
- * 1 3 + > down
- * 2 4 \/ left
- */
-    .section    .icode, "ax", %progbits
-    .align      2
-    .global     lcd_write_yuv420_lines
-    .type       lcd_write_yuv420_lines, %function
-lcd_write_yuv420_lines:
-                                        @ r0 = yuv_src
-                                        @ r1 = width
-                                        @ r2 = stride
-    stmfd       sp!, { r4-r10, lr }     @ save non-scratch
-    ldmia       r0, { r4, r5, r6 }      @ r4 = yuv_src[0] = Y'_p
-                                        @ r5 = yuv_src[1] = Cb_p
-                                        @ r6 = yuv_src[2] = Cr_p
-                                        @
-    mov         r0, #0x70000000         @ r0 = LCD1_BASE_ADDR = 0x70003000
-    orr         r0, r0, #0x3000         @
-                                        @
-    sub         r2, r2, #1              @ Adjust stride because of increment
-10: @ loop line                         @
-    ldrb        r7, [r4], #1            @ r7 = *Y'_p++;
-    ldrb        r8, [r5], #1            @ r8 = *Cb_p++;
-    ldrb        r9, [r6], #1            @ r9 = *Cr_p++;
-                                        @
-    sub         r7, r7, #16             @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @ actually (Y' - 16)*37 and shift right
-    add         r7, r12, r7, asl #5     @ by one less when adding - same for all
-                                        @
-    sub         r8, r8, #128            @ Cb -= 128
-    sub         r9, r9, #128            @ Cr -= 128
-                                        @
-    add         r10, r9, r9, asl #1     @ r10 = Cr*51 + Cb*24
-    add         r10, r10, r10, asl #4   @
-    add         r10, r10, r8, asl #3    @
-    add         r10, r10, r8, asl #4    @
-                                        @
-    add         r14, r9, r9, asl #2     @ r9 = Cr*101
-    add         r14, r14, r9, asl #5    @
-    add         r9, r14, r9, asl #6     @
-                                        @
-    add         r8, r8, #2              @ r8 = bu = (Cb*128 + 128) >> 8
-    mov         r8, r8, asr #2          @
-    add         r9, r9, #256            @ r9 = rv = (r8 + 256) >> 9
-    mov         r9, r9, asr #9          @
-    rsb         r10, r10, #128          @ r10 = guv = (-r9 + 128) >> 8
-    mov         r10, r10, asr #8        @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3 = b = (Y >> 9) + bu
-    add         r14, r9, r7, asr #8     @ r14 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r14            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r14, #31                @ clamp r
-    mvnhi       r14, r14, asr #31       @
-    andhi       r14, r14, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    orr         r7, r3, r7, lsl #5      @ r7  = |00000000|00000000|00000ggg|gggbbbbb|
-    orr         r7, r7, r14, lsl #11    @ r7  = |00000000|00000000|rrrrrggg|gggbbbbb|
-    mov         r14, r7, lsr #8         @ r14 = |00000000|00000000|00000000|rrrrrggg|
-                                        @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r14, [r0, #0x10]        @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r7, [r0, #0x10]         @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r14, r9, r7, asr #8     @ r14 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r14            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r14, #31                @ clamp r
-    mvnhi       r14, r14, asr #31       @
-    andhi       r14, r14, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4], #1           @ r12 = Y' = *(Y'_p++)
-                                        @
-    orr         r7, r3, r7, lsl #5      @ r7  = |00000000|00000000|00000ggg|gggbbbbb|
-    orr         r7, r7, r14, lsl #11    @ r7  = |00000000|00000000|rrrrrggg|gggbbbbb|
-    mov         r14, r7, lsr #8         @ r14 = |00000000|00000000|00000000|rrrrrggg|
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r14, [r0, #0x10]        @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r7, [r0, #0x10]         @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r14, r9, r7, asr #8     @ r14 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r14            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r14, #31                @ clamp r
-    mvnhi       r14, r14, asr #31       @
-    andhi       r14, r14, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    orr         r7, r3, r7, lsl #5      @ r7  = |00000000|00000000|00000ggg|gggbbbbb|
-    orr         r7, r7, r14, lsl #11    @ r7  = |00000000|00000000|rrrrrggg|gggbbbbb|
-    mov         r14, r7, lsr #8         @ r14 = |00000000|00000000|00000000|rrrrrggg|
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r14, [r0, #0x10]        @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r7, [r0, #0x10]         @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
-    add         r12, r7, r7, asl #2     @
-    add         r7, r12, r7, asl #5     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
-    add         r14, r9, r7, asr #8     @ r14 = r = (Y >> 9) + rv
-    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
-                                        @
-    orr         r12, r3, r14            @ check if clamping is needed...
-    orr         r12, r12, r7, asr #1    @ ...at all
-    cmp         r12, #31                @
-    bls         15f @ no clamp          @
-    cmp         r3, #31                 @ clamp b
-    mvnhi       r3, r3, asr #31         @
-    andhi       r3, r3, #31             @
-    cmp         r14, #31                @ clamp r
-    mvnhi       r14, r14, asr #31       @
-    andhi       r14, r14, #31           @
-    cmp         r7, #63                 @ clamp g
-    mvnhi       r7, r7, asr #31         @
-    andhi       r7, r7, #63             @
-15: @ no clamp                          @
-                                        @
-    orr         r7, r3, r7, lsl #5      @ r7  = |00000000|00000000|00000ggg|gggbbbbb|
-    orr         r7, r7, r14, lsl #11    @ r7  = |00000000|00000000|rrrrrggg|gggbbbbb|
-    mov         r14, r7, lsr #8         @ r14 = |00000000|00000000|00000000|rrrrrggg|
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r14, [r0, #0x10]        @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r7, [r0, #0x10]         @
-                                        @
-    subs        r1, r1, #2              @ subtract block from width
-    bgt         10b @ loop line         @
-                                        @
-    ldmpc       regs=r4-r10             @ restore registers and return
-    .ltorg                              @ dump constant pool
-    .size   lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
-
-
-/****************************************************************************
- * void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
- *                                     int width,
- *                                     int stride,
- *                                     int x_screen,
- *                                     int y_screen);
- *
- *   |R|   |1.000000 -0.000001  1.402000| |Y'|
- *   |G| = |1.000000 -0.334136 -0.714136| |Pb|
- *   |B|   |1.000000  1.772000  0.000000| |Pr|
- *   Red scaled at twice g & b but at same precision to place it in correct
- *   bit position after multiply and leave instruction count lower.
- *   |R|   |258   0  408| |Y' -  16|
- *   |G| = |149 -49 -104| |Cb - 128|
- *   |B|   |149 258    0| |Cr - 128|
- *
- * Write four RGB565 pixels in the following order on each loop:
- * 1 3 + > right/down
- * 2 4 \/   down/left
- *
- * Kernel pattern for upright display:
- * 5 3 4 2 +-> right
- * 1 7 0 6 | down
- * 4 2 5 3 \/
- * 0 6 1 7
- *
- * Kernel pattern for clockwise rotated display:
- * 2 6 3 7 +-> down
- * 4 0 5 1 | left
- * 3 7 2 6 \/
- * 5 1 4 0
- */
-    .section    .icode, "ax", %progbits
-    .align      2
-    .global     lcd_write_yuv420_lines_odither
-    .type       lcd_write_yuv420_lines_odither, %function
-lcd_write_yuv420_lines_odither:
-                                        @ r0   = yuv_src
-                                        @ r1   = width
-                                        @ r2   = strideS
-                                        @ r3   = x_screen
-                                        @ [sp] = y_screen
-    stmfd       sp!, { r4-r11, lr }     @ save non-scratch
-    ldmia       r0, { r4, r5, r6 }      @ r4 = yuv_src[0] = Y'_p
-                                        @ r5 = yuv_src[1] = Cb_p
-                                        @ r6 = yuv_src[2] = Cr_p
-                                        @
-    ldr         r0, [sp, #36]           @ Line up pattern and kernel quadrant
-    eor         r14, r3, r0             @
-    and         r14, r14, #0x2          @
-    mov         r14, r14, lsl #6        @ 0x00 or 0x80
-                                        @
-    mov         r0, #0x70000000         @ r0 = LCD1_BASE_ADDR = 0x70003000
-    orr         r0, r0, #0x3000         @
-                                        @
-    sub         r2, r2, #1              @ Adjust stride because of increment
-10: @ loop line                         @
-                                        @
-    ldrb        r7, [r4], #1            @ r7 = *Y'_p++;
-    ldrb        r8, [r5], #1            @ r8 = *Cb_p++;
-    ldrb        r9, [r6], #1            @ r9 = *Cr_p++;
-                                        @
-    eor         r14, r14, #0x80         @ flip pattern quadrant
-                                        @
-    sub         r7, r7, #16             @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @    
-    sub         r8, r8, #128            @ Cb -= 128
-    sub         r9, r9, #128            @ Cr -= 128
-                                        @
-    add         r10, r8, r8, asl #4     @ r10 = guv = Cr*104 + Cb*49
-    add         r10, r10, r8, asl #5    @
-    add         r10, r10, r9, asl #3    @
-    add         r10, r10, r9, asl #5    @
-    add         r10, r10, r9, asl #6    @
-                                        @
-    mov         r8, r8, asl #1          @ r8 = bu = Cb*258
-    add         r8, r8, r8, asl #7      @
-                                        @
-    add         r9, r9, r9, asl #1      @ r9 = rv = Cr*408
-    add         r9, r9, r9, asl #4      @
-    mov         r9, r9, asl #3          @
-                                        @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-                                        @ r8 = bu, r9 = rv, r10 = guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3 = 31/32*b + b/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r + r/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7 = 63/64*g + g/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-#if LCD_WIDTH >= LCD_HEIGHT
-    add         r12, r14, #0x200        @
-#else
-    add         r12, r14, #0x100        @
-#endif
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
-                                        @
-    and         r11, r11, #0xf800       @ r11 = |00000000|00000000|rrrrrggg|gggbbbbb|
-    and         r7, r7, #0x7e00         @
-    orr         r11, r11, r7, lsr #4    @
-    orr         r11, r11, r3, lsr #10   @
-    mov         r7, r11, lsr #8         @ r7 = |00000000|00000000|00000000|rrrrrggg|
-                                        @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r7, [r0, #0x10]         @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r11, [r0, #0x10]        @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3  = 31/32*b' + b'/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r' + r'/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7  = 63/64*g' + g'/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-#if LCD_WIDTH >= LCD_HEIGHT
-    @ This element is zero - use r14    @
-                                        @
-    add         r3, r3, r14             @ b = r3 + delta
-    add         r11, r11, r14, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r14, lsr #1     @ g = r7 + delta/2
-#else
-    add         r12, r14, #0x200        @
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-#endif
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4], #1           @ r12 = Y' = *(Y'_p++)
-                                        @
-    and         r11, r11, #0xf800       @ r11 = |00000000|00000000|rrrrrggg|gggbbbbb|
-    and         r7, r7, #0x7e00         @
-    orr         r11, r11, r7, lsr #4    @
-    orr         r11, r11, r3, lsr #10   @
-    mov         r7, r11, lsr #8         @ r7 = |00000000|00000000|00000000|rrrrrggg|
-                                        @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r7, [r0, #0x10]         @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r11, [r0, #0x10]        @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-                                        @ r8 = bu, r9 = rv, r10 = guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3  = 31/32*b' + b'/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r' + r'/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7  = 63/64*g' + g'/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-#if LCD_WIDTH >= LCD_HEIGHT
-    add         r12, r14, #0x100        @
-#else
-    add         r12, r14, #0x300        @
-#endif
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)    
-                                        @
-    and         r11, r11, #0xf800       @ r11 = |00000000|00000000|rrrrrggg|gggbbbbb|
-    and         r7, r7, #0x7e00         @
-    orr         r11, r11, r7, lsr #4    @
-    orr         r11, r11, r3, lsr #10   @
-    mov         r7, r11, lsr #8         @ r7 = |00000000|00000000|00000000|rrrrrggg|
-                                        @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r7, [r0, #0x10]         @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r11, [r0, #0x10]        @
-                                        @
-    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
-    add         r12, r7, r7, asl #2     @
-    add         r12, r12, r12, asl #4   @
-    add         r7, r12, r7, asl #6     @
-                                        @ compute R, G, and B
-    add         r3, r8, r7              @ r3  = b' = Y + bu
-    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
-    rsb         r7, r10, r7             @ r7  = g' = Y + guv
-                                        @
-    sub         r12, r3, r3, lsr #5     @ r3 = 31/32*b + b/256
-    add         r3, r12, r3, lsr #8     @
-                                        @
-    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r + r/256
-    add         r11, r12, r11, lsr #8   @
-                                        @
-    sub         r12, r7, r7, lsr #6     @ r7 = 63/64*g + g/256
-    add         r7, r12, r7, lsr #8     @
-                                        @
-#if LCD_WIDTH >= LCD_HEIGHT
-    add         r12, r14, #0x300        @
-                                        @
-    add         r3, r3, r12             @ b = r3 + delta
-    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
-#else
-    @ This element is zero - use r14    @
-                                        @
-    add         r3, r3, r14             @ b = r3 + delta
-    add         r11, r11, r14, lsl #1   @ r = r11 + delta*2
-    add         r7, r7, r14, lsr #1     @ g = r7 + delta/2
-#endif
-                                        @
-    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
-    orr         r12, r12, r7            @ ...at all
-    movs        r12, r12, asr #15       @
-    beq         15f @ no clamp          @
-    movs        r12, r3, asr #15        @ clamp b
-    mvnne       r3, r12, lsr #15        @
-    andne       r3, r3, #0x7c00         @ mask b only if clamped
-    movs        r12, r11, asr #16       @ clamp r
-    mvnne       r11, r12, lsr #16       @
-    movs        r12, r7, asr #15        @ clamp g
-    mvnne       r7, r12, lsr #15        @
-15: @ no clamp                          @
-                                        @
-    and         r11, r11, #0xf800       @ r11 = |00000000|00000000|rrrrrggg|gggbbbbb|
-    and         r7, r7, #0x7e00         @
-    orr         r11, r11, r7, lsr #4    @
-    orr         r11, r11, r3, lsr #10   @
-    mov         r7, r11, lsr #8         @ r7 = |00000000|00000000|00000000|rrrrrggg|
-                                        @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r7, [r0, #0x10]         @
-20:                                     @
-    ldr         r3, [r0]                @
-    tst         r3, #LCD1_BUSY_MASK     @
-    bne         20b                     @
-    strb        r11, [r0, #0x10]        @
-                                        @
-    subs        r1, r1, #2              @ subtract block from width
-    bgt         10b @ loop line         @
-                                        @
-    ldmpc       regs=r4-r11             @ restore registers and return
-    .ltorg                              @ dump constant pool
-    .size   lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
diff --git a/firmware/target/arm/philips/sa9200/lcd-sa9200.c b/firmware/target/arm/philips/sa9200/lcd-sa9200.c
deleted file mode 100644
index 3db308e..0000000
--- a/firmware/target/arm/philips/sa9200/lcd-sa9200.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2008 by Mark Arigo
- *
- * 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 "lcd.h"
-#include "kernel.h"
-#include "system.h"
-
-/* Settings to remember when display is turned off */
-static bool invert;
-static bool flip;
-static int  contrast;
-
-static bool power_on;
-static bool display_on;
-
-/* Forward declarations */
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-static void lcd_display_off(void);
-#endif
-
-/* The SA9200 controller closely matches the register defines for the
-   Samsung S6D0151 */
-#define R_START_OSC             0x00
-#define R_DRV_OUTPUT_CONTROL    0x01
-#define R_INVERSION_CONTROL     0x02
-#define R_ENTRY_MODE            0x03
-#define R_DISP_CONTROL          0x07
-#define R_BLANK_PERIOD_CONTROL  0x08
-#define R_FRAME_CYCLE_CONTROL   0x0b
-#define R_EXT_INTERFACE_CONTROL 0x0c
-#define R_POWER_CONTROL1        0x10
-#define R_GAMMA_CONTROL1        0x11
-#define R_POWER_CONTROL2        0x12
-#define R_POWER_CONTROL3        0x13
-#define R_POWER_CONTROL4        0x14
-#define R_RAM_ADDR_SET          0x21
-#define R_WRITE_DATA_2_GRAM     0x22
-#define R_RAM_READ_DATA         0x22
-#define R_GAMMA_FINE_ADJ_POS1   0x30
-#define R_GAMMA_FINE_ADJ_POS2   0x31
-#define R_GAMMA_FINE_ADJ_POS3   0x32
-#define R_GAMMA_GRAD_ADJ_POS    0x33
-#define R_GAMMA_FINE_ADJ_NEG1   0x34
-#define R_GAMMA_FINE_ADJ_NEG2   0x35
-#define R_GAMMA_FINE_ADJ_NEG3   0x36
-#define R_GAMMA_GRAD_ADJ_NEG    0x37
-#define R_GAMMA_CONTROL3        0x38
-#define R_GATE_SCAN_START_POS   0x40
-#define R_1ST_SCR_DRV_POS       0x42
-#define R_2ND_SCR_DRV_POS       0x43
-#define R_HORIZ_RAM_ADDR_POS    0x44
-#define R_VERT_RAM_ADDR_POS     0x45
-#define R_OSC_CONTROL           0x61
-#define R_LOW_POWER_MODE        0x69
-#define R_PRE_DRIVING_PERIOD    0x70
-#define R_GATE_OUT_PERIOD_CTRL  0x71
-#define R_SOFTWARE_RESET        0x72
-
-/* Display status */
-static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
-
-/* wait for LCD */
-static inline void lcd_wait_write(void)
-{
-    while (LCD1_CONTROL & LCD1_BUSY_MASK);
-}
-
-/* send LCD pixel */
-static inline void lcd_send_pixel(unsigned pixel)
-{
-    lcd_wait_write();
-    *(volatile uint8_t *)&LCD1_DATA = pixel >> 8;
-    lcd_wait_write();
-    *(volatile uint8_t *)&LCD1_DATA = pixel;
-}
-
-/* send LCD data */
-static void lcd_send_data(unsigned data)
-{
-    lcd_wait_write();
-    LCD1_DATA = data >> 8;
-    lcd_wait_write();
-    LCD1_DATA = data & 0xff;
-}
-
-/* send LCD command */
-static void lcd_send_command(unsigned cmd)
-{
-    lcd_wait_write();
-    LCD1_CMD = 0;
-    lcd_wait_write();
-    LCD1_CMD = cmd;
-}
-
-static void lcd_write_reg(unsigned reg, unsigned data)
-{
-    lcd_send_command(reg);
-    lcd_send_data(data);
-}
-
-/* LCD init */
-void lcd_init_device(void)
-{
-#if 0
-    /* This is done by the OF bootloader, no need to redo */
-    DEV_INIT1 &= ~0x3000;
-    DEV_INIT1 = DEV_INIT1;
-    DEV_INIT2 &= ~0x400;
-
-    LCD1_CONTROL = 0x4680;
-    udelay(1500);
-    LCD1_CONTROL = 0x4684;
-
-    outl(1, 0x70003018);
-
-    LCD1_CONTROL &= ~0x200;
-    LCD1_CONTROL &= ~0x800;
-    LCD1_CONTROL &= ~0x400;
-    udelay(30000);
-#endif
-
-    /* Already on */
-    power_on = true;
-    display_on = true;
-
-    /* Reset the options */
-    lcd_set_invert_display(false);
-    lcd_set_flip(false);
-    lcd_set_contrast(DEFAULT_CONTRAST_SETTING);
-}
-
-#ifdef HAVE_LCD_SLEEP
-static void lcd_power_on(void)
-{
-    LCD1_CONTROL |= 0x1;
-
-    /** Power ON Sequence **/
-
-    /* Start Oscillation */
-    lcd_write_reg(R_START_OSC, 0x0001);
-    
-    sleep(HZ/20); /* 50ms or more */
-
-    /* DSTB=0, SAP2-0=001, BT2-0=101, DC2-0=000, AP2-0=001, SLP=0, STB=0 */
-    lcd_write_reg(R_POWER_CONTROL1, 0x0d04);
-
-    /* VR1C=0, VRN14-10=10111, VRP14-10=11111 */
-    lcd_write_reg(R_GAMMA_CONTROL1, 0x171f);
-
-    /* SVC3-0=0000, VRH5-4=01 */
-    lcd_write_reg(R_POWER_CONTROL2, 0x0001);
-
-    /* VCMR=1, PON=0, VRH3-0=1101 */
-    lcd_write_reg(R_POWER_CONTROL3, 0x080d);
-
-    /* VDV6-0=0000100, VCOMG=0, VCM6-0=xxxxxxx */
-    lcd_write_reg(R_POWER_CONTROL4, 0x0400 | contrast);
-
-    /* DSTB=0, SAP2-0=010, BT2-0=010, DC2-0=000, AP2-0=010, SLP=0, STB=0 */
-    lcd_write_reg(R_POWER_CONTROL1, 0x1208);
-
-    sleep(HZ/20); /* 50ms or more */
-
-    /* VCMR=1, PON=1, VRH3-0=1100 */
-    lcd_write_reg(R_POWER_CONTROL3, 0x081c);
-
-    sleep(HZ/20); /* OF bootlaoder uses 200ms, no delay in OF firmware */
-
-    /* Instructions for other mode settings (in register order). */
-
-    lcd_write_reg(R_DRV_OUTPUT_CONTROL, flip ? 0x090c : 0x0a0c);
-
-    /* FL1-0=10, FDL=0 */
-    lcd_write_reg(R_INVERSION_CONTROL, 0x0200);
-
-    /* BGR=1, MDT1-0=00, I/D1-0=11, AM=0 */
-    lcd_write_reg(R_ENTRY_MODE, 0x1030);
-
-    /* PT1-0=00, SPT=0, GON=0, DTE=0, CL=0, REV=1, D1-0=01 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0005);
-
-    /* FP3-0=0011, BT3-0=1010 */
-    lcd_write_reg(R_BLANK_PERIOD_CONTROL, 0x030a);
-
-    /* DIV1-0=00, RTN3-0=0000 */
-    lcd_write_reg(R_FRAME_CYCLE_CONTROL, 0x0000);
-
-    /* RM=0, DM1-0=00, RIM1-0=00 */
-    lcd_write_reg(R_EXT_INTERFACE_CONTROL, 0x0000);
-
-    /* PKP1=0x0, PKP0=0x0 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_POS1, 0x0000);
-
-    /* PKP3=0x2, PKP2=0x4 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_POS2, 0x0204);
-
-    /* PKP5=0x0, PKP4=0x1 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_POS3, 0x0001);
-
-    /* PRP1=0x6, PRP0=0x0 */
-    lcd_write_reg(R_GAMMA_GRAD_ADJ_POS, 0x0600);
-
-    /* PKN1=0x6, PKN0=0x7 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1, 0x0607);
-
-    /* PKN3=0x3, PKN2=0x5 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2, 0x0305);
-
-    /* PKN5=0x7, PKN4=0x7 */
-    lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3, 0x0707);
-
-    /* PRN1=0x0, PRN0=0x6 */
-    lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG, 0x0006);
-
-    /* VRN0=0x4, VRP=0x0 */
-    lcd_write_reg(R_GAMMA_CONTROL3, 0x0400);
-
-    /* SCN=0x0 */
-    lcd_write_reg(R_GATE_SCAN_START_POS, 0x0000);
-
-    /* SE1=LCD_HEIGHT-1, SS1=0x0 */
-    lcd_write_reg(R_1ST_SCR_DRV_POS, 0x9f00);
-
-    /* SE2=0x0, SS2=0x0 */
-    lcd_write_reg(R_2ND_SCR_DRV_POS, 0x0000);
-
-    /* HEA=LCD_WIDTH-1, HSA=0x0 */
-    lcd_write_reg(R_HORIZ_RAM_ADDR_POS, 0x7f00);
-
-    /* VEA=LCD_HEIGHT-1, VSA=0x0 */
-    lcd_write_reg(R_VERT_RAM_ADDR_POS, 0x9f00);
-
-    /* Unknown registers */
-    lcd_write_reg(0x00a8, 0x0125);
-    lcd_write_reg(0x00a9, 0x0014);
-    lcd_write_reg(0x00a7, 0x0022);
-
-    power_on = true;
-}
-
-static void lcd_power_off(void)
-{
-    /* Display must be off first */
-    if (display_on)
-        lcd_display_off();
-
-    power_on = false;
-
-    /** Power OFF sequence **/
-
-    /* DSTB=0, SAP2-0=000, BT2-0=001, DC2-0=000, AP2-0=000, SLP=0, STB=0 */
-    lcd_write_reg(R_POWER_CONTROL1, 0x0100);
-
-    /* VCMR=1, PON=0, VRH3-0=1101 */
-    lcd_write_reg(R_POWER_CONTROL3, 0x080d);
-}
-
-void lcd_sleep(void)
-{
-    if (power_on)
-        lcd_power_off();
-
-    /* Set standby mode */
-
-    /* PT1-0=00, SPT=0, GON=1, DTE=1, CL=0, REV=1, D1-0=10 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0036);
-
-    /* DSTB=0, SAP2-0=000, BT2-0=101, DC2-0=000, AP2-0=000, SLP=0, STB=1 */
-    lcd_write_reg(R_POWER_CONTROL1, 0x0501);
-
-    LCD1_CONTROL &= ~0xffff0001;
-}
-#endif
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-static void lcd_display_off(void)
-{
-    display_on = false;
-
-    /** Display OFF sequence **/
-
-    /* PT1-0=10, SPT=0, GON=1, DTE=1, CL=0, REV=1, D1-0=10 */
-    lcd_write_reg(R_DISP_CONTROL, 0x1036);
-
-    sleep(HZ/25); /* 2 or more frames */
-
-    /* PT1-0=10, SPT=0, GON=1, DTE=0, CL=0, REV=1, D1-0=00 */
-    lcd_write_reg(R_DISP_CONTROL, 0x1034);
-
-    sleep(HZ/500); /* 1ms or more */
-
-    /* PT1-0=10, SPT=0, GON=0, DTE=0, CL=0, REV=1, D1-0=00 */
-    lcd_write_reg(R_DISP_CONTROL, 0x1004);
-
-    sleep(HZ/25); /* 2 or more frames */
-}
-#endif
-
-#if defined(HAVE_LCD_ENABLE)
-static void lcd_display_on(void)
-{
-    /* Be sure power is on first */
-    if (!power_on)
-        lcd_power_on();
-
-    /** Display ON Sequence **/
-
-    /* PT1-0=00, SPT=0, GON=1, DTE=0, CL=0, REV=0, D1-0=01 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0021);
-
-    sleep(HZ/500); /* 1ms or more */
-
-    /* PT1-0=00, SPT=0, GON=1, DTE=0, CL=0, REV=0, D1-0=11 */
-    lcd_write_reg(R_DISP_CONTROL, 0x0023);
-
-    sleep(HZ/25); /* 2 or more frames */
-
-    /* PT1-0=10, SPT=0, GON=1, DTE=1, CL=0, REV=x, D1-0=11 */
-    lcd_write_reg(R_DISP_CONTROL, invert ? 0x1033 : 0x1037);
-
-    display_on = true;
-}
-
-void lcd_enable(bool on)
-{
-    if (on == display_on)
-        return;
-
-    if (on)
-    {
-        lcd_display_on();
-        /* Probably out of sync and we don't wanna pepper the code with
-           lcd_update() calls for this. */
-        lcd_update();
-        send_event(LCD_EVENT_ACTIVATION, NULL);
-    }
-    else
-    {
-        lcd_display_off();
-    }
-}
-#endif
-
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-bool lcd_active(void)
-{
-    return display_on;
-}
-#endif
-
-/*** hardware configuration ***/
-int lcd_default_contrast(void)
-{
-    return DEFAULT_CONTRAST_SETTING;
-}
-
-void lcd_set_contrast(int val)
-{
-    contrast = val & 0x7f;
-
-    if (!display_on)
-        return;
-
-    /* VDV6-0=0000100, VCOMG=0, VCM6-0=xxxxxxx */
-    lcd_write_reg(R_POWER_CONTROL4, 0x0400 | contrast);
-}
-
-void lcd_set_invert_display(bool yesno)
-{
-    invert = yesno;
-
-    if (!display_on)
-        return;
-
-    /* PT1-0=10, SPT=0, GON=1, DTE=1, CL=0, REV=x, D1-0=11 */
-    lcd_write_reg(R_DISP_CONTROL, invert ? 0x1033 : 0x1037);
-}
-
-/* turn the display upside down (call lcd_update() afterwards) */
-void lcd_set_flip(bool yesno)
-{
-    flip = yesno;
-
-    if (!display_on)
-        return;
-
-    /* DPL=0, EPL=1, SM=0, GS=x, SS=x, NL4-0=01100 */
-    lcd_write_reg(R_DRV_OUTPUT_CONTROL, flip ? 0x090c : 0x0a0c);
-}
-
-void lcd_yuv_set_options(unsigned options)
-{
-    lcd_yuv_options = options;
-}
-
-/* Performance function to blit a YUV bitmap directly to the LCD */
-void lcd_write_yuv420_lines(unsigned char const * const src[3],
-                            int width,
-                            int stride);
-void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
-                                    int width,
-                                    int stride,
-                                    int x_screen,
-                                    int y_screen);
-void lcd_blit_yuv(unsigned char * const src[3],
-                  int src_x, int src_y, int stride,
-                  int x, int y, int width, int height)
-{
-    const unsigned char *yuv_src[3];
-    const unsigned char *ysrc_max;
-    int options;
-
-    if (!display_on)
-        return;
-
-    width &= ~1;
-    height &= ~1;
-
-    /* calculate the drawing region */
-    lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
-
-    /* convert YUV coordinates to screen coordinates */
-    y = LCD_WIDTH - 1 - y;
-
-    /* 2px strip: cursor moves left, then down in gram */
-    /* BGR=1, MDT1-0=00, I/D1-0=10, AM=0 */
-    lcd_write_reg(R_ENTRY_MODE, 0x1020);
-
-    yuv_src[0] = src[0] + src_y * stride + src_x;
-    yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1);
-    yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
-    ysrc_max = yuv_src[0] + height * stride;
-
-    /* cache options setting */
-    options = lcd_yuv_options;
-
-    do
-    {
-        /* max horiz << 8 | start horiz */
-        lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y << 8) | (y - 1));
-
-        /* position cursor (set AD0-AD15) */
-        lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | y);
-
-        /* start drawing */
-        lcd_send_command(R_WRITE_DATA_2_GRAM);
-
-        if (options & LCD_YUV_DITHER)
-        {
-            lcd_write_yuv420_lines_odither(yuv_src, width, stride,
-                                           y, x);
-        }
-        else
-        {
-            lcd_write_yuv420_lines(yuv_src, width, stride);
-        }
-
-        y -= 2; /* move strip by "down" 2 px */
-        yuv_src[0] += stride << 1;
-        yuv_src[1] += stride >> 1;
-        yuv_src[2] += stride >> 1;
-    }
-    while (yuv_src[0] < ysrc_max);
-
-    /* back to normal right, then down cursor in gram */
-    /* BGR=1, MDT1-0=00, I/D1-0=11, AM=0 */
-    lcd_write_reg(R_ENTRY_MODE, 0x1030);
-}
- 
-/* Update the display.
-   This must be called after all other LCD functions that change the display. */
-void lcd_update(void)
-{
-    const fb_data *addr, *end;
-
-    if (!display_on)
-        return;
-
-    addr = &lcd_framebuffer[0][0];
-    end = &lcd_framebuffer[LCD_HEIGHT - 1][LCD_WIDTH];
-
-    lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (LCD_WIDTH - 1) << 8);
-    lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_HEIGHT - 1) << 8);
-    lcd_write_reg(R_RAM_ADDR_SET, 0);
-    lcd_send_command(R_WRITE_DATA_2_GRAM);
-
-    do
-    {
-        lcd_send_pixel(*addr++);
-        lcd_send_pixel(*addr++);
-    }
-    while (addr < end);
-}
-
-/* Update a fraction of the display. */
-void lcd_update_rect(int x, int y, int width, int height)
-{
-    const fb_data *addr;
-
-    if (!display_on)
-        return;
-
-    if (x + width > LCD_WIDTH)
-        width = LCD_WIDTH - x;
-    if (x < 0)
-        width += x, x = 0;
-    if (width <= 0)
-        return; /* Nothing left to do. */
-
-    if (y + height > LCD_HEIGHT)
-        height = LCD_HEIGHT - y;
-    if (y < 0)
-        height += y, y = 0;
-    if (height <= 0)
-        return; /* Nothing left to do. */
-
-    addr = &lcd_framebuffer[y][x];
-
-    lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
-    lcd_write_reg(R_VERT_RAM_ADDR_POS, ((y + height - 1) << 8) | y);
-    lcd_write_reg(R_RAM_ADDR_SET, (y << 8) | x);
-    lcd_send_command(R_WRITE_DATA_2_GRAM);
-
-    do
-    {
-        int w = width - 1;
-
-        if (w > 0)
-        {
-            do
-            {
-                lcd_send_pixel(*addr++);
-                lcd_send_pixel(*addr++);
-                w -= 2;
-            }
-            while (w > 0);
-        }
-
-        if (w == 0)
-            lcd_send_pixel(*addr++); /* odd width */
-
-        addr += LCD_WIDTH - width;
-    }
-    while (--height > 0);
-}
diff --git a/firmware/target/arm/philips/sa9200/power-sa9200.c b/firmware/target/arm/philips/sa9200/power-sa9200.c
deleted file mode 100644
index b6a3929..0000000
--- a/firmware/target/arm/philips/sa9200/power-sa9200.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2006 by Daniel Ankers
- *
- * 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 <stdbool.h>
-#include "system.h"
-#include "cpu.h"
-#include "ascodec.h"
-#include "as3514.h"
-#include "power.h"
-#include "synaptics-mep.h"
-#include "lcd.h"
-#include "logf.h"
-
-void power_init(void)
-{
-#ifndef BOOTLOADER
-    /* Power on and initialize the touchpad here because we need it for
-       both buttons and button lights */
-    DEV_INIT2 &= ~0x800;
-
-    char byte = ascodec_read(AS3514_CVDD_DCDC3);
-    byte = (byte & ~0x18) | 0x08;
-    ascodec_write(AS3514_CVDD_DCDC3, byte);
-
-    /* LEDs for REW, FFWD, MENU */
-    GPIOD_ENABLE     |=  (0x40 | 0x20 | 0x04);
-    GPIOD_OUTPUT_VAL |=  (0x40 | 0x20 | 0x04);
-    GPIOD_OUTPUT_EN  |=  (0x40 | 0x20 | 0x04);
-    udelay(20000);
-
-    GPIOL_ENABLE     |=  0x10;
-    GPIOL_OUTPUT_VAL &= ~0x10;
-    GPIOL_OUTPUT_EN  |=  0x10;
-    udelay(100000);
-
-    /* enable DATA, ACK, CLK lines */
-    GPIOD_ENABLE     |=  (0x10 | 0x08 | 0x02);
-
-    GPIOD_OUTPUT_EN  |=  0x08; /* ACK  */
-    GPIOD_OUTPUT_VAL |=  0x08; /* high */
-
-    GPIOD_OUTPUT_EN  &= ~0x02; /* CLK  */
-    
-    GPIOD_OUTPUT_EN  |=  0x10; /* DATA */
-    GPIOD_OUTPUT_VAL |=  0x10; /* high */
-
-    if (!touchpad_init())
-    {
-        logf("touchpad not ready");
-    }
-
-    /* Setups specifically for buttons are handled in button-sa9200.c */
-#endif
-}
-
-void power_off(void)
-{
-    char byte;
-
-    /* Backlight off */
-    ascodec_write(AS3514_DCDC15, 0);
-
-#ifdef HAVE_LCD_SLEEP
-    /* LCD off/sleep (otherwise the image slowly fades out) */
-    lcd_sleep();
-#endif
-
-    /* Send shutdown command to PMU */
-    byte = ascodec_read(AS3514_SYSTEM);
-    byte &= ~0x1;   
-    ascodec_write(AS3514_SYSTEM, byte);
-
-    /* Stop interrupts on both cores */
-    disable_interrupt(IRQ_FIQ_STATUS);
-    COP_INT_DIS = -1;
-    CPU_INT_DIS = -1;
-
-    /* Halt everything and wait for device to power off */
-    while (1)
-    {
-        COP_CTL = 0x40000000;
-        CPU_CTL = 0x40000000;
-    }
-}
-
-unsigned int power_input_status(void)
-{
-    unsigned int status = POWER_INPUT_NONE;
-
-    /* GPIOF indicates that the connector is present,
-       GPIOB indicates that there's power there too.
-       Same status bits for both USB and the charger. */
-    if (!(GPIOF_INPUT_VAL & 0x80) && (GPIOB_INPUT_VAL & 0x40))
-        status = POWER_INPUT_MAIN_CHARGER;
-
-    return status;
-}
-
-void ide_power_enable(bool on)
-{
-    (void)on;
-}
diff --git a/firmware/target/arm/philips/sa9200/powermgmt-sa9200.c b/firmware/target/arm/philips/sa9200/powermgmt-sa9200.c
deleted file mode 100644
index 144ca37..0000000
--- a/firmware/target/arm/philips/sa9200/powermgmt-sa9200.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
- * Revisions copyright (C) 2005 by Gerald Van Baren
- *
- * 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 "adc.h"
-#include "powermgmt.h"
-
-const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
-{
-    3400
-};
-
-const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
-{
-    3300
-};
-
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
-const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
-{
-    /* Sansa Li Ion 750mAH, took from battery benchs */
-    { 3300, 3680, 3740, 3760, 3780, 3810, 3870, 3930, 3970, 4070, 4160 },
-};
-
-/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
-const unsigned short percent_to_volt_charge[11] =
-{
-    /* Sansa Li Ion 750mAH FIXME */
-    3300, 3680, 3740, 3760, 3780, 3810, 3870, 3930, 3970, 4070, 4160
-};
diff --git a/firmware/target/arm/philips/sa9200/powermgmt-target.h b/firmware/target/arm/philips/sa9200/powermgmt-target.h
deleted file mode 100644
index 4400cda..0000000
--- a/firmware/target/arm/philips/sa9200/powermgmt-target.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2009 by Michael Sevakis
- * Copyright (C) 2008 by Bertrik Sikken
- *
- * 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 POWERMGMT_TARGET_H
-#define POWERMGMT_TARGET_H
-
-/* NOTE: these values are copied from the Sansa e200v1 */
-
-/* PREFERRED - Check if topped-off and monitor voltage while plugged. */
-#define BATT_FULL_VOLTAGE   4160
-#define BATT_VAUTO_RECHARGE 4100
-#define BATT_CHG_V          CHG_V_4_20V
-#define BATT_CHG_I          CHG_I_300MA
-#define CHARGER_TOTAL_TIMER (4*3600*2) /* 4 hours enough? */
-/* On e200 ADC_RTCSUP seems to represent battery voltage better than
- * ADC_BVDD during charging (ADC_BVDD is way too high) and appears the
- * same in normal use.
- */
-#define ADC_BATTERY         ADC_RTCSUP
-
-void powermgmt_init_target(void);
-void charging_algorithm_step(void);
-void charging_algorithm_close(void);
-
-/* We want to be able to reset the averaging filter */
-#define HAVE_RESET_BATTERY_FILTER
-
-#define BATT_AVE_SAMPLES 32
-
-#endif /*  POWERMGMT_TARGET_H */
diff --git a/firmware/target/arm/portalplayer/adc-pp5020.c b/firmware/target/arm/portalplayer/adc-pp5020.c
new file mode 100644
index 0000000..2d75a7e
--- /dev/null
+++ b/firmware/target/arm/portalplayer/adc-pp5020.c
@@ -0,0 +1,179 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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 "system.h"
+#include "kernel.h"
+#include "thread.h"
+#include "adc.h"
+
+#define ADC_ADDR            (*(volatile unsigned long*)(0x7000ad00))
+#define ADC_STATUS          (*(volatile unsigned long*)(0x7000ad04))
+#define ADC_DATA_1          (*(volatile unsigned long*)(0x7000ad20))
+#define ADC_DATA_2          (*(volatile unsigned long*)(0x7000ad24))
+#define ADC_INIT            (*(volatile unsigned long*)(0x7000ad2c))
+
+#if defined(PBELL_VIBE500)
+#define ADC_UNK             (*(volatile unsigned long*)(0x7000002c))
+#endif
+
+static unsigned short adcdata[NUM_ADC_CHANNELS];
+
+/* Scan ADC so that adcdata[channel] gets updated. */
+unsigned short adc_scan(int channel)
+{
+    unsigned int adc_data_1;
+    unsigned int adc_data_2;
+
+    if (channel >= NUM_ADC_CHANNELS)
+        return 0;
+
+    /* Start conversion */
+    ADC_ADDR |= 0x80000000;
+
+    /* Wait for conversion to complete */
+    while((ADC_STATUS & (0x40<<8*channel))==0);
+
+    /* Stop conversion */
+    ADC_ADDR &=~ 0x80000000;
+
+    /* ADC_DATA_1 and ADC_DATA_2 are both four bytes, one byte per channel.
+       For each channel, ADC_DATA_1 stores the 8-bit msb, ADC_DATA_2 stores the
+       2-bit lsb (in bits 0 and 1). Each channel is 10 bits total. */
+    adc_data_1 = ((ADC_DATA_1 >> (8*channel)) & 0xff);
+    adc_data_2 = ((ADC_DATA_2 >> (8*channel+6)) & 0x3);
+
+    adcdata[channel] = (adc_data_1<<2 | adc_data_2);
+
+#if !(defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330))
+    /* ADC values read low if PLL is enabled */
+    if(PLL_CONTROL & 0x80000000){
+        adcdata[channel] += 0x14;
+        if(adcdata[channel] > 0x400)
+            adcdata[channel] = 0x400;
+    }
+#endif
+
+    return adcdata[channel];
+}
+
+/* Read 10-bit channel data */
+unsigned short adc_read(int channel)
+{
+    return adcdata[channel];
+}
+
+static int adc_counter;
+
+static void adc_tick(void)
+{
+    if(++adc_counter == HZ)
+    {
+        adc_counter = 0;
+        adc_scan(0);
+        adc_scan(1);
+        adc_scan(2);
+        adc_scan(3);
+    }
+}
+
+/* Figured out from how the OF does things */
+void adc_init(void)
+{
+#if defined(PBELL_VIBE500)
+    ADC_UNK |= 0x1000;
+#endif
+
+#if defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
+    ADC_INIT = 0;
+#else
+    ADC_INIT |= 1;
+    ADC_INIT |= 0x40000000;
+#endif
+    udelay(100);
+
+    /* Reset ADC */
+    DEV_RS2 |= 0x20;
+    udelay(100);
+
+    DEV_RS2 &=~ 0x20;
+    udelay(100);
+
+    /* Enable ADC */
+    DEV_EN2 |= 0x20;
+    udelay(100);
+
+    ADC_CLOCK_SRC |= 0x3;
+    udelay(100);
+
+    ADC_ADDR = 0;
+    ADC_ADDR |= 0x40;
+
+#if !(defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330))
+    ADC_ADDR |= 0x20000000;
+    udelay(100);
+
+    ADC_INIT;
+    ADC_INIT = 0;
+    udelay(100);
+#endif
+
+    ADC_STATUS = 0;
+
+    /* Enable channel 0 (battery) */
+    DEV_INIT1  &=~0x3;
+    ADC_ADDR   |= 0x1000000;
+    ADC_STATUS |= 0x20;
+
+    /* Enable channel 1 (unknown) */
+    DEV_INIT1  &=~30;
+    ADC_ADDR   |= 0x2000000;
+    ADC_STATUS |= 0x2000;
+
+#if defined (IRIVER_H10) || defined(IRIVER_H10_5GB) || \
+    defined(MROBE_100)
+    /* Enable channel 2 (H10:remote) */
+    DEV_INIT1  &=~0x300;
+    DEV_INIT1  |= 0x100;
+    ADC_ADDR   |= 0x4000000;
+    ADC_STATUS |= 0x200000;
+
+    /* Enable channel 3 (H10:scroll pad) */
+    DEV_INIT1  &=~0x3000;
+    DEV_INIT1  |= 0x1000;
+    ADC_ADDR   |= 0x8000000;
+    ADC_STATUS |= 0x20000000;
+#endif
+
+#if defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
+    ADC_INIT |= 0x80000000;
+    udelay(100);
+    ADC_INIT = 0;
+#endif
+
+    /* Force a scan of all channels to get initial values */
+    adc_scan(0);
+    adc_scan(1);
+    adc_scan(2);
+    adc_scan(3);
+
+    tick_add_task(adc_tick);
+}
diff --git a/firmware/target/arm/portalplayer/ascodec-pp.c b/firmware/target/arm/portalplayer/ascodec-pp.c
new file mode 100644
index 0000000..49a69d1
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ascodec-pp.c
@@ -0,0 +1,82 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Driver for AS3514 audio codec
+ *
+ * Copyright (c) 2007 Daniel Ankers
+ * Copyright (c) 2007 Christian Gmeiner
+ *
+ * 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 "cpu.h"
+#include "system.h"
+
+#include "audiohw.h"
+#include "i2s.h"
+#include "ascodec-target.h"
+
+/*
+ * Initialise the PP I2C and I2S.
+ */
+void audiohw_init(void)
+{
+    /* normal outputs for CDI and I2S pin groups */
+    DEV_INIT2 &= ~0x300;
+
+    /*mini2?*/
+    DEV_INIT1 &=~0x3000000;
+    /*mini2?*/
+
+    /* I2S device reset */
+    DEV_RS |= DEV_I2S;
+    DEV_RS &=~DEV_I2S;
+
+    /* I2S device enable */
+    DEV_EN |= DEV_I2S;
+
+    /* enable external dev clock clocks */
+    DEV_EN |= DEV_EXTCLOCKS;
+
+    /* external dev clock to 24MHz */
+    outl(inl(0x70000018) & ~0xc, 0x70000018);
+
+#ifdef SANSA_E200
+    /* Prevent pops on startup */
+    GPIOG_ENABLE |= 0x08;
+    GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, 0x08);
+    GPIOG_OUTPUT_EN |= 0x08;
+#endif
+
+    i2s_reset();
+
+    audiohw_preinit();
+}
+
+void ascodec_suppressor_on(bool on)
+{
+    /* CHECK: Good for c200 too? */
+#ifdef SANSA_E200
+    if (on) {
+        /* Set pop prevention */
+        GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, 0x08);
+    } else {
+        /* Release pop prevention */
+        GPIO_CLEAR_BITWISE(GPIOG_OUTPUT_VAL, 0x08);
+    }
+#else
+    (void)on;
+#endif
+} 
diff --git a/firmware/target/arm/portalplayer/ascodec-target.h b/firmware/target/arm/portalplayer/ascodec-target.h
new file mode 100644
index 0000000..68d9905
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ascodec-target.h
@@ -0,0 +1,103 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Driver for AS3514 audio codec
+ *
+ * Copyright (c) 2007 Daniel Ankers
+ * Copyright (c) 2007 Christian Gmeiner
+ *
+ * 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 _ASCODEC_TARGET_H
+#define _ASCODEC_TARGET_H
+
+#include "config.h"
+
+#ifdef CPU_PP
+/* TODO: This header is actually portalplayer specific, and should be
+ * moved into an appropriate subdir  */
+
+#include "as3514.h"
+#include "i2c-pp.h"
+
+static inline int ascodec_write(unsigned int reg, unsigned int value)
+{
+    return pp_i2c_send(AS3514_I2C_ADDR, reg, value);
+}
+
+static inline int ascodec_read(unsigned int reg)
+{
+    return i2c_readbyte(AS3514_I2C_ADDR, reg);
+}
+
+static inline int ascodec_readbytes(int addr, int len, unsigned char *data)
+{
+    return i2c_readbytes(AS3514_I2C_ADDR, addr, len, data);
+}
+
+static inline void ascodec_lock(void)
+{
+    i2c_lock();
+}
+
+static inline void ascodec_unlock(void)
+{
+    i2c_unlock();
+}
+
+static inline bool ascodec_chg_status(void)
+{
+    return ascodec_read(AS3514_IRQ_ENRD0) & CHG_STATUS;
+}
+
+static inline bool ascodec_endofch(void)
+{
+    return ascodec_read(AS3514_IRQ_ENRD0) & CHG_ENDOFCH;
+}
+
+static inline void ascodec_monitor_endofch(void)
+{
+    ascodec_write(AS3514_IRQ_ENRD0, IRQ_ENDOFCH);
+}
+
+static inline void ascodec_wait_adc_finished(void)
+{
+    /*
+     * FIXME: not implemented
+     *
+     * If irqs are not available on the target platform,
+     * this should be most likely implemented by polling
+     * AS3514_IRQ_ENRD2 in the same way powermgmt-ascodec.c
+     * is polling IRQ_ENDOFCH.
+     */
+}
+
+static inline void ascodec_write_charger(int value)
+{
+    ascodec_write(AS3514_CHARGER, value);
+}
+
+static inline int ascodec_read_charger(void)
+{
+    return ascodec_read(AS3514_CHARGER);
+}
+
+extern void ascodec_suppressor_on(bool on);
+
+#endif /* CPU_PP */
+
+#endif /* !_ASCODEC_TARGET_H */
diff --git a/firmware/target/arm/portalplayer/ata-pp5002.c b/firmware/target/arm/portalplayer/ata-pp5002.c
new file mode 100644
index 0000000..2c4bb3b
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ata-pp5002.c
@@ -0,0 +1,54 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* ATA stuff was taken from the iPod code */
+
+#include <stdbool.h>
+#include "system.h"
+#include "ata.h"
+#include "ata-target.h"
+
+void ata_reset() 
+{
+
+}
+
+void ata_enable(bool on)
+{
+    /* TODO: Implement ata_enable() */
+    (void)on;
+}
+
+bool ata_is_coldstart()
+{
+    return false;
+    /* TODO: Implement coldstart variable */
+}
+
+void ata_device_init()
+{
+   /* From ipod-ide.c:ipod_ide_register() */
+    outl(inl(0xc0003024) | (1 << 7), 0xc0003024);
+    outl(inl(0xc0003024) & ~(1<<2), 0xc0003024);
+
+    outl(0x10, 0xc0003000);
+    outl(0x80002150, 0xc0003004);
+}
diff --git a/firmware/target/arm/portalplayer/ata-pp5020.c b/firmware/target/arm/portalplayer/ata-pp5020.c
new file mode 100644
index 0000000..0eb6435
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ata-pp5020.c
@@ -0,0 +1,249 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* ATA stuff was taken from the iPod code */
+
+#include <stdbool.h>
+#include "system.h"
+#include "ata.h"
+#include "ata-target.h"
+
+void ata_reset() 
+{
+
+}
+
+void ata_enable(bool on)
+{
+    /* TODO: Implement ata_enable() */
+    (void)on;
+}
+
+bool ata_is_coldstart()
+{
+    return false;
+    /* TODO: Implement coldstart variable */
+}
+
+void ata_device_init()
+{
+#ifdef SAMSUNG_YH920
+    CPU_INT_DIS = (1<<IDE_IRQ);
+#endif
+#ifdef HAVE_ATA_DMA
+    IDE_DMA_CONTROL |= 2;
+    IDE_DMA_CONTROL &= ~1;
+    IDE0_CFG &= ~0x8010;
+    IDE0_CFG |= 0x20; 
+#else
+
+    /* From ipod-ide.c:ipod_ide_register() */
+    IDE0_CFG |= (1<<5);
+#ifdef IPOD_NANO
+    IDE0_CFG |= (0x10000000); /* cpu > 65MHz */
+#else
+    IDE0_CFG &=~(0x10000000); /* cpu < 65MHz */
+#endif
+#endif
+
+    IDE0_PRI_TIMING0 = 0x10;
+    IDE0_PRI_TIMING1 = 0x80002150;
+}
+
+/* These are PIO timings for 80 Mhz.  At 24 Mhz, 
+   the first value is 0 but the rest are the same.
+   They go in IDE0_PRI_TIMING0.
+   
+   Rockbox used 0x10, and test_disk shows that leads to faster PIO.   
+   If 0x10 is incorrect, these timings may be needed with some devices.
+static const unsigned long pio80mhz[] = {
+    0xC293, 0x43A2, 0x11A1, 0x7232, 0x3131
+}; 
+*/
+
+#ifdef HAVE_ATA_DMA
+/* Timings for multi-word and ultra DMA modes.
+   These go in IDE0_PRI_TIMING1
+ */
+static const unsigned long tm_mwdma[] = {
+    0xF9F92, 0x56562, 0x45451 
+};
+
+static const unsigned long tm_udma[] = { 
+    0x800037C1, 0x80003491, 0x80003371, 
+#if ATA_MAX_UDMA > 2       
+    0x80003271, 0x80003071 
+#endif
+};
+
+#if ATA_MAX_UDMA > 2
+static bool dma_boosted = false;
+static bool dma_needs_boost;
+#endif
+
+/* This function sets up registers for 80 Mhz.
+   Ultra DMA mode 2 works at 30 Mhz.
+ */
+void ata_dma_set_mode(unsigned char mode) {
+    int modeidx;
+
+    (*(volatile unsigned long *)(0x600060C4)) = 0xC0000000; /* 80 Mhz */
+#if !defined(IPOD_NANO)
+    IDE0_CFG &= ~0x10000000;
+#endif
+
+    modeidx = mode & 7;
+    mode &= 0xF8;
+    if (mode == 0x40 && modeidx <= ATA_MAX_UDMA) {
+        IDE0_PRI_TIMING1 = tm_udma[modeidx];
+#if ATA_MAX_UDMA > 2
+        if (modeidx > 2)
+            dma_needs_boost = true;
+        else
+            dma_needs_boost = false;
+#endif
+    } else if (mode == 0x20 && modeidx <= ATA_MAX_MWDMA)
+        IDE0_PRI_TIMING1 = tm_mwdma[modeidx];
+
+#if !defined(IPOD_NANO)
+    IDE0_CFG |= 0x20000000; /* >= 50 Mhz */
+#endif
+} 
+
+#define IDE_CFG_INTRQ           8
+#define IDE_DMA_CONTROL_READ    8
+
+/* This waits for an ATA interrupt using polling.
+   In ATA_CONTROL, CONTROL_nIEN must be cleared.
+ */
+STATICIRAM ICODE_ATTR int ata_wait_intrq(void)
+{
+    long timeout = current_tick + HZ*10;
+    
+    do 
+    {
+        if (IDE0_CFG & IDE_CFG_INTRQ)
+            return 1;
+        ata_keep_active();
+        yield();
+    } while (TIME_BEFORE(current_tick, timeout));
+
+    return 0; /* timeout */
+}
+
+/* This function checks if parameters are appropriate for DMA, 
+   and if they are, it sets up for DMA.
+   
+   If return value is false, caller may use PIO for this transfer.
+   
+   If return value is true, caller must issue a DMA ATA command
+   and then call ata_dma_finish().
+ */
+bool ata_dma_setup(void *addr, unsigned long bytes, bool write) {
+    /* Require cacheline alignment for reads to prevent interference. */
+    if (!write && ((unsigned long)addr & 15))
+        return false;
+
+    /* Writes only need to be word-aligned, but by default DMA
+     * is not used for writing as it appears to be slower.
+     */
+#ifdef ATA_DMA_WRITES
+    if (write && ((unsigned long)addr & 3))
+        return false;
+#else
+    if (write)
+        return false;
+#endif
+
+#if ATA_MAX_UDMA > 2
+    if (dma_needs_boost && !dma_boosted) {
+        cpu_boost(true);
+        dma_boosted = true;
+    }
+#endif
+
+    if (write) {
+        /* If unflushed, old data may be written to disk */
+        cpucache_flush();
+    }
+    else {
+        /* Invalidate cache because new data may be present in RAM */
+        cpucache_invalidate();
+    }
+
+    /* Clear pending interrupts so ata_dma_finish() can wait for an
+       interrupt from this transfer
+     */
+    IDE0_CFG |= IDE_CFG_INTRQ;
+
+    IDE_DMA_CONTROL |= 2;
+    IDE_DMA_LENGTH = bytes - 4;
+
+#if !defined(BOOTLOADER) || defined (HAVE_BOOTLOADER_USB_MODE)
+    if ((unsigned long)addr < DRAM_START)
+        /* Rockbox remaps DRAM to start at 0 */
+        IDE_DMA_ADDR = (unsigned long)addr + DRAM_START;
+    else
+#endif
+        IDE_DMA_ADDR = (unsigned long)addr;
+
+    if (write)
+        IDE_DMA_CONTROL &= ~IDE_DMA_CONTROL_READ;
+    else
+        IDE_DMA_CONTROL |= IDE_DMA_CONTROL_READ;
+
+    IDE0_CFG |= 0x8000;
+
+    return true;
+}
+
+/* This function waits for a DMA transfer to end.
+   It must be called to finish what ata_dma_setup started.
+   
+   Return value is true if DMA completed before the timeout, and false
+   if a timeout happened.
+ */
+bool ata_dma_finish(void) {
+    bool res;
+    
+    /* It may be okay to put this at the end of setup */
+    IDE_DMA_CONTROL |= 1;
+
+    /* Wait for end of transfer.
+       Reading standard ATA status while DMA is in progress causes 
+       failures and hangs.  Because of that, another wait is used.
+     */
+    res = ata_wait_intrq();
+
+    IDE0_CFG &= ~0x8000;
+    IDE_DMA_CONTROL &= ~0x80000001;
+
+#if ATA_MAX_UDMA > 2
+    if (dma_boosted) {
+        cpu_boost(false);
+        dma_boosted = false;
+    }
+#endif
+
+    return res;
+}
+
+#endif /* HAVE_ATA_DMA */
diff --git a/firmware/target/arm/portalplayer/ata-sd-pp.c b/firmware/target/arm/portalplayer/ata-sd-pp.c
new file mode 100644
index 0000000..f83bb60
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ata-sd-pp.c
@@ -0,0 +1,1387 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 Daniel Ankers
+ *
+ * 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" /* for HAVE_MULTIDRIVE */
+#include "fat.h"
+#include "sdmmc.h"
+#include "gcc_extensions.h"
+#ifdef HAVE_HOTSWAP
+#include "sd-pp-target.h"
+#endif
+#include "ata_idle_notify.h"
+#include "system.h"
+#include <string.h>
+#include "thread.h"
+#include "led.h"
+#include "disk.h"
+#include "cpu.h"
+#include "panic.h"
+#include "usb.h"
+#include "sd.h"
+#include "storage.h"
+
+#define SECTOR_SIZE     512
+#define BLOCKS_PER_BANK 0x7a7800
+
+/* Comparing documentations of various MMC/SD controllers revealed, */
+/* that this controller seems to be a mix of PXA27x, PXA255 and */
+/* some PP specific stuff. The register and bit definitions are */
+/* taken from the 'PXA27x Developers Manual', as it appears to be */
+/* the closest match. Known differences and obscurities are commented.*/
+
+#define MMC_STRPCL      (*(volatile unsigned int *)(0x70008200))
+#define MMC_STAT        (*(volatile unsigned int *)(0x70008204))
+#define MMC_CLKRT       (*(volatile unsigned int *)(0x70008208))
+#define MMC_SPI         (*(volatile unsigned int *)(0x7000820c))
+#define MMC_CMDAT       (*(volatile unsigned int *)(0x70008210))
+#define MMC_RESTO       (*(volatile unsigned int *)(0x70008214))
+#define MMC_RDTO        (*(volatile unsigned int *)(0x70008218))
+#define MMC_BLKLEN      (*(volatile unsigned int *)(0x7000821c))
+#define MMC_NUMBLK      (*(volatile unsigned int *)(0x70008220))
+#define MMC_I_MASK      (*(volatile unsigned int *)(0x70008224))
+#define MMC_CMD         (*(volatile unsigned int *)(0x70008228))
+#define MMC_ARGH        (*(volatile unsigned int *)(0x7000822c))
+#define MMC_ARGL        (*(volatile unsigned int *)(0x70008230))
+#define MMC_RES         (*(volatile unsigned int *)(0x70008234))
+
+/* PXA255/27x have separate RX/TX FIFOs with 32x8 bit */
+/* PP502x has a combined Data FIFO with 16x16 bit */
+#define MMC_DATA_FIFO   (*(volatile unsigned int *)(0x70008280))
+
+/* PP specific registers, no other controller seem to have such. */
+#define MMC_SD_STATE    (*(volatile unsigned int *)(0x70008238))
+#define MMC_INIT_1      (*(volatile unsigned int *)(0x70008240))
+#define MMC_INIT_2      (*(volatile unsigned int *)(0x70008244))
+
+/* MMC_STAT bits */
+#define STAT_SDIO_SUSPEND_ACK (1 << 16)
+#define STAT_SDIO_INT         (1 << 15)
+#define STAT_RD_STALLED       (1 << 14)
+#define STAT_END_CMD_RES      (1 << 13)
+#define STAT_PRG_DONE         (1 << 12)
+#define STAT_DATA_TRAN_DONE   (1 << 11)
+#define STAT_SPI_WR_ERR       (1 << 10)
+#define STAT_FLASH_ERR        (1 << 9)
+#define STAT_CLK_EN           (1 << 8)
+#define STAT_RECV_FIFO_FULL   (1 << 7)  /* taken from PXA255 */
+#define STAT_XMIT_FIFO_EMPTY  (1 << 6)  /* taken from PXA255 */
+#define STAT_RES_CRC_ERR      (1 << 5)
+#define STAT_DAT_ERR_TOKEN    (1 << 4)
+#define STAT_CRC_RD_ERR       (1 << 3)
+#define STAT_CRC_WR_ERR       (1 << 2)
+#define STAT_TIME_OUT_RES     (1 << 1)
+#define STAT_TIME_OUT_READ    (1)
+#define STAT_ERROR_BITS       (0x3f)
+ 
+/* MMC_CMDAT bits */
+/* Some of the bits used by the OF don't make much sense with these */
+/* definitions. So they're probably different between PXA and PP502x */
+/* Bits 0-5 appear to match though. */
+#define CMDAT_SDIO_RESUME  (1 << 13)
+#define CMDAT_SDIO_SUSPEND (1 << 12)
+#define CMDAT_SDIO_INT_EN  (1 << 11)
+#define CMDAT_STOP_TRAN    (1 << 10)
+#define CMDAT_SD_4DAT      (1 << 8)
+#define CMDAT_DMA_EN       (1 << 7)
+#define CMDAT_INIT         (1 << 6)
+#define CMDAT_BUSY         (1 << 5)
+#define CMDAT_STRM_BLK     (1 << 4)
+#define CMDAT_WR_RD        (1 << 3)
+#define CMDAT_DATA_EN      (1 << 2)
+#define CMDAT_RES_TYPE3    (3)
+#define CMDAT_RES_TYPE2    (2)
+#define CMDAT_RES_TYPE1    (1)
+ 
+/* MMC_I_MASK bits */
+/* PP502x apparently only has bits 0-3 */
+#define I_MASK_SDIO_SUSPEND_ACK  (1 << 12)
+#define I_MASK_SDIO_INT          (1 << 11)
+#define I_MASK_RD_STALLED        (1 << 10)
+#define I_MASK_RES_ERR           (1 << 9)
+#define I_MASK_DAT_ERR           (1 << 8)
+#define I_MASK_TINT              (1 << 7)
+#define I_MASK_TXFIFO_WR_REQ     (1 << 6)
+#define I_MASK_RXFIFO_RD_REQ     (1 << 5)
+#define I_MASK_CLK_IS_OFF        (1 << 4)
+#define I_MASK_STOP_CMD          (1 << 3)
+#define I_MASK_END_CMD_RES       (1 << 2)
+#define I_MASK_PRG_DONE          (1 << 1)
+#define I_MASK_DATA_TRAN_DONE    (1 << 0)
+
+#define FIFO_LEN        16          /* FIFO is 16 words deep */
+
+#define EC_OK                    0
+#define EC_FAILED                1
+#define EC_NOCARD                2
+#define EC_WAIT_STATE_FAILED     3
+#define EC_CHECK_TIMEOUT_FAILED  4
+#define EC_POWER_UP              5
+#define EC_READ_TIMEOUT          6
+#define EC_WRITE_TIMEOUT         7
+#define EC_TRAN_SEL_BANK         8
+#define EC_TRAN_READ_ENTRY       9
+#define EC_TRAN_READ_EXIT       10
+#define EC_TRAN_WRITE_ENTRY     11
+#define EC_TRAN_WRITE_EXIT      12
+#define EC_FIFO_SEL_BANK_EMPTY  13
+#define EC_FIFO_SEL_BANK_DONE   14
+#define EC_FIFO_ENA_BANK_EMPTY  15
+#define EC_FIFO_READ_FULL       16
+#define EC_FIFO_WR_EMPTY        17
+#define EC_FIFO_WR_DONE         18
+#define EC_COMMAND              19
+#define NUM_EC                  20
+
+/* for compatibility */
+static long last_disk_activity = -1;
+
+/** static, private data **/ 
+static bool initialized = false;
+static unsigned int sd_thread_id = 0;
+
+#define Q_CLOSE    1
+
+static long next_yield = 0;
+#define MIN_YIELD_PERIOD 1000
+
+static tCardInfo card_info[2];
+static tCardInfo *currcard = NULL; /* current active card */
+
+struct sd_card_status
+{
+    int retry;
+    int retry_max;
+};
+
+static struct sd_card_status sd_status[NUM_DRIVES] =
+{
+    { 0, 1  },
+#ifdef HAVE_MULTIDRIVE
+    { 0, 10 }
+#endif
+};
+
+/* Shoot for around 75% usage */
+static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
+static const char         sd_thread_name[] = "ata/sd";
+static struct mutex       sd_mtx SHAREDBSS_ATTR;
+static struct event_queue sd_queue SHAREDBSS_ATTR;
+
+#ifdef HAVE_HOTSWAP
+static int sd_first_drive = 0;
+#endif
+
+/* Posted when card plugged status has changed */
+#define SD_HOTSWAP    1
+/* Actions taken by sd_thread when card status has changed */
+enum sd_thread_actions
+{
+    SDA_NONE      = 0x0,
+    SDA_UNMOUNTED = 0x1,
+    SDA_MOUNTED   = 0x2
+};
+
+/* Private Functions */
+
+static unsigned int check_time[NUM_EC];
+
+static inline bool sd_check_timeout(long timeout, int id)
+{
+    return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout);
+}
+
+static bool sd_poll_status(unsigned int trigger, long timeout)
+{
+    long t = USEC_TIMER;
+
+    while ((MMC_STAT & trigger) == 0)
+    {
+        long time = USEC_TIMER;
+
+        if (TIME_AFTER(time, next_yield))
+        {
+            long ty = USEC_TIMER;
+            yield();
+            timeout += USEC_TIMER - ty;
+            next_yield = ty + MIN_YIELD_PERIOD;
+        }
+
+        if (TIME_AFTER(time, t + timeout))
+            return false;
+    }
+
+    return true;
+}
+
+static int sd_command(unsigned int cmd, unsigned long arg1,
+                      unsigned long *response, unsigned int cmdat)
+{
+    int i, words; /* Number of 16 bit words to read from MMC_RES */
+    unsigned int data[9];
+
+    MMC_CMD = cmd;
+    MMC_ARGH = (unsigned int)((arg1 & 0xffff0000) >> 16);
+    MMC_ARGL = (unsigned int)((arg1 & 0xffff));
+    MMC_CMDAT  = cmdat;
+
+    if (!sd_poll_status(STAT_END_CMD_RES, 100000))
+        return -EC_COMMAND;
+
+    if ((MMC_STAT & STAT_ERROR_BITS) != 0)
+        /* Error sending command */
+        return -EC_COMMAND - (MMC_STAT & STAT_ERROR_BITS)*100;
+
+    if (cmd == SD_GO_IDLE_STATE)
+        return 0; /* no response here */
+
+    words = (cmdat == CMDAT_RES_TYPE2) ? 9 : 3;
+
+    for (i = 0; i < words; i++) /* MMC_RES is read MSB first */
+        data[i] = MMC_RES; /* Read most significant 16-bit word */
+
+    if (response == NULL)
+    {
+        /* response discarded */
+    }
+    else if (cmdat == CMDAT_RES_TYPE2)
+    {
+        /* Response type 2 has the following structure:
+         * [135:135] Start Bit - '0'
+         * [134:134] Transmission bit - '0'
+         * [133:128] Reserved - '111111'
+         * [127:001] CID or CSD register including internal CRC7
+         * [000:000] End Bit - '1'
+         */
+        response[3] = (data[0]<<24) + (data[1]<<8) + (data[2]>>8);
+        response[2] = (data[2]<<24) + (data[3]<<8) + (data[4]>>8);
+        response[1] = (data[4]<<24) + (data[5]<<8) + (data[6]>>8);
+        response[0] = (data[6]<<24) + (data[7]<<8) + (data[8]>>8);
+    }
+    else
+    {
+        /* Response types 1, 1b, 3, 6, 7 have the following structure:
+         * Types 4 and 5 are not supported.
+         *
+         *     [47] Start bit - '0'
+         *     [46] Transmission bit - '0'
+         *  [45:40] R1, R1b, R6, R7: Command index
+         *          R3: Reserved - '111111'
+         *   [39:8] R1, R1b: Card Status
+         *          R3: OCR Register
+         *          R6: [31:16] RCA
+         *              [15: 0] Card Status Bits 23, 22, 19, 12:0
+         *                     [23] COM_CRC_ERROR
+         *                     [22] ILLEGAL_COMMAND
+         *                     [19] ERROR
+         *                   [12:9] CURRENT_STATE
+         *                      [8] READY_FOR_DATA
+         *                    [7:6]
+         *                      [5] SD_APP_CMD
+         *                      [4]
+         *                      [3] AKE_SEQ_ERROR
+         *                      [2] Reserved
+         *                    [1:0] Reserved for test mode
+         *          R7: [19:16] Voltage accepted
+         *              [15:8]  echo-back of check pattern
+         *    [7:1] R1, R1b: CRC7
+         *          R3: Reserved - '1111111'
+         *      [0] End Bit - '1'
+         */
+        response[0] = (data[0]<<24) + (data[1]<<8) + (data[2]>>8);
+    }
+
+    return 0;
+}
+
+static int sd_wait_for_state(unsigned int state, int id)
+{
+    unsigned long response = 0;
+    unsigned int timeout = 0x80000;
+
+    check_time[id] = USEC_TIMER;
+
+    while (1)
+    {
+        int ret = sd_command(SD_SEND_STATUS, currcard->rca, &response, CMDAT_RES_TYPE1);
+        long us;
+
+        if (ret < 0)
+            return ret*100 - id;
+
+        if (((response >> 9) & 0xf) == state)
+        {
+            MMC_SD_STATE = state;
+            return 0;
+        }
+
+        if (!sd_check_timeout(timeout, id))
+            return -EC_WAIT_STATE_FAILED*100 - id;
+
+        us = USEC_TIMER;
+        if (TIME_AFTER(us, next_yield))
+        {
+            yield();
+            timeout += USEC_TIMER - us;
+            next_yield = us + MIN_YIELD_PERIOD;
+        }
+    }
+}
+
+
+static inline bool card_detect_target(void)
+{
+#ifdef HAVE_HOTSWAP
+#ifdef SANSA_E200
+    return (GPIOA_INPUT_VAL & 0x80) == 0; /* low active */
+#elif defined SANSA_C200
+    return (GPIOL_INPUT_VAL & 0x08) != 0; /* high active */
+#endif
+#else
+    return false;
+#endif
+}
+
+
+static inline void copy_read_sectors_fast(unsigned char **buf)
+{
+    /* Copy one chunk of 16 words using best method for start alignment */
+    switch ( (intptr_t)*buf & 3 )
+    {
+    case 0:
+        asm volatile (
+            "ldmia  %[data], { r2-r9 }          \r\n"
+            "orr    r2, r2, r3, lsl #16         \r\n"
+            "orr    r4, r4, r5, lsl #16         \r\n"
+            "orr    r6, r6, r7, lsl #16         \r\n"
+            "orr    r8, r8, r9, lsl #16         \r\n"
+            "stmia  %[buf]!, { r2, r4, r6, r8 } \r\n"
+            "ldmia  %[data], { r2-r9 }          \r\n"
+            "orr    r2, r2, r3, lsl #16         \r\n"
+            "orr    r4, r4, r5, lsl #16         \r\n"
+            "orr    r6, r6, r7, lsl #16         \r\n"
+            "orr    r8, r8, r9, lsl #16         \r\n"
+            "stmia  %[buf]!, { r2, r4, r6, r8 } \r\n"
+            : [buf]"+&r"(*buf)
+            : [data]"r"(&MMC_DATA_FIFO)
+            : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9"
+        );
+        break;
+    case 1:
+        asm volatile (
+            "ldmia  %[data], { r2-r9 }          \r\n"
+            "orr    r3, r2, r3, lsl #16         \r\n"
+            "strb   r3, [%[buf]], #1            \r\n"
+            "mov    r3, r3, lsr #8              \r\n"
+            "strh   r3, [%[buf]], #2            \r\n"
+            "mov    r3, r3, lsr #16             \r\n"
+            "orr    r3, r3, r4, lsl #8          \r\n"
+            "orr    r3, r3, r5, lsl #24         \r\n"
+            "mov    r5, r5, lsr #8              \r\n"
+            "orr    r5, r5, r6, lsl #8          \r\n"
+            "orr    r5, r5, r7, lsl #24         \r\n"
+            "mov    r7, r7, lsr #8              \r\n"
+            "orr    r7, r7, r8, lsl #8          \r\n"
+            "orr    r7, r7, r9, lsl #24         \r\n"
+            "mov    r2, r9, lsr #8              \r\n"
+            "stmia  %[buf]!, { r3, r5, r7 }     \r\n"
+            "ldmia  %[data], { r3-r10 }         \r\n"
+            "orr    r2, r2, r3, lsl #8          \r\n"
+            "orr    r2, r2, r4, lsl #24         \r\n"
+            "mov    r4, r4, lsr #8              \r\n"
+            "orr    r4, r4, r5, lsl #8          \r\n"
+            "orr    r4, r4, r6, lsl #24         \r\n"
+            "mov    r6, r6, lsr #8              \r\n"
+            "orr    r6, r6, r7, lsl #8          \r\n"
+            "orr    r6, r6, r8, lsl #24         \r\n"
+            "mov    r8, r8, lsr #8              \r\n"
+            "orr    r8, r8, r9, lsl #8          \r\n"
+            "orr    r8, r8, r10, lsl #24        \r\n"
+            "mov    r10, r10, lsr #8            \r\n"
+            "stmia  %[buf]!, { r2, r4, r6, r8 } \r\n"
+            "strb   r10, [%[buf]], #1           \r\n"
+            : [buf]"+&r"(*buf)
+            : [data]"r"(&MMC_DATA_FIFO)
+            : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
+        );
+        break;
+    case 2:
+        asm volatile (
+            "ldmia  %[data], { r2-r9 }          \r\n"
+            "strh   r2, [%[buf]], #2            \r\n"
+            "orr    r3, r3, r4, lsl #16         \r\n"
+            "orr    r5, r5, r6, lsl #16         \r\n"
+            "orr    r7, r7, r8, lsl #16         \r\n"
+            "stmia  %[buf]!, { r3, r5, r7 }     \r\n"
+            "ldmia  %[data], { r2-r8, r10 }     \r\n"
+            "orr    r2, r9, r2, lsl #16         \r\n"
+            "orr    r3, r3, r4, lsl #16         \r\n"
+            "orr    r5, r5, r6, lsl #16         \r\n"
+            "orr    r7, r7, r8, lsl #16         \r\n"
+            "stmia  %[buf]!, { r2, r3, r5, r7 } \r\n"
+            "strh   r10, [%[buf]], #2           \r\n"
+            : [buf]"+&r"(*buf)
+            : [data]"r"(&MMC_DATA_FIFO)
+            : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
+        );
+        break;
+    case 3:
+        asm volatile (
+            "ldmia  %[data], { r2-r9 }          \r\n"
+            "orr    r3, r2, r3, lsl #16         \r\n"
+            "strb   r3, [%[buf]], #1            \r\n"
+            "mov    r3, r3, lsr #8              \r\n"
+            "orr    r3, r3, r4, lsl #24         \r\n"
+            "mov    r4, r4, lsr #8              \r\n"
+            "orr    r5, r4, r5, lsl #8          \r\n"
+            "orr    r5, r5, r6, lsl #24         \r\n"
+            "mov    r6, r6, lsr #8              \r\n"
+            "orr    r7, r6, r7, lsl #8          \r\n"
+            "orr    r7, r7, r8, lsl #24         \r\n"
+            "mov    r8, r8, lsr #8              \r\n"
+            "orr    r2, r8, r9, lsl #8          \r\n"
+            "stmia  %[buf]!, { r3, r5, r7 }     \r\n"
+            "ldmia  %[data], { r3-r10 }         \r\n"
+            "orr    r2, r2, r3, lsl #24         \r\n"
+            "mov    r3, r3, lsr #8              \r\n"
+            "orr    r4, r3, r4, lsl #8          \r\n"
+            "orr    r4, r4, r5, lsl #24         \r\n"
+            "mov    r5, r5, lsr #8              \r\n"
+            "orr    r6, r5, r6, lsl #8          \r\n"
+            "orr    r6, r6, r7, lsl #24         \r\n"
+            "mov    r7, r7, lsr #8              \r\n"
+            "orr    r8, r7, r8, lsl #8          \r\n"
+            "orr    r8, r8, r9, lsl #24         \r\n"
+            "mov    r9, r9, lsr #8              \r\n"
+            "orr    r10, r9, r10, lsl #8        \r\n"
+            "stmia  %[buf]!, { r2, r4, r6, r8 } \r\n"
+            "strh   r10, [%[buf]], #2           \r\n"
+            "mov    r10, r10, lsr #16           \r\n"
+            "strb   r10, [%[buf]], #1           \r\n"
+            : [buf]"+&r"(*buf)
+            : [data]"r"(&MMC_DATA_FIFO)
+            : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
+        );
+        break;
+    }
+}
+
+static inline void copy_read_sectors_slow(unsigned char** buf)
+{
+    int cnt = FIFO_LEN;
+    int t;
+
+    /* Copy one chunk of 16 words */
+    asm volatile (
+    "1:                                     \r\n"
+        "ldrh   %[t], [%[data]]             \r\n"
+        "strb   %[t], [%[buf]], #1          \r\n"
+        "mov    %[t], %[t], lsr #8          \r\n"
+        "strb   %[t], [%[buf]], #1          \r\n"
+        "subs   %[cnt], %[cnt], #1          \r\n"
+        "bgt    1b                          \r\n"
+        : [cnt]"+&r"(cnt), [buf]"+&r"(*buf),
+          [t]"=&r"(t)
+        : [data]"r"(&MMC_DATA_FIFO)
+    );
+}
+
+/* Writes have to be kept slow for now */
+static inline void copy_write_sectors(const unsigned char** buf)
+{
+    int cnt = FIFO_LEN - 1;
+    unsigned t;
+    long time;
+
+    time = USEC_TIMER + 3;
+    if  (((intptr_t)*buf & 3) == 0)
+    {
+        asm volatile (
+            "ldmia  %[buf]!, { r3, r5, r7, r9 } \r\n"
+            "mov    r4, r3, lsr #16             \r\n" 
+            "mov    r6, r5, lsr #16             \r\n" 
+            "mov    r8, r7, lsr #16             \r\n" 
+            "mov    r10, r9, lsr #16            \r\n" 
+            "stmia  %[data], { r3-r10 }         \r\n"
+            "ldmia  %[buf]!, { r3, r5, r7, r9 } \r\n"
+            "mov    r4, r3, lsr #16             \r\n" 
+            "mov    r6, r5, lsr #16             \r\n" 
+            "mov    r8, r7, lsr #16             \r\n" 
+            "mov    %[t], r9, lsr #16           \r\n" 
+            "stmia  %[data], { r3-r9 }          \r\n"
+            : [buf]"+&r"(*buf), [t]"=&r"(t) 
+            : [data]"r"(&MMC_DATA_FIFO)
+            : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
+        );
+    }
+    else
+    {
+        do
+        {
+            t  = *(*buf)++;
+            t |= *(*buf)++ << 8;
+            MMC_DATA_FIFO = t;
+        } while (--cnt > 0); /* tail loop is faster */
+        t  = *(*buf)++;
+        t |= *(*buf)++ << 8;
+    }
+    /* Don't write the last word before at least 3 usec have elapsed since FIFO_EMPTY */
+    /* This prevents the 'two bytes inserted' bug. */
+
+    while (!TIME_AFTER(USEC_TIMER, time));
+    MMC_DATA_FIFO = t;
+}
+
+static int sd_select_bank(unsigned char bank)
+{
+    unsigned char card_data[FIFO_LEN*2];// FIFO_LEN words=FIFO_LEN*2 bytes
+    const unsigned char* write_buf;
+    int i, ret;
+
+    memset(card_data, 0, sizeof card_data);
+
+    ret = sd_wait_for_state(SD_TRAN, EC_TRAN_SEL_BANK);
+    if (ret < 0)
+        return ret;
+
+    MMC_BLKLEN = 512;
+    MMC_NUMBLK = 1;
+
+    ret = sd_command(35, 0, NULL, /* CMD35 is vendor specific */
+                     0x1c00 | CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
+    if (ret < 0)
+        return ret;
+
+    MMC_SD_STATE = SD_PRG;
+
+    card_data[0] = bank;
+
+    /* Write the card data */
+    for (i = 0; i < SD_BLOCK_SIZE/2; i += FIFO_LEN)
+    {
+        write_buf = card_data;
+        /* Wait for the FIFO to empty */
+        if (sd_poll_status(STAT_XMIT_FIFO_EMPTY, 10000))
+        {
+            copy_write_sectors(&write_buf); /* Copy one chunk of 16 words */
+            /* clear buffer: only the first chunk contains interesting data (bank), the remaining is zero filling */
+            memset(card_data, 0, sizeof card_data);
+            continue;
+        }
+
+        return -EC_FIFO_SEL_BANK_EMPTY;
+    }
+
+    if (!sd_poll_status(STAT_PRG_DONE, 10000))
+        return -EC_FIFO_SEL_BANK_DONE;
+
+    currcard->current_bank = bank;
+
+    return 0;
+}
+
+static void sd_card_mux(int card_no)
+{
+/* Set the current card mux */
+#if defined(SANSA_E200)
+    if (card_no == 0)
+    {
+        GPO32_VAL |= 0x4;
+
+        GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x7a);
+        GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x7a);
+        GPIO_SET_BITWISE(GPIOD_ENABLE,  0x1f);
+        GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x1f);
+        GPIO_SET_BITWISE(GPIOD_OUTPUT_EN,  0x1f);
+
+        outl((inl(0x70000014) & ~(0x3ffff)) | 0x255aa, 0x70000014);
+    }
+    else
+    {
+        GPO32_VAL &= ~0x4;
+
+        GPIO_CLEAR_BITWISE(GPIOD_ENABLE, 0x1f);
+        GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x1f);
+        GPIO_SET_BITWISE(GPIOA_ENABLE, 0x7a);
+        GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x7a);
+        GPIO_SET_BITWISE( GPIOA_OUTPUT_EN, 0x7a);
+
+        outl(inl(0x70000014) & ~(0x3ffff), 0x70000014);
+    }
+#elif defined(SANSA_C200)
+    if (card_no == 0)
+    {
+        GPO32_VAL |= 0x4;
+
+        GPIO_CLEAR_BITWISE(GPIOD_ENABLE, 0x1f);
+        GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x1f);
+        GPIO_SET_BITWISE(GPIOA_ENABLE, 0x7a);
+        GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x7a);
+        GPIO_SET_BITWISE( GPIOA_OUTPUT_EN, 0x7a);
+
+        outl(inl(0x70000014) & ~(0x3ffff), 0x70000014);
+    }
+    else
+    {
+        GPO32_VAL &= ~0x4;
+
+        GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x7a);
+        GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x7a);
+        GPIO_SET_BITWISE(GPIOD_ENABLE,  0x1f);
+        GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x1f);
+        GPIO_SET_BITWISE(GPIOD_OUTPUT_EN,  0x1f);
+
+        outl((inl(0x70000014) & ~(0x3ffff)) | 0x255aa, 0x70000014);
+    }
+#elif defined(PHILIPS_SA9200)
+    /* only 1 "card" (no external memory card) */
+    (void)card_no;
+
+    GPIO_SET_BITWISE(GPIOH_ENABLE, 0x80);
+    GPIO_SET_BITWISE(GPIOH_OUTPUT_EN, 0x80);
+
+    outl(0x255aa, 0x70000014);
+
+    GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x04);
+    GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x04);
+
+    GPIO_CLEAR_BITWISE(GPIOA_ENABLE, 0x7a);
+    GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x7a);
+
+    GPIO_SET_BITWISE(GPIOH_OUTPUT_VAL, 0x80);
+    GPIO_SET_BITWISE(GPIOH_OUTPUT_EN, 0x80);
+#endif
+}
+
+static void sd_init_device(int card_no)
+{
+/* SD Protocol registers */
+#ifdef HAVE_HOTSWAP
+    unsigned long response = 0;
+#endif
+    unsigned int  i;
+    unsigned char carddata[512];
+    unsigned char *dataptr;
+    unsigned long temp_reg[4];
+    int ret;
+
+/* Enable and initialise controller */
+    MMC_CLKRT = 6;  /* switch to lowest clock rate */
+
+/* Initialise card data as blank */
+    memset(currcard, 0, sizeof(*currcard));
+
+/* Switch card mux to card to initialize */
+    sd_card_mux(card_no);
+
+/* Init NAND */
+    MMC_INIT_1 |=  (1 << 15);
+    MMC_INIT_2 |=  (1 << 15);
+    MMC_INIT_2 &= ~(3 << 12);
+    MMC_INIT_2 |=  (1 << 13);
+    MMC_INIT_1 &= ~(3 << 12);
+    MMC_INIT_1 |=  (1 << 13);
+
+    DEV_EN |= DEV_ATA; /* Enable controller */
+    DEV_RS |= DEV_ATA; /* Reset controller */
+    DEV_RS &=~DEV_ATA; /* Clear Reset */
+
+    MMC_SD_STATE = SD_TRAN;
+
+    MMC_I_MASK = 0xf;  /* disable interrupts */
+
+    ret = sd_command(SD_GO_IDLE_STATE, 0, NULL, 0x100);
+    if (ret < 0)
+        goto card_init_error;
+
+    check_time[EC_POWER_UP] = USEC_TIMER;
+
+#ifdef HAVE_HOTSWAP
+    /* Check for SDHC:
+       - non-SDHC cards simply ignore SD_SEND_IF_COND (CMD8) and we get error -219,
+         which we can just ignore and assume we're dealing with standard SD.
+       - SDHC cards echo back the argument into the response. This is how we
+         tell if the card is SDHC.
+     */
+    ret = sd_command(SD_SEND_IF_COND,0x1aa, &response,
+                     CMDAT_DATA_EN | CMDAT_RES_TYPE3);
+    if ( (ret < 0) && (ret!=-219) )
+            goto card_init_error;
+#endif
+
+    while ((currcard->ocr & (1 << 31)) == 0) /* until card is powered up */
+    {
+        ret = sd_command(SD_APP_CMD, currcard->rca, NULL, CMDAT_RES_TYPE1);
+        if (ret < 0)
+            goto card_init_error;
+
+#ifdef HAVE_HOTSWAP
+        if(response == 0x1aa)
+        {
+            /* SDHC */
+            ret = sd_command(SD_APP_OP_COND, (1<<30)|0x100000,
+                             &currcard->ocr, CMDAT_RES_TYPE3);
+        }
+        else
+#endif /* HAVE_HOTSWAP */
+        {
+            /* SD Standard */
+            ret = sd_command(SD_APP_OP_COND, 0x100000, &currcard->ocr,
+                             CMDAT_RES_TYPE3);
+        }
+
+        if (ret < 0)
+            goto card_init_error;
+
+        if (!sd_check_timeout(5000000, EC_POWER_UP))
+        {
+            ret = -EC_POWER_UP;
+            goto card_init_error;
+        }
+    }
+
+    ret = sd_command(SD_ALL_SEND_CID, 0, temp_reg, CMDAT_RES_TYPE2);
+    if (ret < 0)
+        goto card_init_error;
+
+    for(i=0; i<4; i++)
+        currcard->cid[i] = temp_reg[3-i];
+
+    ret = sd_command(SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, CMDAT_RES_TYPE1);
+    if (ret < 0)
+        goto card_init_error;
+
+    ret = sd_command(SD_SEND_CSD, currcard->rca, temp_reg, CMDAT_RES_TYPE2);
+    if (ret < 0)
+        goto card_init_error;
+
+    for(i=0; i<4; i++)
+        currcard->csd[i] = temp_reg[3-i];
+
+    sd_parse_csd(currcard);
+    
+    MMC_CLKRT = 0;  /* switch to highest clock rate */
+
+    ret = sd_command(SD_SELECT_CARD, currcard->rca, NULL,
+                     0x80 | CMDAT_RES_TYPE1);
+    if (ret < 0)
+        goto card_init_error;
+
+    ret = sd_command(SD_APP_CMD, currcard->rca, NULL, CMDAT_RES_TYPE1);
+    if (ret < 0)
+        goto card_init_error;
+
+    ret = sd_command(SD_SET_BUS_WIDTH, currcard->rca | 2, NULL,
+                     CMDAT_RES_TYPE1); /* 4 bit */
+    if (ret < 0)
+        goto card_init_error;
+
+    ret = sd_command(SD_SET_BLOCKLEN, currcard->blocksize, NULL,
+                     CMDAT_RES_TYPE1);
+    if (ret < 0)
+        goto card_init_error;
+
+    MMC_BLKLEN = currcard->blocksize;
+
+    /* If this card is >4GB & not SDHC, then we need to enable bank switching */
+    if( (currcard->numblocks >= BLOCKS_PER_BANK) &&
+        ((currcard->ocr & (1<<30)) == 0) )
+    {
+        MMC_SD_STATE = SD_TRAN;
+        MMC_NUMBLK = 1;
+
+        ret = sd_command(SD_SWITCH_FUNC, 0x80ffffef, NULL,
+                         0x1c00 | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
+        if (ret < 0)
+            goto card_init_error;
+
+        /* Read 512 bytes from the card.
+        The first 512 bits contain the status information
+        TODO: Do something useful with this! */
+        dataptr = carddata;
+        for (i = 0; i < SD_BLOCK_SIZE/2; i += FIFO_LEN)
+        {
+            /* Wait for the FIFO to be full */
+            if (sd_poll_status(STAT_RECV_FIFO_FULL, 100000))
+            {
+                copy_read_sectors_slow(&dataptr);
+                continue;
+            }
+
+            ret = -EC_FIFO_ENA_BANK_EMPTY;
+            goto card_init_error;
+        }
+    }
+
+    currcard->initialized = 1;
+    return;
+
+    /* Card failed to initialize so disable it */
+card_init_error:
+    currcard->initialized = ret;
+}
+
+/* lock must already be aquired */
+static void sd_select_device(int card_no)
+{
+    currcard = &card_info[card_no];
+
+    if (card_no == 0)
+    {
+        /* Main card always gets a chance */
+        sd_status[0].retry = 0;
+    }
+
+    if (currcard->initialized > 0)
+    {
+        /* This card is already initialized - switch to it */
+        sd_card_mux(card_no);
+        return;
+    }
+
+    if (currcard->initialized == 0)
+    {
+        /* Card needs (re)init */
+        sd_init_device(card_no);
+    }
+}
+
+/* API Functions */
+
+int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
+                     void* inbuf)
+{
+#ifndef HAVE_MULTIDRIVE
+    const int drive = 0;
+#endif
+    int ret;
+    unsigned char *buf, *buf_end;
+    unsigned int bank;
+    
+    /* TODO: Add DMA support. */
+
+    mutex_lock(&sd_mtx);
+    sd_enable(true);
+    led(true);
+
+sd_read_retry:
+    if (drive != 0 && !card_detect_target())
+    {
+        /* no external sd-card inserted */
+        ret = -EC_NOCARD;
+        goto sd_read_error;
+    }
+
+    sd_select_device(drive);
+
+    if (currcard->initialized < 0)
+    {
+        ret = currcard->initialized;
+        goto sd_read_error;
+    }
+
+    last_disk_activity = current_tick;
+
+    /* Only switch banks with non-SDHC cards */
+    if((currcard->ocr & (1<<30))==0)
+    {
+        bank = start / BLOCKS_PER_BANK;
+
+        if (currcard->current_bank != bank)
+        {
+            ret = sd_select_bank(bank);
+            if (ret < 0)
+                goto sd_read_error;
+        }
+    
+        start -= bank * BLOCKS_PER_BANK;
+    }
+
+    ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_ENTRY);
+    if (ret < 0)
+        goto sd_read_error;
+
+    MMC_NUMBLK = incount;
+
+#ifdef HAVE_HOTSWAP
+    if(currcard->ocr & (1<<30) )
+    {
+        /* SDHC */
+        ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL,
+                         0x1c00 | CMDAT_BUSY | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
+    }
+    else
+#endif
+    {
+        ret = sd_command(SD_READ_MULTIPLE_BLOCK, start * SD_BLOCK_SIZE, NULL,
+                         0x1c00 | CMDAT_BUSY | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
+    }
+    if (ret < 0)
+        goto sd_read_error;
+
+    /* TODO: Don't assume SD_BLOCK_SIZE == SECTOR_SIZE */
+
+    buf_end = (unsigned char *)inbuf + incount * currcard->blocksize;
+    for (buf = inbuf; buf < buf_end;)
+    {
+        /* Wait for the FIFO to be full */
+        if (sd_poll_status(STAT_RECV_FIFO_FULL, 0x80000))
+        {
+            copy_read_sectors_fast(&buf); /* Copy one chunk of 16 words */
+            /* TODO: Switch bank if necessary */
+            continue;
+        }
+
+        ret = -EC_FIFO_READ_FULL;
+        goto sd_read_error;
+    }
+
+    last_disk_activity = current_tick;
+
+    ret = sd_command(SD_STOP_TRANSMISSION, 0, NULL, CMDAT_RES_TYPE1);
+    if (ret < 0)
+        goto sd_read_error;
+
+    ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_EXIT);
+    if (ret < 0)
+        goto sd_read_error;
+
+    while (1)
+    {
+        led(false);
+        sd_enable(false);
+        mutex_unlock(&sd_mtx);
+
+        return ret;
+
+sd_read_error:
+        if (sd_status[drive].retry < sd_status[drive].retry_max
+            && ret != -EC_NOCARD)
+        {
+            sd_status[drive].retry++;
+            currcard->initialized = 0;
+            goto sd_read_retry;
+        }
+    }
+}
+
+int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
+                      const void* outbuf)
+{
+/* Write support is not finished yet */
+/* TODO: The standard suggests using ACMD23 prior to writing multiple blocks
+   to improve performance */
+#ifndef HAVE_MULTIDRIVE
+    const int drive = 0;
+#endif
+    int ret;
+    const unsigned char *buf, *buf_end;
+    unsigned int bank;
+
+    mutex_lock(&sd_mtx);
+    sd_enable(true);
+    led(true);
+
+sd_write_retry:
+    if (drive != 0 && !card_detect_target())
+    {
+        /* no external sd-card inserted */
+        ret = -EC_NOCARD;
+        goto sd_write_error;
+    }
+
+    sd_select_device(drive);
+
+    if (currcard->initialized < 0)
+    {
+        ret = currcard->initialized;
+        goto sd_write_error;
+    }
+
+    /* Only switch banks with non-SDHC cards */
+    if((currcard->ocr & (1<<30))==0)
+    {
+        bank = start / BLOCKS_PER_BANK;
+
+        if (currcard->current_bank != bank)
+        {
+            ret = sd_select_bank(bank);
+            if (ret < 0)
+                goto sd_write_error;
+        }
+    
+        start -= bank * BLOCKS_PER_BANK;
+    }
+
+    check_time[EC_WRITE_TIMEOUT] = USEC_TIMER;
+
+    ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_ENTRY);
+    if (ret < 0)
+        goto sd_write_error;
+
+    MMC_NUMBLK = count;
+
+#ifdef HAVE_HOTSWAP
+    if(currcard->ocr & (1<<30) )
+    {
+        /* SDHC */
+        ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL,
+                         CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
+    }
+    else
+#endif
+    {
+        ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start*SD_BLOCK_SIZE, NULL,
+                         CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1);
+    }
+    if (ret < 0)
+        goto sd_write_error;
+
+    buf_end = outbuf + count * currcard->blocksize - 2*FIFO_LEN;
+
+    for (buf = outbuf; buf <= buf_end;)
+    {
+        if (buf == buf_end)
+        {
+            /* Set MMC_SD_STATE to SD_PRG for the last buffer fill */
+            MMC_SD_STATE = SD_PRG;
+        }
+
+        copy_write_sectors(&buf); /* Copy one chunk of 16 words */
+        /* TODO: Switch bank if necessary */
+
+        /* Wait for the FIFO to empty */
+        if (!sd_poll_status(STAT_XMIT_FIFO_EMPTY, 0x80000))
+        {
+            ret = -EC_FIFO_WR_EMPTY;
+            goto sd_write_error;
+        }
+    }
+
+    last_disk_activity = current_tick;
+
+    if (!sd_poll_status(STAT_PRG_DONE, 0x80000))
+    {
+        ret = -EC_FIFO_WR_DONE;
+        goto sd_write_error;
+    }
+
+    ret = sd_command(SD_STOP_TRANSMISSION, 0, NULL, CMDAT_RES_TYPE1);
+    if (ret < 0)
+        goto sd_write_error;
+
+    ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_EXIT);
+    if (ret < 0)
+        goto sd_write_error;
+
+    while (1)
+    {
+        led(false);
+        sd_enable(false);
+        mutex_unlock(&sd_mtx);
+
+        return ret;
+
+sd_write_error:
+        if (sd_status[drive].retry < sd_status[drive].retry_max
+            && ret != -EC_NOCARD)
+        {
+            sd_status[drive].retry++;
+            currcard->initialized = 0;
+            goto sd_write_retry;
+        }
+    }
+}
+
+#ifndef SD_DRIVER_CLOSE
+static void sd_thread(void) NORETURN_ATTR;
+#endif
+static void sd_thread(void)
+{
+    struct queue_event ev;
+    bool idle_notified = false;
+    
+    while (1)
+    {
+        queue_wait_w_tmo(&sd_queue, &ev, HZ);
+
+        switch ( ev.id ) 
+        {
+#ifdef HAVE_HOTSWAP
+        case SYS_HOTSWAP_INSERTED:
+        case SYS_HOTSWAP_EXTRACTED:
+            fat_lock();          /* lock-out FAT activity first -
+                                    prevent deadlocking via disk_mount that
+                                    would cause a reverse-order attempt with
+                                    another thread */
+            mutex_lock(&sd_mtx); /* lock-out card activity - direct calls
+                                    into driver that bypass the fat cache */
+
+            /* We now have exclusive control of fat cache and ata */
+
+            disk_unmount(sd_first_drive+1); /* release "by force", ensure file
+                                        descriptors aren't leaked and any busy
+                                        ones are invalid if mounting */
+
+            /* Force card init for new card, re-init for re-inserted one or
+             * clear if the last attempt to init failed with an error. */
+            card_info[1].initialized = 0;
+            sd_status[1].retry = 0; 
+
+            if (ev.id == SYS_HOTSWAP_INSERTED)
+                disk_mount(sd_first_drive+1);
+
+            queue_broadcast(SYS_FS_CHANGED, 0);
+
+            /* Access is now safe */
+            mutex_unlock(&sd_mtx);
+            fat_unlock();
+            break;
+#endif
+        case SYS_TIMEOUT:
+            if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
+            {
+                idle_notified = false;
+            }
+            else
+            {
+                /* never let a timer wrap confuse us */
+                next_yield = USEC_TIMER;
+
+                if (!idle_notified)
+                {
+                    call_storage_idle_notifys(false);
+                    idle_notified = true;
+                }
+            }
+            break;
+        case SYS_USB_CONNECTED:
+            usb_acknowledge(SYS_USB_CONNECTED_ACK);
+            /* Wait until the USB cable is extracted again */
+            usb_wait_for_disconnect(&sd_queue);
+            break;
+
+#ifdef SD_DRIVER_CLOSE
+        case Q_CLOSE:
+            return;
+#endif
+        }
+    }
+}
+
+#ifdef SD_DRIVER_CLOSE
+void sd_close(void)
+{
+    unsigned int thread_id = sd_thread_id;
+    
+    if (thread_id == 0)
+        return;
+
+    sd_thread_id = 0;
+
+    queue_post(&sd_queue, Q_CLOSE, 0);
+    thread_wait(thread_id);
+}
+#endif /* SD_DRIVER_CLOSE */
+
+void sd_enable(bool on)
+{
+    if(on)
+    {
+        DEV_EN |= DEV_ATA; /* Enable controller */
+    }
+    else
+    {
+        DEV_EN &= ~DEV_ATA; /* Disable controller */
+    }
+}
+
+
+int sd_init(void)
+{
+    int ret = 0;
+
+    if (!initialized)
+        mutex_init(&sd_mtx);
+
+    mutex_lock(&sd_mtx);
+
+    led(false);
+
+    if (!initialized)
+    {
+        initialized = true;
+
+        /* init controller */
+#if defined(PHILIPS_SA9200)
+        GPIOA_ENABLE = 0x00;
+        GPIO_SET_BITWISE(GPIOD_ENABLE, 0x01);
+#else
+        outl(inl(0x70000088) & ~(0x4), 0x70000088);
+        outl(inl(0x7000008c) & ~(0x4), 0x7000008c);
+        GPO32_ENABLE |= 0x4;
+
+        GPIO_SET_BITWISE(GPIOG_ENABLE, (0x3 << 5));
+        GPIO_SET_BITWISE(GPIOG_OUTPUT_EN, (0x3 << 5));
+        GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, (0x3 << 5));
+#endif
+
+#ifdef HAVE_HOTSWAP
+        /* enable card detection port - mask interrupt first */
+#ifdef SANSA_E200
+        GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80);
+
+        GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_EN, 0x80);
+        GPIO_SET_BITWISE(GPIOA_ENABLE, 0x80);
+#elif defined SANSA_C200
+        GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08);
+
+        GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_EN, 0x08);
+        GPIO_SET_BITWISE(GPIOL_ENABLE, 0x08);
+#endif
+#endif
+        sd_select_device(0);
+
+        if (currcard->initialized < 0)
+            ret = currcard->initialized;
+
+        queue_init(&sd_queue, true);
+        sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack),
+            0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
+            IF_COP(, CPU));
+
+        /* enable interupt for the mSD card */
+        sleep(HZ/10);
+#ifdef HAVE_HOTSWAP
+#ifdef SANSA_E200
+        CPU_INT_EN = HI_MASK;
+        CPU_HI_INT_EN = GPIO0_MASK;
+
+        GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80);
+
+        GPIOA_INT_CLR = 0x80;
+
+        /* enable the card detect interrupt */
+        GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80);
+#elif defined SANSA_C200
+        CPU_INT_EN = HI_MASK;
+        CPU_HI_INT_EN = GPIO2_MASK;
+
+        GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08);
+
+        GPIOL_INT_CLR = 0x08;
+    
+        /* enable the card detect interrupt */
+        GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08);
+#endif
+#endif
+    }
+
+    mutex_unlock(&sd_mtx);
+
+    return ret;
+}
+
+tCardInfo *card_get_info_target(int card_no)
+{
+    return &card_info[card_no];
+}
+#ifdef HAVE_HOTSWAP
+static int sd1_oneshot_callback(struct timeout *tmo)
+{
+    (void)tmo;
+
+    /* This is called only if the state was stable for 300ms - check state
+     * and post appropriate event. */
+    if (card_detect_target())
+        queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
+    else
+        queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
+
+    return 0;
+}
+
+/* called on insertion/removal interrupt */
+void microsd_int(void)
+{
+    static struct timeout sd1_oneshot;
+
+#ifdef SANSA_E200
+    GPIO_CLEAR_BITWISE(GPIOA_INT_EN, 0x80);
+    GPIOA_INT_LEV = (0x80 << 8) | (~GPIOA_INPUT_VAL & 0x80);
+    GPIOA_INT_CLR = 0x80;
+    GPIO_SET_BITWISE(GPIOA_INT_EN, 0x80);
+
+#elif defined SANSA_C200
+    GPIO_CLEAR_BITWISE(GPIOL_INT_EN, 0x08);
+    GPIOL_INT_LEV = (0x08 << 8) | (~GPIOL_INPUT_VAL & 0x08);
+    GPIOL_INT_CLR = 0x08;
+    GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08);
+#endif
+    timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0);
+}
+#endif /* HAVE_HOTSWAP */
+
+long sd_last_disk_activity(void)
+{
+    return last_disk_activity;
+}
+
+#ifdef HAVE_HOTSWAP
+bool sd_removable(IF_MD_NONVOID(int drive))
+{
+#ifndef HAVE_MULTIDRIVE
+    const int drive=0;
+#endif
+    return (drive==1);
+}
+
+bool sd_present(IF_MD_NONVOID(int drive))
+{
+#ifndef HAVE_MULTIDRIVE
+    const int drive=0;
+#endif
+    if(drive==0)
+    {
+        return true;
+    }
+    else
+    {
+        return card_detect_target();
+    }
+}
+#endif
+
+#ifdef CONFIG_STORAGE_MULTI
+int sd_num_drives(int first_drive)
+{
+#ifdef HAVE_HOTSWAP
+    /* Store which logical drive number(s) we have been assigned */
+    sd_first_drive = first_drive;
+#else
+    (void)first_drive;
+#endif
+    
+#ifdef HAVE_MULTIDRIVE
+    return 2;
+#else
+    return 1;
+#endif
+}
+#endif
diff --git a/firmware/target/arm/portalplayer/ata-target.h b/firmware/target/arm/portalplayer/ata-target.h
new file mode 100644
index 0000000..779ebed
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ata-target.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifdef CPU_PP
+
+#ifdef HAVE_BOOTLOADER_USB_MODE
+#define ATA_DRIVER_CLOSE
+#endif
+
+/* primary channel */
+#define ATA_DATA        (*((volatile unsigned short*)(IDE_BASE + 0x1e0)))
+#define ATA_ERROR       (*((volatile unsigned char*)(IDE_BASE + 0x1e4)))
+#define ATA_NSECTOR     (*((volatile unsigned char*)(IDE_BASE + 0x1e8)))
+#define ATA_SECTOR      (*((volatile unsigned char*)(IDE_BASE + 0x1ec)))
+#define ATA_LCYL        (*((volatile unsigned char*)(IDE_BASE + 0x1f0)))
+#define ATA_HCYL        (*((volatile unsigned char*)(IDE_BASE + 0x1f4)))
+#define ATA_SELECT      (*((volatile unsigned char*)(IDE_BASE + 0x1f8)))
+#define ATA_COMMAND     (*((volatile unsigned char*)(IDE_BASE + 0x1fc)))
+#define ATA_CONTROL     (*((volatile unsigned char*)(IDE_BASE + 0x3f8)))
+
+#if (CONFIG_CPU == PP5002)
+
+#define ATA_OUT8(reg,val) do { reg = (val); \
+                              while (!(IDE_CFG_STATUS & 0x40)); \
+                          } while (0)
+
+/* Plain C reading and writing. See comment in ata-as-arm.S */
+
+#elif defined CPU_PP502x
+
+/* asm optimized reading and writing */
+#define ATA_OPTIMIZED_READING
+#define ATA_OPTIMIZED_WRITING
+void copy_read_sectors(unsigned char* buf, int wordcount);
+void copy_write_sectors(const unsigned char* buf, int wordcount);
+
+#endif /* CONFIG_CPU */
+
+#endif
+
+void ata_reset(void);
+bool ata_is_coldstart(void);
+void ata_device_init(void);
+
+#ifdef HAVE_ATA_DMA
+
+/* IDE DMA controller registers */
+#define IDE_DMA_CONTROL (*(volatile unsigned long *)(0xc3000400))
+#define IDE_DMA_LENGTH  (*(volatile unsigned long *)(0xc3000408))
+#define IDE_DMA_ADDR    (*(volatile unsigned long *)(0xc300040C))
+
+/* Maximum multi-word DMA mode supported by the controller */
+#define ATA_MAX_MWDMA 2
+
+#ifndef BOOTLOADER    
+/* The PP5020 supports UDMA 4, but it needs cpu boosting and only
+ * improves performance by ~10% with a stock disk.
+ * UDMA 2 is stable at 30 Mhz.
+ * UDMA 1 is stable at 24 Mhz.
+ */
+#if CPUFREQ_NORMAL >= 30000000
+#define ATA_MAX_UDMA 2
+#elif CPUFREQ_NORMAL >= 24000000
+#define ATA_MAX_UDMA 1
+#else
+#error "CPU speeds under 24Mhz have not been tested with DMA"
+#endif
+#else
+/* The bootloader runs at 24 Mhz and needs a slower mode */
+#define ATA_MAX_UDMA 1
+#endif
+
+void ata_dma_set_mode(unsigned char mode);
+bool ata_dma_setup(void *addr, unsigned long bytes, bool write);
+bool ata_dma_finish(void);
+
+#endif /* HAVE_ATA_DMA */
diff --git a/firmware/target/arm/portalplayer/audio-pp.c b/firmware/target/arm/portalplayer/audio-pp.c
new file mode 100644
index 0000000..6b5b082
--- /dev/null
+++ b/firmware/target/arm/portalplayer/audio-pp.c
@@ -0,0 +1,135 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Michael Sevakis
+ *
+ * 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 "system.h"
+#include "cpu.h"
+#include "audio.h"
+#include "sound.h"
+
+#if INPUT_SRC_CAPS != 0
+void audio_set_output_source(int source)
+{
+    if ((unsigned)source >= AUDIO_NUM_SOURCES)
+        source = AUDIO_SRC_PLAYBACK;
+} /* audio_set_output_source */
+
+void audio_input_mux(int source, unsigned flags)
+{
+    (void)flags;
+    /* Prevent pops from unneeded switching */
+    static int last_source = AUDIO_SRC_PLAYBACK;
+#ifdef HAVE_FMRADIO_REC 
+    bool recording = flags & SRCF_RECORDING;
+    static bool last_recording = false;
+#endif
+
+#if defined(IPOD_COLOR) || defined (IPOD_4G)
+    /* The usual magic from IPL - I'm guessing this configures the headphone
+       socket to be input or output. */
+    if ((flags & SRCF_RECORDING) && source != AUDIO_SRC_PLAYBACK)
+    {
+        /* input */
+        GPIO_CLEAR_BITWISE(GPIOI_OUTPUT_VAL, 0x40);
+        GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_VAL, 0x04);
+    }
+    else
+    {
+        /* output */
+        GPIO_SET_BITWISE(GPIOI_OUTPUT_VAL, 0x40);
+        GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x04);
+    }
+#endif /* IPOD_COLOR || IPOD_4G */
+
+    switch (source)
+    {
+        default:                        /* playback - no recording */
+            source = AUDIO_SRC_PLAYBACK;
+        case AUDIO_SRC_PLAYBACK:
+#ifdef HAVE_RECORDING
+            if (source != last_source)
+            {
+                audiohw_set_monitor(false);
+                audiohw_disable_recording();
+            }
+#endif
+        break;
+#ifdef HAVE_MIC_REC
+        case AUDIO_SRC_MIC:             /* recording only */
+            if (source != last_source)
+            {
+                audiohw_set_monitor(false);
+                audiohw_enable_recording(true);  /* source mic */
+            }
+        break;
+#endif
+#ifdef HAVE_LINE_REC
+        case AUDIO_SRC_LINEIN:          /* recording only */
+#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
+            /* Switch line in source to line-in */
+            GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x04);
+#endif
+            if (source != last_source)
+            {
+                audiohw_set_monitor(false);
+                audiohw_enable_recording(false); /* source line */
+            }
+        break;
+#endif
+#ifdef HAVE_FMRADIO_REC
+        case AUDIO_SRC_FMRADIO:         /* recording and playback */
+#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
+            /* Switch line in source to tuner */
+            GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x04);
+            /* Set line-in vol to +12dB, which is proper for H10's */
+            if (!recording)
+                audiohw_set_recvol(0x1f, 0x1f, AUDIO_GAIN_LINEIN);
+#else            /* Set line-in vol to 0dB*/
+            if (!recording)
+                audiohw_set_recvol(0x17, 0x17, AUDIO_GAIN_LINEIN);
+#endif
+
+            if (source == last_source && recording == last_recording)
+                break;
+
+            last_recording = recording;
+
+#if CONFIG_TUNER & IPOD_REMOTE_TUNER
+            /* Ipod FM tuner is in the remote connected to line-in */
+                audiohw_enable_recording(false); /* source line */
+                audiohw_set_monitor(true);  /* enable bypass mode */
+#else
+            if (recording)
+            {
+                audiohw_set_monitor(false);  /* disable bypass mode */
+                audiohw_enable_recording(false); /* select line-in source */
+            }
+            else
+            {
+                audiohw_disable_recording();
+                audiohw_set_monitor(true);  /* enable bypass mode */
+            }
+#endif
+        break;
+#endif
+    } /* end switch */
+
+    last_source = source;
+} /* audio_input_mux */
+#endif /* INPUT_SRC_CAPS != 0 */
diff --git a/firmware/target/arm/portalplayer/boot-pp502x-bl-usb.lds b/firmware/target/arm/portalplayer/boot-pp502x-bl-usb.lds
new file mode 100644
index 0000000..d308584
--- /dev/null
+++ b/firmware/target/arm/portalplayer/boot-pp502x-bl-usb.lds
@@ -0,0 +1,136 @@
+/* Will have been included from boot.lds */
+ENTRY(start)
+OUTPUT_FORMAT(elf32-littlearm)
+OUTPUT_ARCH(arm)
+STARTUP(target/arm/portalplayer/crt0-pp502x-bl-usb.o)
+
+#define DRAMORIG        0x01000000 /* Load at 16 MB */
+#define DRAMSIZE        0x00100000 /* 1MB for bootloader */
+#define MEMEND          (MEMORYSIZE*0x100000) /* From virtual mapping at 0 */
+#define NOCACHE_BASE    0x10000000
+#ifndef IRAMORIG
+#define IRAMORIG 0x40000000
+#endif
+#define IRAMSIZE 0x20000
+#define FLASHORIG 0x001f0000
+#define FLASHSIZE 2M
+
+#define CACHEALIGN_SIZE 16
+
+MEMORY
+{
+    DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
+    IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
+}
+
+SECTIONS
+{
+    . = DRAMORIG;
+    _loadaddress = . + NOCACHE_BASE;
+
+    .text :
+    {
+        *(.init.text)
+        *(.text*)
+        *(.glue_7)
+        *(.glue_7t)
+        . = ALIGN(0x4);
+    } > DRAM
+
+    .rodata :
+    {
+        *(.rodata)  /* problems without this, dunno why */
+        *(.rodata*)
+        *(.rodata.str1.1)
+        *(.rodata.str1.4)
+        . = ALIGN(0x4);
+    } > DRAM
+
+    .data :
+    {
+        *(.data*)
+        . = ALIGN(0x4);
+    } > DRAM
+
+    /* .ncdata section is placed at uncached physical alias address and is
+     * loaded at the proper cached virtual address - no copying is
+     * performed in the init code */
+    .ncdata . + NOCACHE_BASE :
+    {
+        . = ALIGN(CACHEALIGN_SIZE);
+        *(.ncdata*)
+        . = ALIGN(CACHEALIGN_SIZE);
+    } AT> DRAM
+
+    /DISCARD/ . - NOCACHE_BASE :
+    {
+        *(.eh_frame)
+    } > DRAM
+
+    _noloaddram  = .;
+
+    .ibss IRAMORIG (NOLOAD) :
+    {
+        _iedata = .;
+        *(.qharray)
+        *(.ibss)
+        . = ALIGN(0x4);
+        _iend = .;
+    } > IRAM
+
+    .iram _iend :
+    {
+        _iramstart = .;
+        *(.icode)
+        *(.irodata)
+        *(.idata)
+        _iramend = .;
+    } > IRAM AT> DRAM
+
+    _iramcopy = LOADADDR(.iram);
+
+    .loadaddressend :
+    {
+        _loadaddressend = . + NOCACHE_BASE;
+    } AT> DRAM
+
+    .stack (NOLOAD) :
+    {
+        . = ALIGN(8);
+        *(.stack)
+        stackbegin = .;
+        . += 0x2000;
+        stackend = .;
+    } > IRAM
+
+    /* .bss and .ncbss are treated as a single section to use one init loop
+     * to zero them - note "_edata" and "_end" */
+    .bss _noloaddram (NOLOAD) :
+    {
+        _edata = .;
+        *(.bss*)
+        *(COMMON)
+    } > DRAM
+
+    .ncbss . + NOCACHE_BASE (NOLOAD) :
+    {
+        . = ALIGN(CACHEALIGN_SIZE);
+        *(.ncbss*)
+        . = ALIGN(CACHEALIGN_SIZE);
+    } AT> DRAM
+
+    /* This will be aligned by preceding alignments */
+    .endaddr . - NOCACHE_BASE (NOLOAD) :
+    {
+        _end = .;
+    } > DRAM
+
+    /* Reference to all DRAM after loaded bootloader image */
+    .freebuffer _end (NOLOAD) :
+    {
+        . = ALIGN(4);
+        freebuffer = .;
+        . = MEMEND-1;
+        freebufferend = .;
+    }
+}
diff --git a/firmware/target/arm/portalplayer/crt0-pp-bl.S b/firmware/target/arm/portalplayer/crt0-pp-bl.S
new file mode 100644
index 0000000..0168128
--- /dev/null
+++ b/firmware/target/arm/portalplayer/crt0-pp-bl.S
@@ -0,0 +1,217 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * 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"
+
+    .section .init.text,"ax",%progbits
+
+    .global    start
+start:
+
+/* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux 
+ * loader
+ *
+ * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
+ * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
+ *
+ */
+#if CONFIG_CPU == PP5002
+    .equ    PROC_ID,     0xc4000000
+    .equ    CPU_CTRL,    0xcf004054
+    .equ    CPU_STATUS,  0xcf004050
+    .equ    COP_CTRL,    0xcf004058
+    .equ    COP_STATUS,  0xcf004050
+    .equ    IIS_CONFIG,  0xc0002500
+    .equ    SLEEP,       0xca
+    .equ    WAKE,        0xce
+    .equ    CPUSLEEPING, 0x8000
+    .equ    COPSLEEPING, 0x4000
+    .equ    CACHE_CTRL,  0xcf004024
+    .equ    CACHE_ENAB,  0x2 /* Actually the CACHE_CTL_INIT flag */
+#else
+    .equ    PROC_ID,     0x60000000
+    .equ    CPU_CTRL,    0x60007000
+    .equ    CPU_STATUS,  0x60007000
+    .equ    COP_CTRL,    0x60007004
+    .equ    COP_STATUS,  0x60007004
+    .equ    IIS_CONFIG,  0x70002800
+    .equ    SLEEP,       0x80000000
+    .equ    WAKE,        0x0
+    .equ    CPUSLEEPING, 0x80000000
+    .equ    COPSLEEPING, 0x80000000
+    .equ    CACHE_CTRL,  0x6000c000
+    .equ    CACHE_ENAB,  0x1
+#endif
+
+    msr    cpsr_c, #0xdf /* enter sys mode, disable IRQ */
+#ifndef E200R_INSTALLER
+/* 1 - Copy the bootloader to IRAM */
+    /* get the high part of our execute address */
+    bic    r0, pc, #0xff /* r4 = pc & 0xffffff00 */
+
+    /* Copy bootloader to safe area - 0x40000000 (IRAM) */
+    mov    r1, #0x40000000
+    ldr    r2, =_dataend
+1:
+    cmp    r2, r1
+    ldrhi  r3, [r0], #4
+    strhi  r3, [r1], #4
+    bhi    1b
+
+#ifndef IPOD_ARCH
+    /* For builds on targets with mi4 firmware, scramble writes data to 
+       0xe0-0xeb, so jump past that. pad_skip must then exist at an
+       address >= 0xec */
+    b      pad_skip
+
+.space 60*4 
+
+pad_skip:
+#endif /* IPOD_ARCH */
+
+
+/* 2 - Jump both CPU and COP there */
+    ldr    pc, =start_loc    /* jump to the relocated start_loc:  */
+#endif /* E200R_INSTALLER */
+
+start_loc:
+    /* Find out which processor we are */
+    ldr    r0, =PROC_ID
+    ldrb   r0, [r0]
+    cmp    r0, #0x55
+    beq    cpu
+
+cop:
+    /* put us (co-processor) to sleep */
+    ldr    r0, =COP_CTRL
+    mov    r1, #SLEEP
+    str    r1, [r0]
+    nop
+    nop
+    
+    /* Invalidate cache */
+    mov    r0, #1
+    bl     cache_op
+
+    ldr    r0, =startup_loc
+    ldr    pc, [r0]
+
+cpu:
+    /* Wait for COP to be sleeping */
+    ldr    r0, =COP_STATUS
+1:
+    ldr    r1, [r0]
+    tst    r1, #COPSLEEPING
+    beq    1b
+    
+    /* Initialise bss section to zero */
+    ldr    r0, =_edata
+    ldr    r1, =_end
+    mov    r2, #0
+1:
+    cmp    r1, r0
+    strhi  r2, [r0], #4
+    bhi    1b
+       
+    /* Set up some stack and munge it with 0xdeadbeef */
+    ldr    sp, =stackend
+    ldr    r0, =stackbegin
+    ldr    r1, =0xdeadbeef
+1:
+    cmp    sp, r0
+    strhi  r1, [r0], #4
+    bhi    1b
+
+    /* execute the loader - this will load an image to 0x10000000 */
+    bl     main
+
+    /* store actual startup location returned by main() */
+    ldr    r1, =startup_loc
+    str    r0, [r1]
+
+    /* flush cache */    
+    mov    r0, #0
+    bl     cache_op
+
+    /* Wake up the coprocessor before executing the firmware */
+    ldr    r0, =COP_CTRL
+    mov    r1, #WAKE
+    str    r1, [r0]
+
+#if defined(SANSA_C200) || defined(PHILIPS_HDD1630)
+    /* Magic for loading the c200 OF */
+    ldr    r0, =0xb00d10ad
+    mov    r1, #0x700
+    ldr    r2, =0xfff0
+    mov    r3, #0x7
+#endif
+
+#if defined(PHILIPS_HDD6330)
+    /* Magic for loading the HDD6XX0 OF */
+    ldr    r0, =0xb00d10ad
+    mov    r1, #0x800
+    ldr    r2, =0xfff0
+    mov    r3, #0x7
+#endif
+
+    ldr    r4, =startup_loc
+    ldr    pc, [r4]
+
+startup_loc:
+    .word    0x0
+    
+#ifdef IPOD_ARCH
+.align 8    /* starts at 0x100 */
+.global boot_table
+boot_table:
+    /* here comes the boot table, don't move its offset - preceding
+       code+data must stay <= 256 bytes */
+    .space 400
+#endif
+
+cache_op:
+    ldr    r2, =CACHE_CTRL
+    ldr    r1, [r2]
+    tst    r1, #CACHE_ENAB
+    bxeq   lr
+    cmp    r0, #0
+#ifdef CPU_PP502x
+    ldr    r0, =0xf000f044
+    ldr    r1, [r0]
+    orrne  r1, r1, #0x6
+    orreq  r1, r1, #0x2
+    str    r1, [r0]
+1:
+    ldr    r1, [r2]
+    tst    r1, #0x8000
+    bne    1b
+#elif CONFIG_CPU == PP5002
+    ldrne  r0, =0xf0004000
+    ldreq  r0, =0xf000c000
+    add    r1, r0, #0x2000
+    mov    r2, #0
+1:
+    cmp    r1, r0
+    strhi  r2, [r0], #16
+    bhi    1b
+#endif /* CPU type */
+    bx     lr
+
diff --git a/firmware/target/arm/portalplayer/crt0-pp.S b/firmware/target/arm/portalplayer/crt0-pp.S
new file mode 100644
index 0000000..4a9d423
--- /dev/null
+++ b/firmware/target/arm/portalplayer/crt0-pp.S
@@ -0,0 +1,430 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * 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"
+
+    .section .init.text,"ax",%progbits
+
+    .global    start
+start:
+
+/* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux 
+ * loader
+ *
+ * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
+ * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
+ *
+ */
+#if CONFIG_CPU == PP5002
+    .equ    PROC_ID,     0xc4000000
+    .equ    CPU_ICLR,    0xcf001028
+    .equ    CPU_CTRL,    0xcf004054
+    .equ    COP_ICLR,    0xcf001038
+    .equ    COP_CTRL,    0xcf004058
+    .equ    CPU_STATUS,  0xcf004050
+    .equ    COP_STATUS,  0xcf004050
+    .equ    SLEEP,       0x000000ca
+    .equ    WAKE,        0x000000ce
+    .equ    CPUSLEEPING, 0x00008000
+    .equ    COPSLEEPING, 0x00004000
+    .equ    CACHE_CTRL,  0xcf004024
+    .equ    MMAP_LOG,    0xf000f000 /* MMAP0 */
+    .equ    MMAP_PHYS,   0xf000f004
+#if MEMORYSIZE > 32
+    .equ    MMAP_MASK,   0x00003c00
+#else
+    .equ    MMAP_MASK,   0x00003e00
+#endif
+    .equ    MMAP_FLAGS,  0x00003f84
+#else
+    .equ    PROC_ID,     0x60000000
+    .equ    CPU_ICLR,    0x60004028
+    .equ    CPU_CTRL,    0x60007000
+    .equ    CPU_STATUS,  0x60007000
+    .equ    COP_ICLR,    0x60004038
+    .equ    COP_CTRL,    0x60007004
+    .equ    COP_STATUS,  0x60007004
+    .equ    SLEEP,       0x80000000
+    .equ    WAKE,        0x00000000
+    .equ    CPUSLEEPING, 0x80000000
+    .equ    COPSLEEPING, 0x80000000    
+    .equ    CACHE_CTRL,  0x6000c000
+    .equ    MMAP_LOG,    0xf000f000 /* MMAP0 */
+    .equ    MMAP_PHYS,   0xf000f004
+#if MEMORYSIZE > 32
+    .equ    MMAP_MASK,   0x00003c00
+#else
+    .equ    MMAP_MASK,   0x00003e00
+#endif
+    .equ    MMAP_FLAGS,  0x00000f84
+#endif
+
+    msr    cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
+    b      pad_skip
+
+.space 6*4  /* pad to offset 0x20 */
+
+    .ascii "Rockbox"    /* signature for bootloader checking osos */
+    .byte 1             /* osos boot version, only 1 exists for now */
+
+.space 56*4 /* (more than enough) space for exception vectors and mi4 magic */
+
+pad_skip:
+    /* Find out which processor we are - r0 should be preserved for the
+     * duration of the init to avoid constant reloading of the processor ID.
+     * For each stage, CPU proceeds first, then COP. 
+     */
+    ldr    r0, =PROC_ID
+    ldrb   r0, [r0]
+
+    /* We need to remap memory from wherever SDRAM is mapped natively, to
+       base address 0, so we can put our exception vectors there. We don't
+       want to do this remapping while executing from SDRAM, so we copy the
+       remapping code to IRAM, then execute from there. Hence, the following
+       code is compiled for address 0, but is currently executing at either
+       0x28000000 or 0x10000000, depending on chipset version. Do not use any
+       absolute addresses until remapping has been done. */
+
+    /* Cores are stepped though the init in turn: CPU then COP. The the remap
+       stage is completed by each core in turn and then the COP waits for the
+       CPU to finish initializing its kernel where the CPU will wake the COP
+       and wait for the COP to finish. This ensures no threading activity
+       starts until it is safe. */
+    cmp    r0, #0x55
+    
+    /* mask all interrupt sources before setting anything up */
+    ldreq  r2, =CPU_ICLR
+    ldrne  r2, =COP_ICLR    
+    mvn    r1, #0
+    str    r1, [r2]
+
+    /* put us (co-processor) to sleep and wait for CPU to remap */
+    ldrne  r2, =COP_CTRL
+    movne  r1, #SLEEP
+    strne  r1, [r2]
+    nop
+    nop
+    nop
+
+    /* wait for co-processor to sleep then CPU can begin its remapping */
+    ldreq  r2, =COP_STATUS
+1:
+    ldreq  r1, [r2]
+    tsteq  r1, #COPSLEEPING
+    beq    1b
+
+    /* disable cache and local interrupt vectors - it is really not desireable
+       to have them enabled here */
+    ldr    r2, =CACHE_CTRL
+    mov    r1, #0
+    str    r1, [r2]
+
+#if defined(IPOD_VIDEO)
+    /* detect 32mb vs 64mb model */
+    /* we do this here because after SDRAM is remapped, we already assumed */
+    /* its size to be whatever we were compiled for. */
+
+    mov    r2, #0x12000000
+    mov    r3, #64
+    strb   r3, [r2, #-1]   /* first write 64 to last byte of first 32MB bank */
+
+    mov    r2, #0x14000000
+    mov    r3, #32
+    strb   r3, [r2, #-1]   /* now write 32 to last byte of second 32MB bank */
+
+    /* now the last word of the first 32MB bank tells you the RAM size */
+    /* since on a 32MB model both writes will touch the same actual location */
+    /* this is read later on in boot */
+#endif
+
+    mov    r2, #0x40000000
+    ldr    r3, =remap_start
+    ldr    r4, =remap_end
+
+    and    r6, pc, #0xff000000 /* adjust for execute address */
+    orr    r3, r3, r6
+    orr    r4, r4, r6
+
+    /* copy the code to 0x40000000 */
+1:
+    ldr    r5, [r3], #4
+    str    r5, [r2], #4
+    cmp    r3, r4
+    blo    1b
+
+    ldr    r4, =MMAP_FLAGS
+    orr    r4, r4, r6      /* adjust for execute address */
+    ldr    r3, =MMAP_PHYS
+    ldr    r2, =MMAP_MASK  /* ldr is more flexible */
+    ldr    r1, =MMAP_LOG
+    mov    pc, #0x40000000 
+
+remap_start:
+    str    r2, [r1]
+    str    r4, [r3]
+    ldr    r1, L_post_remap
+    bx     r1
+L_post_remap:
+    .word remap_end
+remap_end:
+
+    cmp    r0, #0x55
+    ldr    r4, =COP_CTRL
+    /* Wakeup co-processor to let it do remappings */
+    moveq  r3, #WAKE
+    /* Sleep us (co-processor) and wait for CPU to do kernel initialization */
+    movne  r3, #SLEEP
+    str    r3, [r4]
+    nop
+    nop
+    nop
+
+    /* Jump to co-processor init */
+    ldrne  pc, =cop_init
+
+cpu_init:
+    /* Wait for COP to go to sleep before proceeding */
+    ldr    r4, =COP_STATUS
+1:
+    ldr    r3, [r4]
+    tst    r3, #COPSLEEPING
+    beq    1b
+    
+    /* Vectors and IRAM copy is done first since they are reclaimed for
+     * other uninitialized sections */
+
+    /* Copy exception handler code to address 0 */
+    ldr    r2, =_vectorsstart
+    ldr    r3, =_vectorsend
+    ldr    r4, =_vectorscopy
+1:
+    cmp    r3, r2
+    ldrhi  r5, [r4], #4
+    strhi  r5, [r2], #4
+    bhi    1b
+    
+    /* Copy the IRAM */
+    ldr    r2, =_iramcopy
+    ldr    r3, =_iramstart
+    ldr    r4, =_iramend
+1:
+    cmp    r4, r3
+    ldrhi  r5, [r2], #4
+    strhi  r5, [r3], #4
+    bhi    1b
+
+#ifdef HAVE_INIT_ATTR
+    /* copy init code to codec buffer */
+    ldr    r2, =_initstart
+    ldr    r3, =_initend
+    ldr    r4, =_initcopy
+
+1:
+    cmp     r3, r2
+    ldrhi   r5, [r4], #4
+    strhi   r5, [r2], #4
+    bhi 1b
+#endif
+
+    /* Zero out IBSS */
+    ldr    r2, =_iedata
+    ldr    r3, =_iend
+    mov    r4, #0
+1:
+    cmp    r3, r2
+    strhi  r4, [r2], #4
+    bhi    1b
+
+    /* Initialise bss section to zero */
+    ldr    r2, =_edata
+    ldr    r3, =_end
+    mov    r4, #0
+1:
+    cmp    r3, r2
+    strhi  r4, [r2], #4
+    bhi    1b
+
+#if NUM_CORES > 1
+    /* Set up idle stack and munge it with 0xdeadbeef */
+    ldr    r2, =cpu_idlestackbegin
+    ldr    r3, =cpu_idlestackend
+1:
+    cmp    r3, r2
+    strhi  r4, [r2], #4
+    bhi    1b
+#endif
+
+    /* Set up stack for IRQ mode */ 
+    msr    cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
+    ldr    sp, =irq_stack
+    /* Set up stack for FIQ mode */ 
+    msr    cpsr_c, #0xd1 /* IRQ/FIQ disabled */
+    ldr    sp, =fiq_stack
+
+    /* Let svc, abort and undefined modes use irq stack */
+    msr    cpsr_c, #0xd3 /* IRQ/FIQ disabled */
+    ldr    sp, =irq_stack
+    msr    cpsr_c, #0xd7 /* IRQ/FIQ disabled */
+    ldr    sp, =irq_stack
+    msr    cpsr_c, #0xdb /* IRQ/FIQ disabled */
+    ldr    sp, =irq_stack
+
+    /* Switch to sys mode */
+    msr    cpsr_c, #0xdf
+
+    /* Load stack munge value */    
+    ldr    r4, =0xdeadbeef
+
+    /* Set up some stack and munge it with 0xdeadbeef */
+    ldr    r2, =stackbegin
+    ldr    sp, =stackend
+1:
+    cmp    sp, r2
+    strhi  r4, [r2], #4
+    bhi    1b
+
+    /* Delay waking the COP until thread initialization is complete unless dual-core
+       support is not enabled in which case the cop_main function does not perform
+       any kernel or thread initialization. It's just a trivial sleep loop. */
+#if NUM_CORES == 1
+    ldr    r4, =COP_CTRL
+    mov    r3, #WAKE
+    str    r3, [r4]
+#endif
+
+    ldr    pc, =main
+    /* main() should never return */
+
+cop_init:
+#if NUM_CORES > 1
+    /* Wait for CPU to go to sleep at the end of its kernel init */
+    ldr    r4, =CPU_STATUS
+1:
+    ldr    r3, [r4]
+    tst    r3, #CPUSLEEPING
+    beq    1b
+#endif
+
+    /* Set up stack for IRQ mode */
+    msr    cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */
+    ldr    sp, =cop_irq_stack
+    /* Set up stack for FIQ mode */
+    msr    cpsr_c, #0xd1 /* IRQ/FIQ disabled */
+    ldr    sp, =cop_fiq_stack
+
+    /* Let svc, abort and undefined modes use irq stack */
+    msr    cpsr_c, #0xd3 /* IRQ/FIQ disabled */
+    ldr    sp, =cop_irq_stack
+    msr    cpsr_c, #0xd7 /* IRQ/FIQ disabled */
+    ldr    sp, =cop_irq_stack
+    msr    cpsr_c, #0xdb /* IRQ/FIQ disabled */
+    ldr    sp, =cop_irq_stack
+
+    /* Switch to sys mode */
+    msr    cpsr_c, #0xdf
+
+    /* Set up idle stack for COP and munge it with 0xdeadbeef */
+    ldr    sp, =cop_idlestackend
+    ldr    r2, =cop_idlestackbegin
+    ldr    r4, =0xdeadbeef
+2:
+    cmp    sp, r2
+    strhi  r4, [r2], #4
+    bhi    2b
+   
+    /* Run cop_main() in apps/main.c */
+    ldr    pc, =cop_main
+
+/* Exception handlers. Will be copied to address 0 after memory remapping */
+    .section .vectors,"aw"
+    ldr    pc, [pc, #24]
+    ldr    pc, [pc, #24]
+    ldr    pc, [pc, #24]
+    ldr    pc, [pc, #24]
+    ldr    pc, [pc, #24]
+    ldr    pc, [pc, #24]
+    ldr    pc, [pc, #24]
+    ldr    pc, [pc, #24]
+
+    /* Exception vectors */
+    .global vectors
+vectors:
+    .word  start 
+    .word  undef_instr_handler
+    .word  software_int_handler
+    .word  prefetch_abort_handler
+    .word  data_abort_handler
+    .word  reserved_handler
+    .word  irq_handler
+    .word  fiq_handler
+
+    .text
+
+/* All illegal exceptions call into UIE with exception address as first
+   parameter. This is calculated differently depending on which exception
+   we're in. Second parameter is exception number, used for a string lookup
+   in UIE.
+ */
+undef_instr_handler:
+    sub    r0, lr, #4
+    mov    r1, #0
+    b      UIE
+
+/* We run sys mode most of the time, and should never see a software
+   exception being thrown. Make it illegal and call UIE.
+ */
+software_int_handler:
+reserved_handler:
+    sub    r0, lr, #4
+    mov    r1, #4
+    b      UIE
+
+prefetch_abort_handler:
+    sub    r0, lr, #4
+    mov    r1, #1
+    b      UIE
+
+data_abort_handler:
+    sub    r0, lr, #8 
+    mov    r1, #2
+    b      UIE
+
+/* Align stacks to cache line boundary */
+    .balign 32
+    
+/* 256 words of IRQ stack */
+    .space 256*4
+irq_stack:
+
+/* 256 words of COP IRQ stack */
+    .space 256*4
+cop_irq_stack:
+
+/* 256 words of FIQ stack */
+    .space 256*4
+fiq_stack:
+
+/* We'll need this soon - just reserve the symbol */
+#if 0
+/* 256 words of COP FIQ stack */
+    .space 256*4
+#endif
+cop_fiq_stack:
diff --git a/firmware/target/arm/portalplayer/crt0-pp502x-bl-usb.S b/firmware/target/arm/portalplayer/crt0-pp502x-bl-usb.S
new file mode 100644
index 0000000..7b0489b
--- /dev/null
+++ b/firmware/target/arm/portalplayer/crt0-pp502x-bl-usb.S
@@ -0,0 +1,367 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ * Copyright (C) 2010 by Michael Sevakis
+ *
+ * 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"
+
+/* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux 
+ * loader
+ *
+ * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
+ * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
+ *
+ */
+    .equ    PROC_ID,     0x60000000
+    .equ    CPU_IDIS,    0x60004028
+    .equ    CPU_CTRL,    0x60007000
+    .equ    CPU_STATUS,  0x60007000
+    .equ    COP_IDIS,    0x60004038
+    .equ    COP_CTRL,    0x60007004
+    .equ    COP_STATUS,  0x60007004
+    .equ    CPU_SLEEPING,0x80000000
+    .equ    COP_SLEEPING,0x80000000
+    .equ    SLEEP,       0x80000000
+    .equ    WAKE,        0x00000000
+    .equ    MMAP_LOG,    0xf000f000 /* MMAP0 */
+    .equ    MMAP_PHYS,   0xf000f004
+    .equ    INT_VECT_TBL,0x6000f100
+    .equ    CACHE_CTRL,  0x6000c000
+    .equ    CACHE_ENAB,  0x1
+    .equ    CACHE_OP_COMMIT_DISCARD, 0x1
+    .equ    CACHE_OP_COMMIT        , 0x0
+#if MEMORYSIZE > 32
+    .equ    MMAP_MASK,   0x00003c00
+#else
+    .equ    MMAP_MASK,   0x00003e00
+#endif
+    .equ    MMAP_FLAGS,  0x00000f84
+
+/*
+ * Entry point
+ */
+    .section .init.text,"ax",%progbits
+    .global  start
+start:
+    b       newstart
+
+#ifdef IPOD_ARCH
+.align 8    /* starts at 0x100 */
+.global boot_table
+boot_table:
+    /* here comes the boot table, don't move its offset - preceding
+       code+data must stay <= 256 bytes */
+    .space  400
+#else /* !IPOD_ARCH */
+    /* (more than enough) space for exception vectors and mi4 magic */
+    .space  68*4
+#endif /* IPOD_ARCH */
+
+newstart:
+    msr     cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
+    adr     r4, start     /* cache initial load address */
+
+    /* Copy startup stub to IRAM since we need to both move the bootloader's
+     * location, which could overlap itself, and setup the memory mapper. */
+    adr     r0, start_stub_begin
+    mov     r1, #0x40000000
+    adr     r2, start_stub_end
+1:
+    ldr     r3, [r0], #4
+    str     r3, [r1], #4
+    cmp     r0, r2
+    blo     1b
+    mov     pc, #0x40000000
+
+start_stub_begin:
+    ldr     r0, =PROC_ID
+    ldrb    r0, [r0]
+    cmp     r0, #0x55
+    beq     cpu
+
+cop:
+    mov     r0, #CACHE_OP_COMMIT_DISCARD
+    bl      cache_operation
+
+    ldr     r1, =COP_CTRL
+    mov     r0, #SLEEP
+
+    /* sleep us (co-processor) while bootloader is copied */
+    str     r0, [r1]
+    nop
+    nop
+    nop
+
+    /* branch to final physical load address */
+    ldr     r2, =1f
+    and     r4, r4, #0xfc000000
+    add     pc, r2, r4
+1:
+    /* wait for bootloader to finish */
+    str     r0, [r1]
+    nop
+    nop
+    nop
+
+    /* branch to the address returned by main() */
+    adr     r0, startup_loc
+    ldr     pc, [r0]
+
+cpu:
+    /* wait for COP to sleep */
+    ldr     r1, =COP_STATUS
+1:
+    ldr     r0, [r1]
+    tst     r0, #COP_SLEEPING
+    beq     1b
+
+    mov     r0, #CACHE_OP_COMMIT_DISCARD
+    bl      cache_operation
+
+    /* move bootloader to the correct load address if needed */
+    ldr     r1, =_loadaddress
+    cmp     r4, r1
+    ldrne   r2, =_loadaddressend
+    movne   r0, r4
+    sublo   r3, r2, r1 /* size */
+    addlo   r0, r0, r3 /* initial load end addr */
+1: /* lower to higher move - copy up */
+    cmphi   r2, r1
+    ldrhi   r3, [r0], #4
+    strhi   r3, [r1], #4
+    bhi     1b
+1: /* higher to lower move - copy down */
+    cmplo   r1, r2
+    ldrlo   r3, [r0, #-4]!
+    strlo   r3, [r2, #-4]!
+    blo     1b
+
+    mov     r0, #CACHE_OP_COMMIT
+    bl      cache_operation
+
+    and     r4, r4, #0xfc000000
+
+    ldr     r0, =MMAP_FLAGS
+    orr     r0, r0, r4 /* adjust for execute address */
+    ldr     r1, =MMAP_MASK
+    ldr     r2, =MMAP_LOG
+    ldr     r3, =MMAP_PHYS
+    str     r1, [r2] /* MMAP_LOG = MMAP_MASK */
+    str     r0, [r3] /* MMAP_PHYS = MMAP_FLAGS | SDRAM base addr */
+
+    /* wake the COP to jump it to the correct place */
+    ldr     r1, =COP_CTRL
+    mov     r0, #WAKE
+    str     r0, [r1]
+
+    /* wait for COP to halt then loading may proceed */
+    ldr     r1, =COP_STATUS
+1:
+    ldr     r0, [r1]
+    tst     r0, #COP_SLEEPING
+    beq     1b
+
+    ldr     r0, =start_stub_end
+    add     pc, r0, r4
+
+cache_operation: /* (bool commit_discard) */
+    ldr     r2, =CACHE_CTRL
+    ldr     r1, [r2]
+    tst     r1, #CACHE_ENAB
+    bxeq    lr
+    cmp     r0, #CACHE_OP_COMMIT
+    ldr     r0, =0xf000f044
+    ldr     r1, [r0]
+    orrne   r1, r1, #0x6
+    orreq   r1, r1, #0x2
+    str     r1, [r0]
+1:
+    ldr     r1, [r2]
+    tst     r1, #0x8000
+    bne     1b
+    bx      lr
+    .ltorg /* constants used in stub come with us to IRAM */
+start_stub_end:
+    /* now executing from final physical address */
+
+    /* copy the vector addresses to the table */
+    ldr     r0, =INT_VECT_TBL
+    adr     r1, vectorsstart
+    adr     r2, vectorsend
+1:
+    cmp     r2, r1
+    ldrhi   r3, [r1], #4
+    strhi   r3, [r0], #4
+    bhi     1b
+
+    /* Copy the IRAM */
+    ldr     r0, =_iramcopy
+    ldr     r1, =_iramstart
+    ldr     r2, =_iramend
+1:
+    cmp     r2, r1
+    ldrhi   r3, [r0], #4
+    strhi   r3, [r1], #4
+    bhi     1b
+
+    mov     r0, #0
+
+    /* Zero out IBSS */
+    ldr     r1, =_iedata
+    ldr     r2, =_iend
+1:
+    cmp     r2, r1
+    strhi   r0, [r1], #4
+    bhi     1b
+
+    /* Initialise bss/ncbss sections to zero */
+    ldr     r1, =_edata
+    ldr     r2, =_end
+1:
+    cmp     r2, r1
+    strhi   r0, [r1], #4
+    bhi     1b
+
+    /* Set up stack for IRQ mode */ 
+    msr     cpsr_c, #0xd2 /* IRQ/FIQ disabled */
+    ldr     sp, =irq_stack
+    /* Let svc, abort and undefined modes use irq stack */
+    msr     cpsr_c, #0xd3
+    ldr     sp, =irq_stack
+    msr     cpsr_c, #0xd7 /* IRQ/FIQ disabled */
+    ldr     sp, =irq_stack
+    msr     cpsr_c, #0xdb /* IRQ/FIQ disabled */
+    ldr     sp, =irq_stack
+
+    /* Switch back to sys mode */
+    msr     cpsr_c, #0xdf
+
+    /* Set up some stack and munge it with 0xdeadbeef */
+    ldr     r0, =0xdeadbeef
+    ldr     r1, =stackbegin
+    ldr     sp, =stackend
+1:
+    cmp     sp, r1
+    strhi   r0, [r1], #4
+    bhi     1b
+
+    /* execute the loader - this will load an image to 0x10000000 */
+    ldr     r0, =main
+    mov     lr, pc
+    bx      r0
+
+    /* store actual startup location returned by main() */
+    ldr     r1, =startup_loc
+    str     r0, [r1]
+
+    /* write back anything loaded + startup_loc */
+    mov     r0, #CACHE_OP_COMMIT
+    bl      cache_operation
+
+    mov     r0, #0
+
+    /* disable memory mapper */
+    ldr     r1, =MMAP_LOG
+    ldr     r2, =MMAP_PHYS
+    str     r0, [r1]
+    str     r0, [r2]
+
+    /* bring COP back to life */
+    ldr     r1, =COP_CTRL
+    mov     r0, #WAKE
+    str     r0, [r1]
+
+    /* after this point, r0-r3 are reserved for OF magic */
+
+#if defined(SANSA_C200) || defined(PHILIPS_HDD1630)
+    /* Magic for loading the c200 OF */
+    ldr     r0, =0xb00d10ad
+    mov     r1, #0x700
+    ldr     r2, =0xfff0
+    mov     r3, #0x7
+#endif
+
+#if defined(PHILIPS_HDD6330)
+    /* Magic for loading the HDD6XX0 OF */
+    ldr     r0, =0xb00d10ad
+    mov     r1, #0x800
+    ldr     r2, =0xfff0
+    mov     r3, #0x7
+#endif
+
+    /* branch to the address returned by main() */
+    adr     r4, startup_loc
+    ldr     pc, [r4]
+
+startup_loc:
+    .word   0x00000000
+
+/* exception handlers: will be copied to local vector table */
+vectorsstart:
+    .word   newstart 
+    .word   undef_instr_handler
+    .word   software_int_handler
+    .word   prefetch_abort_handler
+    .word   data_abort_handler
+    .word   reserved_handler
+    .word   irq_handler
+    .word   fiq_handler
+vectorsend:
+
+    .text
+
+/* All illegal exceptions call into UIE with exception address as first
+   parameter. This is calculated differently depending on which exception
+   we're in. Second parameter is exception number, used for a string lookup
+   in UIE.
+ */
+undef_instr_handler:
+    sub     r0, lr, #4
+    mov     r1, #0
+    b       UIE
+
+/* We run sys mode most of the time, and should never see a software
+   exception being thrown. Make it illegal and call UIE.
+ */
+software_int_handler:
+reserved_handler:
+    sub     r0, lr, #4
+    mov     r1, #4
+    b       UIE
+
+prefetch_abort_handler:
+    sub     r0, lr, #4
+    mov     r1, #1
+    b       UIE
+
+data_abort_handler:
+    sub     r0, lr, #8 
+    mov     r1, #2
+    b       UIE
+
+/* should never happen in the bootloader */
+fiq_handler:
+    subs    pc, lr, #4
+
+/* 256 words of IRQ stack */
+    .section .bss
+    .balign 16
+    .space  256*4
+irq_stack:
diff --git a/firmware/target/arm/portalplayer/debug-pp.c b/firmware/target/arm/portalplayer/debug-pp.c
new file mode 100644
index 0000000..5f252db
--- /dev/null
+++ b/firmware/target/arm/portalplayer/debug-pp.c
@@ -0,0 +1,232 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 Dave Chapman
+ *
+ * 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 "system.h"
+#include <stdbool.h>
+#include "font.h"
+#include "lcd.h"
+#include "button.h"
+#include "powermgmt.h"
+#include "adc.h"
+#include "iap.h"
+#include "hwcompat.h"
+#include "debug-target.h"
+
+static int perfcheck(void)
+{
+    int result;
+
+    asm (
+        "mrs     r2, CPSR            \n"
+        "orr     r0, r2, #0xc0       \n" /* disable IRQ and FIQ */
+        "msr     CPSR_c, r0          \n"
+        "mov     %[res], #0          \n"
+        "ldr     r0, [%[timr]]       \n"
+        "add     r0, r0, %[tmo]      \n"
+    "1:                              \n"
+        "add     %[res], %[res], #1  \n"
+        "ldr     r1, [%[timr]]       \n"
+        "cmp     r1, r0              \n"
+        "bmi     1b                  \n"
+        "msr     CPSR_c, r2          \n" /* reset IRQ and FIQ state */
+        :
+        [res]"=&r"(result)
+        :
+        [timr]"r"(&USEC_TIMER),
+        [tmo]"r"(
+#if CONFIG_CPU == PP5002
+        16000
+#else /* PP5020/5022/5024 */
+        10226
+#endif
+        )
+        :
+        "r0", "r1", "r2"
+    );
+    return result;
+}
+
+bool dbg_ports(void)
+{
+    int line;
+
+    lcd_clear_display();
+    lcd_setfont(FONT_SYSFIXED);
+
+    while(1)
+    {
+        line = 0;
+#if defined(CPU_PP502x)
+#if (LCD_HEIGHT >= 176) /* Only for displays with appropriate height. */
+        lcd_puts(0, line++, "GPIO ENABLE:");
+        lcd_putsf(0, line++, "A: %02x  E: %02x  I: %02x",
+                               (unsigned int)GPIOA_ENABLE,
+                               (unsigned int)GPIOE_ENABLE,
+                               (unsigned int)GPIOI_ENABLE);
+        lcd_putsf(0, line++, "B: %02x  F: %02x  J: %02x",
+                               (unsigned int)GPIOB_ENABLE,
+                               (unsigned int)GPIOF_ENABLE,
+                               (unsigned int)GPIOJ_ENABLE);
+        lcd_putsf(0, line++, "C: %02x  G: %02x  K: %02x",
+                               (unsigned int)GPIOC_ENABLE,
+                               (unsigned int)GPIOG_ENABLE,
+                               (unsigned int)GPIOK_ENABLE);
+        lcd_putsf(0, line++, "D: %02x  H: %02x  L: %02x",
+                               (unsigned int)GPIOD_ENABLE,
+                               (unsigned int)GPIOH_ENABLE,
+                               (unsigned int)GPIOL_ENABLE);
+        line++;
+#endif
+        lcd_puts(0, line++, "GPIO INPUT VAL:");
+        lcd_putsf(0, line++, "A: %02x  E: %02x  I: %02x",
+                               (unsigned int)GPIOA_INPUT_VAL,
+                               (unsigned int)GPIOE_INPUT_VAL,
+                               (unsigned int)GPIOI_INPUT_VAL);
+        lcd_putsf(0, line++, "B: %02x  F: %02x  J: %02x",
+                               (unsigned int)GPIOB_INPUT_VAL,
+                               (unsigned int)GPIOF_INPUT_VAL,
+                               (unsigned int)GPIOJ_INPUT_VAL);
+        lcd_putsf(0, line++, "C: %02x  G: %02x  K: %02x",
+                               (unsigned int)GPIOC_INPUT_VAL,
+                               (unsigned int)GPIOG_INPUT_VAL,
+                               (unsigned int)GPIOK_INPUT_VAL);
+        lcd_putsf(0, line++, "D: %02x  H: %02x  L: %02x",
+                               (unsigned int)GPIOD_INPUT_VAL,
+                               (unsigned int)GPIOH_INPUT_VAL,
+                               (unsigned int)GPIOL_INPUT_VAL);
+        line++;
+        lcd_putsf(0, line++, "GPO32_VAL: %08lx", GPO32_VAL);
+        lcd_putsf(0, line++, "GPO32_EN:  %08lx", GPO32_ENABLE);
+        lcd_putsf(0, line++, "DEV_EN:    %08lx", DEV_EN);
+        lcd_putsf(0, line++, "DEV_EN2:   %08lx", DEV_EN2);
+        lcd_putsf(0, line++, "DEV_EN3:   %08lx", inl(0x60006044)); /* to be verified */
+        lcd_putsf(0, line++, "DEV_INIT1: %08lx", DEV_INIT1);
+        lcd_putsf(0, line++, "DEV_INIT2: %08lx", DEV_INIT2);
+#ifdef ADC_ACCESSORY
+        lcd_putsf(0, line++, "ACCESSORY: %d", adc_read(ADC_ACCESSORY));
+#endif
+#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
+        lcd_putsf(0, line++, "4066_ISTAT: %d", adc_read(ADC_4066_ISTAT));
+#endif
+
+#if defined(IPOD_ACCESSORY_PROTOCOL)
+        const unsigned char *serbuf = iap_get_serbuf();
+        lcd_putsf(0, line++, "IAP: %02x %02x %02x %02x %02x %02x %02x %02x", 
+         serbuf[0], serbuf[1], serbuf[2], serbuf[3], serbuf[4], serbuf[5],
+         serbuf[6], serbuf[7]);
+#endif
+
+#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
+        line++;
+        lcd_putsf(0, line++, "BATT: %03x UNK1: %03x",
+                                adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
+        lcd_putsf(0, line++, "REM:  %03x PAD: %03x",
+                                 adc_read(ADC_REMOTE), adc_read(ADC_SCROLLPAD));
+#elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330)
+        line++;
+        lcd_putsf(0, line++, "BATT: %03x UNK1: %03x",
+                                adc_read(ADC_BATTERY), adc_read(ADC_UNKNOWN_1));
+#elif defined(SANSA_E200) || defined(PHILIPS_SA9200)
+        lcd_putsf(0, line++, "ADC_BVDD:     %4d", adc_read(ADC_BVDD));
+        lcd_putsf(0, line++, "ADC_RTCSUP:   %4d", adc_read(ADC_RTCSUP));
+        lcd_putsf(0, line++, "ADC_UVDD:     %4d", adc_read(ADC_UVDD));
+        lcd_putsf(0, line++, "ADC_CHG_IN:   %4d", adc_read(ADC_CHG_IN));
+        lcd_putsf(0, line++, "ADC_CVDD:     %4d", adc_read(ADC_CVDD));
+        lcd_putsf(0, line++, "ADC_BATTEMP:  %4d", adc_read(ADC_BATTEMP));
+        lcd_putsf(0, line++, "ADC_MICSUP1:  %4d", adc_read(ADC_MICSUP1));
+        lcd_putsf(0, line++, "ADC_MICSUP2:  %4d", adc_read(ADC_MICSUP2));
+        lcd_putsf(0, line++, "ADC_VBE1:     %4d", adc_read(ADC_VBE1));
+        lcd_putsf(0, line++, "ADC_VBE2:     %4d", adc_read(ADC_VBE2));
+        lcd_putsf(0, line++, "ADC_I_MICSUP1:%4d", adc_read(ADC_I_MICSUP1));
+#if !defined(PHILIPS_SA9200)
+        lcd_putsf(0, line++, "ADC_I_MICSUP2:%4d", adc_read(ADC_I_MICSUP2));
+        lcd_putsf(0, line++, "ADC_VBAT:     %4d", adc_read(ADC_VBAT));
+#endif
+#endif
+
+#elif CONFIG_CPU == PP5002
+        lcd_putsf(0, line++, "GPIO_A: %02x GPIO_B: %02x",
+                 (unsigned int)GPIOA_INPUT_VAL, (unsigned int)GPIOB_INPUT_VAL);
+        lcd_putsf(0, line++, "GPIO_C: %02x GPIO_D: %02x",
+                 (unsigned int)GPIOC_INPUT_VAL, (unsigned int)GPIOD_INPUT_VAL);
+
+        lcd_putsf(0, line++, "DEV_EN:       %08lx", DEV_EN);
+        lcd_putsf(0, line++, "CLOCK_ENABLE: %08lx", CLOCK_ENABLE);
+        lcd_putsf(0, line++, "CLOCK_SOURCE: %08lx", CLOCK_SOURCE);
+        lcd_putsf(0, line++, "PLL_CONTROL:  %08lx", PLL_CONTROL);
+        lcd_putsf(0, line++, "PLL_DIV:      %08lx", PLL_DIV);
+        lcd_putsf(0, line++, "PLL_MULT:     %08lx", PLL_MULT);
+        lcd_putsf(0, line++, "TIMING1_CTL:  %08lx", TIMING1_CTL);
+        lcd_putsf(0, line++, "TIMING2_CTL:  %08lx", TIMING2_CTL);
+#endif
+        lcd_update();
+        if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL))
+        {
+            lcd_setfont(FONT_UI);
+            return false;
+        }
+    }
+    return false;
+}
+
+bool dbg_hw_info(void)
+{
+    int line = 0;
+#if defined(CPU_PP502x)
+    char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
+                          (PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
+                          (PP_VER1 >> 24) & 0xff, (PP_VER1 >> 16) & 0xff,
+                          (PP_VER1 >> 8) & 0xff, (PP_VER1) & 0xff, '\0' };
+#elif CONFIG_CPU == PP5002
+    char pp_version[] = { (PP_VER4 >> 8) & 0xff, PP_VER4 & 0xff,
+                          (PP_VER3 >> 8) & 0xff, PP_VER3 & 0xff,
+                          (PP_VER2 >> 8) & 0xff, PP_VER2 & 0xff,
+                          (PP_VER1 >> 8) & 0xff, PP_VER1 & 0xff, '\0' };
+#endif
+
+    lcd_setfont(FONT_SYSFIXED);
+    lcd_clear_display();
+
+    lcd_puts(0, line++, "[Hardware info]");
+
+#ifdef IPOD_ARCH
+    lcd_putsf(0, line++, "HW rev: 0x%08lx", IPOD_HW_REVISION);
+#endif
+
+#if defined(IPOD_COLOR) || defined(IPOD_NANO)
+    extern int lcd_type; /* Defined in lcd-colornano.c */
+
+    lcd_putsf(0, line++, "LCD type: %d", lcd_type);
+#endif
+
+    lcd_putsf(0, line++, "PP version: %s", pp_version);
+
+    lcd_putsf(0, line++, "Est. clock (kHz): %d", perfcheck());
+
+    lcd_update();
+
+    /* wait for exit */
+    while (button_get_w_tmo(HZ/10) != (DEBUG_CANCEL|BUTTON_REL));
+
+    lcd_setfont(FONT_UI);
+    return false;
+}
diff --git a/firmware/target/arm/portalplayer/debug-target.h b/firmware/target/arm/portalplayer/debug-target.h
new file mode 100644
index 0000000..28f9532
--- /dev/null
+++ b/firmware/target/arm/portalplayer/debug-target.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2010 by Marcin Bukat
+ *
+ * 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.
+ *
+ ****************************************************************************/
+#if (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
+    (CONFIG_KEYPAD == IPOD_3G_PAD) || \
+    (CONFIG_KEYPAD == IPOD_4G_PAD)
+#   define DEBUG_CANCEL  BUTTON_MENU
+
+#elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
+#   define DEBUG_CANCEL  BUTTON_REW
+
+#elif (CONFIG_KEYPAD == MROBE100_PAD)
+#   define DEBUG_CANCEL  BUTTON_MENU
+
+#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
+      (CONFIG_KEYPAD == SANSA_C200_PAD)
+#   define DEBUG_CANCEL  BUTTON_LEFT
+
+#elif (CONFIG_KEYPAD == PHILIPS_SA9200_PAD) || \
+      (CONFIG_KEYPAD == PHILIPS_HDD1630_PAD)
+#   define DEBUG_CANCEL  BUTTON_POWER
+
+#elif (CONFIG_KEYPAD == PHILIPS_HDD6330_PAD)
+#   define DEBUG_CANCEL  BUTTON_PREV
+
+#elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
+#   define DEBUG_CANCEL  BUTTON_PLAY
+
+#elif (CONFIG_KEYPAD == PBELL_VIBE500_PAD)
+#   define DEBUG_CANCEL  BUTTON_CANCEL
+#endif
+bool dbg_ports(void);
+bool dbg_hw_info(void);
diff --git a/firmware/target/arm/portalplayer/i2c-pp.c b/firmware/target/arm/portalplayer/i2c-pp.c
new file mode 100644
index 0000000..58740b5
--- /dev/null
+++ b/firmware/target/arm/portalplayer/i2c-pp.c
@@ -0,0 +1,314 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * PP502X and PP5002 I2C driver
+ *
+ * Based on code from the ipodlinux project - http://ipodlinux.org/
+ * Adapted for Rockbox in November 2005
+ *
+ * Original file: linux/arch/armnommu/mach-ipod/hardware.c
+ *
+ * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ * 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 "cpu.h"
+#include "kernel.h"
+#include "thread.h"
+#include "logf.h"
+#include "system.h"
+#include "i2c.h"
+#include "i2c-pp.h"
+#include "ascodec.h"
+#include "as3514.h"
+
+#define I2C_CTRL    (*(volatile unsigned char*)(I2C_BASE+0x00))
+#define I2C_ADDR    (*(volatile unsigned char*)(I2C_BASE+0x04))
+#define I2C_DATA(X) (*(volatile unsigned char*)(I2C_BASE+0xc+(4*X)))
+#define I2C_STATUS  (*(volatile unsigned char*)(I2C_BASE+0x1c))
+
+/* I2C_CTRL bit definitions */
+#define I2C_SEND    0x80
+
+/* I2C_STATUS bit definitions */
+#define I2C_BUSY    (1<<6)
+
+/* Local functions definitions */
+static struct mutex i2c_mtx SHAREDBSS_ATTR;
+
+#define POLL_TIMEOUT (HZ)
+
+static int pp_i2c_wait_not_busy(void)
+{
+    unsigned long timeout;
+    timeout = current_tick + POLL_TIMEOUT;
+    while (TIME_BEFORE(current_tick, timeout)) {
+         if (!(I2C_STATUS & I2C_BUSY)) {
+            return 0;
+         }
+         yield();
+    }
+
+    return -1;
+}
+
+static int pp_i2c_read_bytes(unsigned int addr, int len, unsigned char *data)
+{
+    int i;
+
+    if (len < 1 || len > 4)
+    {
+        return -1;
+    }
+
+    if (pp_i2c_wait_not_busy() < 0)
+    {
+        return -2;
+    }
+
+    {
+        int old_irq_level = disable_irq_save();
+
+        /* clear top 15 bits, left shift 1, or in 0x1 for a read */
+        I2C_ADDR = ((addr << 17) >> 16) | 0x1;
+
+        I2C_CTRL |= 0x20;
+
+        I2C_CTRL = (I2C_CTRL & ~0x6) | ((len-1) << 1);
+
+        I2C_CTRL |= I2C_SEND;
+
+        restore_irq(old_irq_level);
+
+        if (pp_i2c_wait_not_busy() < 0)
+        {
+            return -2;
+        }
+
+        old_irq_level = disable_irq_save();
+
+        if (data)
+        {
+            for ( i = 0; i < len; i++ )
+                *data++ = I2C_DATA(i);
+        }
+
+        restore_irq(old_irq_level);
+    }
+
+    return 0;
+}
+
+static int pp_i2c_send_bytes(unsigned int addr, int len, unsigned char *data)
+{
+    int i;
+
+    if (len < 1 || len > 4)
+    {
+        return -1;
+    }
+
+    if (pp_i2c_wait_not_busy() < 0)
+    {
+        return -2;
+    }
+
+    {
+        int old_irq_level = disable_irq_save();
+
+        /* clear top 15 bits, left shift 1 */
+        I2C_ADDR = (addr << 17) >> 16;
+
+        I2C_CTRL &= ~0x20;
+
+        for ( i = 0; i < len; i++ )
+        {
+            I2C_DATA(i) = *data++;
+        }
+
+        I2C_CTRL = (I2C_CTRL & ~0x6) | ((len-1) << 1);
+
+        I2C_CTRL |= I2C_SEND;
+
+        restore_irq(old_irq_level);
+    }
+
+    return 0;
+}
+
+static int pp_i2c_send_byte(unsigned int addr, int data0)
+{
+    unsigned char data[1];
+
+    data[0] = data0;
+
+    return pp_i2c_send_bytes(addr, 1, data);
+}
+
+/* Public functions */
+void i2c_lock(void)
+{
+    mutex_lock(&i2c_mtx);
+}
+
+void i2c_unlock(void)
+{
+    mutex_unlock(&i2c_mtx);
+}
+
+int i2c_readbytes(unsigned int dev_addr, int addr, int len, unsigned char *data)
+{
+    int i, n;
+
+    mutex_lock(&i2c_mtx);
+
+    if (addr >= 0)
+        pp_i2c_send_byte(dev_addr, addr);
+
+    i = 0;
+    while (len > 0)
+    {
+        n = (len < 4) ? len : 4;
+
+        if (pp_i2c_read_bytes(dev_addr, n, data + i) < 0)
+            break;
+
+        len -= n;
+        i   += n;
+    }
+
+    mutex_unlock(&i2c_mtx);
+
+    return i;
+}
+
+int i2c_readbyte(unsigned int dev_addr, int addr)
+{
+    unsigned char data;
+
+    mutex_lock(&i2c_mtx);
+    pp_i2c_send_byte(dev_addr, addr);
+    pp_i2c_read_bytes(dev_addr, 1, &data);
+    mutex_unlock(&i2c_mtx);
+
+    return (int)data;
+}
+
+int i2c_sendbytes(unsigned int addr, int len, const unsigned char *data)
+{
+    int i, n;
+
+    mutex_lock(&i2c_mtx);
+
+    i = 0;
+    while (len > 0)
+    {
+        n = (len < 4) ? len : 4;
+
+        if (pp_i2c_send_bytes(addr, n, (unsigned char *)(data + i)) < 0)
+            break;
+
+        len -= n;
+        i   += n;
+    }
+
+    mutex_unlock(&i2c_mtx);
+
+    return i;
+}
+
+int pp_i2c_send(unsigned int addr, int data0, int data1)
+{
+    int retval;
+    unsigned char data[2];
+
+    data[0] = data0;
+    data[1] = data1;
+
+    mutex_lock(&i2c_mtx);
+    retval = pp_i2c_send_bytes(addr, 2, data);
+    mutex_unlock(&i2c_mtx);
+
+    return retval;
+}
+
+void i2c_init(void)
+{
+    /* From ipodlinux */
+    mutex_init(&i2c_mtx);
+
+#ifdef IPOD_MINI
+    /* GPIO port C disable port 0x10 */
+    GPIOC_ENABLE &= ~0x10;
+
+    /* GPIO port C disable port 0x20 */
+    GPIOC_ENABLE &= ~0x20;
+#endif
+
+#if CONFIG_I2C == I2C_PP5002
+    DEV_EN |= 0x2;
+#else
+    DEV_EN |= DEV_I2C;  /* Enable I2C */
+#endif
+    DEV_RS |= DEV_I2C;  /* Start I2C Reset */
+    DEV_RS &=~DEV_I2C;  /* End I2C Reset */
+
+#if CONFIG_I2C == I2C_PP5020
+    outl(0x0, 0x600060a4);
+#if defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) || \
+    defined(SAMSUNG_YH820) || defined(SAMSUNG_YH920) || \
+    defined(SAMSUNG_YH925) || defined(PBELL_VIBE500)
+    outl(inl(0x600060a4) | 0x20, 0x600060a4);
+    outl(inl(0x7000c020) | 0x3, 0x7000c020);
+    outl(0x55, 0x7000c02c);
+    outl(0x54, 0x7000c030);
+#else
+    outl(0x80 | (0 << 8), 0x600060a4);
+#endif
+#elif CONFIG_I2C == I2C_PP5024
+#if defined(SANSA_E200) || defined(PHILIPS_SA9200)
+    /* Sansa OF sets this to 0x20 first, communicates with the AS3514
+       then sets it to 0x23 - this still works fine though */
+    outl(0x0, 0x600060a4);
+    outl(0x23, 0x600060a4);
+#elif defined(SANSA_C200)
+    /* This is the init sequence from the Sansa c200 bootloader.
+       I'm not sure what's really necessary. */
+    pp_i2c_wait_not_busy();
+
+    outl(0, 0x600060a4);
+    outl(0x64, 0x600060a4);
+
+    outl(0x55, 0x7000c02c);
+    outl(0x54, 0x7000c030);
+
+    outl(0, 0x600060a4);
+    outl(0x1e, 0x600060a4);
+
+    ascodec_write(AS3514_SUPERVISOR, 5);
+#elif defined(PHILIPS_SA9200)
+    outl(0x0, 0x600060a4);
+    outl(inl(0x600060a4) | 0x20, 0x600060a4);
+
+    outl(inl(0x7000c020) | 0x3, 0x7000c020);
+    outl(0x55, 0x7000c02c);
+    outl(0x54, 0x7000c030);
+#endif
+#endif
+
+    i2c_readbyte(0x8, 0);
+}
diff --git a/firmware/target/arm/portalplayer/i2s-pp.c b/firmware/target/arm/portalplayer/i2s-pp.c
new file mode 100644
index 0000000..83f3951
--- /dev/null
+++ b/firmware/target/arm/portalplayer/i2s-pp.c
@@ -0,0 +1,95 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Portalplayer specific code for I2S
+ *
+ * Based on code from the ipodlinux project - http://ipodlinux.org/
+ * Adapted for Rockbox in December 2005
+ *
+ * Original file: linux/arch/armnommu/mach-ipod/audio.c
+ *
+ * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ * 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 "system.h"
+#include "cpu.h"
+#include "i2s.h"
+#if defined (SANSA_E200) || defined (SANSA_C200)
+#include "audiohw.h"
+#include "pcm_sampr.h"
+#endif
+
+#if CONFIG_CPU == PP5002
+void i2s_reset(void)
+{
+    /* I2S device reset */
+    DEV_RS |= DEV_I2S;
+    DEV_RS &= ~DEV_I2S;
+
+    /* I2S controller enable */
+    IISCONFIG |= IIS_ENABLE;
+
+    /* reset DAC and ADC fifo */
+    IISFIFO_CFG |= IIS_RXCLR | IIS_TXCLR;
+}
+#else /* PP502X */
+
+/*
+ * Reset the I2S BIT.FORMAT I2S, 16bit, FIFO.FORMAT 32bit
+ */
+void i2s_reset(void)
+{
+    /* I2S soft reset */
+    IISCONFIG |= IIS_RESET;
+    IISCONFIG &= ~IIS_RESET;
+
+    /* BIT.FORMAT */
+    IISCONFIG = ((IISCONFIG & ~IIS_FORMAT_MASK) | IIS_FORMAT_IIS);
+    /* BIT.SIZE */
+    IISCONFIG = ((IISCONFIG & ~IIS_SIZE_MASK) | IIS_SIZE_16BIT);
+
+    /* FIFO.FORMAT */
+    /* If BIT.SIZE < FIFO.FORMAT low bits will be 0 */
+#ifdef HAVE_AS3514
+    /* AS3514 can only operate as I2S Slave */
+    IISCONFIG |= IIS_MASTER;
+
+    /* Set I2S to 44.1kHz */
+#ifdef PHILIPS_SA9200
+    /* values taken from the SA9200 OF */
+    IISCLK = (IISCLK & ~0x1ff) | 31;
+    IISDIV = (IISDIV & ~0xc0000000) | (2 << 30);
+    IISDIV = (IISDIV & ~0x3f) | 16;
+#elif defined (SANSA_E200) || defined (SANSA_C200)
+    audiohw_set_sampr_dividers(HW_FREQ_DEFAULT);
+#else
+    IISCLK = (IISCLK & ~0x1ff) | 33;
+    IISDIV = 7;
+#endif
+#endif /* HAVE_AS3514 */
+
+    IISCONFIG = ((IISCONFIG & ~IIS_FIFO_FORMAT_MASK) | IIS_FIFO_FORMAT_LE16_2);
+
+    /* RX_ATN_LVL = when 12 slots full */
+    /* TX_ATN_LVL = DMA request when 4 slots empty */
+    IISFIFO_CFG |= IIS_RX_FULL_LVL_12 | IIS_TX_EMPTY_LVL_4;
+
+    /* Rx.CLR = 1, TX.CLR = 1 */
+    IISFIFO_CFG |= IIS_RXCLR | IIS_TXCLR;
+}
+
+#endif /* CONFIG_CPU == */
diff --git a/firmware/target/arm/portalplayer/ipod/1g2g/adc-ipod-1g2g.c b/firmware/target/arm/portalplayer/ipod/1g2g/adc-ipod-1g2g.c
new file mode 100644
index 0000000..37c719f
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/1g2g/adc-ipod-1g2g.c
@@ -0,0 +1,126 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Jens Arnold
+ *
+ * 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 "hwcompat.h"
+#include "kernel.h"
+#include "adc.h"
+#include "adc-target.h"
+#include "system-target.h"
+
+static struct mutex adc_mtx SHAREDBSS_ATTR;
+
+/* used in the 2nd gen ADC interrupt */
+static unsigned int_data;
+static int int_status = -1;
+
+unsigned short adc_scan(int channel)
+{
+    unsigned short data = 0;
+
+    (void)channel; /* there is only one */
+    mutex_lock(&adc_mtx);
+
+    if ((IPOD_HW_REVISION >> 16) == 1)
+    {
+        int i;
+        unsigned pval = GPIOB_OUTPUT_VAL;
+
+        GPIOB_OUTPUT_VAL = pval | 0x04;  /* B2 -> high */
+        udelay(2);
+
+        GPIOB_OUTPUT_VAL = pval;         /* B2 -> low */
+        udelay(10);
+
+        for (i = 0; i < 8; i++)
+        {
+            GPIOB_OUTPUT_VAL = pval | 0x02; /* B1 -> high */
+            udelay(1);
+
+            data = (data << 1) | ((GPIOB_INPUT_VAL & 0x08) >> 3);
+
+            GPIOB_OUTPUT_VAL = pval;     /* B1 -> low */
+            udelay(15);
+        }
+    }
+    else if ((IPOD_HW_REVISION >> 16) == 2)
+    {
+        int_status = 0;
+        GPIOB_INT_LEV    |= 0x04; /* high active */
+        GPIOB_INT_EN     |= 0x04; /* enable interrupt */
+        GPIOB_OUTPUT_VAL |= 0x0a; /* B1, B3 -> high: start conversion */
+
+        while (int_status >= 0)
+            yield();
+
+        data = int_data & 0xff;
+    }
+    mutex_unlock(&adc_mtx);
+    return data;
+}
+
+/* Used for 2nd gen only. Conversion can take several milliseconds there. */
+void ipod_2g_adc_int(void)
+{
+    if (GPIOB_INPUT_VAL & 0x04)
+    {
+        int_data = (int_data << 1) | ((GPIOB_INPUT_VAL & 0x10) >> 4);
+
+        GPIOB_OUTPUT_VAL &= ~0x0a; /* B1, B3 -> low */
+        /* B3 needs to be set low in the first call only, but then stays low
+         * anyway so no need for special handling */
+    }
+    else
+    {
+        if (++int_status > 8)
+        {
+            GPIOB_INT_EN &= ~0x04;
+            int_status = -1;
+        }
+        else
+            GPIOB_OUTPUT_VAL |= 0x02;  /* B1 -> high */
+    }
+    GPIOB_INT_LEV ^= 0x04; /* toggle interrupt level */
+    GPIOB_INT_CLR  = 0x04; /* acknowledge interrupt */
+}
+
+void adc_init(void)
+{
+    mutex_init(&adc_mtx);
+    
+    GPIOB_ENABLE |= 0x1e;  /* enable B1..B4 */
+
+    if ((IPOD_HW_REVISION >> 16) == 1)
+    {
+        GPIOB_OUTPUT_EN  = (GPIOB_OUTPUT_EN & ~0x08) | 0x16;
+                                         /* B1, B2, B4 -> output, B3 -> input */
+        GPIOB_OUTPUT_VAL = (GPIOB_OUTPUT_VAL & ~0x06) | 0x10;
+                                         /* B1, B2 -> low, B4 -> high */
+    }
+    else if ((IPOD_HW_REVISION >> 16) == 2)
+    {
+        GPIOB_OUTPUT_EN   = (GPIOB_OUTPUT_EN & ~0x14) | 0x0a;
+                                         /* B1, B3 -> output, B2, B4 -> input */
+        GPIOB_OUTPUT_VAL &= ~0x0a;       /* B1, B3 -> low */
+        while (GPIOB_INPUT_VAL & 0x04);  /* wait for B2 == 0 */
+    }
+}
diff --git a/firmware/target/arm/portalplayer/ipod/1g2g/adc-target.h b/firmware/target/arm/portalplayer/ipod/1g2g/adc-target.h
new file mode 100644
index 0000000..5b0ce4b
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/1g2g/adc-target.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Jens Arnold
+ *
+ * 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 _ADC_TARGET_H_
+#define _ADC_TARGET_H_
+
+#define NUM_ADC_CHANNELS 1
+
+#define ADC_BATTERY 0
+#define ADC_UNREG_POWER ADC_BATTERY
+
+/* Force a scan now */
+unsigned short adc_scan(int channel);
+void ipod_2g_adc_int(void);
+static inline unsigned short adc_read(int channel)
+{ 
+    return adc_scan(channel); 
+}
+#endif
diff --git a/firmware/target/arm/portalplayer/ipod/1g2g/backlight-1g2g.c b/firmware/target/arm/portalplayer/ipod/1g2g/backlight-1g2g.c
new file mode 100644
index 0000000..b779781
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/1g2g/backlight-1g2g.c
@@ -0,0 +1,37 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * 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 "system.h"
+#include "lcd.h"
+#include "backlight.h"
+#include "backlight-target.h"
+
+void _backlight_on(void)
+{
+    LCD1_CONTROL |= 0x02;
+    lcd_set_backlight_inversion(true);
+}
+
+void _backlight_off(void)
+{
+    LCD1_CONTROL &= ~0x02;
+    lcd_set_backlight_inversion(false);
+}
diff --git a/firmware/target/arm/portalplayer/ipod/1g2g/backlight-target.h b/firmware/target/arm/portalplayer/ipod/1g2g/backlight-target.h
new file mode 100644
index 0000000..2282605
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/1g2g/backlight-target.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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 BACKLIGHT_TARGET_H
+#define BACKLIGHT_TARGET_H
+
+#define _backlight_init() false
+void _backlight_on(void);
+void _backlight_off(void);
+
+#endif
diff --git a/firmware/target/arm/portalplayer/ipod/1g2g/powermgmt-1g2g.c b/firmware/target/arm/portalplayer/ipod/1g2g/powermgmt-1g2g.c
new file mode 100644
index 0000000..1bc5de9
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/1g2g/powermgmt-1g2g.c
@@ -0,0 +1,68 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
+ * Revisions copyright (C) 2005 by Gerald Van Baren
+ *
+ * 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 "adc.h"
+#include "powermgmt.h"
+#include "hwcompat.h"
+
+/* FIXME: Properly calibrate values. Current values "inherited" from
+ * iriver H100 */
+
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+    3380
+};
+
+const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
+{
+    3020
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
+const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
+{
+    { 3370, 3650, 3700, 3740, 3780, 3820, 3870, 3930, 4000, 4080, 4160 }
+};
+
+#if CONFIG_CHARGING
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+const unsigned short percent_to_volt_charge[11] =
+{
+    3540, 3860, 3930, 3980, 4000, 4020, 4040, 4080, 4130, 4180, 4230
+};
+#endif /* CONFIG_CHARGING */
+
+#define BATTERY_SCALE_FACTOR_1G 4200
+#define BATTERY_SCALE_FACTOR_2G 6630
+/* full-scale ADC readout (2^8) in millivolt */
+
+/* Returns battery voltage from ADC [millivolts] */
+unsigned int battery_adc_voltage(void)
+{
+    unsigned adcval = adc_read(ADC_UNREG_POWER);
+
+    if ((IPOD_HW_REVISION >> 16) == 1)
+        return (adcval * BATTERY_SCALE_FACTOR_1G) >> 8;
+    else
+        return (adcval * BATTERY_SCALE_FACTOR_2G) >> 8;
+}
diff --git a/firmware/target/arm/portalplayer/ipod/3g/backlight-3g.c b/firmware/target/arm/portalplayer/ipod/3g/backlight-3g.c
new file mode 100644
index 0000000..77088e3
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/3g/backlight-3g.c
@@ -0,0 +1,34 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * 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 "system.h"
+#include "backlight.h"
+#include "backlight-target.h"
+
+void _backlight_on(void)
+{
+    LCD1_CONTROL |= 0x02;
+}
+
+void _backlight_off(void)
+{
+    LCD1_CONTROL &= ~0x02;
+}
diff --git a/firmware/target/arm/portalplayer/ipod/adc-ipod-pcf.c b/firmware/target/arm/portalplayer/ipod/adc-ipod-pcf.c
new file mode 100644
index 0000000..5040e21
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/adc-ipod-pcf.c
@@ -0,0 +1,95 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * 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 "system.h"
+#include "kernel.h"
+#include "thread.h"
+#include "string.h"
+#include "adc.h"
+#include "pcf50605.h"
+#include "i2c-pp.h"
+
+struct adc_struct {
+    long timeout;
+    void (*conversion)(unsigned short *data);
+    short channelnum;
+    unsigned short data;
+};
+
+static struct adc_struct adcdata[NUM_ADC_CHANNELS] IDATA_ATTR;
+
+static unsigned short _adc_read(struct adc_struct *adc)
+{
+    if (TIME_AFTER(current_tick, adc->timeout)) {
+        unsigned char data[2];
+        unsigned short value;
+
+        i2c_lock();
+
+        /* 5x per 2 seconds */
+        adc->timeout = current_tick + (HZ * 2 / 5);
+
+        /* ADCC1, 10 bit, start */
+        pcf50605_write(0x2f, (adc->channelnum << 1) | 0x1);
+        pcf50605_read_multiple(0x30, data, 2); /* ADCS1, ADCS2 */
+        value   = data[0];
+        value <<= 2;
+        value  |= data[1] & 0x3;
+
+        if (adc->conversion) {
+            adc->conversion(&value);
+        }
+        adc->data = value;
+
+        i2c_unlock();
+        return value;
+    } else
+    {
+        return adc->data;
+    }
+}
+
+/* Force an ADC scan _now_ */
+unsigned short adc_scan(int channel) {
+    struct adc_struct *adc = &adcdata[channel];
+    adc->timeout = 0;
+    return _adc_read(adc);
+}
+
+/* Retrieve the ADC value, only does a scan periodically */
+unsigned short adc_read(int channel) {
+    return _adc_read(&adcdata[channel]);
+}
+
+void adc_init(void)
+{
+    struct adc_struct *adc_battery = &adcdata[ADC_BATTERY];
+    adc_battery->channelnum = 0x2; /* ADCVIN1, resistive divider */
+    adc_battery->timeout = 0;
+    adcdata[ADC_ACCESSORY].channelnum = 4;
+    adcdata[ADC_ACCESSORY].timeout = 0;
+#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
+    adcdata[ADC_4066_ISTAT].channelnum = 7;
+    adcdata[ADC_4066_ISTAT].timeout = 0;
+#endif
+    _adc_read(adc_battery);
+}
diff --git a/firmware/target/arm/portalplayer/ipod/adc-target.h b/firmware/target/arm/portalplayer/ipod/adc-target.h
new file mode 100644
index 0000000..6fa8877
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/adc-target.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * 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 _ADC_TARGET_H_
+#define _ADC_TARGET_H_
+
+#define ADC_BATTERY 0
+#define ADC_ACCESSORY 1
+#define ADC_UNREG_POWER ADC_BATTERY
+#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
+#define ADC_4066_ISTAT 2
+#define NUM_ADC_CHANNELS 3
+#else
+#define NUM_ADC_CHANNELS 2
+#endif
+ 
+/* Force a scan now */
+unsigned short adc_scan(int channel);
+#endif
diff --git a/firmware/target/arm/portalplayer/ipod/app.lds b/firmware/target/arm/portalplayer/ipod/app.lds
new file mode 100644
index 0000000..d6a457e
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/app.lds
@@ -0,0 +1,208 @@
+#include "config.h"
+
+ENTRY(start)
+
+OUTPUT_FORMAT(elf32-littlearm)
+OUTPUT_ARCH(arm)
+STARTUP(target/arm/portalplayer/crt0-pp.o)
+
+#define PLUGINSIZE PLUGIN_BUFFER_SIZE
+#define CODECSIZE CODEC_SIZE
+
+#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - CODECSIZE
+
+#define DRAMORIG 0x00000000
+#define IRAMORIG 0x40000000
+#define IRAMSIZE 0xc000
+
+#ifdef CPU_PP502x
+#define NOCACHE_BASE 	0x10000000
+#else
+#define NOCACHE_BASE 	0x28000000
+#endif
+
+#define CACHEALIGN_SIZE 16
+
+/* End of the audio buffer, where the codec buffer starts */
+#define ENDAUDIOADDR  (DRAMORIG + DRAMSIZE)
+
+/* Where the codec buffer ends, and the plugin buffer starts */
+#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
+
+MEMORY
+{
+    DRAM : ORIGIN = DRAMORIG,     LENGTH = DRAMSIZE
+    IRAM : ORIGIN = IRAMORIG,     LENGTH = IRAMSIZE
+}
+
+SECTIONS
+{
+    .text :
+    {
+        loadaddress = .;
+        _loadaddress = .;
+        . = ALIGN(0x200);
+        *(.init.text)
+        *(.text*)
+        *(.glue_7)
+        *(.glue_7t)
+        . = ALIGN(0x4);
+    } > DRAM
+
+    .rodata :
+    {
+        *(.rodata)  /* problems without this, dunno why */
+        *(.rodata*)
+        *(.rodata.str1.1)
+        *(.rodata.str1.4)
+        . = ALIGN(0x4);
+
+        /* Pseudo-allocate the copies of the data sections */
+        _datacopy = .;
+    } > DRAM
+
+    /* TRICK ALERT! For RAM execution, we put the .data section at the
+       same load address as the copy. Thus, we don't waste extra RAM
+       when we don't actually need the copy.  */
+    .data : AT ( _datacopy )
+    {
+        _datastart = .;
+        *(.data*)
+        . = ALIGN(0x4);
+        _dataend  = .;
+    } > DRAM
+
+#if NOCACHE_BASE != 0
+    /* .ncdata section is placed at uncached physical alias address and is
+     * loaded at the proper cached virtual address - no copying is
+     * performed in the init code */
+    .ncdata . + NOCACHE_BASE :
+    {
+        . = ALIGN(CACHEALIGN_SIZE);
+        *(.ncdata*)
+        . = ALIGN(CACHEALIGN_SIZE);
+    } AT> DRAM
+#endif
+    
+    /DISCARD/ :
+    {
+        *(.eh_frame)
+    }
+
+    .vectors 0x0 :
+    {
+        _vectorsstart = .;
+        *(.vectors);
+        _vectorsend = .;
+    } AT> DRAM
+
+    _vectorscopy = LOADADDR(.vectors);
+    _noloaddram  = LOADADDR(.vectors);
+
+    .ibss IRAMORIG (NOLOAD) :
+    {
+        _iedata = .;
+        *(.qharray)
+        *(.ibss)
+        . = ALIGN(0x4);
+        _iend = .;
+    } > IRAM
+
+    .iram _iend :
+    {
+        _iramstart = .;
+        *(.icode)
+        *(.irodata)
+        *(.idata)
+        . = ALIGN(0x4);
+        _iramend = .;
+    } > IRAM AT> DRAM
+
+    _iramcopy = LOADADDR(.iram);
+
+
+    .init ENDAUDIOADDR : 
+    {
+        . = ALIGN(4);
+        _initstart = .;
+        *(.init)
+        _initend = .;
+    } AT> DRAM
+
+    _initcopy = LOADADDR(.init);
+
+    .idle_stacks (NOLOAD) :
+    {
+       *(.idle_stacks)
+#if NUM_CORES > 1
+       cpu_idlestackbegin = .;
+       . += IDLE_STACK_SIZE;
+       cpu_idlestackend = .;
+#endif
+       cop_idlestackbegin = .;
+       . += IDLE_STACK_SIZE;
+       cop_idlestackend = .;
+    } > IRAM
+
+    .stack (NOLOAD) :
+    {
+       *(.stack)
+       stackbegin = .;
+       . += 0x2000;
+       stackend = .;
+    } > IRAM
+    
+    /* .bss and .ncbss are treated as a single section to use one init loop to
+     * zero it - note "_edata" and "_end" */
+    .bss _noloaddram (NOLOAD) :
+    {
+       _edata = .;
+        *(.bss*)
+        *(COMMON)
+        . = ALIGN(0x4);
+    } > DRAM
+
+#if NOCACHE_BASE != 0
+    .ncbss . + NOCACHE_BASE (NOLOAD):
+    {
+    	. = ALIGN(CACHEALIGN_SIZE);
+        *(.ncbss*)
+    	. = ALIGN(CACHEALIGN_SIZE);
+    } AT> DRAM
+#endif
+
+    /* This will be aligned by preceding alignments */
+    .endaddr . - NOCACHE_BASE (NOLOAD) :
+    {
+        _end = .;
+    } > DRAM
+
+    .audiobuf (NOLOAD) :
+    {
+        _audiobuffer = .;
+        . = ALIGN(0x4);
+        audiobuffer = .;
+    } > DRAM
+    
+    .audiobufend ENDAUDIOADDR (NOLOAD) :
+    {
+#ifdef IPOD_VIDEO
+        audiobufend_lds = .;
+#else
+        audiobufend = .;
+#endif
+        _audiobufend = .;
+    } > DRAM
+
+    .codec ENDAUDIOADDR (NOLOAD) :
+    {
+        codecbuf = .;
+        _codecbuf = .;
+    }
+
+    .plugin ENDADDR (NOLOAD) :
+    {
+        _pluginbuf = .;
+        pluginbuf = .;
+    }
+}
diff --git a/firmware/target/arm/portalplayer/ipod/backlight-4g_color.c b/firmware/target/arm/portalplayer/ipod/backlight-4g_color.c
new file mode 100644
index 0000000..befb036
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/backlight-4g_color.c
@@ -0,0 +1,82 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * 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 <stdlib.h>
+#include "cpu.h"
+#include "kernel.h"
+#include "thread.h"
+#include "i2c.h"
+#include "debug.h"
+#include "rtc.h"
+#include "usb.h"
+#include "power.h"
+#include "system.h"
+#include "button.h"
+#include "timer.h"
+#include "backlight.h"
+#include "backlight-target.h"
+
+/* Index 0 is a dummy, 1..31 are used */
+static unsigned char log_brightness[32] = {
+      0,   1,   2,   4,   6,   9,  12,  16,  20,  25,  30,  36,
+     42,  49,  56,  64,  72,  81,  90, 100, 110, 121, 132, 144,
+    156, 169, 182, 196, 210, 225, 240, 255
+};
+
+static unsigned brightness = 100;   /* 1 to 255 */
+static bool enabled = false;
+
+/* Handling B03 in _backlight_on() and _backlight_off() makes backlight go off
+ * without delay. Not doing that does a short (fixed) fade out. Opt for the
+ * latter. */
+
+void _backlight_on(void)
+{
+    /* brightness full */
+    outl(0x80000000 | (brightness << 16), 0x7000a010);
+    GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
+    enabled = true;
+}
+
+void _backlight_off(void)
+{
+    outl(0x80000000, 0x7000a010);
+    GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
+    enabled = false;
+}
+
+void _backlight_set_brightness(int val)
+{
+    brightness = log_brightness[val];
+    if (enabled)
+        outl(0x80000000 | (brightness << 16), 0x7000a010);
+}
+
+bool _backlight_init(void)
+{
+    GPIO_SET_BITWISE(GPIOB_ENABLE, 0x0c); /* B02 and B03 enable */
+    GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x08); /* B03 = 1 */
+    GPO32_ENABLE &= ~0x2000000; /* D01 disable, so pwm takes over */
+    DEV_EN |= DEV_PWM;   /* PWM enable */
+
+    _backlight_on();
+    return true;
+}
diff --git a/firmware/target/arm/portalplayer/ipod/backlight-mini1g_mini2g.c b/firmware/target/arm/portalplayer/ipod/backlight-mini1g_mini2g.c
new file mode 100644
index 0000000..1d57b77
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/backlight-mini1g_mini2g.c
@@ -0,0 +1,45 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * 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 <stdlib.h>
+#include "cpu.h"
+#include "kernel.h"
+#include "thread.h"
+#include "i2c.h"
+#include "debug.h"
+#include "rtc.h"
+#include "usb.h"
+#include "power.h"
+#include "system.h"
+#include "button.h"
+#include "timer.h"
+#include "backlight.h"
+#include "backlight-target.h"
+
+void _backlight_hw_on(void)
+{
+    GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
+}
+
+void _backlight_hw_off(void)
+{
+    GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
+}
diff --git a/firmware/target/arm/portalplayer/ipod/backlight-nano_video.c b/firmware/target/arm/portalplayer/ipod/backlight-nano_video.c
new file mode 100644
index 0000000..2f56f94
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/backlight-nano_video.c
@@ -0,0 +1,131 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * 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 <stdlib.h>
+#include "cpu.h"
+#include "kernel.h"
+#include "thread.h"
+#include "i2c.h"
+#include "debug.h"
+#include "rtc.h"
+#include "usb.h"
+#include "power.h"
+#include "system.h"
+#include "button.h"
+#include "timer.h"
+#include "backlight.h"
+#include "backlight-target.h"
+
+static int brightness = 1;   /* 1 to 32 */
+static int current_dim = 16; /* default after enabling the backlight dimmer */
+static bool enabled = false;
+
+void _backlight_set_brightness(int val)
+{
+    int oldlevel;
+
+    if (current_dim < val)
+    {
+        do
+        {
+            oldlevel = disable_irq_save();
+            GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
+            udelay(10);
+            GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
+            restore_irq(oldlevel);
+            udelay(10);
+        }
+        while (++current_dim < val);
+    }
+    else if (current_dim > val)
+    {
+        do
+        {
+            oldlevel = disable_irq_save();
+            GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
+            udelay(200);
+            GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
+            restore_irq(oldlevel);
+            udelay(10);
+        }
+        while (--current_dim > val);
+    }
+    brightness = val;
+}
+
+void _backlight_hw_enable(bool on)
+{
+#ifdef HAVE_LCD_SLEEP
+    if (on)
+        /* If the fade-out is interrupted, enabled will be true, but 
+           lcd_awake() needs to be called anyways because the LCD 
+           may be sleeping.
+         */
+        lcd_awake();
+#endif
+
+    if (on == enabled)
+        return;
+
+    if (on)
+    {
+        GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
+        GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
+        sleep(HZ/100);
+        current_dim = 16;
+        _backlight_set_brightness(brightness);
+    }
+    else
+    {
+        GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
+        GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x08);
+        sleep(HZ/20);
+    }
+    enabled = on;
+}
+
+/* Switch the backlight on. Works only if the backlight circuit is enabled.
+ * Called in ISR context for fading, so it must be fast. */
+void _backlight_led_on(void)
+{
+    GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 0x80);
+}
+
+/* Switch the backlight off. Keeps the backlight circuit enabled.
+ * Called in ISR context for fading, so it must be fast. */
+void _backlight_led_off(void)
+{
+    GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_VAL, 0x80);
+}
+
+bool _backlight_init(void)
+{
+    GPIO_SET_BITWISE(GPIOB_ENABLE, 0x08);
+    GPIO_SET_BITWISE(GPIOB_OUTPUT_EN, 0x08);
+    GPIO_SET_BITWISE(GPIOD_ENABLE, 0x80);
+    GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x80);
+    _backlight_hw_enable(true);
+    GPIO_SET_BITWISE(GPIOL_ENABLE, 0x80);
+    GPIO_SET_BITWISE(GPIOL_OUTPUT_EN, 0x80);
+    GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 0x80);
+
+    return true;
+}
diff --git a/firmware/target/arm/portalplayer/ipod/backlight-target.h b/firmware/target/arm/portalplayer/ipod/backlight-target.h
new file mode 100644
index 0000000..9b6a96b
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/backlight-target.h
@@ -0,0 +1,81 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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 BACKLIGHT_TARGET_H
+#define BACKLIGHT_TARGET_H
+
+#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
+
+bool _backlight_init(void);
+void _backlight_set_brightness(int val);
+void _backlight_led_on(void);
+void _backlight_led_off(void);
+void _backlight_hw_enable(bool on);
+
+#ifdef HAVE_LCD_SLEEP
+void lcd_awake(void);
+#endif
+
+#ifdef BOOTLOADER
+#define _backlight_on()  do { _backlight_hw_enable(true); \
+                              _backlight_led_on(); } while(0)
+#define _backlight_off() do { _backlight_led_off(); \
+                              _backlight_hw_enable(false); } while(0)
+#else /* !BOOTLOADER */
+#define _backlight_on_isr() _backlight_led_on()
+#define _backlight_off_isr() _backlight_led_off()
+#define _backlight_on_normal()  do { _backlight_hw_enable(true); \
+                                     _backlight_led_on(); } while(0)
+#define _backlight_off_normal() do { _backlight_led_off(); \
+                                     _backlight_hw_enable(false); } while(0)
+#define _BACKLIGHT_FADE_ENABLE
+#endif /* !BOOTLOADER */
+
+#elif defined(IPOD_4G) || defined(IPOD_COLOR)
+
+bool _backlight_init(void);
+void _backlight_on(void);
+void _backlight_off(void);
+void _backlight_set_brightness(int val);
+
+#elif defined(IPOD_MINI) || defined(IPOD_MINI2G)
+
+#define _backlight_init() true
+void _backlight_hw_on(void);
+void _backlight_hw_off(void);
+
+#ifdef BOOTLOADER
+#define _backlight_on() _backlight_hw_on()
+#define _backlight_off() _backlight_hw_off()
+#else
+#define _backlight_on_isr() _backlight_hw_on()
+#define _backlight_off_isr() _backlight_hw_off()
+#define _backlight_on_normal() _backlight_hw_on()
+#define _backlight_off_normal() _backlight_hw_off()
+#endif
+
+#elif defined(IPOD_1G2G) || defined(IPOD_3G)
+
+#define _backlight_init() true
+void _backlight_on(void);
+void _backlight_off(void);
+#endif
+
+#endif
diff --git a/firmware/target/arm/portalplayer/ipod/boot.lds b/firmware/target/arm/portalplayer/ipod/boot.lds
new file mode 100644
index 0000000..00a3295
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/boot.lds
@@ -0,0 +1,80 @@
+#include "config.h"
+
+ENTRY(start)
+OUTPUT_FORMAT(elf32-littlearm)
+OUTPUT_ARCH(arm)
+STARTUP(target/arm/portalplayer/crt0-pp-bl.o)
+
+#define DRAMSIZE (MEMORYSIZE * 0x100000)
+
+#if CONFIG_CPU == PP5020
+#define DRAMORIG 0x10000000
+#define IRAMORIG 0x40000000
+#define IRAMSIZE 0x18000
+#define FLASHORIG 0x001f0000
+#define FLASHSIZE 2M
+#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
+#define DRAMORIG 0x10000000
+#ifndef IRAMORIG
+#define IRAMORIG 0x40000000
+#endif
+#define IRAMSIZE 0x20000
+#define FLASHORIG 0x001f0000
+#define FLASHSIZE 2M
+#elif CONFIG_CPU == PP5002
+#define DRAMORIG 0x28000000
+#define IRAMORIG 0x40000000
+#define IRAMSIZE 0x18000
+#define FLASHORIG 0x001f0000
+#define FLASHSIZE 2M
+#endif
+
+MEMORY
+{
+    DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
+    IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
+}
+
+SECTIONS
+{
+  . = IRAMORIG;
+
+  .text : {
+    *(.init.text)
+    *(.text*)
+    *(.glue_7)
+    *(.glue_7t)
+  } > IRAM
+
+  .data : {
+    *(.icode)
+    *(.irodata)
+    *(.idata)
+    *(.data*)
+    *(.ncdata*)
+    *(.rodata*)
+    _dataend = . ;
+  } > IRAM
+
+  .stack (NOLOAD) : {
+     *(.stack)
+     _stackbegin = .;
+     stackbegin = .;
+     . += 0x2000;
+     _stackend = .;
+     stackend = .;
+  } > IRAM
+
+  /* The bss section is too large for IRAM - we just move it 16MB into the
+     DRAM */
+
+  . = DRAMORIG;
+  .bss . + (16*1024*1024) (NOLOAD) : {
+     _edata = .;
+     *(.bss*);
+     *(.ibss);
+     *(COMMON)
+     *(.ncbss*);
+     _end = .;
+  } > DRAM
+}
diff --git a/firmware/target/arm/portalplayer/ipod/button-1g-3g.c b/firmware/target/arm/portalplayer/ipod/button-1g-3g.c
new file mode 100644
index 0000000..045a0f6
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/button-1g-3g.c
@@ -0,0 +1,354 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Daniel Stenberg
+ *
+ * iPod driver based on code from the ipodlinux project - http://ipodlinux.org
+ * Adapted for Rockbox in December 2005
+ * Original file: linux/arch/armnommu/mach-ipod/keyboard.c
+ * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/*
+ * Rockbox button functions
+ */
+
+#include <stdlib.h>
+#include "config.h"
+#include "cpu.h"
+#include "system.h"
+#include "button.h"
+#include "kernel.h"
+#include "backlight.h"
+#include "serial.h"
+#include "power.h"
+#include "powermgmt.h"
+#include "hwcompat.h"
+
+static int int_btn = BUTTON_NONE;
+#ifdef IPOD_1G2G
+/* The 1st Gen wheel draws ~12mA when enabled permanently. Therefore
+ * we only enable it for a very short time to check for changes every
+ * tick, and only keep it enabled if there is activity. */
+#define WHEEL_TIMEOUT (HZ/4)
+#endif
+
+#define WHEELCLICKS_PER_ROTATION  96
+#define WHEEL_BASE_SENSITIVITY     6 /* Compute every ... clicks */
+#define WHEEL_REPEAT_VELOCITY     45 /* deg/s */
+#define WHEEL_SMOOTHING_VELOCITY 100 /* deg/s */
+
+static void handle_scroll_wheel(int new_scroll)
+{
+    static const signed char scroll_state[4][4] = {
+        {0, 1, -1, 0},
+        {-1, 0, 0, 1},
+        {1, 0, 0, -1},
+        {0, -1, 1, 0}
+    };
+
+    static int prev_scroll = -1;
+    static int direction = 0;
+    static int count = 0;
+    static long next_backlight_on = 0;
+
+    static unsigned long last_wheel_usec = 0;
+    static unsigned long wheel_delta = 1ul << 24;
+    static unsigned long wheel_velocity = 0;
+    static int prev_keypost = BUTTON_NONE;
+
+    int wheel_keycode = BUTTON_NONE;
+    int scroll;
+    unsigned long usec;
+    unsigned long v;
+
+    if (prev_scroll == -1) {
+        prev_scroll = new_scroll;
+        return;
+    }
+
+    scroll = scroll_state[prev_scroll][new_scroll];
+    prev_scroll = new_scroll;
+
+    if (direction != scroll) {
+        /* direction reversal or was hold - reset all */
+        direction = scroll;
+        prev_keypost = BUTTON_NONE;
+        wheel_velocity = 0;
+        wheel_delta = 1ul << 24;
+        count = 0;
+    }
+
+    /* poke backlight every 1/4s of activity */
+    if (TIME_AFTER(current_tick, next_backlight_on)) {
+        backlight_on();
+        reset_poweroff_timer();
+        next_backlight_on = current_tick + HZ/4;
+    }
+
+    /* has wheel travelled far enough? */
+    if (++count < WHEEL_BASE_SENSITIVITY) {
+        return;
+    }
+
+    /* reset travel count and do calculations */
+    count = 0;
+
+    /* 1st..3rd Gen wheel has inverse direction mapping
+     * compared to Mini 1st Gen wheel. */
+    switch (direction) {
+        case 1:
+            wheel_keycode = BUTTON_SCROLL_BACK;
+            break;
+        case -1:
+            wheel_keycode = BUTTON_SCROLL_FWD;
+            break;
+        default:
+            /* only happens if we get out of sync */
+            return;
+    }
+
+    /* have a keycode */
+
+    usec = USEC_TIMER;
+    v = usec - last_wheel_usec;
+
+    /* calculate deg/s based upon sensitivity-adjusted interrupt period */
+
+    if ((long)v <= 0) {
+        /* timer wrapped (no activity for awhile), skip acceleration */
+        v = 0;
+        wheel_delta = 1ul << 24;
+    }
+    else {
+        if (v > 0xfffffffful/WHEELCLICKS_PER_ROTATION) {
+            v = 0xfffffffful/WHEELCLICKS_PER_ROTATION; /* check overflow below */
+        }
+
+        v = 360000000ul*WHEEL_BASE_SENSITIVITY / (v*WHEELCLICKS_PER_ROTATION);
+
+        if (v > 0xfffffful)
+            v = 0xfffffful; /* limit to 24 bits */
+    }
+
+    if (v < WHEEL_SMOOTHING_VELOCITY) {
+        /* very slow - no smoothing */
+        wheel_velocity = v;
+        /* ensure backlight never gets stuck for an extended period if tick
+         * wrapped such that next poke is very far ahead */
+        next_backlight_on = current_tick - 1;
+    }
+    else {
+        /* some velocity filtering to smooth things out */
+        wheel_velocity = (7*wheel_velocity + v) / 8;
+    }
+
+    if (queue_empty(&button_queue)) {
+        int key = wheel_keycode;
+
+        if (v >= WHEEL_REPEAT_VELOCITY && prev_keypost == key) {
+            /* quick enough and same key is being posted more than once in a
+             * row - generate repeats - use unsmoothed v to guage */
+            key |= BUTTON_REPEAT;
+        }
+
+        prev_keypost = wheel_keycode;
+
+        /* post wheel keycode with wheel data */
+        queue_post(&button_queue, key,
+                   (wheel_velocity >= WHEEL_ACCEL_START ? (1ul << 31) : 0)
+                    | wheel_delta | wheel_velocity);
+        /* message posted - reset delta */
+        wheel_delta = 1ul << 24;
+    }
+    else {
+        /* skipped post - increment delta and limit to 7 bits */
+        wheel_delta += 1ul << 24;
+
+        if (wheel_delta > (0x7ful << 24))
+            wheel_delta = 0x7ful << 24;
+    }
+
+    last_wheel_usec = usec;
+}
+
+static int ipod_3g_button_read(void)
+{
+    unsigned char source, state;
+    int btn = BUTTON_NONE;
+    
+    /* get source of interupts */
+    source = GPIOA_INT_STAT;
+
+    /* get current keypad status */
+    state = GPIOA_INPUT_VAL;
+    
+    /* toggle interrupt level */
+    GPIOA_INT_LEV = ~state;
+
+    /* ack any active interrupts */
+    GPIOA_INT_CLR = source;
+
+#ifdef IPOD_3G
+    static bool was_hold = false;
+
+    if (was_hold && source == 0x40 && state == 0xbf) {
+        return BUTTON_NONE;
+    }
+    was_hold = false;
+
+    if ((state & 0x20) == 0) {
+        /* 3g hold switch is active low */
+        was_hold = true;
+        /* hold switch on 3g causes all outputs to go low */
+        /* we shouldn't interpret these as key presses */
+        return BUTTON_NONE;
+    }
+#elif defined IPOD_1G2G
+    if (state & 0x20) {
+        /* 1g/2g hold switch is active high */
+        return BUTTON_NONE;
+    }
+#endif
+    if ((state & 0x1) == 0) {
+        btn |= BUTTON_RIGHT;
+    }
+    if ((state & 0x2) == 0) {
+        btn |= BUTTON_SELECT;
+    }
+    if ((state & 0x4) == 0) {
+        btn |= BUTTON_PLAY;
+    }
+    if ((state & 0x8) == 0) {
+        btn |= BUTTON_LEFT;
+    }
+    if ((state & 0x10) == 0) {
+        btn |= BUTTON_MENU;
+    }
+
+    if (source & 0xc0) {
+        handle_scroll_wheel((state & 0xc0) >> 6);
+    }
+
+    return btn;
+}
+
+void ipod_3g_button_int(void)
+{
+    CPU_INT_DIS = GPIO_MASK;
+    int_btn = ipod_3g_button_read();
+    CPU_INT_EN = GPIO_MASK;
+}
+
+void button_init_device(void)
+{
+    GPIOA_ENABLE = 0xff;
+    GPIOA_OUTPUT_EN = 0;
+
+    GPIOA_INT_LEV = ~GPIOA_INPUT_VAL;
+    GPIOA_INT_CLR = GPIOA_INT_STAT;
+
+#ifdef IPOD_1G2G
+    if ((IPOD_HW_REVISION >> 16) == 1)
+    {   /* enable scroll wheel */
+        GPIOB_ENABLE |= 0x01;
+        GPIOB_OUTPUT_EN |= 0x01;
+        GPIOB_OUTPUT_VAL |= 0x01;
+    }
+#endif
+    GPIOA_INT_EN  = 0xff;
+
+    CPU_INT_EN = GPIO_MASK;
+}
+
+/*
+ * Get button pressed from hardware
+ */
+int button_read_device(void)
+{
+    static bool hold_button = false;
+    bool hold_button_old;
+#ifdef IPOD_1G2G
+    static int wheel_timeout = 0;
+    static unsigned char last_wheel_value = 0;
+    unsigned char wheel_value;
+
+    if ((IPOD_HW_REVISION >> 16) == 1)
+    {
+        if (!hold_button && (wheel_timeout == 0))
+        {
+            GPIOB_OUTPUT_VAL |= 0x01; /* enable wheel */
+            udelay(50);               /* let the voltage settle */
+        }
+        wheel_value = GPIOA_INPUT_VAL >> 6;
+        if (wheel_value != last_wheel_value)
+        {
+            last_wheel_value = wheel_value;
+            wheel_timeout = WHEEL_TIMEOUT; /* keep wheel enabled */
+            GPIOA_INT_EN = 0xff;      /* enable wheel interrupts */
+        }
+        if (wheel_timeout)
+            wheel_timeout--;
+        else
+        {
+            GPIOA_INT_EN = 0x3f;       /* disable wheel interrupts */
+            GPIOB_OUTPUT_VAL &= ~0x01; /* disable wheel */
+        }
+    }
+#endif
+
+    /* normal buttons */
+    hold_button_old = hold_button;
+    hold_button = button_hold();
+
+    if (hold_button != hold_button_old)
+        backlight_hold_changed(hold_button);
+
+    return int_btn;
+}
+
+bool button_hold(void)
+{
+#ifdef IPOD_1G2G
+    return (GPIOA_INPUT_VAL & 0x20);
+#else
+    return !(GPIOA_INPUT_VAL & 0x20);
+#endif
+}
+
+bool headphones_inserted(void)
+{
+#ifdef IPOD_1G2G
+    if ((IPOD_HW_REVISION >> 16) == 2)
+    {
+        /* 2G uses GPIO B bit 0 */
+        return (GPIOB_INPUT_VAL & 0x1)?true:false;
+    }
+    else
+    {
+        /* 1G has no headphone detection, so fake insertion */
+        return (true);
+    }
+#else
+    /* 3G uses GPIO C bit 0 */
+    return (GPIOC_INPUT_VAL & 0x1)?true:false;
+#endif
+}
+
+
diff --git a/firmware/target/arm/portalplayer/ipod/button-clickwheel.c b/firmware/target/arm/portalplayer/ipod/button-clickwheel.c
new file mode 100644
index 0000000..2c15e0e
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/button-clickwheel.c
@@ -0,0 +1,472 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Daniel Stenberg
+ *
+ * iPod driver based on code from the ipodlinux project - http://ipodlinux.org
+ * Adapted for Rockbox in December 2005
+ * Original file: linux/arch/armnommu/mach-ipod/keyboard.c
+ * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/*
+ * Rockbox button functions
+ */
+
+#include <stdlib.h>
+#include "config.h"
+#include "cpu.h"
+#include "system.h"
+#include "button.h"
+#include "kernel.h"
+#include "backlight.h"
+#include "serial.h"
+#include "power.h"
+#include "powermgmt.h"
+#if defined(IPOD_NANO2G) || defined(IPOD_6G)
+#include "pmu-target.h"
+#endif
+
+#define WHEEL_FAST_OFF_TIMEOUT   250000 /* timeout for acceleration = 250ms */
+#define WHEEL_REPEAT_TIMEOUT     250000 /* timeout for button repeat = 250ms */
+#define WHEEL_UNTOUCH_TIMEOUT    150000 /* timeout for untouching wheel = 150ms */
+
+#ifdef CPU_PP
+#define CLICKWHEEL_DATA   (*(volatile unsigned long*)(0x7000c140))
+#elif CONFIG_CPU==S5L8701 || CONFIG_CPU==S5L8702
+#define CLICKWHEEL_DATA   WHEELRX
+#else
+#error CPU architecture not supported!
+#endif
+
+#define WHEELCLICKS_PER_ROTATION     96 /* wheelclicks per full rotation */
+
+/* This amount of clicks is needed for at least scrolling 1 item. Choose small values 
+ * to have high sensitivity but few precision, choose large values to have less 
+ * sensitivity and good precision. */
+#if defined(IPOD_NANO) || defined(IPOD_NANO2G)
+#define WHEEL_SENSITIVITY 6 /* iPod nano has smaller wheel, lower sensitivity needed */
+#else
+#define WHEEL_SENSITIVITY 4 /* default sensitivity */
+#endif
+
+int  old_wheel_value  = -1;
+int  new_wheel_value  = 0;
+int  repeat           = 0;
+int  wheel_delta      = 0;
+bool wheel_is_touched = false;
+unsigned int  accumulated_wheel_delta = 0;
+unsigned int  wheel_repeat            = 0;
+unsigned int  wheel_velocity          = 0;
+unsigned long last_wheel_usec         = 0;
+
+/* Variable to use for setting button status in interrupt handler */
+int int_btn = BUTTON_NONE;
+#ifdef HAVE_WHEEL_POSITION
+    static int wheel_position = -1;
+    static bool send_events = true;
+#endif
+
+#if CONFIG_CPU==S5L8701 || CONFIG_CPU==S5L8702
+static struct semaphore button_init_wakeup;
+#endif
+
+#if CONFIG_CPU==S5L8702
+static long holdswitch_last_read;
+static bool holdswitch_last_value;
+#endif
+
+#ifdef CPU_PP
+static void opto_i2c_init(void)
+{
+    DEV_EN |= DEV_OPTO;
+    DEV_RS |= DEV_OPTO;
+    udelay(5);
+    DEV_RS &= ~DEV_OPTO; /* finish reset */
+    DEV_INIT1 |= INIT_BUTTONS; /* enable buttons (needed for "hold"-detection) */
+
+    outl(0xc00a1f00, 0x7000c100);
+    outl(0x01000000, 0x7000c104);
+}
+#endif
+
+static inline int ipod_4g_button_read(void)
+{
+    int whl = -1;
+    int btn = BUTTON_NONE;
+
+#ifdef CPU_PP    
+    if ((inl(0x7000c104) & 0x04000000) != 0) 
+    {
+#endif
+        unsigned status = CLICKWHEEL_DATA;
+
+        if ((status & 0x800000ff) == 0x8000001a) 
+        {
+            if (status & 0x00000100)
+                btn |= BUTTON_SELECT;
+            if (status & 0x00000200)
+                btn |= BUTTON_RIGHT;
+            if (status & 0x00000400)
+                btn |= BUTTON_LEFT;
+            if (status & 0x00000800)
+                btn |= BUTTON_PLAY;
+            if (status & 0x00001000)
+                btn |= BUTTON_MENU;
+            if (status & 0x40000000) 
+            {
+                unsigned long usec = USEC_TIMER;
+                
+                /* Highest wheel = 0x5F, clockwise increases */
+                new_wheel_value = (status >> 16) & 0x7f;
+                whl = new_wheel_value;
+                
+                /* switch on backlight (again), reset power-off timer */
+                backlight_on();
+                reset_poweroff_timer();
+                
+                /* Check whether the scrollwheel was untouched by accident or by will. */
+                /* This is needed because wheel may be untoched very shortly during rotation */
+                if ( (!wheel_is_touched) && TIME_AFTER(usec, last_wheel_usec + WHEEL_UNTOUCH_TIMEOUT) )
+                {
+                    /* wheel has been really untouched -> reset internal variables */
+                    old_wheel_value         = -1;
+                    wheel_velocity          = 0;
+                    accumulated_wheel_delta = 0;
+                    wheel_repeat            = BUTTON_NONE;
+                }
+                else
+                {
+                    /* wheel was shortly untouched by accident -> leave internal variables */
+                    wheel_is_touched = true;
+                }
+
+                if (old_wheel_value >= 0)
+                {
+                    /* This is for later = BUTTON_SCROLL_TOUCH;*/
+                    wheel_delta = new_wheel_value - old_wheel_value;
+                    unsigned int wheel_keycode = BUTTON_NONE;
+
+                    /* Taking into account wrapping during transition from highest 
+                     * to lowest wheel position and back */
+                    if      (wheel_delta < -WHEELCLICKS_PER_ROTATION/2)
+                        wheel_delta += WHEELCLICKS_PER_ROTATION; /* Forward wrapping case */
+                    else if (wheel_delta >  WHEELCLICKS_PER_ROTATION/2)
+                        wheel_delta -= WHEELCLICKS_PER_ROTATION; /* Backward wrapping case */
+    
+                    /* Getting direction and wheel_keycode from wheel_delta.
+                     * Need at least some clicks to be sure to avoid haptic fuzziness */
+                    if      (wheel_delta >=  WHEEL_SENSITIVITY)
+                        wheel_keycode = BUTTON_SCROLL_FWD;
+                    else if (wheel_delta <= -WHEEL_SENSITIVITY)
+                        wheel_keycode = BUTTON_SCROLL_BACK;
+                    else 
+                        wheel_keycode = BUTTON_NONE;
+
+                    if (wheel_keycode != BUTTON_NONE)
+                    {
+                        long v = (usec - last_wheel_usec) & 0x7fffffff;
+                        
+                        /* undo signedness */
+                        wheel_delta = (wheel_delta>0) ? wheel_delta : -wheel_delta;
+                        
+                        /* add the current wheel_delta */
+                        accumulated_wheel_delta += wheel_delta;
+
+                        v = v ? (1000000 * wheel_delta) / v : 0;  /* clicks/sec = 1000000 * clicks/usec */
+                        v = (v * 360) / WHEELCLICKS_PER_ROTATION; /* conversion to degree/sec */
+                        v = (v<0) ? -v : v;                       /* undo signedness */
+            
+                        /* some velocity filtering to smooth things out */
+                        wheel_velocity = (15 * wheel_velocity + v) / 16;
+                        /* limit to 24 bit */
+                        wheel_velocity = (wheel_velocity>0xffffff) ? 0xffffff : wheel_velocity;
+
+                        /* assume REPEAT = off */
+                        repeat = 0;
+                        
+                        /* direction reversals must nullify acceleration and accumulator */
+                        if (wheel_keycode != wheel_repeat)
+                        {
+                            wheel_repeat            = wheel_keycode;
+                            wheel_velocity          = 0;
+                            accumulated_wheel_delta = 0;
+                        }
+                        /* on same direction REPEAT is assumed when new click is within timeout */
+                        else if (TIME_BEFORE(usec, last_wheel_usec + WHEEL_REPEAT_TIMEOUT))
+                        {
+                            repeat = BUTTON_REPEAT;
+                        }
+                        /* timeout nullifies acceleration and accumulator */
+                        if (TIME_AFTER(usec, last_wheel_usec + WHEEL_FAST_OFF_TIMEOUT))
+                        {
+                            wheel_velocity          = 0;
+                            accumulated_wheel_delta = 0;
+                        }
+
+#ifdef HAVE_WHEEL_POSITION
+                        if (send_events) 
+#endif
+                        /* The queue should have no other events when scrolling */
+                        if (queue_empty(&button_queue))
+                        {
+                            /* each WHEEL_SENSITIVITY clicks = scrolling 1 item */
+                            accumulated_wheel_delta /= WHEEL_SENSITIVITY;
+#ifdef HAVE_SCROLLWHEEL
+                            /* use data-format for HAVE_SCROLLWHEEL */
+                            /* always use acceleration mode (1<<31) */
+                            /* always set message post count to (1<<24) for iPod */
+                            /* this way the scrolling is always calculated from wheel_velocity */
+                            queue_post(&button_queue, wheel_keycode | repeat, 
+                                       (1<<31) | (1 << 24) | wheel_velocity);
+                                       
+#else
+                            queue_post(&button_queue, wheel_keycode | repeat, 
+                                       (accumulated_wheel_delta << 16) | new_wheel_value);
+#endif
+                            accumulated_wheel_delta = 0;
+                        }
+                        last_wheel_usec = usec;
+                        old_wheel_value = new_wheel_value;
+                    }
+                }
+                else
+                {
+                    /* scrollwheel was touched for the first time after finger lifting */
+                    old_wheel_value = new_wheel_value;
+                    wheel_is_touched = true;
+                }
+            }
+            else
+            {
+                /* In this case the finger was lifted from the scrollwheel. */
+                wheel_is_touched = false; 
+            }
+
+        }
+#if CONFIG_CPU==S5L8701 || CONFIG_CPU==S5L8702
+        else if ((status & 0x8000FFFF) == 0x8000023A)
+        {
+            if (status & 0x00010000)
+                btn |= BUTTON_SELECT;
+            if (status & 0x00020000)
+                btn |= BUTTON_RIGHT;
+            if (status & 0x00040000)
+                btn |= BUTTON_LEFT;
+            if (status & 0x00080000)
+                btn |= BUTTON_PLAY;
+            if (status & 0x00100000)
+                btn |= BUTTON_MENU;
+            semaphore_release(&button_init_wakeup);
+        }
+#endif
+
+#ifdef CPU_PP    
+    }
+#endif
+
+#ifdef HAVE_WHEEL_POSITION
+    /* Save the new absolute wheel position */
+    wheel_position = whl;
+#endif
+    return btn;
+}
+
+#ifdef HAVE_WHEEL_POSITION
+int wheel_status(void)
+{
+    return wheel_position;
+}
+ 
+void wheel_send_events(bool send)
+{
+    send_events = send;
+}
+#endif
+
+#ifdef CPU_PP
+void ipod_4g_button_int(void)
+{
+    CPU_HI_INT_DIS = I2C_MASK;
+
+    /* The following delay was 250 in the ipodlinux source, but 50 seems to 
+       work fine - tested on Nano, Color/Photo and Video. */
+    udelay(50);
+
+    int_btn = ipod_4g_button_read();
+    
+    outl(inl(0x7000c104) | 0x0c000000, 0x7000c104);
+    outl(0x400a1f00, 0x7000c100);
+
+    CPU_HI_INT_EN = I2C_MASK;
+}
+
+void button_init_device(void)
+{
+    opto_i2c_init();
+    
+    /* hold button - enable as input */
+    GPIOA_ENABLE |= 0x20;
+    GPIOA_OUTPUT_EN &= ~0x20; 
+    
+    /* unmask interrupt */
+    CPU_INT_EN = HI_MASK;
+    CPU_HI_INT_EN = I2C_MASK;
+}
+
+bool button_hold(void)
+{
+    return (GPIOA_INPUT_VAL & 0x20)?false:true;
+}
+
+bool headphones_inserted(void)
+{
+    return (GPIOA_INPUT_VAL & 0x80)?true:false;
+}
+#else
+void INT_WHEEL(void)
+{
+    int clickwheel_events = WHEELINT;
+
+    /* Clear interrupts */
+    if (clickwheel_events & 4) WHEELINT = 4;
+    if (clickwheel_events & 2) WHEELINT = 2;
+    if (clickwheel_events & 1) WHEELINT = 1;
+
+    int_btn = ipod_4g_button_read();
+}
+
+static void s5l_clickwheel_init(void)
+{
+#if CONFIG_CPU==S5L8701
+    PWRCONEXT &= ~1;
+    PCON15 = (PCON15 & ~0xFFFF0000) | 0x22220000;
+    PUNK15 = 0xF0;
+    WHEEL08 = 0x3A980;
+    WHEEL00 = 0x280000;
+    WHEEL10 = 3;
+    PCON10 = (PCON10 & ~0xFF0) | 0x10;
+    PDAT10 |= 2;
+    WHEELTX = 0x8000023A;
+    WHEEL04 |= 1;
+    PDAT10 &= ~2;
+#elif CONFIG_CPU==S5L8702
+    //TODO: Implement
+#endif
+}
+
+void button_init_device(void)
+{
+    semaphore_init(&button_init_wakeup, 1, 0);
+#if CONFIG_CPU==S5L8701
+    INTMSK |= (1<<26);
+#elif CONFIG_CPU==S5L8702
+    holdswitch_last_read = USEC_TIMER;
+    holdswitch_last_value = (pmu_read(0x87) & 2) == 0;
+#endif
+    s5l_clickwheel_init();
+    semaphore_wait(&button_init_wakeup, HZ / 10);
+}
+
+bool button_hold(void)
+{
+#if CONFIG_CPU==S5L8701
+    bool value = (PDAT14 & (1 << 6)) == 0;
+    if (value)
+        PCON15 = PCON15 & ~0xffff0000;
+    else PCON15 = (PCON15 & ~0xffff0000) | 0x22220000;
+    return value;
+#elif CONFIG_CPU==S5L8702
+    if (USEC_TIMER - holdswitch_last_read > 100000)
+    {
+        holdswitch_last_read = USEC_TIMER;
+        holdswitch_last_value = (pmu_read(0x87) & 2) == 0;
+    }
+    if (holdswitch_last_value)
+        PCON(14) = PCON(14) & ~0xffffff00;
+    else PCON(14) = (PCON(14) & ~0xffffff00) | 0x22222200;
+    return holdswitch_last_value;
+#endif
+}
+
+bool headphones_inserted(void)
+{
+#if CONFIG_CPU==S5L8701
+    return ((PDAT14 & (1 << 5)) != 0);
+#elif CONFIG_CPU==S5L8702
+    return ((PDATA & (1 << 6)) != 0);
+    return false;
+#endif
+}
+#endif
+
+/*
+ * Get button pressed from hardware
+ */
+int button_read_device(void)
+{
+    static bool hold_button = false;
+    bool hold_button_old;
+
+    /* normal buttons */
+    hold_button_old = hold_button;
+    hold_button = button_hold();
+
+    if (hold_button != hold_button_old)
+    {
+#ifndef BOOTLOADER
+        backlight_hold_changed(hold_button);
+#endif
+        
+        if (hold_button)
+        {
+#ifdef CPU_PP
+            /* lock -> disable wheel sensor */
+            DEV_EN &= ~DEV_OPTO;
+#elif CONFIG_CPU==S5L8701
+            pmu_ldo_power_off(1); /* disable clickwheel power supply */
+            WHEEL00 = 0;
+            WHEEL10 = 0;
+            PWRCONEXT |= 1;
+#elif CONFIG_CPU==S5L8702
+            //TODO: Implement
+#endif
+        }
+        else
+        {
+#ifdef CPU_PP
+            /* unlock -> enable wheel sensor */
+            DEV_EN |= DEV_OPTO;
+            opto_i2c_init();
+#elif CONFIG_CPU==S5L8701
+            pmu_ldo_power_on(1); /* enable clickwheel power supply */
+            s5l_clickwheel_init();
+#elif CONFIG_CPU==S5L8702
+            //TODO: Implement
+#endif
+        }
+    }
+
+    /* The int_btn variable is set in the button interrupt handler */
+#ifdef IPOD_ACCESSORY_PROTOCOL
+    return int_btn | remote_control_rx();
+#else
+    return int_btn;
+#endif
+}
diff --git a/firmware/target/arm/portalplayer/ipod/button-mini1g.c b/firmware/target/arm/portalplayer/ipod/button-mini1g.c
new file mode 100644
index 0000000..d4a75c9
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/button-mini1g.c
@@ -0,0 +1,296 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Daniel Stenberg
+ *
+ * iPod driver based on code from the ipodlinux project - http://ipodlinux.org
+ * Adapted for Rockbox in December 2005
+ * Original file: linux/arch/armnommu/mach-ipod/keyboard.c
+ * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/*
+ * Rockbox button functions
+ */
+
+#include <stdlib.h>
+#include "config.h"
+#include "cpu.h"
+#include "system.h"
+#include "button.h"
+#include "kernel.h"
+#include "backlight.h"
+#include "serial.h"
+#include "power.h"
+#include "powermgmt.h"
+
+#define WHEELCLICKS_PER_ROTATION  96
+#define WHEEL_BASE_SENSITIVITY     6 /* Compute every ... clicks */
+#define WHEEL_REPEAT_VELOCITY     45 /* deg/s */
+#define WHEEL_SMOOTHING_VELOCITY 100 /* deg/s */
+
+/* Variable to use for setting button status in interrupt handler */
+int int_btn = BUTTON_NONE;
+
+static void handle_scroll_wheel(int new_scroll)
+{
+    static const signed char scroll_state[4][4] = {
+        {0, 1, -1, 0},
+        {-1, 0, 0, 1},
+        {1, 0, 0, -1},
+        {0, -1, 1, 0}
+    };
+
+    static int prev_scroll = -1;
+    static int direction = 0;
+    static int count = 0;
+    static long next_backlight_on = 0;
+
+    int wheel_keycode = BUTTON_NONE;
+    int scroll;
+
+    static unsigned long wheel_delta = 1ul << 24;
+    static unsigned long wheel_velocity = 0;
+    static unsigned long last_wheel_usec = 0;
+    static int prev_keypost = BUTTON_NONE;
+
+    unsigned long usec;
+    unsigned long v;
+
+    if ( prev_scroll == -1 ) {
+        prev_scroll = new_scroll;
+        return;
+    }
+    
+    scroll = scroll_state[prev_scroll][new_scroll];
+    prev_scroll = new_scroll;
+
+    if (direction != scroll) {
+        /* direction reversal or was hold - reset all */
+        direction = scroll;
+        count = 0;
+        prev_keypost = BUTTON_NONE;
+        wheel_velocity = 0;
+        wheel_delta = 1ul << 24;
+        return;
+    }
+
+   /* poke backlight every 1/4s of activity */
+    if (TIME_AFTER(current_tick, next_backlight_on)) {
+        backlight_on();
+        reset_poweroff_timer();
+        next_backlight_on = current_tick + HZ/4;
+    }
+
+    if (++count < WHEEL_BASE_SENSITIVITY)
+        return;
+
+    count = 0;
+    /* Mini 1st Gen wheel has inverse direction mapping
+     * compared to 1st..3rd Gen wheel. */
+    switch (direction) {
+        case 1:
+            wheel_keycode = BUTTON_SCROLL_FWD;
+            break;
+        case -1:
+            wheel_keycode = BUTTON_SCROLL_BACK;
+            break;
+        default:
+            /* only happens if we get out of sync */
+            break;
+    }
+
+    /* have a keycode */
+
+    usec = USEC_TIMER;
+    v = usec - last_wheel_usec;
+
+    /* calculate deg/s based upon sensitivity-adjusted interrupt period */
+
+    if ((long)v <= 0) {
+        /* timer wrapped (no activity for awhile), skip acceleration */
+        v = 0;
+        wheel_delta = 1ul << 24;
+    }
+    else {
+        if (v > 0xfffffffful/WHEELCLICKS_PER_ROTATION) {
+            v = 0xfffffffful/WHEELCLICKS_PER_ROTATION; /* check overflow below */
+        }
+
+        v = 360000000ul*WHEEL_BASE_SENSITIVITY / (v*WHEELCLICKS_PER_ROTATION);
+
+        if (v > 0xfffffful)
+            v = 0xfffffful; /* limit to 24 bits */
+    }
+
+    if (v < WHEEL_SMOOTHING_VELOCITY) {
+        /* very slow - no smoothing */
+        wheel_velocity = v;
+        /* ensure backlight never gets stuck for an extended period if tick
+         * wrapped such that next poke is very far ahead */
+        next_backlight_on = current_tick - 1;
+    }
+    else {
+        /* some velocity filtering to smooth things out */
+        wheel_velocity = (7*wheel_velocity + v) / 8;
+    }
+
+    if (queue_empty(&button_queue)) {
+        int key = wheel_keycode;
+
+        if (v >= WHEEL_REPEAT_VELOCITY && prev_keypost == key) {
+            /* quick enough and same key is being posted more than once in a
+             * row - generate repeats - use unsmoothed v to guage */
+            key |= BUTTON_REPEAT;
+        }
+
+        prev_keypost = wheel_keycode;
+
+        /* post wheel keycode with wheel data */
+        queue_post(&button_queue, key,
+                   (wheel_velocity >= WHEEL_ACCEL_START ? (1ul << 31) : 0)
+                    | wheel_delta | wheel_velocity);
+        /* message posted - reset delta */
+        wheel_delta = 1ul << 24;
+    }
+    else {
+        /* skipped post - increment delta and limit to 7 bits */
+        wheel_delta += 1ul << 24;
+
+        if (wheel_delta > (0x7ful << 24))
+            wheel_delta = 0x7ful << 24;
+    }
+
+    last_wheel_usec = usec;
+}
+
+/* mini 1 only, mini 2G uses iPod 4G code */
+static int ipod_mini_button_read(void)
+{
+    unsigned char source, wheel_source, state, wheel_state;
+    int btn = BUTTON_NONE;
+
+    /* The ipodlinux source had a udelay(250) here, but testing has shown that
+       it is not needed - tested on mini 1g. */
+    /* udelay(250);*/
+
+    /* get source(s) of interupt */
+    source = GPIOA_INT_STAT & 0x3f;
+    wheel_source = GPIOB_INT_STAT & 0x30;
+
+    if (source == 0 && wheel_source == 0) {
+        return BUTTON_NONE; /* not for us */
+    }
+
+    /* get current keypad & wheel status */
+    state = GPIOA_INPUT_VAL & 0x3f;
+    wheel_state = GPIOB_INPUT_VAL & 0x30;
+
+    /* toggle interrupt level */
+    GPIOA_INT_LEV = ~state;
+    GPIOB_INT_LEV = ~wheel_state;
+
+   /* ack any active interrupts */
+    if (source)
+        GPIOA_INT_CLR = source;
+    if (wheel_source)
+        GPIOB_INT_CLR = wheel_source;
+
+   if (button_hold())
+        return BUTTON_NONE;
+
+    /* hold switch causes all outputs to go low    */
+    /* we shouldn't interpret these as key presses */
+        if (!(state & 0x1))
+            btn |= BUTTON_SELECT;
+        if (!(state & 0x2))
+            btn |= BUTTON_MENU;
+        if (!(state & 0x4))
+            btn |= BUTTON_PLAY;
+        if (!(state & 0x8))
+            btn |= BUTTON_RIGHT;
+        if (!(state & 0x10))
+            btn |= BUTTON_LEFT;
+
+        if (wheel_source & 0x30) {
+            handle_scroll_wheel((wheel_state & 0x30) >> 4);
+        }
+
+    return btn;
+}
+
+void ipod_mini_button_int(void)
+{
+    CPU_HI_INT_DIS = GPIO0_MASK;
+    int_btn = ipod_mini_button_read();
+    //CPU_INT_EN = 0x40000000;
+    CPU_HI_INT_EN = GPIO0_MASK;
+}
+
+void button_init_device(void)
+{
+    /* iPod Mini G1 */
+    /* buttons - enable as input */
+    GPIOA_ENABLE |= 0x3f;
+    GPIOA_OUTPUT_EN &= ~0x3f;
+    /* scroll wheel- enable as input */
+    GPIOB_ENABLE |= 0x30; /* port b 4,5 */
+    GPIOB_OUTPUT_EN &= ~0x30; /* port b 4,5 */
+    /* buttons - set interrupt levels */
+    GPIOA_INT_LEV = ~(GPIOA_INPUT_VAL & 0x3f);
+    GPIOA_INT_CLR = GPIOA_INT_STAT & 0x3f;
+    /* scroll wheel - set interrupt levels */
+    GPIOB_INT_LEV = ~(GPIOB_INPUT_VAL & 0x30);
+    GPIOB_INT_CLR = GPIOB_INT_STAT & 0x30;
+    /* enable interrupts */
+    GPIOA_INT_EN = 0x3f;
+    GPIOB_INT_EN = 0x30;
+    /* unmask interrupt */
+    CPU_INT_EN = 0x40000000;
+    CPU_HI_INT_EN = GPIO0_MASK;
+}
+
+/*
+ * Get button pressed from hardware
+ */
+int button_read_device(void)
+{
+    static bool hold_button = false;
+    bool hold_button_old;
+
+    /* normal buttons */
+    hold_button_old = hold_button;
+    hold_button = button_hold();
+
+    if (hold_button != hold_button_old)
+        backlight_hold_changed(hold_button);
+
+    /* The int_btn variable is set in the button interrupt handler */
+    return int_btn;
+}
+
+bool button_hold(void)
+{
+    return (GPIOA_INPUT_VAL & 0x20)?false:true;
+}
+
+bool headphones_inserted(void)
+{
+    return (GPIOA_INPUT_VAL & 0x80)?true:false;
+}
diff --git a/firmware/target/arm/portalplayer/ipod/button-target.h b/firmware/target/arm/portalplayer/ipod/button-target.h
new file mode 100644
index 0000000..67bdc72
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/button-target.h
@@ -0,0 +1,78 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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 _BUTTON_TARGET_H_
+#define _BUTTON_TARGET_H_
+
+#include <stdbool.h>
+#include "config.h"
+
+#define HAS_BUTTON_HOLD
+
+bool button_hold(void);
+void button_init_device(void);
+int button_read_device(void);
+
+void ipod_mini_button_int(void);
+void ipod_3g_button_int(void);
+void ipod_4g_button_int(void);
+
+/* iPod specific button codes */
+
+#define BUTTON_SELECT       0x00000001
+#define BUTTON_MENU         0x00000002
+
+#define BUTTON_LEFT         0x00000004
+#define BUTTON_RIGHT        0x00000008
+#define BUTTON_SCROLL_FWD   0x00000010
+#define BUTTON_SCROLL_BACK  0x00000020
+
+#define BUTTON_PLAY         0x00000040
+
+#define BUTTON_MAIN (BUTTON_SELECT|BUTTON_MENU\
+                |BUTTON_LEFT|BUTTON_RIGHT|BUTTON_SCROLL_FWD\
+                |BUTTON_SCROLL_BACK|BUTTON_PLAY)
+
+    /* Remote control's buttons */
+#ifdef IPOD_ACCESSORY_PROTOCOL
+#define BUTTON_RC_PLAY      0x00100000
+#define BUTTON_RC_STOP      0x00080000
+
+#define BUTTON_RC_LEFT      0x00040000
+#define BUTTON_RC_RIGHT     0x00020000
+#define BUTTON_RC_VOL_UP    0x00010000
+#define BUTTON_RC_VOL_DOWN  0x00008000
+
+#define BUTTON_REMOTE (BUTTON_RC_PLAY|BUTTON_RC_STOP\
+                |BUTTON_RC_LEFT|BUTTON_RC_RIGHT\
+                |BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN)
+#else
+#define BUTTON_REMOTE 0
+#endif
+
+/* This is for later
+#define  BUTTON_SCROLL_TOUCH 0x00000200
+*/
+
+
+#define POWEROFF_BUTTON BUTTON_PLAY
+#define POWEROFF_COUNT 40
+
+#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/portalplayer/ipod/lcd-as-color-nano.S b/firmware/target/arm/portalplayer/ipod/lcd-as-color-nano.S
new file mode 100644
index 0000000..f6f9cc5
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/lcd-as-color-nano.S
@@ -0,0 +1,287 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id:$
+ *
+ * Copyright (C) 2010-2011 by Andree Buschmann
+ *
+ * Generic asm helper function used by YUV blitting.
+ *
+ * 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"
+
+/**************************************************************************** 
+ * #define FORCE_FIFO_WAIT
+ *
+ * This is not needed in YUV blitting when the LCD IF is fast enough. In this
+ * case YUV-to-RGB conversion per pixel needs longer than the transfer of a 
+ * pixel via the LCD IF.
+ ****************************************************************************/
+
+#include "config.h"
+
+/* Set FIFO wait for both iPod Color and iPod nano1G until we know for which
+ * devices we can switch this off. */
+#define FORCE_FIFO_WAIT
+
+    .section .icode, "ax", %progbits
+    
+/****************************************************************************
+ * extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
+ *                                    const unsigned LCD_BASE,
+ *                                    int width,
+ *                                    int stride);
+ *
+ *   Conversion from Motion JPEG and MPEG Y'PbPr to RGB is:
+ *   |R|   |1.164  0.000  1.596| |Y' -  16|
+ *   |G| = |1.164 -0.391 -0.813| |Pb - 128|
+ *   |B|   |1.164  2.018  0.000| |Pr - 128|
+ *
+ *   Scaled, normalized, rounded and tweaked to yield RGB 565:
+ *   |R|   |74   0 101| |Y' -  16| >> 9
+ *   |G| = |74 -24 -51| |Cb - 128| >> 8
+ *   |B|   |74 128   0| |Cr - 128| >> 9
+ *
+ * Converts two lines from YUV to RGB565 and writes to LCD at once. First loop
+ * loads Cb/Cr, calculates the chroma offset and saves them to buffer. Within
+ * the second loop these chroma offset are reloaded from buffer. Within each 
+ * loop two pixels are calculated and written to LCD. 
+ */
+    .align      2
+    .global     lcd_write_yuv420_lines
+    .type       lcd_write_yuv420_lines, %function
+lcd_write_yuv420_lines:
+                                      /* r0 = src = yuv_src */
+                                      /* r1 = dst = LCD_BASE */
+                                      /* r2 = width */
+                                      /* r3 = stride */                
+    stmfd       sp!, { r4-r10, lr }   /* save non-scratch */
+    ldmia       r0, { r9, r10, r12 }  /* r9 = yuv_src[0] = Y'_p */
+                                      /* r10 = yuv_src[1] = Cb_p */
+                                      /* r12 = yuv_src[2] = Cr_p */
+    add         r3, r9, r3            /* r3 = &ysrc[stride] */
+    add         r4, r2, r2, asr #1    /* chroma buffer lenght = width/2 *3 */
+    mov         r4, r4, asl #2        /*   use words for str/ldm possibility */
+    add         r4, r4, #19           /*   plus room for 4 additional words, */
+    bic         r4, r4, #3            /*   rounded up to multiples of 4 byte */
+    sub         sp, sp, r4            /*   and allocate on stack */
+    stmia       sp, {r1-r4}           /* LCD_BASE, width, &ysrc[stride], stack_alloc */
+
+    mov         r7, r2                /* r7 = loop count */
+    add         r8, sp, #16           /* chroma buffer */
+    add         lr, r1, #0x100        /* LCD data port = LCD2_BASE + 0x100 */
+
+    /* 1st loop start */
+10:                                   /* loop start */
+
+    ldrb        r0, [r10], #1         /* r0 = *usrc++ = *Cb_p++ */
+    ldrb        r1, [r12], #1         /* r1 = *vsrc++ = *Cr_p++ */
+
+    sub         r0, r0, #128          /* r0 = Cb-128 */
+    sub         r1, r1, #128          /* r1 = Cr-128 */
+
+    add         r2, r1, r1, asl #1    /* r2 = Cr*51 + Cb*24 */
+    add         r2, r2, r2, asl #4   
+    add         r2, r2, r0, asl #3   
+    add         r2, r2, r0, asl #4   
+
+    add         r4, r1, r1, asl #2    /* r1 = Cr*101 */
+    add         r4, r4, r1, asl #5
+    add         r1, r4, r1, asl #6
+
+    add         r1, r1, #256          /* r1 = rv = (r1 + 256) >> 9 */
+    mov         r1, r1, asr #9
+    rsb         r2, r2, #128          /* r2 = guv = (-r2 + 128) >> 8 */
+    mov         r2, r2, asr #8       
+    add         r0, r0, #2            /* r0 = bu = (Cb*128 + 256) >> 9 */
+    mov         r0, r0, asr #2       
+    stmia       r8!, {r0-r2}          /* store r0, r1 and r2 to chroma buffer */
+
+    /* 1st loop, first pixel */
+    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
+    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
+    add         r3, r5, r5, asl #2
+    add         r5, r3, r5, asl #5
+
+    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
+    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
+    add         r4, r0, r5, asr #8    /* r4 = b = (Y >> 9) + bu */
+
+    orr         r5, r6, r4            /* check if clamping is needed... */
+    orr         r5, r5, r3, asr #1    /* ...at all */
+    cmp         r5, #31                 
+    bls         15f                   /* -> no clamp */
+    cmp         r6, #31               /* clamp r */
+    mvnhi       r6, r6, asr #31         
+    andhi       r6, r6, #31             
+    cmp         r3, #63               /* clamp g */
+    mvnhi       r3, r3, asr #31
+    andhi       r3, r3, #63
+    cmp         r4, #31               /* clamp b */
+    mvnhi       r4, r4, asr #31         
+    andhi       r4, r4, #31          
+15:                                   /* no clamp */
+
+    /* calculate pixel_1 and save to r4 for later pixel packing */
+    orr         r4, r4, r3, lsl #5    /* pixel_1 = r<<11 | g<<5 | b */
+    orr         r4, r4, r6, lsl #11   /* r4 = pixel_1 */
+
+    /* 1st loop, second pixel */
+    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
+    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
+    add         r3, r5, r5, asl #2
+    add         r5, r3, r5, asl #5
+
+    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
+    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
+    add         r5, r0, r5, asr #8    /* r5 = b = (Y >> 9) + bu */   
+
+    orr         r0, r6, r5            /* check if clamping is needed... */
+    orr         r0, r0, r3, asr #1    /* ...at all */
+    cmp         r0, #31                 
+    bls         15f                   /* -> no clamp */
+    cmp         r6, #31               /* clamp r */
+    mvnhi       r6, r6, asr #31         
+    andhi       r6, r6, #31             
+    cmp         r3, #63               /* clamp g */
+    mvnhi       r3, r3, asr #31
+    andhi       r3, r3, #63
+    cmp         r5, #31               /* clamp b */
+    mvnhi       r5, r5, asr #31         
+    andhi       r5, r5, #31          
+15:                                   /* no clamp */
+
+    /* calculate pixel_2 and pack with pixel_1 before writing */
+    orr         r5, r5, r3, lsl #5    /* pixel_2 = r<<11 | g<<5 | b */
+    orr         r5, r5, r6, lsl #11   /* r5 = pixel_2 */
+#ifdef FORCE_FIFO_WAIT
+    /* wait for FIFO half full */
+.fifo_wait1:
+    ldr         r3, [lr, #-0xE0]      /* while !(LCD2_BLOCK_CTRL & 0x1000000); */
+    tst         r3, #0x1000000
+    beq         .fifo_wait1
+#endif
+
+    mov         r3, r4, lsl #8        /* swap pixel_1 */
+    and         r3, r3, #0xff00
+    add         r4, r3, r4, lsr #8
+    
+    orr         r4, r4, r5, lsl #24   /* swap pixel_2 and pack with pixel_1 */
+    mov         r5, r5, lsr #8
+    orr         r4, r4, r5, lsl #16
+
+    str         r4, [lr]              /* write pixel_1 and pixel_2 */
+
+    subs        r7, r7, #2            /* check for loop end */
+    bgt         10b                   /* back to beginning  */
+    /* 1st loop end */
+
+    /* Reload several registers for pointer rewinding for next loop */
+    add         r8, sp, #16           /* chroma buffer */
+    ldmia       sp, { r1, r7, r9}     /* r1  = LCD_BASE */
+                                      /* r7  = loop count */
+                                      /* r9 = &ysrc[stride] */   
+
+    /* 2nd loop start */
+20:                                   /* loop start */
+    /* restore r0 (bu), r1 (rv) and r2 (guv) from chroma buffer */
+    ldmia       r8!, {r0-r2}
+
+    /* 2nd loop, first pixel */
+    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
+    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
+    add         r3, r5, r5, asl #2
+    add         r5, r3, r5, asl #5
+
+    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
+    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
+    add         r4, r0, r5, asr #8    /* r4 = b = (Y >> 9) + bu */
+
+    orr         r5, r6, r4            /* check if clamping is needed... */
+    orr         r5, r5, r3, asr #1    /* ...at all */
+    cmp         r5, #31                 
+    bls         15f                   /* -> no clamp */
+    cmp         r6, #31               /* clamp r */
+    mvnhi       r6, r6, asr #31         
+    andhi       r6, r6, #31             
+    cmp         r3, #63               /* clamp g */
+    mvnhi       r3, r3, asr #31
+    andhi       r3, r3, #63
+    cmp         r4, #31               /* clamp b */
+    mvnhi       r4, r4, asr #31         
+    andhi       r4, r4, #31          
+15:                                   /* no clamp */
+    /* calculate pixel_1 and save to r4 for later pixel packing */
+    orr         r4, r4, r3, lsl #5    /* pixel_1 = r<<11 | g<<5 | b */
+    orr         r4, r4, r6, lsl #11   /* r4 = pixel_1 */
+
+    /* 2nd loop, second pixel */
+    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
+    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
+    add         r3, r5, r5, asl #2
+    add         r5, r3, r5, asl #5
+
+    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
+    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
+    add         r5, r0, r5, asr #8    /* r5 = b = (Y >> 9) + bu */
+
+    orr         r0, r6, r5            /* check if clamping is needed... */
+    orr         r0, r0, r3, asr #1    /* ...at all */
+    cmp         r0, #31                 
+    bls         15f                   /* -> no clamp */
+    cmp         r6, #31               /* clamp r */
+    mvnhi       r6, r6, asr #31         
+    andhi       r6, r6, #31             
+    cmp         r3, #63               /* clamp g */
+    mvnhi       r3, r3, asr #31
+    andhi       r3, r3, #63
+    cmp         r5, #31               /* clamp b */
+    mvnhi       r5, r5, asr #31         
+    andhi       r5, r5, #31          
+15:                                   /* no clamp */
+
+    /* calculate pixel_2 and pack with pixel_1 before writing */
+    orr         r5, r5, r3, lsl #5    /* pixel_2 = r<<11 | g<<5 | b */
+    orr         r5, r5, r6, lsl #11   /* r5 = pixel_2 */
+#ifdef FORCE_FIFO_WAIT
+    /* wait for FIFO half full */
+.fifo_wait2:
+    ldr         r3, [lr, #-0xE0]      /* while !(LCD2_BLOCK_CTRL & 0x1000000); */
+    tst         r3, #0x1000000
+    beq         .fifo_wait2
+#endif
+
+    mov         r3, r4, lsl #8        /* swap pixel_1 */
+    and         r3, r3, #0xff00
+    add         r4, r3, r4, lsr #8
+    
+    orr         r4, r4, r5, lsl #24   /* swap pixel_2 and pack with pixel_1 */
+    mov         r5, r5, lsr #8
+    orr         r4, r4, r5, lsl #16
+    
+    str         r4, [lr]              /* write pixel_1 and pixel_2 */
+
+    subs        r7, r7, #2            /* check for loop end */
+    bgt         20b                   /* back to beginning  */
+    /* 2nd loop end */
+
+    ldr         r3, [sp, #12]
+    add         sp, sp, r3            /* deallocate buffer */
+    ldmpc       regs=r4-r10           /* restore registers */
+
+    .ltorg
+    .size   lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
diff --git a/firmware/target/arm/portalplayer/ipod/lcd-as-gray.S b/firmware/target/arm/portalplayer/ipod/lcd-as-gray.S
new file mode 100644
index 0000000..cfd179a
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/lcd-as-gray.S
@@ -0,0 +1,272 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2008 by Jens Arnold
+ *
+ * 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"
+
+#if CONFIG_CPU == PP5002
+    .section    .icode,"ax",%progbits
+#else
+    .text
+#endif
+    .align      2
+
+
+    .global     lcd_write_data
+    .type       lcd_write_data,%function
+
+lcd_write_data:
+    ldr     r12, =LCD1_BASE
+
+.loop:
+    ldrb    r2, [r0], #1
+
+#ifdef IPOD_MINI2G
+    ldrb    r3, [r0], #1
+    orr     r2, r3, r2, lsl #8
+    orr     r2, r2, #0x760000
+1:
+    ldr     r3, [r12]
+    tst     r3, #LCD1_BUSY_MASK
+    bne     1b
+    str     r2, [r12, #0x08]
+#else
+1:
+    ldr     r3, [r12]
+    tst     r3, #LCD1_BUSY_MASK
+    bne     1b
+    str     r2, [r12, #0x10]
+
+    ldrb    r2, [r0], #1
+1:
+    ldr     r3, [r12]
+    tst     r3, #LCD1_BUSY_MASK
+    bne     1b
+    str     r2, [r12, #0x10]
+#endif
+
+    subs    r1, r1, #1
+    bne     .loop
+
+    bx      lr
+    .size   lcd_write_data,.-lcd_write_data
+    
+
+#ifdef IPOD_MINI2G
+
+    .global     lcd_write_data_shifted
+    .type       lcd_write_data_shifted,%function
+    
+lcd_write_data_shifted:
+    stmfd   sp!, {r4, lr}
+    ldr     lr, =LCD1_BASE
+    mov     r12, #0x760000
+    ldrb    r2, [r0], #1
+
+.sloop:
+    ldrb    r3, [r0], #1
+    orr     r2, r3, r2, lsl #8
+    ldrb    r3, [r0], #1
+    orr     r2, r3, r2, lsl #8
+    mov     r4, r2, lsl #12
+    orr     r4, r12, r4, lsr #16
+1:
+    ldr     r3, [lr]
+    tst     r3, #LCD1_BUSY_MASK
+    bne     1b
+    str     r4, [lr, #0x08]
+
+    subs    r1, r1, #1
+    bne     .sloop
+
+    ldmpc   regs=r4
+    .size   lcd_write_data_shifted,.-lcd_write_data_shifted
+    
+#elif defined IPOD_MINI
+
+    .global     lcd_write_data_shifted
+    .type       lcd_write_data_shifted,%function
+    
+lcd_write_data_shifted:
+    str     lr, [sp, #-4]!
+    ldr     lr, =LCD1_BASE
+    ldrb    r2, [r0], #1
+
+.sloop:
+    ldrb    r3, [r0], #1
+    orr     r2, r3, r2, lsl #8
+    mov     r12, r2, lsr #4
+1:
+    ldr     r3, [lr]
+    tst     r3, #LCD1_BUSY_MASK
+    bne     1b
+    str     r12, [lr, #0x10]
+
+    ldrb    r3, [r0], #1
+    orr     r2, r3, r2, lsl #8
+    mov     r12, r2, lsr #4
+1:
+    ldr     r3, [lr]
+    tst     r3, #LCD1_BUSY_MASK
+    bne     1b
+    str     r12, [lr, #0x10]
+
+    subs    r1, r1, #1
+    bne     .sloop
+
+    ldrpc
+    .size   lcd_write_data_shifted,.-lcd_write_data_shifted
+
+#endif
+
+    .global     lcd_mono_data
+    .type       lcd_mono_data,%function
+    
+lcd_mono_data:
+    stmfd   sp!, {r4, lr}
+    ldr     lr, =LCD1_BASE
+    adr     r12, .dibits
+
+.mloop:
+    ldrb    r2, [r0], #1
+    mov     r3, r2, lsr #4
+    ldrb    r4, [r12, r3]
+
+#ifdef IPOD_MINI2G
+    and     r3, r2, #0x0f
+    ldrb    r3, [r12, r3]
+    orr     r4, r3, r4, lsl #8
+    orr     r4, r4, #0x760000
+1:
+    ldr     r3, [lr]
+    tst     r3, #LCD1_BUSY_MASK
+    bne     1b
+    str     r4, [lr, #0x08]
+#else
+1:
+    ldr     r3, [lr]
+    tst     r3, #LCD1_BUSY_MASK
+    bne     1b
+    str     r4, [lr, #0x10]
+
+    and     r3, r2, #0x0f
+    ldrb    r4, [r12, r3]
+1:
+    ldr     r3, [lr]
+    tst     r3, #LCD1_BUSY_MASK
+    bne     1b
+    str     r4, [lr, #0x10]
+#endif
+
+    subs    r1, r1, #1
+    bne     .mloop
+
+    ldmpc   regs=r4
+
+.dibits:
+    .byte   0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F
+    .byte   0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF
+
+    .size   lcd_mono_data,.-lcd_mono_data
+
+
+    .global     lcd_grey_data
+    .type       lcd_grey_data,%function
+
+/* A high performance function to write grey phase data to the display,
+ * one or multiple pixels.
+ *
+ * Arguments:
+ *   r0 - pixel value data address
+ *   r1 - pixel phase data address
+ *   r2 - pixel block count
+ *
+ * Register usage:
+ *   r3/r4 - current block of phases
+ *   r5/r6 - lcd data accumulators
+ *   r6/r7 - current block of values
+ *   r12 - phase signs mask
+ *   lr  - lcd bridge address
+ */
+
+lcd_grey_data:
+    stmfd   sp!, {r4-r7, lr}
+    mov     r12, #0x80
+    orr     r12, r12, r12, lsl #8
+    orr     r12, r12, r12, lsl #16
+    ldr     lr, =LCD1_BASE
+
+.greyloop:
+    ldmia   r1, {r3-r4}         /* Fetch 8 pixel phases */
+
+    bic     r5, r12, r3         /* r5 = 3.......2.......1.......0....... */
+    orr     r5, r5, r5, lsr #10 /* r5 = 3.......2.3.....1.2.....0.1..... */
+    orr     r5, r5, r5, lsr #10 /* r5 = 3.......2.3.....1.2.3...0.1.2... */
+    orr     r5, r5, r5, lsr #10 /* r5 = 3.......2.3.....1.2.3...0.1.2.3. */
+    orr     r5, r5, r5, lsr #1  /* r5 = 33......2233....112233..00112233 */
+    bic     r3, r3, r12
+
+#ifndef IPOD_MINI2G  /* 8 bit parallel bridge mode */
+1:
+    ldr     r6, [lr]
+    tst     r6, #LCD1_BUSY_MASK
+    bne     1b
+
+    str     r5, [lr, #0x10]
+#endif
+
+    ldmia   r0!, {r6-r7}        /* Fetch 8 pixel values */
+    add     r3, r3, r6
+
+    bic     r6, r12, r4         /* r6 = 7.......6.......5.......4....... */
+    orr     r6, r6, r6, lsr #10 /* r6 = 7.......6.7.....5.6.....4.5..... */
+    orr     r6, r6, r6, lsr #10 /* r6 = 7.......6.7.....5.6.7...4.5.6... */
+    orr     r6, r6, r6, lsr #10 /* r6 = 7.......6.7.....5.6.7...4.5.6.7. */
+    orr     r6, r6, r6, lsr #1  /* r6 = 77......6677....556677..44556677 */
+    bic     r4, r4, r12
+
+    add     r4, r4, r7
+    stmia   r1!, {r3-r4}
+
+#ifdef IPOD_MINI2G   /* 16 bit serial bridge mode */
+    and     r5, r5, #0xff       /* r5 = ........................00112233 */
+    and     r6, r6, #0xff       /* r6 = ........................44556677 */
+    orr     r5, r6, r5, lsl #8  /* r5 = ................0011223344556677 */
+    orr     r5, r5, #0x760000   /* data marker */
+#endif
+
+1:
+    ldr     r7, [lr]
+    tst     r7, #LCD1_BUSY_MASK
+    bne     1b
+
+#ifdef IPOD_MINI2G
+    str     r5, [lr, #0x08]
+#else
+    str     r6, [lr, #0x10]
+#endif
+
+    subs    r2, r2, #1
+    bne     .greyloop
+
+    ldmpc   regs=r4-r7
+    .size   lcd_grey_data,.-lcd_grey_data
+
diff --git a/firmware/target/arm/portalplayer/ipod/lcd-color_nano.c b/firmware/target/arm/portalplayer/ipod/lcd-color_nano.c
new file mode 100644
index 0000000..589e865
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/lcd-color_nano.c
@@ -0,0 +1,326 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Rockbox driver for iPod LCDs
+ *
+ * Based on code from the ipodlinux project - http://ipodlinux.org/
+ * Adapted for Rockbox in November 2005
+ *
+ * Original file: linux/arch/armnommu/mach-ipod/fb.c
+ *
+ * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ * 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 "lcd.h"
+#include "kernel.h"
+#include "system.h"
+#include "hwcompat.h"
+#include "backlight-target.h"
+
+/* LCD command codes for HD66789R */
+#define LCD_CNTL_RAM_ADDR_SET           0x21
+#define LCD_CNTL_WRITE_TO_GRAM          0x22
+#define LCD_CNTL_HORIZ_RAM_ADDR_POS     0x44
+#define LCD_CNTL_VERT_RAM_ADDR_POS      0x45
+
+/*** globals ***/
+int lcd_type = 1; /* 0,2 = "old" Color/Photo; 1,3 = similar to HD66789R */
+
+static inline void lcd_wait_write(void)
+{
+    while (LCD2_PORT & LCD2_BUSY_MASK);
+}
+
+static void lcd_cmd_data(unsigned cmd, unsigned data)
+{
+    if ((lcd_type&1) == 0) {  /* 16 bit transfers */
+        lcd_wait_write();
+        LCD2_PORT = LCD2_CMD_MASK | cmd;
+        lcd_wait_write();
+        LCD2_PORT = LCD2_CMD_MASK | data;
+    } else {
+        lcd_wait_write();
+        LCD2_PORT = LCD2_CMD_MASK;
+        LCD2_PORT = LCD2_CMD_MASK | cmd;
+        lcd_wait_write();
+        LCD2_PORT = LCD2_DATA_MASK | (data >> 8);
+        LCD2_PORT = LCD2_DATA_MASK | (data & 0xff);
+    }
+}
+
+/*** hardware configuration ***/
+
+#ifdef HAVE_LCD_CONTRAST
+void lcd_set_contrast(int val)
+{
+  /* TODO: Implement lcd_set_contrast() */
+  (void)val;
+}
+#endif
+
+#ifdef HAVE_LCD_INVERT
+void lcd_set_invert_display(bool yesno)
+{
+#ifdef IPOD_NANO    /* this has only been tested on the ipod nano */
+    lcd_cmd_data(0x07, 0x73 | (yesno ? 0 : (1<<2)));
+#endif
+}
+#endif
+
+#ifdef HAVE_LCD_FLIP
+/* turn the display upside down (call lcd_update() afterwards) */
+void lcd_set_flip(bool yesno)
+{
+  /* TODO: Implement lcd_set_flip() */
+  (void)yesno;
+}
+#endif
+
+/* LCD init */
+void lcd_init_device(void)
+{  
+#if CONFIG_LCD == LCD_IPODCOLOR
+    if (IPOD_HW_REVISION == 0x60000) {
+        lcd_type = 0;
+    } else {
+        lcd_type = (GPIOA_INPUT_VAL & 0x2) | ((GPIOA_INPUT_VAL & 0x10) >> 4);
+    }
+    if ((lcd_type&1) == 0) {
+        lcd_cmd_data(0xef, 0x0);
+        lcd_cmd_data(0x01, 0x0);
+        lcd_cmd_data(0x80, 0x1);
+        lcd_cmd_data(0x10, 0xc);
+        lcd_cmd_data(0x18, 0x6);
+        lcd_cmd_data(0x7e, 0x4);
+        lcd_cmd_data(0x7e, 0x5);
+        lcd_cmd_data(0x7f, 0x1);
+    }
+#elif CONFIG_LCD == LCD_IPODNANO
+    /* iPodLinux doesn't appear have any LCD init code for the Nano */
+#endif
+}
+
+#ifdef HAVE_LCD_SHUTDOWN
+void lcd_shutdown(void) {
+    /* Immediately switch off the backlight to avoid flashing. */
+#if defined(IPOD_NANO)
+    _backlight_hw_enable(false);
+#elif defined(IPOD_COLOR)
+    _backlight_off();
+#endif
+
+    if ((lcd_type&1) == 0) {
+        /* lcd_type 0 and 2 */
+        lcd_cmd_data(0x00EF, 0x0000);
+        lcd_cmd_data(0x0080, 0x0000); udelay(1000);
+        lcd_cmd_data(0x0001, 0x0001);
+    } else if (lcd_type == 1) {
+        /* lcd_type 1 */
+        lcd_cmd_data(0x0007, 0x0236); sleep( 40*HZ/1000);
+        lcd_cmd_data(0x0007, 0x0226); sleep( 40*HZ/1000);
+        lcd_cmd_data(0x0007, 0x0204);
+        lcd_cmd_data(0x0010, 0x7574); sleep(200*HZ/1000);
+        lcd_cmd_data(0x0010, 0x7504); sleep( 50*HZ/1000);
+        lcd_cmd_data(0x0010, 0x0501);
+    } else {
+        /* lcd_type 3 */
+        lcd_cmd_data(0x0007, 0x4016); sleep( 20*HZ/1000);
+        lcd_cmd_data(0x0059, 0x0011); sleep( 20*HZ/1000);
+        lcd_cmd_data(0x0059, 0x0003); sleep( 20*HZ/1000);
+        lcd_cmd_data(0x0059, 0x0002); sleep( 20*HZ/1000);
+        lcd_cmd_data(0x0010, 0x6360); sleep(200*HZ/1000);
+        lcd_cmd_data(0x0010, 0x6300); sleep( 50*HZ/1000);
+        lcd_cmd_data(0x0010, 0x0300);
+        lcd_cmd_data(0x0059, 0x0000);
+        lcd_cmd_data(0x0007, 0x4004);
+        lcd_cmd_data(0x0010, 0x0301);
+    }
+}
+#endif
+
+/* Helper function to set up drawing region and start drawing */
+static void lcd_setup_drawing_region(int x, int y, int width, int height)
+{
+    int y0, x0, y1, x1;
+    
+    /* calculate the drawing region */
+#if CONFIG_LCD == LCD_IPODNANO
+    y0 = x;                         /* start horiz */
+    y1 = (x + width) - 1;           /* max horiz */
+    x0 = y;                         /* start vert */
+    x1 = (y + height) - 1;          /* max vert */
+#elif CONFIG_LCD == LCD_IPODCOLOR
+    y0 = y;                         /* start vert */
+    y1 = (y + height) - 1;          /* end vert */
+    x1 = (LCD_WIDTH - 1) - x;       /* end horiz */
+    x0 = (x1 - width) + 1;          /* start horiz */
+#endif
+
+    /* setup the drawing region */
+    if ((lcd_type&1) == 0) {
+        /* x0 and x1 need to be swapped until 
+         * proper direction setup is added */
+        lcd_cmd_data(0x12, y0);      /* start vert */
+        lcd_cmd_data(0x13, x1);      /* start horiz */
+        lcd_cmd_data(0x15, y1);      /* end vert */
+        lcd_cmd_data(0x16, x0);      /* end horiz */
+    } else {
+        /* max horiz << 8 | start horiz */
+        lcd_cmd_data(LCD_CNTL_HORIZ_RAM_ADDR_POS, (y1 << 8) | y0);
+        /* max vert << 8 | start vert */
+        lcd_cmd_data(LCD_CNTL_VERT_RAM_ADDR_POS, (x1 << 8) | x0);
+
+        /* start vert = max vert */
+#if CONFIG_LCD == LCD_IPODCOLOR
+        x0 = x1;
+#endif
+
+        /* position cursor (set AD0-AD15) */
+        /* start vert << 8 | start horiz */
+        lcd_cmd_data(LCD_CNTL_RAM_ADDR_SET, ((x0 << 8) | y0));
+
+        /* start drawing */
+        lcd_wait_write();
+        LCD2_PORT = LCD2_CMD_MASK;
+        LCD2_PORT = (LCD2_CMD_MASK|LCD_CNTL_WRITE_TO_GRAM);
+    }
+}
+
+/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
+extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
+                                   const unsigned int lcd_baseadress,
+                                   int width,
+                                   int stride);
+
+/* Performance function to blit a YUV bitmap directly to the LCD */
+void lcd_blit_yuv(unsigned char * const src[3],
+                  int src_x, int src_y, int stride,
+                  int x, int y, int width, int height)
+{
+    int z;
+    unsigned char const * yuv_src[3];
+
+    width  = (width  + 1) & ~1; /* ensure width is even  */
+    height = (height + 1) & ~1; /* ensure height is even */
+
+    lcd_setup_drawing_region(x, y, width, height);
+
+    z = stride * src_y;
+    yuv_src[0] = src[0] + z + src_x;
+    yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
+    yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
+
+    while (height > 0) {
+        int r, h, pixels_to_write;
+
+        pixels_to_write = (width * height) * 2;
+        h = height;
+
+        /* calculate how much we can do in one go */
+        if (pixels_to_write > 0x10000) {
+            h = ((0x10000/2) / width) & ~1; /* ensure h is even */
+            pixels_to_write = (width * h) * 2;
+        }
+        
+        LCD2_BLOCK_CTRL   = 0x10000080;
+        LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
+        LCD2_BLOCK_CTRL   = 0x34000000;
+
+        r = h>>1; /* lcd_write_yuv420_lines writes two lines at once */
+        do {
+            lcd_write_yuv420_lines(yuv_src, LCD2_BASE, width, stride);
+            yuv_src[0] += stride << 1;
+            yuv_src[1] += stride >> 1;
+            yuv_src[2] += stride >> 1;
+        } while (--r > 0);
+        
+        /* transfer of pixels_to_write bytes finished */
+        while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
+        LCD2_BLOCK_CONFIG = 0;
+        
+        height -= h;
+    }
+}
+
+/* Helper function writes 'count' consecutive pixels from src to LCD IF */
+static void lcd_write_line(int count, unsigned long *src)
+{
+    do {
+        while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_TXOK)); /* FIFO wait */
+        LCD2_BLOCK_DATA = *src++;                     /* output 2 pixels */
+        count -= 2;
+    } while (count > 0);
+}
+
+/* Update a fraction of the display. */
+void lcd_update_rect(int x, int y, int width, int height)
+{
+    unsigned long *addr;
+
+    /* Ensure both x and width are even to be able to read 32-bit aligned 
+     * data from lcd_framebuffer */
+    x     =  x & ~1;            /* use the smaller even number */
+    width = (width + 1) & ~1;   /* use the bigger even number  */
+
+    lcd_setup_drawing_region(x, y, width, height);
+
+    addr = (unsigned long*)&lcd_framebuffer[y][x];
+
+    while (height > 0) {
+        int r, h, pixels_to_write;
+
+        pixels_to_write = (width * height) * 2;
+        h = height;
+
+        /* calculate how much we can do in one go */
+        if (pixels_to_write > 0x10000) {
+            h = ((0x10000/2) / width) & ~1; /* ensure h is even */
+            pixels_to_write = (width * h) * 2;
+        }
+
+        LCD2_BLOCK_CTRL   = 0x10000080;
+        LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1);
+        LCD2_BLOCK_CTRL   = 0x34000000;
+
+        if (LCD_WIDTH == width) {
+            /* for each row and column in a single call */
+            lcd_write_line(h*width, addr);
+            addr += LCD_WIDTH/2*h;
+        } else {
+            /* for each row */
+            for (r = 0; r < h; r++) {
+                lcd_write_line(width, addr);
+                addr += LCD_WIDTH/2;
+            }
+        }
+
+        /* transfer of pixels_to_write bytes finished */
+        while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY));
+        LCD2_BLOCK_CONFIG = 0;
+
+        height -= h;
+    }
+}
+
+/* Update the display.
+   This must be called after all other LCD functions that change the display. */
+void lcd_update(void)
+{
+    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
+}
diff --git a/firmware/target/arm/portalplayer/ipod/lcd-gray.c b/firmware/target/arm/portalplayer/ipod/lcd-gray.c
new file mode 100644
index 0000000..11d4cba
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/lcd-gray.c
@@ -0,0 +1,363 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Rockbox driver for iPod LCDs
+ *
+ * Based on code from the ipodlinux project - http://ipodlinux.org/
+ * Adapted for Rockbox in November 2005
+ *
+ * Original file: linux/arch/armnommu/mach-ipod/fb.c
+ *
+ * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ * 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 "lcd.h"
+#include "kernel.h"
+#include "system.h"
+#include "hwcompat.h"
+
+/* LCD command codes for HD66753 */
+
+#define R_START_OSC             0x00
+#define R_DRV_OUTPUT_CONTROL    0x01
+#define R_DRV_WAVEFORM_CONTROL  0x02
+#define R_POWER_CONTROL         0x03
+#define R_CONTRAST_CONTROL      0x04
+#define R_ENTRY_MODE            0x05
+#define R_ROTATION              0x06
+#define R_DISPLAY_CONTROL       0x07
+#define R_CURSOR_CONTROL        0x08
+#define R_HORIZONTAL_CURSOR_POS 0x0b
+#define R_VERTICAL_CURSOR_POS   0x0c
+#define R_1ST_SCR_DRV_POS       0x0d
+#define R_2ND_SCR_DRV_POS       0x0e
+#define R_RAM_WRITE_MASK        0x10
+#define R_RAM_ADDR_SET          0x11
+#define R_RAM_DATA              0x12
+
+#ifdef HAVE_BACKLIGHT_INVERSION
+/* The backlight makes the LCD appear negative on the 1st/2nd gen */
+static bool lcd_inverted = false;
+static bool lcd_backlit = false;
+#if NUM_CORES > 1
+/* invert_display() and the lcd_blit_* functions need to be corelocked */
+static struct corelock cl IBSS_ATTR;
+#endif
+static void invert_display(void);
+#endif
+
+#if defined(IPOD_1G2G) || defined(IPOD_3G)
+#define POWER_REG_H 0x1120   /* 1/7 Bias, 5x step-up @ clk/8 */
+#else
+#define POWER_REG_H 0x1200   /* 1/7 Bias, 6x step-up @ clk/32 */
+#endif
+
+#define CONTRAST_REG_H 0x400
+
+#if defined(IPOD_1G2G)
+#define DEFAULT_CONTRAST 45
+#elif defined(IPOD_3G)
+#define DEFAULT_CONTRAST 50
+#elif defined(IPOD_MINI) || defined(IPOD_MINI2G)
+#define DEFAULT_CONTRAST 42
+#elif defined(IPOD_4G)
+#define DEFAULT_CONTRAST 35
+#endif
+
+/* needed for flip */
+static int addr_offset;
+#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
+static int pix_offset;
+void lcd_write_data_shifted(const fb_data* p_bytes, int count);
+#endif
+
+/* wait for LCD with timeout */
+static inline void lcd_wait_write(void)
+{
+    while (LCD1_CONTROL & LCD1_BUSY_MASK);
+}
+
+/* send LCD command */
+static void lcd_prepare_cmd(unsigned cmd)
+{
+    lcd_wait_write();
+#ifdef IPOD_MINI2G
+    LCD1_CMD = cmd | 0x740000;
+#else
+    LCD1_CMD = 0;
+    lcd_wait_write();
+    LCD1_CMD = cmd;
+#endif
+}
+
+/* send LCD command and data */
+static void lcd_cmd_and_data(unsigned cmd, unsigned data)
+{
+    lcd_wait_write();
+#ifdef IPOD_MINI2G
+    LCD1_CMD = cmd | 0x740000;
+    lcd_wait_write();
+    LCD1_CMD = data | 0x760000;
+#else
+    LCD1_CMD = 0;
+    lcd_wait_write();
+    LCD1_CMD = cmd;
+    lcd_wait_write();
+    LCD1_DATA = data >> 8;
+    lcd_wait_write();
+    LCD1_DATA = data & 0xff;
+#endif
+}
+
+/* LCD init */
+void lcd_init_device(void)
+{
+#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
+    corelock_init(&cl);
+#endif
+#ifdef IPOD_MINI2G /* serial LCD hookup */
+    lcd_wait_write();
+    LCD1_CONTROL = 0x01730084; /* fastest setting */
+#elif defined(IPOD_1G2G) || defined(IPOD_3G)
+    LCD1_CONTROL = (LCD1_CONTROL & 0x0002) | 0x0084; 
+                   /* fastest setting, keep backlight bit */
+#else
+    LCD1_CONTROL = 0x0084; /* fastest setting */
+#endif
+
+    lcd_cmd_and_data(R_DRV_WAVEFORM_CONTROL, 0x48);
+                     /* C waveform, no EOR, 9 lines inversion */
+    lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0xc);
+    lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0019);
+    lcd_set_contrast(DEFAULT_CONTRAST);
+#ifdef HAVE_BACKLIGHT_INVERSION
+    invert_display();
+#endif
+    lcd_set_flip(false);
+    lcd_cmd_and_data(R_ENTRY_MODE, 0x0000);
+}
+
+/*** hardware configuration ***/
+
+int lcd_default_contrast(void)
+{
+    return DEFAULT_CONTRAST;
+}
+
+/* Rockbox stores the contrast as 0..63 - we add 64 to it */
+void lcd_set_contrast(int val)
+{
+    if (val < 0) val = 0;
+    else if (val > 63) val = 63;
+
+    lcd_cmd_and_data(R_CONTRAST_CONTROL, CONTRAST_REG_H | (val + 64));
+}
+
+#ifdef HAVE_BACKLIGHT_INVERSION
+static void invert_display(void)
+{
+    static bool last_invert = false;
+    bool new_invert = lcd_inverted ^ lcd_backlit;
+
+    if (new_invert != last_invert)
+    {
+        int oldlevel = disable_irq_save();
+#if NUM_CORES > 1
+        corelock_lock(&cl);
+        lcd_cmd_and_data(R_DISPLAY_CONTROL, new_invert? 0x0027 : 0x0019);
+        corelock_unlock(&cl);
+#else
+        lcd_cmd_and_data(R_DISPLAY_CONTROL, new_invert? 0x0027 : 0x0019);
+#endif
+        restore_irq(oldlevel);
+        last_invert = new_invert;
+    }
+}
+
+void lcd_set_invert_display(bool yesno)
+{
+    lcd_inverted = yesno;
+    invert_display();
+}
+
+void lcd_set_backlight_inversion(bool yesno)
+{
+    lcd_backlit = yesno;
+    invert_display();
+}
+#else
+void lcd_set_invert_display(bool yesno)
+{
+    lcd_cmd_and_data(R_DISPLAY_CONTROL, yesno ? 0x0027 : 0x0019);
+}
+#endif
+
+/* turn the display upside down (call lcd_update() afterwards) */
+void lcd_set_flip(bool yesno)
+{
+#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
+    if (yesno) 
+    {    /* 168x112, inverse COM order */
+        lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020d);
+        lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8316);    /* 22..131 */
+        addr_offset = (22 << 5) | (20 - 4);
+        pix_offset = -2;
+    }
+    else 
+    {   /* 168x112,  inverse SEG order */
+        lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010d);
+        lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00);    /* 0..109 */
+        addr_offset = 20;
+        pix_offset = 0;
+    }
+#else
+    if (yesno) 
+    {   /* 168x128, inverse SEG & COM order */
+        lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030f);
+        lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304);    /* 4..131 */
+        addr_offset = (4 << 5) | (20 - 1);
+    } 
+    else 
+    {   /* 168x128 */
+        lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000f);
+        lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00);    /* 0..127 */
+        addr_offset = 20;
+    }
+#endif
+}
+
+#ifdef HAVE_LCD_ENABLE
+void lcd_enable(bool on)
+{
+    if (on)
+    {
+        lcd_cmd_and_data(R_START_OSC, 1);               /* start oscillation */
+        sleep(HZ/10);                                           /* wait 10ms */
+        lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H); /*clear standby mode */
+        lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0xc);
+                                                   /* enable opamp & booster */
+    }
+    else
+    {
+        lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H);
+                                               /* switch off opamp & booster */
+        lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0x1);
+                                                       /* enter standby mode */
+    }
+}
+#endif /* HAVE_LCD_ENABLE */
+
+/*** update functions ***/
+
+/* Helper function. */
+void lcd_mono_data(const unsigned char *data, int count);
+
+/* Performance function that works with an external buffer
+   note that x, bwidtht and stride are in 8-pixel units! */
+void lcd_blit_mono(const unsigned char *data, int bx, int y, int bwidth,
+                   int height, int stride)
+{
+#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
+    corelock_lock(&cl);
+#endif
+    while (height--)
+    {
+        lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx);
+        lcd_prepare_cmd(R_RAM_DATA);
+        lcd_mono_data(data, bwidth);
+        data += stride;
+    }
+#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
+    corelock_unlock(&cl);
+#endif
+}
+
+/* Helper function for lcd_grey_phase_blit(). */
+void lcd_grey_data(unsigned char *values, unsigned char *phases, int count);
+
+/* Performance function that works with an external buffer
+   note that bx and bwidth are in 8-pixel units! */
+void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
+                         int bx, int y, int bwidth, int height, int stride)
+{
+#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
+    corelock_lock(&cl);
+#endif
+    while (height--)
+    {
+        lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx);
+        lcd_prepare_cmd(R_RAM_DATA);
+        lcd_grey_data(values, phases, bwidth);
+        values += stride;
+        phases += stride;
+    }
+#if (NUM_CORES > 1) && defined(HAVE_BACKLIGHT_INVERSION)
+    corelock_unlock(&cl);
+#endif
+}
+
+void lcd_update_rect(int x, int y, int width, int height)
+{
+    int xmax, ymax;
+
+    if (x + width > LCD_WIDTH)
+        width = LCD_WIDTH - x;
+    if (width <= 0)
+        return;
+    
+    ymax = y + height - 1;
+    if (ymax >= LCD_HEIGHT)
+        ymax = LCD_HEIGHT - 1;
+
+#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
+    x += pix_offset;
+#endif
+     /* writing is done in 16-bit units (8 pixels) */
+    xmax = (x + width - 1) >> 3;
+    x >>= 3;
+    width = xmax - x + 1;
+
+    for (; y <= ymax; y++) 
+    {
+        lcd_cmd_and_data(R_RAM_ADDR_SET, (y << 5) + addr_offset - x);
+        lcd_prepare_cmd(R_RAM_DATA);
+
+#if defined(IPOD_MINI) || defined(IPOD_MINI2G)
+        if (pix_offset == -2)
+            lcd_write_data_shifted(&lcd_framebuffer[y][2*x], width);
+        else
+#endif
+            lcd_write_data(&lcd_framebuffer[y][2*x], width);
+    }
+}
+
+/* Update the display. */
+void lcd_update(void)
+{
+    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
+}
+
+#ifdef HAVE_LCD_SHUTDOWN
+/* LCD powerdown */
+void lcd_shutdown(void)
+{
+    lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0x00); /* Turn off op amp power */
+    lcd_cmd_and_data(R_POWER_CONTROL, POWER_REG_H | 0x02); /* Put LCD driver in standby */
+}
+#endif
diff --git a/firmware/target/arm/portalplayer/ipod/power-ipod.c b/firmware/target/arm/portalplayer/ipod/power-ipod.c
new file mode 100644
index 0000000..ef59417
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/power-ipod.c
@@ -0,0 +1,249 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * 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 "kernel.h"
+#include "system.h"
+#include "power.h"
+#include "logf.h"
+#include "pcf50605.h"
+#include "usb.h"
+#include "lcd.h"
+#include "string.h"
+#ifdef HAVE_USB_CHARGING_ENABLE
+#include "usb_core.h"   /* for usb_charging_maxcurrent_change */
+#endif
+
+void power_init(void)
+{
+#if defined(IPOD_1G2G) || defined(IPOD_3G)
+    GPIOC_ENABLE |= 0x40;      /* GPIO C6 is HDD power (low active) */
+    GPIOC_OUTPUT_VAL &= ~0x40; /* on by default */
+    GPIOC_OUTPUT_EN |= 0x40;   /* enable output */
+#endif
+#ifndef IPOD_1G2G
+    pcf50605_init();
+#endif
+}
+
+#if CONFIG_CHARGING
+unsigned int power_input_status(void)
+{
+    unsigned int status = POWER_INPUT_NONE;
+
+#if defined(IPOD_NANO) || defined(IPOD_VIDEO)
+    if ((GPIOL_INPUT_VAL & 0x08) == 0)
+        status = POWER_INPUT_MAIN_CHARGER;
+
+    if ((GPIOL_INPUT_VAL & 0x10) != 0)
+        status |= POWER_INPUT_USB_CHARGER;
+    /* */
+#elif defined(IPOD_4G) || defined(IPOD_COLOR) \
+       || defined(IPOD_MINI) || defined(IPOD_MINI2G)
+    /* C2 is firewire power */
+    if ((GPIOC_INPUT_VAL & 0x04) == 0)
+        status = POWER_INPUT_MAIN_CHARGER;
+
+    if ((GPIOD_INPUT_VAL & 0x08) != 0)
+        status |= POWER_INPUT_USB_CHARGER;
+    /* */
+#elif defined(IPOD_3G)
+    /* firewire power */
+    if ((GPIOC_INPUT_VAL & 0x10) == 0)
+        status = POWER_INPUT_MAIN_CHARGER;
+    /* */
+#else
+    /* This needs filling in for other ipods. */
+#endif
+
+    return status;
+}
+
+/* Returns true if the unit is charging the batteries. */
+bool charging_state(void) {
+#if defined(IPOD_COLOR)
+    /* 0x70000088 appears to be the input value for GPO32 bits.
+       Write a zero to 0x70000088 before reading.
+       To enable input set the corresponding 0x7000008C bit,
+       and clear the corresponding GPO32_ENABLE bit. */
+    outl(0, 0x70000088);
+    return (inl(0x70000088) & 1)?false:true;
+#else
+    return (GPIOB_INPUT_VAL & 0x01)?false:true;
+#endif
+}
+#endif /* CONFIG_CHARGING */
+
+
+void ide_power_enable(bool on)
+{
+#if defined(IPOD_1G2G) || defined(IPOD_3G)
+    if (on)
+        GPIOC_OUTPUT_VAL &= ~0x40;
+    else
+        GPIOC_OUTPUT_VAL |= 0x40;
+#elif defined(IPOD_4G) || defined(IPOD_COLOR) \
+   || defined(IPOD_MINI) || defined(IPOD_MINI2G)
+    if (on)
+    {
+        GPIO_CLEAR_BITWISE(GPIOJ_OUTPUT_VAL, 0x04);
+        DEV_EN |= DEV_IDE0;
+    }
+    else
+    {
+        DEV_EN &= ~DEV_IDE0;
+        GPIO_SET_BITWISE(GPIOJ_OUTPUT_VAL, 0x04);
+    }
+#elif defined(IPOD_VIDEO)
+    if (on)
+    {
+        GPO32_VAL &= ~0x40000000;
+        sleep(1);  /* only need 4 ms */
+        DEV_EN |= DEV_IDE0;
+        GPIOG_ENABLE = 0;
+        GPIOH_ENABLE = 0;
+        GPIO_CLEAR_BITWISE(GPIOI_ENABLE, 0xBF);
+        GPIO_CLEAR_BITWISE(GPIOK_ENABLE, 0x1F);
+        udelay(10);
+    }
+    else
+    {
+        DEV_EN &= ~DEV_IDE0;
+        udelay(10);
+        GPIOG_ENABLE = 0xFF;
+        GPIOH_ENABLE = 0xFF;
+        GPIO_SET_BITWISE(GPIOI_ENABLE, 0xBF);
+        GPIO_SET_BITWISE(GPIOK_ENABLE, 0x1F);
+        GPO32_VAL |= 0x40000000;
+    }
+#else /* Nano */
+    (void)on;  /* Do nothing. */
+#endif
+}
+
+bool ide_powered(void)
+{
+#if defined(IPOD_1G2G) || defined(IPOD_3G)
+    return !(GPIOC_OUTPUT_VAL & 0x40);
+#elif defined(IPOD_4G) || defined(IPOD_COLOR) \
+   || defined(IPOD_MINI) || defined(IPOD_MINI2G)
+    return !(GPIOJ_OUTPUT_VAL & 0x04);
+#elif defined(IPOD_VIDEO)
+    return !(GPO32_VAL & 0x40000000);
+#else /* Nano */
+    return true; /* Pretend we are always powered */
+#endif
+}
+
+void power_off(void)
+{
+#if defined(HAVE_LCD_COLOR) && !defined(HAVE_LCD_SHUTDOWN)
+    /* Clear the screen and backdrop to
+    remove ghosting effect on shutdown */
+    lcd_set_backdrop(NULL);
+    lcd_set_background(LCD_WHITE);
+    lcd_clear_display();
+    lcd_update();
+    sleep(HZ/16);
+#endif
+
+#ifndef BOOTLOADER
+#ifdef IPOD_1G2G
+    /* we cannot turn off the 1st gen/ 2nd gen yet. Need to figure out sleep mode. */
+    system_reboot();
+#else
+    /* We don't turn off the ipod, we put it in a deep sleep */
+    /* Clear latter part of iram (the part used by plugins/codecs) to ensure
+     * that the OF behaves properly on boot. There is some kind of boot
+     * failure flag there which otherwise may not be cleared.
+     */
+#if CONFIG_CPU == PP5022
+    memset((void*)0x4000c000, 0, 0x14000);
+#elif CONFIG_CPU == PP5020
+    memset((void*)0x4000c000, 0, 0xc000);
+#endif
+    pcf50605_standby_mode();
+#endif
+#endif
+}
+
+#ifdef HAVE_USB_CHARGING_ENABLE
+void usb_charging_maxcurrent_change(int maxcurrent)
+{
+    bool suspend_charging = (maxcurrent < 100);
+    bool fast_charging = (maxcurrent >= 500);
+
+    /* This GPIO is connected to the LTC4066's SUSP pin */
+    /* Setting it high prevents any power being drawn over USB */
+    /* which supports USB suspend */
+#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
+    if (suspend_charging)
+        GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 4);
+    else
+        GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_VAL, 4);
+#elif defined(IPOD_MINI2G)
+    if (suspend_charging)
+        GPIO_SET_BITWISE(GPIOJ_OUTPUT_VAL, 2);
+    else
+        GPIO_CLEAR_BITWISE(GPIOJ_OUTPUT_VAL, 2);
+#else /* Color, 4G, Mini G1 */
+    if (suspend_charging)
+        GPO32_VAL |= 0x8000000;
+    else
+        GPO32_VAL &= ~0x8000000;
+#endif
+
+    /* This GPIO is connected to the LTC4066's HPWR pin */
+    /* Setting it low limits current to 100mA, setting it high allows 500mA */
+#if defined(IPOD_VIDEO) || defined(IPOD_NANO)
+    if (fast_charging)
+        GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 4);
+    else
+        GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_VAL, 4);
+#else
+    if (fast_charging)
+        GPO32_VAL |= 0x40;
+    else 
+        GPO32_VAL &= ~0x40;
+#endif
+
+    /* This GPIO is connected to the LTC4066's CLDIS pin */
+    /* Setting it high allows up to 1.5A of current to be drawn */
+    /* This doesn't appear to actually be safe even with an AC charger */
+    /* so for now it is disabled. It's not known (or maybe doesn't exist) */
+    /* on all models. */
+#if 0
+#if defined(IPOD_VIDEO)
+    if (unlimited_charging)
+        GPO32_VAL |= 0x10000000;
+    else 
+        GPO32_VAL &= ~0x10000000;
+#elif defined(IPOD_4G) || defined(IPOD_COLOR)
+    if (unlimited_charging)
+        GPO32_VAL |= 0x200;
+    else 
+        GPO32_VAL &= ~0x200;
+#endif
+    /* This might be GPIOD & 40 on 2G */
+#endif
+}
+#endif /* HAVE_USB_CHARGING_ENABLE */
diff --git a/firmware/target/arm/portalplayer/ipod/powermgmt-ipod-pcf.c b/firmware/target/arm/portalplayer/ipod/powermgmt-ipod-pcf.c
new file mode 100644
index 0000000..44e908a
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/powermgmt-ipod-pcf.c
@@ -0,0 +1,134 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
+ * Revisions copyright (C) 2005 by Gerald Van Baren
+ *
+ * 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 "adc.h"
+#include "powermgmt.h"
+#include "pcf5060x.h"
+#include "pcf50605.h"
+#include "audiohw.h"
+
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+#if   defined(IPOD_NANO)
+    3330
+#elif defined(IPOD_VIDEO)
+    3500
+#elif defined(IPOD_COLOR)
+    3300
+#elif defined(IPOD_3G)
+    3700
+#else
+    /* FIXME: calibrate value for other iPods */
+    3300
+#endif
+};
+
+const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
+{
+#if   defined(IPOD_NANO)
+    3230
+#elif defined(IPOD_VIDEO)
+    3300
+#elif defined(IPOD_COLOR)
+    3300
+#elif defined(IPOD_3G)
+    3500
+#else
+    /* FIXME: calibrate value for other iPods */
+    3000
+#endif
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
+const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
+{
+#if   defined(IPOD_NANO)
+    /* measured values */
+    { 3230, 3620, 3700, 3730, 3750, 3780, 3830, 3890, 3950, 4030, 4160 },
+#elif defined(IPOD_VIDEO)
+    /* iPod Video 30GB Li-Ion 400mAh */
+    { 3600, 3720, 3750, 3780, 3810, 3840, 3880, 3950, 4020, 4100, 4180 },
+#elif defined(IPOD_COLOR)
+    /* iPod Photo 30GB, see FS#9072 */
+    { 3450, 3660, 3700, 3730, 3750, 3770, 3820, 3870, 3920, 4040, 4170 },
+#elif defined(IPOD_3G)
+    /* iPod 3G 40GB, first approach based upon measurements */
+    { 3720, 3740, 3760, 3780, 3830, 3870, 3910, 3970, 4020, 4060, 4090 },
+#else
+    /* FIXME: calibrate value for other iPods */
+    /* Table is "provisional" from IPOD_COLOR */
+    { 3450, 3660, 3700, 3730, 3750, 3770, 3820, 3870, 3920, 4040, 4170 }
+#endif
+};
+
+#if CONFIG_CHARGING
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+const unsigned short percent_to_volt_charge[11] =
+{
+#if   defined(IPOD_NANO)
+    /* measured values */
+    3230, 3620, 3700, 3730, 3750, 3780, 3830, 3890, 3950, 4030, 4160
+#elif defined(IPOD_VIDEO)
+    /* iPOD Video 30GB Li-Ion 400mAh */
+    3600, 3720, 3750, 3780, 3810, 3840, 3880, 3950, 4020, 4100, 4180
+#elif defined(IPOD_COLOR)
+    /* iPod Photo 30GB, see FS#9072 */
+    3450, 3660, 3700, 3730, 3750, 3770, 3820, 3870, 3920, 4040, 4170
+#elif defined(IPOD_3G)
+    /* iPod 3G 40GB, first approach based upon measurements */
+    3720, 3740, 3760, 3780, 3830, 3870, 3910, 3970, 4020, 4060, 4090
+#else
+    /* FIXME: calibrate value for other iPods */
+    /* Table is "provisional" from IPOD_COLOR */
+    3450, 3660, 3700, 3730, 3750, 3770, 3820, 3870, 3920, 4040, 4170
+#endif
+};
+#endif /* CONFIG_CHARGING */
+
+#define BATTERY_SCALE_FACTOR 6000
+/* full-scale ADC readout (2^10) in millivolt */
+
+/* Returns battery voltage from ADC [millivolts] */
+unsigned int battery_adc_voltage(void)
+{
+    return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
+}
+
+#ifdef HAVE_ACCESSORY_SUPPLY
+void accessory_supply_set(bool enable)
+{
+    /* Set accessory power supply to 3.3V, otherwise switch it off. */
+    unsigned char value = enable ? 0xf8 : 0x18;
+    
+    /* Write to register. */
+    pcf50605_write(PCF5060X_D2REGC1, value);
+}
+#endif
+
+#ifdef HAVE_LINEOUT_POWEROFF
+void lineout_set(bool enable)
+{
+    /* Call audio hardware driver implementation */
+    audiohw_enable_lineout(enable);
+}
+#endif
diff --git a/firmware/target/arm/portalplayer/ipod/video/battery-video.c b/firmware/target/arm/portalplayer/ipod/video/battery-video.c
new file mode 100644
index 0000000..b4c4602
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/video/battery-video.c
@@ -0,0 +1,33 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id $
+ *
+ * Default battery capacity for ipod video
+ *
+ * Copyright (c) 2011 Frank Gevaerts
+ *
+ * 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 "system.h"
+
+int battery_default_capacity(void)
+{
+    if(probed_ramsize==64)
+        return BATTERY_CAPACITY_DEFAULT_THICK;
+    else
+        return BATTERY_CAPACITY_DEFAULT_THIN;
+}
diff --git a/firmware/target/arm/portalplayer/ipod/video/lcd-as-video.S b/firmware/target/arm/portalplayer/ipod/video/lcd-as-video.S
new file mode 100644
index 0000000..47155b8
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/video/lcd-as-video.S
@@ -0,0 +1,302 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2007 by Andree Buschmann
+ *
+ * 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"
+
+    .section .icode, "ax", %progbits
+
+/****************************************************************************
+ * void lcd_write_data(const fb_data *addr, 
+ *                     int pixelcount);
+ * 
+ * Writes pixelcount pixels from src-pointer (lcd_framebuffer) to BCM dataport.
+ * Use the sequence 2:2:2:2 (2 = read/write 2 regs) for best performance.
+ */
+    .align  2
+    .global lcd_write_data
+    .type   lcd_write_data, %function
+                                      /* r0 = addr, must be aligned */
+lcd_write_data:                       /* r1 = pixel count, must be even */
+    stmfd   sp!, {r4, lr}
+    mov     lr, #0x30000000           /* LCD data port */
+
+    subs    r1, r1, #16
+.loop16:
+    ldmgeia r0!, {r2-r3}
+    stmgeia lr,  {r2-r3}
+    ldmgeia r0!, {r2-r3}
+    stmgeia lr,  {r2-r3}
+    ldmgeia r0!, {r2-r3}
+    stmgeia lr,  {r2-r3}
+    ldmgeia r0!, {r2-r3}
+    stmgeia lr,  {r2-r3}
+    subges  r1, r1, #16
+    bge     .loop16
+
+    /* no need to correct the count, we're just checking bits from now */
+    tst     r1, #8
+    ldmneia r0!, {r2-r4, r12}
+    stmneia lr,  {r2-r4, r12}
+    tst     r1, #4
+    ldmneia r0!, {r2-r3}
+    stmneia lr,  {r2-r3}
+    tst     r1, #2
+    ldrne   r3, [r0], #4
+    strne   r3, [lr]
+
+    ldmpc   regs=r4
+
+/****************************************************************************
+ * extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
+ *                                    unsigned bcmaddr
+ *                                    int width,
+ *                                    int stride);
+ *
+ *   Conversion from Motion JPEG and MPEG Y'PbPr to RGB is:
+ *   |R|   |1.164  0.000  1.596| |Y' -  16|
+ *   |G| = |1.164 -0.391 -0.813| |Pb - 128|
+ *   |B|   |1.164  2.018  0.000| |Pr - 128|
+ *
+ *   Scaled, normalized, rounded and tweaked to yield RGB 565:
+ *   |R|   |74   0 101| |Y' -  16| >> 9
+ *   |G| = |74 -24 -51| |Cb - 128| >> 8
+ *   |B|   |74 128   0| |Cr - 128| >> 9
+ *
+ * Converts two lines from YUV to RGB565 and writes to BCM at once. First loop
+ * loads Cb/Cr, calculates the chroma offset and saves them to buffer. Within
+ * the second loop these chroma offset are reloaded from buffer.
+ * Within each loop two pixels are calculated and written to BCM. Before each
+ * loop the desired destination address is transmitted to BCM.
+ */
+    .align      2
+    .global     lcd_write_yuv420_lines
+    .type       lcd_write_yuv420_lines, %function
+lcd_write_yuv420_lines:
+                                      /* r0 = src = yuv_src */
+                                      /* r1 = dst = bcmaddr */
+                                      /* r2 = width */
+                                      /* r3 = stride */                
+    stmfd       sp!, { r4-r10, lr }   /* save non-scratch */
+    ldmia       r0, { r9, r10, r12 }  /* r9 = yuv_src[0] = Y'_p */
+                                      /* r10 = yuv_src[1] = Cb_p */
+                                      /* r12 = yuv_src[2] = Cr_p */
+    add         r3, r9, r3            /* r3 = &ysrc[stride] */
+    add         r4, r2, r2, asr #1    /* chroma buffer lenght = width/2 *3 */
+    mov         r4, r4, asl #2        /*   use words for str/ldm possibility */
+    add         r4, r4, #19           /*   plus room for 4 additional words, */
+    bic         r4, r4, #3            /*   rounded up to multiples of 4 byte */
+    sub         sp, sp, r4            /*   and allocate on stack */
+    stmia       sp, {r1-r4}           /* bcmaddr, width, &ysrc[stride], stack_alloc */
+
+    mov         r7, r2                /* r7 = loop count */
+    add         r8, sp, #16           /* chroma buffer */
+    mov         lr, #0x30000000       /* LCD data port */
+    
+    /* The following writes dest address to BCM and waits for write ready */
+    orr         r2, lr, #0x00010000   /* r2 = BCM_WR_ADDR32 */
+    orr         r6, lr, #0x00030000   /* r6 = BCM_CONTROL */
+    str         r1, [r2]              /* BCM_WR_ADDR32 = bcmaddr */
+.busy_1:
+    ldrh        r1, [r6]              /* while (!(BCM_CONTROL & 0x2)) */
+    tst         r1, #0x2
+    beq         .busy_1      
+
+    /* 1st loop start */
+10:                                   /* loop start */
+
+    ldrb        r0, [r10], #1         /* r0 = *usrc++ = *Cb_p++ */
+    ldrb        r1, [r12], #1         /* r1 = *vsrc++ = *Cr_p++ */
+
+    sub         r0, r0, #128          /* r0 = Cb-128 */
+    sub         r1, r1, #128          /* r1 = Cr-128 */
+
+    add         r2, r1, r1, asl #1    /* r2 = Cr*51 + Cb*24 */
+    add         r2, r2, r2, asl #4   
+    add         r2, r2, r0, asl #3   
+    add         r2, r2, r0, asl #4   
+
+    add         r4, r1, r1, asl #2    /* r1 = Cr*101 */
+    add         r4, r4, r1, asl #5
+    add         r1, r4, r1, asl #6
+
+    add         r1, r1, #256          /* r1 = rv = (r1 + 256) >> 9 */
+    mov         r1, r1, asr #9
+    rsb         r2, r2, #128          /* r2 = guv = (-r2 + 128) >> 8 */
+    mov         r2, r2, asr #8       
+    add         r0, r0, #2            /* r0 = bu = (Cb*128 + 256) >> 9 */
+    mov         r0, r0, asr #2       
+    stmia       r8!, {r0-r2}          /* store r0, r1 and r2 to chroma buffer */
+    
+    /* 1st loop, first pixel */
+    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
+    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
+    add         r3, r5, r5, asl #2
+    add         r5, r3, r5, asl #5
+    
+    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
+    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
+    add         r4, r0, r5, asr #8    /* r4 = b = (Y >> 9) + bu */
+ 
+    orr         r5, r6, r4            /* check if clamping is needed... */
+    orr         r5, r5, r3, asr #1    /* ...at all */
+    cmp         r5, #31                 
+    bls         15f                   /* -> no clamp */
+    cmp         r6, #31               /* clamp r */
+    mvnhi       r6, r6, asr #31         
+    andhi       r6, r6, #31             
+    cmp         r3, #63               /* clamp g */
+    mvnhi       r3, r3, asr #31
+    andhi       r3, r3, #63
+    cmp         r4, #31               /* clamp b */
+    mvnhi       r4, r4, asr #31         
+    andhi       r4, r4, #31          
+15:                                   /* no clamp */
+
+    /* calculate pixel_1 and save to r5 for later pixel packing */
+    orr         r4, r4, r3, lsl #5    /* pixel_1 = r<<11 | g<<5 | b */
+    orr         r5, r4, r6, lsl #11   /* r5 = pixel_1 */
+
+    /* 1st loop, second pixel */
+    ldrb        r4, [r9], #1          /* r4 = *ysrc++ = *Y'_p++ */
+    sub         r4, r4, #16           /* r4 = (Y'-16) * 74 */
+    add         r3, r4, r4, asl #2
+    add         r4, r3, r4, asl #5
+    
+    add         r6, r1, r4, asr #8    /* r6 = r = (Y >> 9) + rv */
+    add         r3, r2, r4, asr #7    /* r3 = g = (Y >> 8) + guv */
+    add         r4, r0, r4, asr #8    /* r4 = b = (Y >> 9) + bu */   
+    
+    orr         r0, r6, r4            /* check if clamping is needed... */
+    orr         r0, r0, r3, asr #1    /* ...at all */
+    cmp         r0, #31                 
+    bls         15f                   /* -> no clamp */
+    cmp         r6, #31               /* clamp r */
+    mvnhi       r6, r6, asr #31         
+    andhi       r6, r6, #31             
+    cmp         r3, #63               /* clamp g */
+    mvnhi       r3, r3, asr #31
+    andhi       r3, r3, #63
+    cmp         r4, #31               /* clamp b */
+    mvnhi       r4, r4, asr #31         
+    andhi       r4, r4, #31          
+15:                                   /* no clamp */
+
+    /* calculate pixel_2 and pack with pixel_1 before writing */
+    orr         r4, r4, r3, lsl #5    /* pixel_2 = r<<11 | g<<5 | b */
+    orr         r4, r4, r6, lsl #11   /* r4 = pixel_2 */
+    orr         r4, r5, r4, lsl #16   /* r4 = pixel_2<<16 | pixel_1 */
+    str         r4, [lr]              /* write packed pixels */
+  
+    subs        r7, r7, #2            /* check for loop end */
+    bgt         10b                   /* back to beginning  */
+    /* 1st loop end */
+    
+    /* Reload several registers for pointer rewinding for next loop */
+    add         r8, sp, #16           /* chroma buffer */
+    ldmia       sp, { r1, r7, r9}     /* r1  = bcmaddr */
+                                      /* r7  = loop count */
+                                      /* r9 = &ysrc[stride] */
+    
+    /* The following writes dest address to BCM and waits for write ready */
+    orr         r2, lr, #0x00010000   /* r2 = BCM_WR_ADDR32 */
+    orr         r6, lr, #0x00030000   /* r6 = BCM_CONTROL */
+    add         r1, r1, #640          /* dst += (LCD_WIDTH*2) */
+    str         r1, [r2]              /* BCM_WR_ADDR32 = dst */
+.busy_2:
+    ldrh        r1, [r6]              /* while (!(BCM_CONTROL & 0x2)) */
+    tst         r1, #0x2
+    beq         .busy_2      
+                                      
+
+    /* 2nd loop start */
+20:                                   /* loop start */
+    /* restore r0 (bu), r1 (rv) and r2 (guv) from chroma buffer */
+    ldmia       r8!, {r0-r2}
+  
+    /* 2nd loop, first pixel */
+    ldrb        r5, [r9], #1          /* r5 = *ysrc++ = *Y'_p++ */
+    sub         r5, r5, #16           /* r5 = (Y'-16) * 74 */
+    add         r3, r5, r5, asl #2
+    add         r5, r3, r5, asl #5
+    
+    add         r6, r1, r5, asr #8    /* r6 = r = (Y >> 9) + rv */
+    add         r3, r2, r5, asr #7    /* r3 = g = (Y >> 8) + guv */
+    add         r4, r0, r5, asr #8    /* r4 = b = (Y >> 9) + bu */
+   
+    orr         r5, r6, r4            /* check if clamping is needed... */
+    orr         r5, r5, r3, asr #1    /* ...at all */
+    cmp         r5, #31                 
+    bls         15f                   /* -> no clamp */
+    cmp         r6, #31               /* clamp r */
+    mvnhi       r6, r6, asr #31         
+    andhi       r6, r6, #31             
+    cmp         r3, #63               /* clamp g */
+    mvnhi       r3, r3, asr #31
+    andhi       r3, r3, #63
+    cmp         r4, #31               /* clamp b */
+    mvnhi       r4, r4, asr #31         
+    andhi       r4, r4, #31          
+15:                                   /* no clamp */
+    /* calculate pixel_1 and save to r5 for later pixel packing */
+    orr         r4, r4, r3, lsl #5    /* pixel_1 = r<<11 | g<<5 | b */
+    orr         r5, r4, r6, lsl #11   /* r5 = pixel_1 */
+    
+    /* 2nd loop, second pixel */
+    ldrb        r4, [r9], #1          /* r4 = *ysrc++ = *Y'_p++ */
+    sub         r4, r4, #16           /* r4 = (Y'-16) * 74 */
+    add         r3, r4, r4, asl #2
+    add         r4, r3, r4, asl #5
+    
+    add         r6, r1, r4, asr #8    /* r6 = r = (Y >> 9) + rv */
+    add         r3, r2, r4, asr #7    /* r3 = g = (Y >> 8) + guv */
+    add         r4, r0, r4, asr #8    /* r4 = b = (Y >> 9) + bu */
+  
+    orr         r0, r6, r4            /* check if clamping is needed... */
+    orr         r0, r0, r3, asr #1    /* ...at all */
+    cmp         r0, #31                 
+    bls         15f                   /* -> no clamp */
+    cmp         r6, #31               /* clamp r */
+    mvnhi       r6, r6, asr #31         
+    andhi       r6, r6, #31             
+    cmp         r3, #63               /* clamp g */
+    mvnhi       r3, r3, asr #31
+    andhi       r3, r3, #63
+    cmp         r4, #31               /* clamp b */
+    mvnhi       r4, r4, asr #31         
+    andhi       r4, r4, #31          
+15:                                   /* no clamp */
+   
+    /* calculate pixel_2 and pack with pixel_1 before writing */
+    orr         r4, r4, r3, lsl #5    /* pixel_2 = r<<11 | g<<5 | b */
+    orr         r4, r4, r6, lsl #11   /* r4 = pixel_2 */
+    orr         r4, r5, r4, lsl #16   /* r4 = pixel_2<<16 | pixel_1 */
+    str         r4, [lr]              /* write packed pixels */
+    
+    subs        r7, r7, #2            /* check for loop end */
+    bgt         20b                   /* back to beginning  */
+    /* 2nd loop end */
+
+    ldr         r3, [sp, #12]
+    add         sp, sp, r3            /* deallocate buffer */
+    ldmpc       regs=r4-r10           /* restore registers */
+
+    .ltorg
+    .size   lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
diff --git a/firmware/target/arm/portalplayer/ipod/video/lcd-video.c b/firmware/target/arm/portalplayer/ipod/video/lcd-video.c
new file mode 100644
index 0000000..c499e9f
--- /dev/null
+++ b/firmware/target/arm/portalplayer/ipod/video/lcd-video.c
@@ -0,0 +1,658 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * LCD driver for iPod Video
+ *
+ * Based on code from the ipodlinux project - http://ipodlinux.org/
+ * Adapted for Rockbox in December 2005
+ *
+ * Original file: linux/arch/armnommu/mach-ipod/fb.c
+ *
+ * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
+ *
+ * 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 <sys/types.h> /* off_t */
+#include "config.h"
+#include "cpu.h"
+#include "lcd.h"
+#include "kernel.h"
+#include "system.h"
+#ifdef HAVE_LCD_SLEEP
+/* Included only for lcd_awake() prototype */
+#include "backlight-target.h"
+#endif
+
+/* The BCM bus width is 16 bits. But since the low address bits aren't decoded
+ * by the chip (the 3 BCM address bits are mapped to address bits 16..18 of the
+ * PP5022), writing 32 bits (and even more, using 'stmia') at once works. */
+#define BCM_DATA      (*(volatile unsigned short*)(0x30000000))
+#define BCM_DATA32    (*(volatile unsigned long *)(0x30000000))
+#define BCM_WR_ADDR   (*(volatile unsigned short*)(0x30010000))
+#define BCM_WR_ADDR32 (*(volatile unsigned long *)(0x30010000))
+#define BCM_RD_ADDR   (*(volatile unsigned short*)(0x30020000))
+#define BCM_RD_ADDR32 (*(volatile unsigned long *)(0x30020000))
+#define BCM_CONTROL   (*(volatile unsigned short*)(0x30030000))
+
+#define BCM_ALT_DATA      (*(volatile unsigned short*)(0x30040000))
+#define BCM_ALT_DATA32    (*(volatile unsigned long *)(0x30040000))
+#define BCM_ALT_WR_ADDR   (*(volatile unsigned short*)(0x30050000))
+#define BCM_ALT_WR_ADDR32 (*(volatile unsigned long *)(0x30050000))
+#define BCM_ALT_RD_ADDR   (*(volatile unsigned short*)(0x30060000))
+#define BCM_ALT_RD_ADDR32 (*(volatile unsigned long *)(0x30060000))
+#define BCM_ALT_CONTROL   (*(volatile unsigned short*)(0x30070000))
+
+/* Time until the BCM is considered stalled and will be re-kicked.
+ * Must be guaranteed to be >~ 20ms. */
+#define BCM_UPDATE_TIMEOUT (HZ/20)
+/* An LCD update command done while the LCD is off needs >~ 200ms */
+#define BCM_LCDINIT_TIMEOUT (HZ/2)
+
+/* Addresses within BCM */
+#define BCMA_SRAM_BASE   0
+#define BCMA_COMMAND     0x1F8
+#define BCMA_STATUS      0x1FC
+#define BCMA_CMDPARAM    0xE0000    /* Parameters/data for commands */
+#define BCMA_SDRAM_BASE  0xC0000000
+#define BCMA_TV_FB       0xC0000000 /* TV out framebuffer */
+#define BCMA_TV_BMPDATA  0xC0200000 /* BMP data for TV out functions */
+
+/* BCM commands.  Write them to BCMA_COMMAND.  Note BCM_CMD encoding. */
+#define BCM_CMD(x) ((~((unsigned long)x) << 16) | ((unsigned long)x))
+#define BCMCMD_LCD_UPDATE     BCM_CMD(0)
+/* Execute "M25 Diagnostics".  Status displayed on LCD.  Takes <40s */
+#define BCMCMD_SELFTEST       BCM_CMD(1)
+#define BCMCMD_TV_PALBMP      BCM_CMD(2)
+#define BCMCMD_TV_NTSCBMP     BCM_CMD(3)
+/* BCM_CMD(4) may be another TV-related command */
+/* The following might do more depending on word at 0xE00000 */
+#define BCMCMD_LCD_UPDATERECT BCM_CMD(5)
+#define BCMCMD_LCD_SLEEP      BCM_CMD(8)
+/* BCM_CMD(12) involved in shutdown */
+/* Macrovision analog copy prevention is on by default on TV output.
+   Execute this command after enabling TV out to turn it off.
+ */
+#define BCMCMD_TV_MVOFF       BCM_CMD(14)
+
+enum lcd_status
+{
+    LCD_IDLE,
+    LCD_INITIAL,
+    LCD_NEED_UPDATE,
+    LCD_UPDATING
+};
+
+struct
+{
+    long update_timeout;  /* also used to ensure BCM stays off for >= 50 ms */
+    enum lcd_status state;
+    bool blocked;
+#if NUM_CORES > 1
+    struct corelock cl;   /* inter-core sync */
+#endif
+#ifdef HAVE_LCD_SLEEP
+    bool display_on;
+    bool waking;
+    struct semaphore initwakeup;
+#endif
+} lcd_state IBSS_ATTR;
+
+#ifdef HAVE_LCD_SLEEP
+const fb_data *flash_vmcs_offset;
+unsigned flash_vmcs_length;
+
+#define ROM_BASE        0x20000000
+#define ROM_ID(a,b,c,d) (unsigned int)(  ((unsigned int)(d))        | \
+                                        (((unsigned int)(c)) << 8)  | \
+                                        (((unsigned int)(b)) << 16) | \
+                                        (((unsigned int)(a)) << 24) )
+
+/* Get address and length of iPod flash section.
+   Based on part of FS#6721.  This may belong elsewhere.
+   (BCM initialization uploads the vmcs section to the BCM.)
+ */
+static bool flash_get_section(const unsigned int imageid,
+                              void **offset,
+                              unsigned int *length)
+{
+    unsigned long *p = (unsigned long*)(ROM_BASE + 0xffe00);
+    unsigned char *csp, *csend;
+    unsigned long checksum;
+
+    /* Find the image in the directory */
+    while (1)
+    {
+        if (p[0] != ROM_ID('f','l','s','h'))
+            return false;
+        if (p[1] == imageid)
+            break;
+        p += 10;
+    }
+
+    *offset = (void *)(ROM_BASE + p[3]);
+    *length = p[4];
+
+    /* Verify checksum.  Probably unnecessary, but it's fast. */
+    checksum = 0;
+    csend = (unsigned char *)(ROM_BASE + p[3] + p[4]);
+    for(csp = (unsigned char *)(ROM_BASE + p[3]); csp < csend; csp++)
+    {
+        checksum += *csp;
+    }
+
+    return checksum == p[7];
+}
+#endif /* HAVE_LCD_SLEEP */
+
+static inline void bcm_write_addr(unsigned address)
+{
+    BCM_WR_ADDR32 = address;       /* write destination address */
+
+    while (!(BCM_CONTROL & 0x2));  /* wait for it to be write ready */
+}
+
+static inline void bcm_write32(unsigned address, unsigned value)
+{
+
+    bcm_write_addr(address);       /* set destination address */
+
+    BCM_DATA32 = value;            /* write value */
+}
+
+static inline unsigned bcm_read32(unsigned address)
+{
+    while (!(BCM_RD_ADDR & 1));
+
+    BCM_RD_ADDR32 = address;       /* write source address */
+
+    while (!(BCM_CONTROL & 0x10)); /* wait for it to be read ready */
+
+    return BCM_DATA32;             /* read value */
+}
+
+#ifdef HAVE_LCD_SLEEP
+static void continue_lcd_awake(void)
+{
+    lcd_state.waking = false;
+    semaphore_release(&(lcd_state.initwakeup));
+}
+#endif
+
+#ifndef BOOTLOADER
+static void lcd_tick(void)
+{
+    /* No core level interrupt mask - already in interrupt context */
+#if NUM_CORES > 1
+    corelock_lock(&lcd_state.cl);
+#endif
+
+    if (!lcd_state.blocked && lcd_state.state >= LCD_NEED_UPDATE)
+    {
+        unsigned data = bcm_read32(BCMA_COMMAND);
+        bool bcm_is_busy = (data == BCMCMD_LCD_UPDATE || data == 0xFFFF);
+
+        if (((lcd_state.state == LCD_NEED_UPDATE) && !bcm_is_busy)
+            /* Update requested and BCM is no longer busy. */
+         || (TIME_AFTER(current_tick, lcd_state.update_timeout) && bcm_is_busy))
+            /* BCM still busy after timeout, i.e. stalled. */
+        {
+            bcm_write32(BCMA_COMMAND, BCMCMD_LCD_UPDATE);  /* Kick off update */
+            BCM_CONTROL = 0x31;
+            lcd_state.update_timeout = current_tick + BCM_UPDATE_TIMEOUT;
+            lcd_state.state = LCD_UPDATING;
+#ifdef HAVE_LCD_SLEEP
+            if (lcd_state.waking)
+                continue_lcd_awake();
+#endif
+        }
+        else if ((lcd_state.state == LCD_UPDATING) && !bcm_is_busy)
+        {
+            /* Update finished properly and no new update pending. */
+            lcd_state.state = LCD_IDLE;
+#ifdef HAVE_LCD_SLEEP
+            if (lcd_state.waking)
+                continue_lcd_awake();
+#endif
+        }
+    }
+#if NUM_CORES > 1
+    corelock_unlock(&lcd_state.cl);
+#endif
+}
+
+static inline void lcd_block_tick(void)
+{
+    int oldlevel = disable_irq_save();
+
+#if NUM_CORES > 1
+    corelock_lock(&lcd_state.cl);
+    lcd_state.blocked = true;
+    corelock_unlock(&lcd_state.cl);
+#else
+    lcd_state.blocked = true;
+#endif
+    restore_irq(oldlevel);
+}
+
+static void lcd_unblock_and_update(void)
+{
+    unsigned data;
+    bool bcm_is_busy;
+    int oldlevel = disable_irq_save();
+
+#if NUM_CORES > 1
+    corelock_lock(&lcd_state.cl);
+#endif
+    data = bcm_read32(BCMA_COMMAND);
+    bcm_is_busy = (data == BCMCMD_LCD_UPDATE || data == 0xFFFF);
+
+    if (!bcm_is_busy || (lcd_state.state == LCD_INITIAL) ||
+        TIME_AFTER(current_tick, lcd_state.update_timeout))
+    {
+        bcm_write32(BCMA_COMMAND, BCMCMD_LCD_UPDATE);  /* Kick off update */
+        BCM_CONTROL = 0x31;
+        lcd_state.update_timeout = current_tick + BCM_UPDATE_TIMEOUT;
+        lcd_state.state = LCD_UPDATING;
+#ifdef HAVE_LCD_SLEEP
+        if (lcd_state.waking)
+            continue_lcd_awake();
+#endif
+    }
+    else
+    {
+         lcd_state.state = LCD_NEED_UPDATE; /* Post update request */
+    }
+    lcd_state.blocked = false;
+
+#if NUM_CORES > 1
+    corelock_unlock(&lcd_state.cl);
+#endif
+    restore_irq(oldlevel);
+}
+
+#else /* BOOTLOADER */
+
+#define lcd_block_tick()
+
+static void lcd_unblock_and_update(void)
+{
+    unsigned data;
+
+    if (lcd_state.state != LCD_INITIAL)
+    {
+        data = bcm_read32(BCMA_COMMAND);
+        while (data == BCMCMD_LCD_UPDATE || data == 0xFFFF)
+        {
+            yield();
+            data = bcm_read32(BCMA_COMMAND);
+        }
+    }
+    bcm_write32(BCMA_COMMAND, BCMCMD_LCD_UPDATE);  /* Kick off update */
+    BCM_CONTROL = 0x31;
+    lcd_state.state = LCD_IDLE;
+}
+#endif /* BOOTLOADER */
+
+/*** hardware configuration ***/
+
+void lcd_set_contrast(int val)
+{
+  /* TODO: Implement lcd_set_contrast() */
+  (void)val;
+}
+
+void lcd_set_invert_display(bool yesno)
+{
+  /* TODO: Implement lcd_set_invert_display() */
+  (void)yesno;
+}
+
+/* turn the display upside down (call lcd_update() afterwards) */
+void lcd_set_flip(bool yesno)
+{
+  /* TODO: Implement lcd_set_flip() */
+  (void)yesno;
+}
+
+/* LCD init */
+void lcd_init_device(void)
+{
+    /* These port initializations are supposed to be done when initializing
+       the BCM.  None of it is changed when shutting down the BCM.
+     */
+    GPO32_ENABLE |= 0xC000;
+    GPIO_CLEAR_BITWISE(GPIOC_ENABLE, 0x80);
+    /* This pin is used for BCM interrupts */
+    GPIOC_ENABLE |= 0x40;
+    GPIOC_OUTPUT_EN &= ~0x40;
+    GPO32_ENABLE &= ~1;
+
+    lcd_state.blocked = false;
+    lcd_state.state = LCD_INITIAL;
+#ifndef BOOTLOADER
+#if NUM_CORES > 1
+    corelock_init(&lcd_state.cl);
+#endif
+#ifdef HAVE_LCD_SLEEP
+    if (!flash_get_section(ROM_ID('v', 'm', 'c', 's'),
+                           (void **)(&flash_vmcs_offset), &flash_vmcs_length))
+        /* BCM cannot be shut down because firmware wasn't found */
+        flash_vmcs_length = 0;
+    else
+    {
+        /* lcd_write_data needs an even number of 16 bit values */
+        flash_vmcs_length = ((flash_vmcs_length + 3) >> 1) & ~1;
+    }
+    semaphore_init(&(lcd_state.initwakeup), 1, 0);
+    lcd_state.waking = false;
+
+    if (GPO32_VAL & 0x4000)
+    {
+        /* BCM is powered.  Assume it is initialized. */
+        lcd_state.display_on = true;
+        tick_add_task(&lcd_tick);
+    }
+    else
+    {
+        /* BCM is not powered, so it needs to be initialized.
+           This can only happen when loading Rockbox via ROLO.
+         */
+        lcd_state.update_timeout = current_tick;
+        lcd_state.display_on = false;
+        lcd_awake();
+    }
+#else /* !HAVE_LCD_SLEEP */
+    tick_add_task(&lcd_tick);
+#endif
+#endif /* !BOOTLOADER */
+}
+
+/*** update functions ***/
+
+/* Update a fraction of the display. */
+void lcd_update_rect(int x, int y, int width, int height)
+{
+    const fb_data *addr;
+    unsigned bcmaddr;
+
+#ifdef HAVE_LCD_SLEEP
+    if (!lcd_state.display_on)
+        return;
+#endif
+
+    if (x + width >= LCD_WIDTH)
+        width = LCD_WIDTH - x;
+    if (y + height >= LCD_HEIGHT)
+        height = LCD_HEIGHT - y;
+
+    if ((width <= 0) || (height <= 0))
+        return; /* Nothing left to do. */
+
+    /* Ensure x and width are both even. The BCM doesn't like small unaligned
+     * writes and would just ignore them. */
+    width = (width + (x & 1) + 1) & ~1;
+    x &= ~1;
+
+    /* Prevent the tick from triggering BCM updates while we're writing. */
+    lcd_block_tick();
+
+    addr = &lcd_framebuffer[y][x];
+    bcmaddr = BCMA_CMDPARAM + (LCD_WIDTH*2) * y + (x << 1);
+
+    if (width == LCD_WIDTH)
+    {
+        bcm_write_addr(bcmaddr);
+        lcd_write_data(addr, width * height);
+    }
+    else
+    {
+        do
+        {
+            bcm_write_addr(bcmaddr);
+            bcmaddr += (LCD_WIDTH*2);
+            lcd_write_data(addr, width);
+            addr += LCD_WIDTH;
+        }
+        while (--height > 0);
+    }
+    lcd_unblock_and_update();
+}
+
+/* Update the display.
+   This must be called after all other LCD functions that change the display. */
+void lcd_update(void)
+{
+    lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
+}
+
+/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */
+extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
+                                   unsigned bcmaddr,
+                                   int width,
+                                   int stride);
+
+/* Performance function to blit a YUV bitmap directly to the LCD */
+void lcd_blit_yuv(unsigned char * const src[3],
+                  int src_x, int src_y, int stride,
+                  int x, int y, int width, int height)
+{
+    unsigned bcmaddr;
+    off_t z;
+    unsigned char const * yuv_src[3];
+
+#ifdef HAVE_LCD_SLEEP
+    if (!lcd_state.display_on)
+        return;
+#endif
+
+    /* Sorry, but width and height must be >= 2 or else */
+    width &= ~1;
+
+    z = stride * src_y;
+    yuv_src[0] = src[0] + z + src_x;
+    yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1);
+    yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
+
+    /* Prevent the tick from triggering BCM updates while we're writing. */
+    lcd_block_tick();
+
+    bcmaddr = BCMA_CMDPARAM + (LCD_WIDTH*2) * y + (x << 1);
+    height >>= 1;
+
+    do
+    {
+        lcd_write_yuv420_lines(yuv_src, bcmaddr, width, stride);
+        bcmaddr += (LCD_WIDTH*4);  /* Skip up two lines */
+        yuv_src[0] += stride << 1;
+        yuv_src[1] += stride >> 1; /* Skip down one chroma line */
+        yuv_src[2] += stride >> 1;
+    }
+    while (--height > 0);
+
+    lcd_unblock_and_update();
+}
+
+#ifdef HAVE_LCD_SLEEP
+/* Executes a BCM command immediately and waits for it to complete.
+   Other BCM commands (eg. LCD updates or lcd_tick) must not interfere.
+ */
+static void bcm_command(unsigned cmd)
+{
+    unsigned status;
+
+    bcm_write32(BCMA_COMMAND,  cmd);
+
+    BCM_CONTROL = 0x31;
+
+    while (1)
+    {
+        status = bcm_read32(BCMA_COMMAND);
+        if (status != cmd && status != 0xFFFF)
+            break;
+        yield();
+    }
+}
+
+static void bcm_powerdown(void)
+{
+    /* Immediately switch off the backlight to avoid flashing. */
+    _backlight_hw_enable(false);
+    
+    /* Not sure what this does. */
+    bcm_write32(0x10001400, bcm_read32(0x10001400) & ~0xF0);
+
+    /* Blanks the LCD and decreases power consumption
+       below what clearing the LCD would achieve.
+       Executing an LCD update command wakes it.
+     */
+    bcm_command(BCMCMD_LCD_SLEEP);
+
+    /* Not sure if this does anything */
+    bcm_command(BCM_CMD(0xC));
+
+    /* Further cuts power use, probably by powering down BCM.
+       After this point, BCM needs to be bootstrapped
+     */
+    GPO32_VAL &= ~0x4000;
+}
+
+/* Data written to BCM_CONTROL and BCM_ALT_CONTROL */
+const unsigned char bcm_bootstrapdata[] =
+{
+    0xA1, 0x81, 0x91, 0x02, 0x12, 0x22, 0x72, 0x62
+};
+
+static void bcm_init(void)
+{
+    int i;
+
+    /* Power up BCM */
+    GPO32_VAL |= 0x4000;
+    sleep(HZ/20);
+
+    /* Bootstrap stage 1 */
+
+    STRAP_OPT_A &= ~0xF00;
+    outl(0x1313, 0x70000040);
+
+    /* Interrupt-related code for future use
+       GPIOC_INT_LEV |= 0x40;
+       GPIOC_INT_EN |= 0x40;
+       CPU_HI_INT_EN |= 0x40000;
+    */
+
+    /* Bootstrap stage 2 */
+
+    while (BCM_ALT_CONTROL & 0x80);
+    while (!(BCM_ALT_CONTROL & 0x40));
+
+    for (i = 0; i < 8; i++)
+    {
+        BCM_CONTROL = bcm_bootstrapdata[i];
+    }
+
+    for (i = 3; i < 8; i++)
+    {
+        BCM_ALT_CONTROL = bcm_bootstrapdata[i];
+    }
+
+    while ((BCM_RD_ADDR & 1) == 0 || (BCM_ALT_RD_ADDR & 1) == 0);
+
+    (void)BCM_WR_ADDR;
+    (void)BCM_ALT_WR_ADDR;
+
+    /* Bootstrap stage 3: upload firmware */
+
+    while (BCM_ALT_CONTROL & 0x80);
+    while (!(BCM_ALT_CONTROL & 0x40));
+
+    /* Upload firmware to BCM SRAM */
+    bcm_write_addr(BCMA_SRAM_BASE);
+    lcd_write_data(flash_vmcs_offset, flash_vmcs_length);
+
+    bcm_write32(BCMA_COMMAND,  0);
+    bcm_write32(0x10000C00, 0xC0000000);
+
+    while (!(bcm_read32(0x10000C00) & 1));
+
+    bcm_write32(0x10000C00, 0);
+    bcm_write32(0x10000400, 0xA5A50002);
+
+    while (bcm_read32(BCMA_COMMAND) == 0)
+        yield();
+
+    /* sleep(HZ/2) apparently unneeded */
+}
+
+void lcd_awake(void)
+{
+    if (!lcd_state.display_on && flash_vmcs_length != 0)
+    {
+        /* Ensure BCM has been off for >= 50 ms */
+        long sleepwait = lcd_state.update_timeout + HZ/20 - current_tick;
+        if (sleepwait > 0 && sleepwait < HZ/20)
+            sleep(sleepwait);
+
+        bcm_init();
+
+        /* Start the first LCD update, which also initializes the LCD */
+        lcd_state.state = LCD_INITIAL;
+        lcd_state.display_on = true;
+        lcd_update();
+        lcd_state.update_timeout = current_tick + BCM_LCDINIT_TIMEOUT;
+
+        /* Wait for end of first LCD update, so LCD isn't white
+           when the backlight turns on.
+         */
+        lcd_state.waking = true;
+        tick_add_task(&lcd_tick);
+        semaphore_wait(&(lcd_state.initwakeup), TIMEOUT_BLOCK);
+
+        send_event(LCD_EVENT_ACTIVATION, NULL);
+    }
+}
+
+void lcd_sleep(void)
+{
+    if (lcd_state.display_on && flash_vmcs_length != 0)
+    {
+        lcd_state.display_on = false;
+
+        /* Wait for BCM to finish work */
+        while (lcd_state.state != LCD_INITIAL && lcd_state.state != LCD_IDLE)
+            yield();
+
+        tick_remove_task(&lcd_tick);
+        bcm_powerdown();
+
+        /* Remember time to ensure BCM stays off for >= 50 ms */
+        lcd_state.update_timeout = current_tick;
+    }
+}
+
+bool lcd_active(void)
+{
+    return lcd_state.display_on;
+}
+
+#ifdef HAVE_LCD_SHUTDOWN
+void lcd_shutdown(void)
+{
+    lcd_sleep();
+}
+#endif /* HAVE_LCD_SHUTDOWN */
+#endif /* HAVE_LCD_SLEEP */
diff --git a/firmware/target/arm/portalplayer/iriver/app.lds b/firmware/target/arm/portalplayer/iriver/app.lds
new file mode 100644
index 0000000..612fcb5
--- /dev/null
+++ b/firmware/target/arm/portalplayer/iriver/app.lds
@@ -0,0 +1,204 @@
+#include "config.h"
+
+ENTRY(start)
+
+OUTPUT_FORMAT(elf32-littlearm)
+OUTPUT_ARCH(arm)
+STARTUP(target/arm/portalplayer/crt0-pp.o)
+
+#define PLUGINSIZE PLUGIN_BUFFER_SIZE
+#define CODECSIZE CODEC_SIZE
+
+#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - CODECSIZE
+
+#define DRAMORIG 0x00000000
+#define IRAMORIG 0x40000000
+#define IRAMSIZE 0xc000
+
+#ifdef CPU_PP502x
+#define NOCACHE_BASE 	0x10000000
+#else
+#define NOCACHE_BASE 	0x28000000
+#endif
+
+#define CACHEALIGN_SIZE 16
+
+/* End of the audio buffer, where the codec buffer starts */
+#define ENDAUDIOADDR  (DRAMORIG + DRAMSIZE)
+
+/* Where the codec buffer ends, and the plugin buffer starts */
+#define ENDADDR (ENDAUDIOADDR + CODECSIZE)
+
+MEMORY
+{
+    DRAM : ORIGIN = DRAMORIG,     LENGTH = DRAMSIZE
+    IRAM : ORIGIN = IRAMORIG,     LENGTH = IRAMSIZE
+}
+
+SECTIONS
+{
+    .text :
+    {
+        loadaddress = .;
+        _loadaddress = .;
+        . = ALIGN(0x200);
+        *(.init.text)
+        *(.text*)
+        *(.glue_7)
+        *(.glue_7t)
+        . = ALIGN(0x4);
+    } > DRAM
+
+    .rodata :
+    {
+        *(.rodata)  /* problems without this, dunno why */
+        *(.rodata*)
+        *(.rodata.str1.1)
+        *(.rodata.str1.4)
+        . = ALIGN(0x4);
+
+        /* Pseudo-allocate the copies of the data sections */
+        _datacopy = .;
+    } > DRAM
+
+    /* TRICK ALERT! For RAM execution, we put the .data section at the
+       same load address as the copy. Thus, we don't waste extra RAM
+       when we don't actually need the copy.  */
+    .data : AT ( _datacopy )
+    {
+        _datastart = .;
+        *(.data*)
+        . = ALIGN(0x4);
+        _dataend  = .;
+    } > DRAM
+
+#if NOCACHE_BASE != 0
+    /* .ncdata section is placed at uncached physical alias address and is
+     * loaded at the proper cached virtual address - no copying is
+     * performed in the init code */
+    .ncdata . + NOCACHE_BASE :
+    {
+        . = ALIGN(CACHEALIGN_SIZE);
+        *(.ncdata*)
+        . = ALIGN(CACHEALIGN_SIZE);
+    } AT> DRAM
+#endif
+    
+    /DISCARD/ :
+    {
+        *(.eh_frame)
+    }
+
+    .vectors 0x0 :
+    {
+        _vectorsstart = .;
+        *(.vectors);
+        _vectorsend = .;
+    } AT> DRAM
+
+    _vectorscopy = LOADADDR(.vectors);
+    _noloaddram  = LOADADDR(.vectors);
+
+    .ibss IRAMORIG (NOLOAD) :
+    {
+        _iedata = .;
+        *(.qharray)
+        *(.ibss)
+        . = ALIGN(0x4);
+        _iend = .;
+    } > IRAM
+
+    .iram _iend :
+    {
+        _iramstart = .;
+        *(.icode)
+        *(.irodata)
+        *(.idata)
+        . = ALIGN(0x4);
+        _iramend = .;
+    } > IRAM AT> DRAM
+
+    _iramcopy = LOADADDR(.iram);
+
+
+    .init ENDAUDIOADDR : 
+    {
+        . = ALIGN(4);
+        _initstart = .;
+        *(.init)
+        _initend = .;
+    } AT> DRAM
+
+    _initcopy = LOADADDR(.init);
+
+    .idle_stacks (NOLOAD) :
+    {
+       *(.idle_stacks)
+#if NUM_CORES > 1
+       cpu_idlestackbegin = .;
+       . += IDLE_STACK_SIZE;
+       cpu_idlestackend = .;
+#endif
+       cop_idlestackbegin = .;
+       . += IDLE_STACK_SIZE;
+       cop_idlestackend = .;
+    } > IRAM
+
+    .stack (NOLOAD) :
+    {
+       *(.stack)
+       stackbegin = .;
+       . += 0x2000;
+       stackend = .;
+    } > IRAM
+    
+    /* .bss and .ncbss are treated as a single section to use one init loop to
+     * zero it - note "_edata" and "_end" */
+    .bss _noloaddram (NOLOAD) :
+    {
+       _edata = .;
+        *(.bss*)
+        *(COMMON)
+        . = ALIGN(0x4);
+    } > DRAM
+
+#if NOCACHE_BASE != 0
+    .ncbss . + NOCACHE_BASE (NOLOAD):
+    {
+    	. = ALIGN(CACHEALIGN_SIZE);
+        *(.ncbss*)
+    	. = ALIGN(CACHEALIGN_SIZE);
+    } AT> DRAM
+#endif
+
+    /* This will be aligned by preceding alignments */
+    .endaddr . - NOCACHE_BASE (NOLOAD) :
+    {
+        _end = .;
+    } > DRAM
+
+    .audiobuf (NOLOAD) :
+    {
+        _audiobuffer = .;
+        . = ALIGN(0x4);
+        audiobuffer = .;
+    } > DRAM
+    
+    .audiobufend ENDAUDIOADDR (NOLOAD) :
+    {
+        audiobufend = .;
+        _audiobufend = .;
+    } > DRAM
+
+    .codec ENDAUDIOADDR (NOLOAD) :
+    {
+        codecbuf = .;
+        _codecbuf = .;
+    }
+
+    .plugin ENDADDR (NOLOAD) :
+    {
+        _pluginbuf = .;
+        pluginbuf = .;
+    }
+}
diff --git a/firmware/target/arm/portalplayer/iriver/backlight-target.h b/firmware/target/arm/portalplayer/iriver/backlight-target.h
new file mode 100644
index 0000000..a27b489
--- /dev/null
+++ b/firmware/target/arm/portalplayer/iriver/backlight-target.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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 BACKLIGHT_TARGET_H
+#define BACKLIGHT_TARGET_H
+
+#define _backlight_init() true
+void _backlight_on(void);
+void _backlight_off(void);
+
+#endif
diff --git a/firmware/target/arm/portalplayer/iriver/boot.lds b/firmware/target/arm/portalplayer/iriver/boot.lds
new file mode 100644
index 0000000..ed4fc35
--- /dev/null
+++ b/firmware/target/arm/portalplayer/iriver/boot.lds
@@ -0,0 +1,2 @@
+#include "config.h"
+#include "../boot-pp502x-bl-usb.lds"
diff --git a/firmware/target/arm/portalplayer/iriver/h10/adc-target.h b/firmware/target/arm/portalplayer/iriver/h10/adc-target.h
new file mode 100644
index 0000000..ba3e98d
--- /dev/null
+++ b/firmware/target/arm/portalplayer/iriver/h10/adc-target.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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 _ADC_TARGET_H_
+#define _ADC_TARGET_H_
+
+#define NUM_ADC_CHANNELS 4
+
+#define ADC_BATTERY     0
+#define ADC_UNKNOWN_1   1
+#define ADC_REMOTE      2
+#define ADC_SCROLLPAD   3
+#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
+
+/* Force a scan now */
+unsigned short adc_scan(int channel);
+
+#endif
diff --git a/firmware/target/arm/portalplayer/iriver/h10/backlight-h10.c b/firmware/target/arm/portalplayer/iriver/h10/backlight-h10.c
new file mode 100644
index 0000000..db10f39
--- /dev/null
+++ b/firmware/target/arm/portalplayer/iriver/h10/backlight-h10.c
@@ -0,0 +1,42 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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 "system.h"
+#include "backlight.h"
+#include "backlight-target.h"
+#include "lcd.h"
+
+void _backlight_on(void)
+{
+#ifdef HAVE_LCD_ENABLE
+    lcd_enable(true); /* power on lcd + visible display */
+#endif
+    GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 0x20);
+}
+
+void _backlight_off(void)
+{
+    GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_VAL, 0x20);
+#ifdef HAVE_LCD_ENABLE
+    lcd_enable(false); /* power off visible display */
+#endif
+}
diff --git a/firmware/target/arm/portalplayer/iriver/h10/button-h10.c b/firmware/target/arm/portalplayer/iriver/h10/button-h10.c
new file mode 100644
index 0000000..6710f39
--- /dev/null
+++ b/firmware/target/arm/portalplayer/iriver/h10/button-h10.c
@@ -0,0 +1,148 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* Custom written for the H10 based on analysis of the GPIO data */
+
+
+#include <stdlib.h>
+#include "config.h"
+#include "cpu.h"
+#include "system.h"
+#include "button.h"
+#include "kernel.h"
+#include "backlight.h"
+#include "adc.h"
+
+
+void button_init_device(void)
+{
+    /* Enable REW, FF, Play, Left, Right, Hold buttons */
+    GPIO_SET_BITWISE(GPIOA_ENABLE, 0xfc);
+    
+    /* Enable POWER button */
+    GPIO_SET_BITWISE(GPIOB_ENABLE, 0x01);
+    
+    /* We need to output to pin 6 of GPIOD when reading the scroll pad value */
+    GPIO_SET_BITWISE(GPIOD_ENABLE, 0x40);
+    GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x40);
+    GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x40);
+}
+
+bool button_hold(void)
+{
+    return (GPIOA_INPUT_VAL & 0x4)?false:true;
+}
+
+bool remote_button_hold(void)
+{
+    return adc_scan(ADC_REMOTE) < 0x2B;
+}
+
+/*
+ * Get button pressed from hardware
+ */
+int button_read_device(void)
+{
+    int btn = BUTTON_NONE;
+    int data;
+    unsigned char state;
+    static bool hold_button = false;
+    static bool remote_hold_button = false;
+    bool hold_button_old;
+    bool remote_hold_button_old;
+
+    /* Hold */
+    hold_button_old = hold_button;
+    hold_button = button_hold();
+
+#ifndef BOOTLOADER
+    /* light handling */
+    if (hold_button != hold_button_old)
+    {
+        backlight_hold_changed(hold_button);
+    }
+#endif
+
+    /* device buttons */
+    if (!hold_button)
+    {
+        /* Read normal buttons */
+        state = GPIOA_INPUT_VAL & 0xf8;
+        if ((state & 0x8) == 0) btn |= BUTTON_FF;
+        if ((state & 0x10) == 0) btn |= BUTTON_PLAY;
+        if ((state & 0x20) == 0) btn |= BUTTON_REW;
+        if ((state & 0x40) == 0) btn |= BUTTON_RIGHT;
+        if ((state & 0x80) == 0) btn |= BUTTON_LEFT;
+        
+        /* Read power button */
+        if (GPIOB_INPUT_VAL & 0x1) btn |= BUTTON_POWER;
+        
+        /* Read scroller */
+        if ( GPIOD_INPUT_VAL & 0x20 )
+        {
+            GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x40);
+            udelay(250);
+            data = adc_scan(ADC_SCROLLPAD);
+            GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x40);
+            
+            if(data < 0x224)
+            {
+                btn |= BUTTON_SCROLL_DOWN;
+            } else {
+                btn |= BUTTON_SCROLL_UP;
+            }
+        }
+    }
+    
+    /* remote buttons */
+    remote_hold_button_old = remote_hold_button;
+
+    data = adc_scan(ADC_REMOTE);
+    remote_hold_button = data < 0x2B;
+
+#ifndef BOOTLOADER
+    if (remote_hold_button != remote_hold_button_old)
+        backlight_hold_changed(remote_hold_button);
+#endif
+
+    if(!remote_hold_button)
+    {
+        if (data < 0x3FF)
+        {
+            if(data < 0x204)
+                if(data < 0x155)
+                    btn |= BUTTON_RC_FF;
+                else
+                    btn |= BUTTON_RC_REW;
+            else
+                if(data < 0x2D0)
+                   btn |= BUTTON_RC_VOL_DOWN;
+                else
+                    btn |= BUTTON_RC_VOL_UP;
+        }
+    }
+
+    /* remote play button should be dead if hold */
+    if (!remote_hold_button && !(GPIOA_INPUT_VAL & 0x1))
+        btn |= BUTTON_RC_PLAY;
+    
+    return btn;
+}
diff --git a/firmware/target/arm/portalplayer/iriver/h10/button-target.h b/firmware/target/arm/portalplayer/iriver/h10/button-target.h
new file mode 100644
index 0000000..c2d7165
--- /dev/null
+++ b/firmware/target/arm/portalplayer/iriver/h10/button-target.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* Custom written for the H10 */
+
+#ifndef _BUTTON_TARGET_H_
+#define _BUTTON_TARGET_H_
+
+#include <stdbool.h>
+#include "config.h"
+
+#define HAS_BUTTON_HOLD
+#define HAS_REMOTE_BUTTON_HOLD
+
+bool button_hold(void);
+bool remote_button_hold(void);
+void button_init_device(void);
+int button_read_device(void);
+
+/* iriver H10 specific button codes */
+
+    /* Main unit's buttons */
+#define BUTTON_POWER        0x00000001
+
+#define BUTTON_LEFT         0x00000002
+#define BUTTON_RIGHT        0x00000004
+
+#define BUTTON_REW          0x00000008
+#define BUTTON_PLAY         0x00000010
+#define BUTTON_FF           0x00000020
+
+#define BUTTON_SCROLL_UP    0x00000040
+#define BUTTON_SCROLL_DOWN  0x00000080
+
+#define BUTTON_MAIN (BUTTON_POWER|BUTTON_LEFT|BUTTON_RIGHT|BUTTON_REW\
+                |BUTTON_PLAY|BUTTON_FF|BUTTON_SCROLL_UP|BUTTON_SCROLL_DOWN)
+
+    /* Remote control's buttons */
+#define BUTTON_RC_REW       0x00080000
+#define BUTTON_RC_PLAY      0x00100000
+#define BUTTON_RC_FF        0x00200000
+#define BUTTON_RC_VOL_UP    0x00400000
+#define BUTTON_RC_VOL_DOWN  0x00800000
+
+#define BUTTON_REMOTE (BUTTON_RC_PLAY|BUTTON_RC_VOL_UP|BUTTON_RC_VOL_DOWN\
+                |BUTTON_RC_REW|BUTTON_RC_FF)
+
+#define POWEROFF_BUTTON     BUTTON_POWER
+#define RC_POWEROFF_BUTTON  BUTTON_RC_PLAY
+#define POWEROFF_COUNT 10
+
+#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/arm/portalplayer/iriver/h10/fmradio_i2c-h10.c b/firmware/target/arm/portalplayer/iriver/h10/fmradio_i2c-h10.c
new file mode 100644
index 0000000..bee1c6e
--- /dev/null
+++ b/firmware/target/arm/portalplayer/iriver/h10/fmradio_i2c-h10.c
@@ -0,0 +1,211 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ * Physical interface of the Philips TEA5767 in iriver H10 series
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ *
+ * 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 "logf.h"
+#include "system.h"
+#include "fmradio_i2c.h"
+
+/* cute little functions, atomic read-modify-write */
+
+#define SDA_OUTINIT GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x08)
+#define SDA_HI_IN   GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x08)
+#define SDA_LO_OUT  GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x08)
+#define SDA         (GPIOD_INPUT_VAL & 0x08)
+
+#define SCL_INPUT   GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x10)
+#define SCL_OUTPUT  GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x10)
+#define SCL_LO      GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x10)
+#define SCL_HI      GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL,0x10)
+#define SCL         (GPIOD_INPUT_VAL & 0x10)
+
+#define DELAY   udelay(2)
+
+static void fmradio_i2c_start(void)
+{
+    SCL_HI;
+    SCL_OUTPUT;
+    SDA_HI_IN;
+    SDA_OUTINIT;
+    DELAY;
+    SDA_LO_OUT;
+    DELAY;
+    SCL_LO;
+}
+
+static void fmradio_i2c_stop(void)
+{
+   SDA_LO_OUT;
+   DELAY;
+   SCL_HI;
+   DELAY;
+   SDA_HI_IN;
+}
+
+/* Generate ACK or NACK */
+static void fmradio_i2c_ack(bool nack)
+{
+    /* Here's the deal. The slave is slow, and sometimes needs to wait
+       before it can receive the acknowledge. Therefore it forces the clock
+       low until it is ready. We need to poll the clock line until it goes
+       high before we release the ack.
+
+       In their infinite wisdom, iriver didn't pull up the SCL line, so
+       we have to drive the SCL high repeatedly to simulate a pullup. */
+    
+    if (nack)
+        SDA_HI_IN;
+    else
+        SDA_LO_OUT;
+    DELAY;
+
+    SCL_HI;
+    do
+    {
+        SCL_OUTPUT;  /* Set the clock to output */
+        SCL_INPUT;   /* Set the clock to input */
+        DELAY;
+    }
+    while(!SCL);  /* and wait for the slave to release it */
+
+    SCL_OUTPUT;
+    SCL_LO;
+}
+
+static int fmradio_i2c_getack(void)
+{
+    int ret = 1;
+
+    /* Here's the deal. The slave is slow, and sometimes needs to wait
+       before it can send the acknowledge. Therefore it forces the clock
+       low until it is ready. We need to poll the clock line until it goes
+       high before we read the ack.
+
+       In their infinite wisdom, iriver didn't pull up the SCL line, so
+       we have to drive the SCL high repeatedly to simulate a pullup. */
+
+    SDA_HI_IN;
+    DELAY;
+
+    SCL_HI;          /* set clock to high */
+    do
+    {
+        SCL_OUTPUT;  /* Set the clock to output */
+        SCL_INPUT;   /* Set the clock to input */
+        DELAY;
+    }
+    while(!SCL);     /* and wait for the slave to release it */
+
+    if (SDA)
+        ret = 0;    /* ack failed */
+    
+    SCL_OUTPUT;
+    SCL_LO;
+
+    return ret;
+}
+
+static void fmradio_i2c_outb(unsigned char byte)
+{
+   int i;
+
+   /* clock out each bit, MSB first */
+   for ( i=0x80; i; i>>=1 ) {
+      if ( i & byte )
+         SDA_HI_IN;
+      else
+         SDA_LO_OUT;
+      DELAY;
+      SCL_HI;
+      DELAY;
+      SCL_LO;
+
+      DELAY;
+   }
+}
+
+static unsigned char fmradio_i2c_inb(void)
+{
+   int i;
+   unsigned char byte = 0;
+
+   SDA_HI_IN;
+   /* clock in each bit, MSB first */
+   for ( i=0x80; i; i>>=1 ) {
+       DELAY;
+       SCL_HI;
+       DELAY;
+       if ( SDA )
+           byte |= i;
+       SCL_LO;
+   }
+
+   return byte;
+}
+
+int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count)
+{
+    int i,x=0;
+
+    fmradio_i2c_start();
+    fmradio_i2c_outb(address & 0xfe);
+    if (fmradio_i2c_getack())
+    {
+        for (i=0; i<count; i++)
+        {
+            fmradio_i2c_outb(buf[i]);
+            if (!fmradio_i2c_getack())
+            {
+                x=-2;
+                break;
+            }
+        }
+    }
+    else
+    {
+        logf("fmradio_i2c_write() - no ack\n");
+        x=-1;
+    }
+    fmradio_i2c_stop();
+    return x;
+}
+
+int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
+{
+    int i,x=0;
+    
+    fmradio_i2c_start();
+    fmradio_i2c_outb(address | 1);
+
+    if (fmradio_i2c_getack())
+    {
+        for (i=count; i>0; i--)
+        {
+            *buf++ = fmradio_i2c_inb();
+            fmradio_i2c_ack(i == 1);
+        }
+    }
+    else
+        x=-1;
+    fmradio_i2c_stop();
+    return x;
+}
diff --git a/firmware/target/arm/portalplayer/iriver/h10/lcd-as-h10.S b/firmware/target/arm/portalplayer/iriver/h10/lcd-as-h10.S
new file mode 100644
index 0000000..8e851d8
--- /dev/null
+++ b/firmware/target/arm/portalplayer/iriver/h10/lcd-as-h10.S
@@ -0,0 +1,538 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2007-2008 by Michael Sevakis
+ *
+ * H10 20GB LCD assembly routines
+ *
+ * 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"
+
+/****************************************************************************
+ * void lcd_write_yuv_420_lines(unsigned char const * const src[3],
+ *                              int width,
+ *                              int stride);
+ *
+ *   |R|   |1.000000 -0.000001  1.402000| |Y'|
+ *   |G| = |1.000000 -0.334136 -0.714136| |Pb|
+ *   |B|   |1.000000  1.772000  0.000000| |Pr|
+ *   Scaled, normalized, rounded and tweaked to yield RGB 565:
+ *   |R|   |74   0 101| |Y' -  16| >> 9
+ *   |G| = |74 -24 -51| |Cb - 128| >> 8
+ *   |B|   |74 128   0| |Cr - 128| >> 9
+ *
+ * Write four RGB565 pixels in the following order on each loop:
+ * 1 3 + > down
+ * 2 4 \/ left
+ */
+    .section    .icode, "ax", %progbits
+    .align      2
+    .global     lcd_write_yuv420_lines
+    .type       lcd_write_yuv420_lines, %function
+lcd_write_yuv420_lines:
+                                        @ r0 = yuv_src
+                                        @ r1 = width
+                                        @ r2 = stride
+    stmfd       sp!, { r4-r11, lr }     @ save non-scratch
+    ldmia       r0, { r4, r5, r6 }      @ r4 = yuv_src[0] = Y'_p
+                                        @ r5 = yuv_src[1] = Cb_p
+                                        @ r6 = yuv_src[2] = Cr_p
+                                        @
+    mov         r0, #0x7000000c         @ r0 = &LCD2_PORT = 0x70008a0c
+    add         r0, r0, #0x8a00         @
+    mov         r14, #LCD2_DATA_MASK    @
+                                        @
+    sub         r2, r2, #1              @ Adjust stride because of increment
+10: @ loop line                         @
+    ldrb        r7, [r4], #1            @ r7 = *Y'_p++;
+    ldrb        r8, [r5], #1            @ r8 = *Cb_p++;
+    ldrb        r9, [r6], #1            @ r9 = *Cr_p++;
+                                        @
+    sub         r7, r7, #16             @ r7 = Y = (Y' - 16)*74
+    add         r12, r7, r7, asl #2     @ actually (Y' - 16)*37 and shift right
+    add         r7, r12, r7, asl #5     @ by one less when adding - same for all
+                                        @
+    sub         r8, r8, #128            @ Cb -= 128
+    sub         r9, r9, #128            @ Cr -= 128
+                                        @
+    add         r10, r9, r9, asl #1     @ r10 = Cr*51 + Cb*24
+    add         r10, r10, r10, asl #4   @
+    add         r10, r10, r8, asl #3    @
+    add         r10, r10, r8, asl #4    @
+                                        @
+    add         r11, r9, r9, asl #2     @ r9 = Cr*101
+    add         r11, r11, r9, asl #5    @
+    add         r9, r11, r9, asl #6     @
+                                        @
+    add         r8, r8, #2              @ r8 = bu = (Cb*128 + 128) >> 8
+    mov         r8, r8, asr #2          @
+    add         r9, r9, #256            @ r9 = rv = (r8 + 256) >> 9
+    mov         r9, r9, asr #9          @
+    rsb         r10, r10, #128          @ r10 = guv = (-r9 + 128) >> 8
+    mov         r10, r10, asr #8        @
+                                        @ compute R, G, and B
+    add         r3, r8, r7, asr #8      @ r3 = b = (Y >> 9) + bu
+    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
+    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
+                                        @
+    orr         r12, r3, r11            @ check if clamping is needed...
+    orr         r12, r12, r7, asr #1    @ ...at all
+    cmp         r12, #31                @
+    bls         15f @ no clamp          @
+    cmp         r3, #31                 @ clamp b
+    mvnhi       r3, r3, asr #31         @
+    andhi       r3, r3, #31             @
+    cmp         r11, #31                @ clamp r
+    mvnhi       r11, r11, asr #31       @
+    andhi       r11, r11, #31           @
+    cmp         r7, #63                 @ clamp g
+    mvnhi       r7, r7, asr #31         @
+    andhi       r7, r7, #63             @
+15: @ no clamp                          @
+                                        @
+    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
+                                        @
+    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
+    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
+                                        @
+    orr         r7, r14, r3, lsr #8     @ store pixel
+    orr         r11, r14, r3            @
+20:                                     @
+    ldr         r3, [r0]                @
+    tst         r3, #LCD2_BUSY_MASK     @
+    bne         20b                     @
+    str         r7, [r0]                @
+    str         r11, [r0]               @
+                                        @
+    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
+    add         r12, r7, r7, asl #2     @
+    add         r7, r12, r7, asl #5     @
+                                        @ compute R, G, and B
+    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
+    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
+    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
+                                        @
+    orr         r12, r3, r11            @ check if clamping is needed...
+    orr         r12, r12, r7, asr #1    @ ...at all
+    cmp         r12, #31                @
+    bls         15f @ no clamp          @
+    cmp         r3, #31                 @ clamp b
+    mvnhi       r3, r3, asr #31         @
+    andhi       r3, r3, #31             @
+    cmp         r11, #31                @ clamp r
+    mvnhi       r11, r11, asr #31       @
+    andhi       r11, r11, #31           @
+    cmp         r7, #63                 @ clamp g
+    mvnhi       r7, r7, asr #31         @
+    andhi       r7, r7, #63             @
+15: @ no clamp                          @
+                                        @
+    ldrb        r12, [r4], #1           @ r12 = Y' = *(Y'_p++)
+                                        @
+    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
+    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
+                                        @
+    orr         r7, r14, r3, lsr #8     @ store pixel
+    orr         r11, r14, r3            @
+20:                                     @
+    ldr         r3, [r0]                @
+    tst         r3, #LCD2_BUSY_MASK     @
+    bne         20b                     @
+    str         r7, [r0]                @
+    str         r11, [r0]               @
+                                        @
+    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
+    add         r12, r7, r7, asl #2     @
+    add         r7, r12, r7, asl #5     @
+                                        @ compute R, G, and B
+    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
+    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
+    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
+                                        @
+    orr         r12, r3, r11            @ check if clamping is needed...
+    orr         r12, r12, r7, asr #1    @ ...at all
+    cmp         r12, #31                @
+    bls         15f @ no clamp          @
+    cmp         r3, #31                 @ clamp b
+    mvnhi       r3, r3, asr #31         @
+    andhi       r3, r3, #31             @
+    cmp         r11, #31                @ clamp r
+    mvnhi       r11, r11, asr #31       @
+    andhi       r11, r11, #31           @
+    cmp         r7, #63                 @ clamp g
+    mvnhi       r7, r7, asr #31         @
+    andhi       r7, r7, #63             @
+15: @ no clamp                          @
+                                        @
+    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
+                                        @
+    orr         r3, r3, r7, lsl #5      @ r3 = b | (g << 5)
+    orr         r3, r3, r11, lsl #11    @ r3 |= (r << 11)
+                                        @
+    orr         r7, r14, r3, lsr #8     @ store pixel
+    orr         r11, r14, r3            @
+20:                                     @
+    ldr         r3, [r0]                @
+    tst         r3, #LCD2_BUSY_MASK     @
+    bne         20b                     @
+    str         r7, [r0]                @
+    str         r11, [r0]               @
+                                        @
+    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*74
+    add         r12, r7, r7, asl #2     @
+    add         r7, r12, r7, asl #5     @
+                                        @ compute R, G, and B
+    add         r3, r8, r7, asr #8      @ r3  = b = (Y >> 9) + bu
+    add         r11, r9, r7, asr #8     @ r11 = r = (Y >> 9) + rv
+    add         r7, r10, r7, asr #7     @ r7  = g = (Y >> 8) + guv
+                                        @
+    orr         r12, r3, r11            @ check if clamping is needed...
+    orr         r12, r12, r7, asr #1    @ ...at all
+    cmp         r12, #31                @
+    bls         15f @ no clamp          @
+    cmp         r3, #31                 @ clamp b
+    mvnhi       r3, r3, asr #31         @
+    andhi       r3, r3, #31             @
+    cmp         r11, #31                @ clamp r
+    mvnhi       r11, r11, asr #31       @
+    andhi       r11, r11, #31           @
+    cmp         r7, #63                 @ clamp g
+    mvnhi       r7, r7, asr #31         @
+    andhi       r7, r7, #63             @
+15: @ no clamp                          @
+                                        @
+    orr         r3, r3, r11, lsl #11    @ r3 = b | (r << 11)
+    orr         r3, r3, r7, lsl #5      @ r3 |= (g << 5)
+                                        @
+    orr         r7, r14, r3, lsr #8     @ store pixel
+    orr         r11, r14, r3            @
+20:                                     @
+    ldr         r3, [r0]                @
+    tst         r3, #LCD2_BUSY_MASK     @
+    bne         20b                     @
+    str         r7, [r0]                @
+    str         r11, [r0]               @
+                                        @
+    subs        r1, r1, #2              @ subtract block from width
+    bgt         10b @ loop line         @
+                                        @
+    ldmpc       regs=r4-r11             @ restore registers and return
+    .ltorg                              @ dump constant pool
+    .size   lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
+
+
+/****************************************************************************
+ * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
+ *                                      int width,
+ *                                      int stride,
+ *                                      int x_screen,
+ *                                      int y_screen);
+ *
+ *   |R|   |1.000000 -0.000001  1.402000| |Y'|
+ *   |G| = |1.000000 -0.334136 -0.714136| |Pb|
+ *   |B|   |1.000000  1.772000  0.000000| |Pr|
+ *   Red scaled at twice g & b but at same precision to place it in correct
+ *   bit position after multiply and leave instruction count lower.
+ *   |R|   |258   0  408| |Y' -  16|
+ *   |G| = |149 -49 -104| |Cb - 128|
+ *   |B|   |149 258    0| |Cr - 128|
+ *
+ * Write four RGB565 pixels in the following order on each loop:
+ * 1 3 + > down
+ * 2 4 \/ left
+ *
+ * Kernel pattern (raw|use order):
+ * 5 3 4 2     row0    row2         > down
+ * 1 7 0 6 | 5 1 3 7 4 0 2 6 col0     left
+ * 4 2 5 3 | 4 0 2 6 5 1 3 7 col2  \/
+ * 0 6 1 7
+ */
+    .section    .icode, "ax", %progbits
+    .align      2
+    .global     lcd_write_yuv420_lines_odither
+    .type       lcd_write_yuv420_lines_odither, %function
+lcd_write_yuv420_lines_odither:
+                                        @ r0   = yuv_src
+                                        @ r1   = width
+                                        @ r2   = stride
+                                        @ r3   = x_screen
+                                        @ [sp] = y_screen
+    stmfd       sp!, { r4-r11, lr }     @ save non-scratch
+    ldmia       r0, { r4, r5, r6 }      @ r4 = yuv_src[0] = Y'_p
+                                        @ r5 = yuv_src[1] = Cb_p
+                                        @ r6 = yuv_src[2] = Cr_p
+                                        @
+    ldr         r0, [sp, #36]           @ Line up pattern and kernel quadrant
+    eor         r14, r3, r0             @
+    and         r14, r14, #0x2          @
+    mov         r14, r14, lsl #6        @ 0x00 or 0x80
+                                        @
+    mov         r0, #0x7000000c         @ r0 = &LCD2_PORT = 0x70008a0c
+    add         r0, r0, #0x8a00         @
+                                        @
+    sub         r2, r2, #1              @ Adjust stride because of increment
+10: @ loop line                         @
+                                        @
+    ldrb        r7, [r4], #1            @ r7 = *Y'_p++;
+    ldrb        r8, [r5], #1            @ r8 = *Cb_p++;
+    ldrb        r9, [r6], #1            @ r9 = *Cr_p++;
+                                        @
+    eor         r14, r14, #0x80         @ flip pattern quadrant
+                                        @
+    sub         r7, r7, #16             @ r7 = Y = (Y' - 16)*149
+    add         r12, r7, r7, asl #2     @
+    add         r12, r12, r12, asl #4   @
+    add         r7, r12, r7, asl #6     @
+                                        @    
+    sub         r8, r8, #128            @ Cb -= 128
+    sub         r9, r9, #128            @ Cr -= 128
+                                        @
+    add         r10, r8, r8, asl #4     @ r10 = guv = Cr*104 + Cb*49
+    add         r10, r10, r8, asl #5    @
+    add         r10, r10, r9, asl #3    @
+    add         r10, r10, r9, asl #5    @
+    add         r10, r10, r9, asl #6    @
+                                        @
+    mov         r8, r8, asl #1          @ r8 = bu = Cb*258
+    add         r8, r8, r8, asl #7      @
+                                        @
+    add         r9, r9, r9, asl #1      @ r9 = rv = Cr*408
+    add         r9, r9, r9, asl #4      @
+    mov         r9, r9, asl #3          @
+                                        @
+                                        @ compute R, G, and B
+    add         r3, r8, r7              @ r3  = b' = Y + bu
+    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
+    rsb         r7, r10, r7             @ r7  = g' = Y + guv
+                                        @
+                                        @ r8 = bu, r9 = rv, r10 = guv
+                                        @
+    sub         r12, r3, r3, lsr #5     @ r3 = 31/32*b + b/256
+    add         r3, r12, r3, lsr #8     @
+                                        @
+    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r + r/256
+    add         r11, r12, r11, lsr #8   @
+                                        @
+    sub         r12, r7, r7, lsr #6     @ r7 = 63/64*g + g/256
+    add         r7, r12, r7, lsr #8     @
+                                        @
+    add         r12, r14, #0x200        @
+                                        @
+    add         r3, r3, r12             @ b = r3 + delta
+    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
+    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
+                                        @
+    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
+    orr         r12, r12, r7            @ ...at all
+    movs        r12, r12, asr #15       @
+    beq         15f @ no clamp          @
+    movs        r12, r3, asr #15        @ clamp b
+    mvnne       r3, r12, lsr #15        @
+    andne       r3, r3, #0x7c00         @ mask b only if clamped
+    movs        r12, r11, asr #16       @ clamp r
+    mvnne       r11, r12, lsr #16       @
+    movs        r12, r7, asr #15        @ clamp g
+    mvnne       r7, r12, lsr #15        @
+15: @ no clamp                          @
+                                        @
+    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)
+                                        @
+    and         r11, r11, #0xf800       @ pack pixel
+    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
+    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
+    orr         r3, r11, r3, lsr #10    @              (b >> 10)
+                                        @
+    mov         r11, #LCD2_DATA_MASK    @ store pixel
+    orr         r7, r11, r3, lsr #8     @
+    orr         r11, r11, r3            @
+20:                                     @
+    ldr         r3, [r0]                @
+    tst         r3, #LCD2_BUSY_MASK     @
+    bne         20b                     @
+    str         r7, [r0]                @
+    str         r11, [r0]               @
+                                        @
+    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
+    add         r12, r7, r7, asl #2     @
+    add         r12, r12, r12, asl #4   @
+    add         r7, r12, r7, asl #6     @
+                                        @ compute R, G, and B
+    add         r3, r8, r7              @ r3  = b' = Y + bu
+    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
+    rsb         r7, r10, r7             @ r7  = g' = Y + guv
+                                        @
+    sub         r12, r3, r3, lsr #5     @ r3  = 31/32*b' + b'/256
+    add         r3, r12, r3, lsr #8     @
+                                        @
+    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r' + r'/256
+    add         r11, r12, r11, lsr #8   @
+                                        @
+    sub         r12, r7, r7, lsr #6     @ r7  = 63/64*g' + g'/256
+    add         r7, r12, r7, lsr #8     @
+                                        @
+    @ This element is zero - use r14    @
+                                        @
+    add         r3, r3, r14             @ b = r3 + delta
+    add         r11, r11, r14, lsl #1   @ r = r11 + delta*2
+    add         r7, r7, r14, lsr #1     @ g = r7 + delta/2
+                                        @
+    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
+    orr         r12, r12, r7            @ ...at all
+    movs        r12, r12, asr #15       @
+    beq         15f @ no clamp          @
+    movs        r12, r3, asr #15        @ clamp b
+    mvnne       r3, r12, lsr #15        @
+    andne       r3, r3, #0x7c00         @ mask b only if clamped
+    movs        r12, r11, asr #16       @ clamp r
+    mvnne       r11, r12, lsr #16       @
+    movs        r12, r7, asr #15        @ clamp g
+    mvnne       r7, r12, lsr #15        @
+15: @ no clamp                          @
+                                        @
+    ldrb        r12, [r4], #1           @ r12 = Y' = *(Y'_p++)
+                                        @
+    and         r11, r11, #0xf800       @ pack pixel
+    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
+    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
+    orr         r3, r11, r3, lsr #10    @              (b >> 10)
+                                        @
+    mov         r11, #LCD2_DATA_MASK    @ store pixel
+    orr         r7, r11, r3, lsr #8     @
+    orr         r11, r11, r3            @
+20:                                     @
+    ldr         r3, [r0]                @
+    tst         r3, #LCD2_BUSY_MASK     @
+    bne         20b                     @
+    str         r7, [r0]                @
+    str         r11, [r0]               @
+                                        @
+    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
+    add         r12, r7, r7, asl #2     @
+    add         r12, r12, r12, asl #4   @
+    add         r7, r12, r7, asl #6     @
+                                        @ compute R, G, and B
+    add         r3, r8, r7              @ r3  = b' = Y + bu
+    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
+    rsb         r7, r10, r7             @ r7  = g' = Y + guv
+                                        @
+                                        @ r8 = bu, r9 = rv, r10 = guv
+                                        @
+    sub         r12, r3, r3, lsr #5     @ r3  = 31/32*b' + b'/256
+    add         r3, r12, r3, lsr #8     @
+                                        @
+    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r' + r'/256
+    add         r11, r12, r11, lsr #8   @
+                                        @
+    sub         r12, r7, r7, lsr #6     @ r7  = 63/64*g' + g'/256
+    add         r7, r12, r7, lsr #8     @
+                                        @
+    add         r12, r14, #0x100        @
+                                        @
+    add         r3, r3, r12             @ b = r3 + delta
+    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
+    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
+                                        @
+    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
+    orr         r12, r12, r7            @ ...at all
+    movs        r12, r12, asr #15       @
+    beq         15f @ no clamp          @
+    movs        r12, r3, asr #15        @ clamp b
+    mvnne       r3, r12, lsr #15        @
+    andne       r3, r3, #0x7c00         @ mask b only if clamped
+    movs        r12, r11, asr #16       @ clamp r
+    mvnne       r11, r12, lsr #16       @
+    movs        r12, r7, asr #15        @ clamp g
+    mvnne       r7, r12, lsr #15        @
+15: @ no clamp                          @
+                                        @
+    ldrb        r12, [r4, r2]           @ r12 = Y' = *(Y'_p + stride)    
+                                        @
+    and         r11, r11, #0xf800       @ pack pixel
+    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
+    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
+    orr         r3, r11, r3, lsr #10    @              (b >> 10)
+                                        @
+    mov         r11, #LCD2_DATA_MASK    @ store pixel
+    orr         r7, r11, r3, lsr #8     @
+    orr         r11, r11, r3            @
+20:                                     @
+    ldr         r3, [r0]                @
+    tst         r3, #LCD2_BUSY_MASK     @
+    bne         20b                     @
+    str         r7, [r0]                @
+    str         r11, [r0]               @
+                                        @
+    sub         r7, r12, #16            @ r7 = Y = (Y' - 16)*149
+    add         r12, r7, r7, asl #2     @
+    add         r12, r12, r12, asl #4   @
+    add         r7, r12, r7, asl #6     @
+                                        @ compute R, G, and B
+    add         r3, r8, r7              @ r3  = b' = Y + bu
+    add         r11, r9, r7, asl #1     @ r11 = r' = Y*2 + rv
+    rsb         r7, r10, r7             @ r7  = g' = Y + guv
+                                        @
+    sub         r12, r3, r3, lsr #5     @ r3 = 31/32*b + b/256
+    add         r3, r12, r3, lsr #8     @
+                                        @
+    sub         r12, r11, r11, lsr #5   @ r11 = 31/32*r + r/256
+    add         r11, r12, r11, lsr #8   @
+                                        @
+    sub         r12, r7, r7, lsr #6     @ r7 = 63/64*g + g/256
+    add         r7, r12, r7, lsr #8     @
+                                        @
+    add         r12, r14, #0x300        @
+                                        @
+    add         r3, r3, r12             @ b = r3 + delta
+    add         r11, r11, r12, lsl #1   @ r = r11 + delta*2
+    add         r7, r7, r12, lsr #1     @ g = r7 + delta/2
+                                        @
+    orr         r12, r3, r11, asr #1    @ check if clamping is needed...
+    orr         r12, r12, r7            @ ...at all
+    movs        r12, r12, asr #15       @
+    beq         15f @ no clamp          @
+    movs        r12, r3, asr #15        @ clamp b
+    mvnne       r3, r12, lsr #15        @
+    andne       r3, r3, #0x7c00         @ mask b only if clamped
+    movs        r12, r11, asr #16       @ clamp r
+    mvnne       r11, r12, lsr #16       @
+    movs        r12, r7, asr #15        @ clamp g
+    mvnne       r7, r12, lsr #15        @
+15: @ no clamp                          @
+                                        @
+    and         r11, r11, #0xf800       @ pack pixel
+    and         r7, r7, #0x7e00         @ r3 = pixel = (r & 0xf800) |
+    orr         r11, r11, r7, lsr #4    @              ((g & 0x7e00) >> 4) |
+    orr         r3, r11, r3, lsr #10    @              (b >> 10)
+                                        @
+    mov         r11, #LCD2_DATA_MASK    @ store pixel
+    orr         r7, r11, r3, lsr #8     @
+    orr         r11, r11, r3            @
+20:                                     @
+    ldr         r3, [r0]                @
+    tst         r3, #LCD2_BUSY_MASK     @
+    bne         20b                     @
+    str         r7, [r0]                @
+    str         r11, [r0]               @
+                                        @
+    subs        r1, r1, #2              @ subtract block from width
+    bgt         10b @ loop line         @
+                                        @
+    ldmpc       regs=r4-r11             @ restore registers and return
+    .ltorg                              @ dump constant pool
+    .size   lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
diff --git a/firmware/target/arm/portalplayer/iriver/h10/lcd-h10_20gb.c b/firmware/target/arm/portalplayer/iriver/h10/lcd-h10_20gb.c
new file mode 100644
index 0000000..596276a
--- /dev/null
+++ b/firmware/target/arm/portalplayer/iriver/h10/lcd-h10_20gb.c
@@ -0,0 +1,551 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Barry Wardell
+ *
+ * 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 "lcd.h"
+#include "kernel.h"
+#include "system.h"
+
+/** Initialized in lcd_init_device() **/
+/* Is the power turned on? */
+static bool power_on;
+/* Is the display turned on? */
+static bool display_on;
+/* Amount of vertical offset. Used for flip offset correction/detection. */
+static int y_offset;
+/* Reverse flag. Must be remembered when display is turned off. */
+static unsigned short disp_control_rev;
+/* Contrast setting << 8 */
+static int lcd_contrast;
+
+static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
+
+/* Forward declarations */
+#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
+static void lcd_display_off(void);
+#endif
+
+/* register defines for the Renesas HD66773R */
+#define R_START_OSC             0x00
+#define R_DEVICE_CODE_READ      0x00
+#define R_DRV_OUTPUT_CONTROL    0x01
+#define R_DRV_AC_CONTROL        0x02
+#define R_POWER_CONTROL1        0x03
+#define R_POWER_CONTROL2        0x04
+#define R_ENTRY_MODE            0x05
+#define R_COMPARE_REG           0x06
+#define R_DISP_CONTROL          0x07
+#define R_FRAME_CYCLE_CONTROL   0x0b
+#define R_POWER_CONTROL3        0x0c
+#define R_POWER_CONTROL4        0x0d
+#define R_POWER_CONTROL5        0x0e
+#define R_GATE_SCAN_START_POS   0x0f
+#define R_VERT_SCROLL_CONTROL   0x11
+#define R_1ST_SCR_DRV_POS       0x14
+#define R_2ND_SCR_DRV_POS       0x15
+#define R_HORIZ_RAM_ADDR_POS    0x16
+#define R_VERT_RAM_ADDR_POS     0x17
+#define R_RAM_WRITE_DATA_MASK   0x20
+#define R_RAM_ADDR_SET          0x21
+#define R_WRITE_DATA_2_GRAM     0x22
+#define R_RAM_READ_DATA         0x22
+#define R_GAMMA_FINE_ADJ_POS1   0x30
+#define R_GAMMA_FINE_ADJ_POS2   0x31
+#define R_GAMMA_FINE_ADJ_POS3   0x32
+#define R_GAMMA_GRAD_ADJ_POS    0x33
+#define R_GAMMA_FINE_ADJ_NEG1   0x34
+#define R_GAMMA_FINE_ADJ_NEG2   0x35
+#define R_GAMMA_FINE_ADJ_NEG3   0x36
+#define R_GAMMA_GRAD_ADJ_NEG    0x37
+#define R_GAMMA_AMP_ADJ_POS     0x3a
+#define R_GAMMA_AMP_ADJ_NEG     0x3b
+
+static inline void lcd_wait_write(void)
+{
+    while (LCD2_PORT & LCD2_BUSY_MASK);
+}
+
+/* Send command */
+static inline void lcd_send_cmd(unsigned v)
+{
+    lcd_wait_write();
+    LCD2_PORT = LCD2_CMD_MASK;
+    LCD2_PORT = LCD2_CMD_MASK | v;
+}
+
+/* Send 16-bit data */
+static inline void lcd_send_data(unsigned v)
+{
+    lcd_wait_write();
+    LCD2_PORT = LCD2_DATA_MASK | (v >> 8);    /* Send MSB first */
+    LCD2_PORT = LCD2_DATA_MASK | (v & 0xff);
+}
+
+/* Send 16-bit data byte-swapped. Only needed until we can use block transfer. */
+static inline void lcd_send_data_swapped(unsigned v)
+{
+    lcd_wait_write();
+    LCD2_PORT = LCD2_DATA_MASK | (v & 0xff);  /* Send LSB first */
+    LCD2_PORT = LCD2_DATA_MASK | (v >> 8);    
+}
+
+/* Write value to register */
+static void lcd_write_reg(int reg, int val)
+{
+    lcd_send_cmd(reg);
+    lcd_send_data(val);
+}
+
+/*** hardware configuration ***/
+
+int lcd_default_contrast(void)
+{
+    return DEFAULT_CONTRAST_SETTING;
+}
+
+void lcd_set_contrast(int val)
+{
+    /* Clamp val in range 0-14, 16-30 */
+    if (val < 1)
+        val = 0;
+    else if (val <= 15)
+        --val;
+    else if