summaryrefslogtreecommitdiffstats
path: root/firmware/target/coldfire
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2010-04-26 21:40:16 +0000
committerMarcin Bukat <marcin.bukat@gmail.com>2010-04-26 21:40:16 +0000
commit28d54c6016459ffe93c0be2efea7de27c38d783c (patch)
tree9a7a71481f0a82599616a3e9f4e5bdad9fee8d6c /firmware/target/coldfire
parentb09d3aec392538ca0934644ff6357c41aaa4c323 (diff)
downloadrockbox-28d54c6016459ffe93c0be2efea7de27c38d783c.tar.gz
rockbox-28d54c6016459ffe93c0be2efea7de27c38d783c.zip
Add MPIO HD200 port - new files
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25725 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/coldfire')
-rw-r--r--firmware/target/coldfire/mpio/app.lds145
-rw-r--r--firmware/target/coldfire/mpio/ata-as-mpio.S757
-rw-r--r--firmware/target/coldfire/mpio/ata-mpio.c57
-rw-r--r--firmware/target/coldfire/mpio/ata-target.h77
-rw-r--r--firmware/target/coldfire/mpio/audio-mpio.c49
-rw-r--r--firmware/target/coldfire/mpio/boot.lds81
-rw-r--r--firmware/target/coldfire/mpio/boot.lds.flash81
-rw-r--r--firmware/target/coldfire/mpio/boot.lds.iram81
-rw-r--r--firmware/target/coldfire/mpio/button-target.h55
-rw-r--r--firmware/target/coldfire/mpio/fmradio_i2c-mpio.c40
-rw-r--r--firmware/target/coldfire/mpio/hd200/adc-hd200.c84
-rw-r--r--firmware/target/coldfire/mpio/hd200/adc-target.h41
-rw-r--r--firmware/target/coldfire/mpio/hd200/backlight-hd200.c86
-rw-r--r--firmware/target/coldfire/mpio/hd200/backlight-target.h35
-rw-r--r--firmware/target/coldfire/mpio/hd200/button-hd200.c123
-rw-r--r--firmware/target/coldfire/mpio/hd200/lcd-as-hd200.S103
-rw-r--r--firmware/target/coldfire/mpio/hd200/lcd-hd200.c241
-rw-r--r--firmware/target/coldfire/mpio/hd200/power-hd200.c113
-rw-r--r--firmware/target/coldfire/mpio/hd200/powermgmt-hd200.c59
-rw-r--r--firmware/target/coldfire/mpio/hd200/system-hd200.c125
-rw-r--r--firmware/target/coldfire/mpio/hd200/usb-hd200.c81
-rw-r--r--firmware/target/coldfire/wmcodec-coldfire.c52
22 files changed, 2566 insertions, 0 deletions
diff --git a/firmware/target/coldfire/mpio/app.lds b/firmware/target/coldfire/mpio/app.lds
new file mode 100644
index 0000000000..d087f997c8
--- /dev/null
+++ b/firmware/target/coldfire/mpio/app.lds
@@ -0,0 +1,145 @@
+#include "config.h"
+
+ENTRY(start)
+
+OUTPUT_FORMAT(elf32-m68k)
+STARTUP(target/coldfire/crt0.o)
+
+#define PLUGINSIZE PLUGIN_BUFFER_SIZE
+#define CODECSIZE CODEC_SIZE
+
+#ifdef DEBUG
+#define STUBOFFSET 0x10000
+#else
+#define STUBOFFSET 0
+#endif
+
+#define DRAMSIZE (MEMORYSIZE * 0x100000) - PLUGINSIZE - STUBOFFSET - CODECSIZE
+
+#define DRAMORIG 0x31000000 + STUBOFFSET
+#define IRAMORIG 0x10000000
+#define IRAMSIZE 0xc000
+
+/* 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
+{
+ .vectors :
+ {
+ loadaddress = .;
+ _loadaddress = .;
+ KEEP(*(.resetvectors));
+ *(.resetvectors);
+ KEEP(*(.vectors));
+ *(.vectors);
+ } > DRAM
+
+ .text :
+ {
+ . = ALIGN(0x200);
+ *(.init.text)
+ *(.text*)
+ . = 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
+
+ /DISCARD/ :
+ {
+ *(.eh_frame)
+ }
+
+ .iram IRAMORIG :
+ {
+ _iramstart = .;
+ *(.icode)
+ *(.irodata)
+ *(.idata)
+ _iramend = .;
+ } > IRAM AT> DRAM
+
+ _iramcopy = LOADADDR(.iram);
+ _noloaddram = LOADADDR(.iram);
+
+ .ibss (NOLOAD) :
+ {
+ _iedata = .;
+ *(.ibss)
+ . = ALIGN(0x4);
+ _iend = .;
+ } > IRAM
+
+ .stack (NOLOAD) :
+ {
+ *(.stack)
+ stackbegin = .;
+ . += 0x2000;
+ stackend = .;
+ } > IRAM
+
+ .bss _noloaddram (NOLOAD) :
+ {
+ _edata = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(0x4);
+ _end = .;
+ } > DRAM
+
+ .audiobuf (NOLOAD) :
+ {
+ . = ALIGN(4);
+ _audiobuffer = .;
+ audiobuffer = .;
+ } > DRAM
+
+ .audiobufend ENDAUDIOADDR (NOLOAD) :
+ {
+ audiobufend = .;
+ _audiobufend = .;
+ } > DRAM
+
+ .codec ENDAUDIOADDR (NOLOAD) :
+ {
+ codecbuf = .;
+ _codecbuf = .;
+ }
+
+ .plugin ENDADDR (NOLOAD) :
+ {
+ _pluginbuf = .;
+ pluginbuf = .;
+ }
+}
+
diff --git a/firmware/target/coldfire/mpio/ata-as-mpio.S b/firmware/target/coldfire/mpio/ata-as-mpio.S
new file mode 100644
index 0000000000..4a6bd3e613
--- /dev/null
+++ b/firmware/target/coldfire/mpio/ata-as-mpio.S
@@ -0,0 +1,757 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: ata-as-coldfire.S 17847 2008-06-28 18:10:04Z bagder $
+ *
+ * Copyright (C) 2006 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.
+ *
+ ****************************************************************************/
+
+ .section .icode,"ax",@progbits
+
+ .equ .ata_port, 0x20000020
+ .equ .swapmask, 0x00FF00FF
+ .align 2
+ .global copy_read_sectors
+ .type copy_read_sectors,@function
+
+/* Read a number of words from the ATA data port
+ *
+ * Utilises line bursts, assumes there is at least one full line to copy.
+ *
+ * Arguments:
+ * (4,%sp) - buffer address
+ * (8,%sp) - word count
+ *
+ * Register usage:
+ * %a0 - current address
+ * %a1 - end address
+ * %a2 - ata port
+ * %d0 - scratch
+ * %d1 - shift count
+ * %d2-%d6 - read buffers
+ *
+ * %d7 - byte swap scrach register
+ * %a3 - byte swap mask
+ */
+
+copy_read_sectors:
+ lea.l (-32, %sp), %sp
+ movem.l %d2-%d7/%a2-%a3, (%sp)
+ movem.l (36, %sp), %a0-%a1
+ add.l %a1, %a1
+ add.l %a0, %a1
+ lea.l .ata_port, %a2
+ lea.l .swapmask, %a3
+
+ move.l %a0, %d0
+ btst.l #0, %d0 /* 16-bit aligned? */
+ jeq .r_aligned /* yes, do word copy */
+
+ /* not 16-bit aligned */
+ subq.l #1, %a1 /* last byte is done unconditionally */
+ moveq.l #24, %d1 /* preload shift count */
+
+ move.w (%a2), %d2 /* load initial word */
+ move.b %d2, (%a0)+ /* write high byte of it, aligns dest addr */
+ /* we have byte swapped */
+
+ btst.l #1, %d0 /* longword aligned? (testing old d0 value!) */
+ bne.b .r_end_u_w1 /* yes, skip leading word handling */
+
+ swap %d2 /* move initial word up */
+ move.w (%a2), %d2 /* combine with second word */
+
+ /* byte swap d2 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d2, %d7 /* d7 = .B.D */
+ eor.l %d7, %d2 /* d2 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d2 /* d2 = .A.C */
+ or.l %d7, %d2 /* d2 = BADC */
+
+ move.l %d2, %d3
+ lsr.l #8, %d3
+ move.w %d3, (%a0)+ /* write bytes 2 and 3 as word */
+
+.r_end_u_w1:
+ moveq.l #12, %d0
+ add.l %a0, %d0
+ and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
+ cmp.l %a0, %d0 /* any leading longwords? */
+ bls.b .r_end_u_l1 /* no: skip loop */
+
+.r_loop_u_l1:
+ move.w (%a2), %d3 /* load first word */
+ swap %d3 /* move to upper 16 bit */
+ move.w (%a2), %d3 /* load second word */
+
+ /* byte swap d3 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d3, %d7 /* d7 = .B.D */
+ eor.l %d7, %d3 /* d3 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d3 /* d3 = .A.C */
+ or.l %d7, %d3 /* d3 = BADC */
+
+ move.l %d3, %d4
+ lsl.l %d1, %d2
+ lsr.l #8, %d3
+ or.l %d3, %d2 /* combine old low byte with new top 3 bytes */
+ move.l %d2, (%a0)+ /* store as long */
+ move.l %d4, %d2
+ cmp.l %a0, %d0 /* run up to first line bound */
+ bhi.b .r_loop_u_l1
+
+.r_end_u_l1:
+ lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
+
+.r_loop_u_line:
+ move.w (%a2), %d3 /* load 1st word */
+ swap %d3 /* move to upper 16 bit */
+ move.w (%a2), %d3 /* load 2nd word */
+
+ /* byte swap d3 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d3, %d7 /* d7 = .B.D */
+ eor.l %d7, %d3 /* d3 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d3 /* d3 = .A.C */
+ or.l %d7, %d3 /* d3 = BADC */
+
+ move.l %d3, %d0
+ lsl.l %d1, %d2
+ lsr.l #8, %d0
+ or.l %d0, %d2 /* combine old low byte with new top 3 bytes */
+ move.w (%a2), %d4 /* load 3rd word */
+ swap %d4 /* move to upper 16 bit */
+ move.w (%a2), %d4 /* load 4th word */
+
+ /* byte swap d4 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d4, %d7 /* d7 = .B.D */
+ eor.l %d7, %d4 /* d4 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d4 /* d4 = .A.C */
+ or.l %d7, %d4 /* d4 = BADC */
+
+ move.l %d4, %d0
+ lsl.l %d1, %d3
+ lsr.l #8, %d0
+ or.l %d0, %d3 /* combine old low byte with new top 3 bytes */
+ move.w (%a2), %d5 /* load 5th word */
+ swap %d5 /* move to upper 16 bit */
+ move.w (%a2), %d5 /* load 6th word */
+
+ /* byte swap d5 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d5, %d7 /* d7 = .B.D */
+ eor.l %d7, %d5 /* d5 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d5 /* d5 = .A.C */
+ or.l %d7, %d5 /* d5 = BADC */
+
+ move.l %d5, %d0
+ lsl.l %d1, %d4
+ lsr.l #8, %d0
+ or.l %d0, %d4 /* combine old low byte with new top 3 bytes */
+ move.w (%a2), %d6 /* load 7th word */
+ swap %d6 /* move to upper 16 bit */
+ move.w (%a2), %d6 /* load 8th word */
+
+ /* byte swap d6 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d6, %d7 /* d7 = .B.D */
+ eor.l %d7, %d6 /* d6 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d6 /* d6 = .A.C */
+ or.l %d7, %d6 /* d6 = BADC */
+
+ move.l %d6, %d0
+ lsl.l %d1, %d5
+ lsr.l #8, %d0
+ or.l %d0, %d5 /* combine old low byte with new top 3 bytes */
+ movem.l %d2-%d5, (%a0) /* store line */
+ lea.l (16, %a0), %a0
+ move.l %d6, %d2
+ cmp.l %a0, %a1 /* run up to last line bound */
+ bhi.b .r_loop_u_line
+
+ lea.l (12, %a1), %a1 /* readjust for longword loop */
+ cmp.l %a0, %a1 /* any trailing longwords? */
+ bls.b .r_end_u_l2 /* no: skip loop */
+
+.r_loop_u_l2:
+ move.w (%a2), %d3 /* load first word */
+ swap %d3 /* move to upper 16 bit */
+ move.w (%a2), %d3 /* load second word */
+
+ /* byte swap d3 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d3, %d7 /* d7 = .B.D */
+ eor.l %d7, %d3 /* d3 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d3 /* d3 = .A.C */
+ or.l %d7, %d3 /* d3 = BADC */
+
+ move.l %d3, %d4
+ lsl.l %d1, %d2
+ lsr.l #8, %d3
+ or.l %d3, %d2 /* combine old low byte with new top 3 bytes */
+ move.l %d2, (%a0)+ /* store as long */
+ move.l %d4, %d2
+ cmp.l %a0, %a1 /* run up to last long bound */
+ bhi.b .r_loop_u_l2
+
+.r_end_u_l2:
+ addq.l #2, %a1 /* back to final end address */
+ cmp.l %a0, %a1 /* one word left? */
+ bls.b .r_end_u_w2
+
+ swap %d2 /* move old word to upper 16 bits */
+ move.w (%a2), %d2 /* load final word */
+
+ /* byte swap d2 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d2, %d7 /* d7 = .B.D */
+ eor.l %d7, %d2 /* d2 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d2 /* d2 = .A.C */
+ or.l %d7, %d2 /* d2 = BADC */
+
+ move.l %d2, %d3
+ lsr.l #8, %d3
+ move.w %d3, (%a0)+ /* write bytes 2 and 3 as word */
+
+.r_end_u_w2:
+ move.b %d2, (%a0)+ /* store final byte */
+ bra.w .r_exit
+
+ /* 16-bit aligned */
+.r_aligned:
+ btst.l #1, %d0 /* longword aligned? */
+ beq.b .r_end_a_w1 /* yes, skip leading word handling */
+
+ /* copy initial word */
+ /* initial word has to be swapped */
+ move.w (%a2), %d7
+ move.b %d7, (%a0)+
+ lsr.l #8, %d7
+ move.b %d7, (%a0)+
+
+.r_end_a_w1:
+ moveq.l #12, %d0
+ add.l %a0, %d0
+ and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
+ cmp.l %a0, %d0 /* any leading longwords? */
+ bls.b .r_end_a_l1 /* no: skip loop */
+
+.r_loop_a_l1:
+ move.w (%a2), %d1 /* load first word */
+ swap %d1 /* move it to upper 16 bits */
+ move.w (%a2), %d1 /* load second word */
+
+ /* byte swap d1 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d1, %d7 /* d7 = .B.D */
+ eor.l %d7, %d1 /* d1 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d1 /* d1 = .A.C */
+ or.l %d7, %d1 /* d1 = BADC */
+
+ move.l %d1, (%a0)+ /* store as long */
+ cmp.l %a0, %d0 /* run up to first line bound */
+ bhi.b .r_loop_a_l1
+
+.r_end_a_l1:
+ lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
+
+.r_loop_a_line:
+ move.w (%a2), %d0 /* load 1st word */
+ swap %d0 /* move it to upper 16 bits */
+ move.w (%a2), %d0 /* load 2nd word */
+
+ /* byte swap d0 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d0, %d7 /* d7 = .B.D */
+ eor.l %d7, %d0 /* d0 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d0 /* d0 = .A.C */
+ or.l %d7, %d0 /* d0 = BADC */
+
+ move.w (%a2), %d1 /* load 3rd word */
+ swap %d1 /* move it to upper 16 bits */
+ move.w (%a2), %d1 /* load 4th word */
+
+ /* byte swap d1 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d1, %d7 /* d7 = .B.D */
+ eor.l %d7, %d1 /* d1 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d1 /* d1 = .A.C */
+ or.l %d7, %d1 /* d1 = BADC */
+
+ move.w (%a2), %d2 /* load 5th word */
+ swap %d2 /* move it to upper 16 bits */
+ move.w (%a2), %d2 /* load 6th word */
+
+ /* byte swap d2 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d2, %d7 /* d7 = .B.D */
+ eor.l %d7, %d2 /* d2 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d2 /* d2 = .A.C */
+ or.l %d7, %d2 /* d2 = BADC */
+
+ move.w (%a2), %d3 /* load 7th word */
+ swap %d3 /* move it to upper 16 bits */
+ move.w (%a2), %d3 /* load 8th word */
+
+ /* byte swap d3 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d3, %d7 /* d7 = .B.D */
+ eor.l %d7, %d3 /* d3 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d3 /* d3 = .A.C */
+ or.l %d7, %d3 /* d3 = BADC */
+
+ movem.l %d0-%d3, (%a0) /* store line */
+ lea.l (16, %a0), %a0
+ cmp.l %a0, %a1 /* run up to last line bound */
+ bhi.b .r_loop_a_line
+
+ lea.l (12, %a1), %a1 /* readjust for longword loop */
+ cmp.l %a0, %a1 /* any trailing longwords? */
+ bls.b .r_end_a_l2 /* no: skip loop */
+
+.r_loop_a_l2:
+ move.w (%a2), %d1 /* read first word */
+ swap %d1 /* move it to upper 16 bits */
+ move.w (%a2), %d1 /* read second word */
+
+ /* byte swap d1 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d1, %d7 /* d7 = .B.D */
+ eor.l %d7, %d1 /* d1 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d1 /* d1 = .A.C */
+ or.l %d7, %d1 /* d1 = BADC */
+
+ move.l %d1, (%a0)+ /* store as long */
+ cmp.l %a0, %a1 /* run up to last long bound */
+ bhi.b .r_loop_a_l2
+
+.r_end_a_l2:
+ addq.l #2, %a1 /* back to final end address */
+ cmp.l %a0, %a1 /* one word left? */
+ bls.b .r_end_a_w2
+
+ /* copy final word */
+ /* final word has to be swapped */
+ move.w (%a2), %d7
+ move.b %d7, (%a0)+
+ lsr.l #8, %d7
+ move.b %d7, (%a0)+
+
+.r_end_a_w2:
+
+.r_exit:
+ movem.l (%sp), %d2-%d7/%a2-%a3
+ lea.l (32, %sp), %sp
+ rts
+
+.r_end:
+ .size copy_read_sectors,.r_end-copy_read_sectors
+
+ .align 2
+ .global copy_write_sectors
+ .type copy_write_sectors,@function
+
+#if 0
+/* Write a number of words to the ATA data port
+ *
+ * Utilises line bursts, assumes there is at least one full line to copy.
+ *
+ * Arguments:
+ * (4,%sp) - buffer address
+ * (8,%sp) - word count
+ *
+ * Register usage:
+ * %a0 - current address
+ * %a1 - end address
+ * %a2 - ata port
+ * %d0 - scratch
+ * %d1 - shift count
+ * %d2-%d6 - read buffers
+ *
+ * %d7 - swap scrach
+ * %a3 - swap mask
+ */
+
+copy_write_sectors:
+ lea.l (-32, %sp), %sp
+ movem.l %d2-%d7/%a2-%a3, (%sp)
+ movem.l (36, %sp), %a0-%a1
+ add.l %a1, %a1
+ add.l %a0, %a1
+ lea.l .ata_port, %a2
+ lea.l .swapmask, %a3
+
+ move.l %a0, %d0
+ btst.l #0, %d0 /* 16-bit aligned? */
+ beq .w_aligned /* yes, do word copy */
+
+ /* not 16-bit aligned */
+ subq.l #1, %a1 /* last byte is done unconditionally */
+ moveq.l #24, %d1 /* preload shift count */
+
+ move.b (%a0)+, %d2
+
+ btst.l #1, %d0 /* longword aligned? (testing old d0 value!) */
+ bne.b .w_end_u_w1 /* yes, skip leading word handling */
+
+ swap %d2
+ move.w (%a0)+, %d2
+ move.l %d2, %d3
+ lsr.l #8, %d3
+
+ /* low word of %d3 has to be byte swaped */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d3, %d7 /* d7 = .B.D */
+ eor.l %d7, %d3 /* d3 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d3 /* d3 = .A.C */
+ or.l %d7, %d3 /* d3 = BADC */
+
+ move.w %d3, (%a2)
+
+.w_end_u_w1:
+ moveq.l #12, %d0
+ add.l %a0, %d0
+ and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
+ cmp.l %a0, %d0 /* any leading longwords? */
+ bls.b .w_end_u_l1 /* no: skip loop */
+
+.w_loop_u_l1:
+ move.l (%a0)+, %d3
+ move.l %d3, %d4
+ lsl.l %d1, %d2
+ lsr.l #8, %d3
+ or.l %d3, %d2
+
+ /* byte swap d2 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d2, %d7 /* d7 = .B.D */
+ eor.l %d7, %d2 /* d2 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d2 /* d2 = .A.C */
+ or.l %d7, %d2 /* d2 = BADC */
+
+ swap %d2
+ move.w %d2, (%a2)
+ swap %d2
+ move.w %d2, (%a2)
+ move.l %d4, %d2
+ cmp.l %a0, %d0 /* run up to first line bound */
+ bhi.b .w_loop_u_l1
+
+.w_end_u_l1:
+ lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
+
+.w_loop_u_line:
+ movem.l (%a0), %d3-%d6
+ lea.l (16, %a0), %a0
+ move.l %d3, %d0
+ lsl.l %d1, %d2
+ lsr.l #8, %d0
+ or.l %d0, %d2
+
+ /* byte swap d2 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d2, %d7 /* d7 = .B.D */
+ eor.l %d7, %d2 /* d2 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d2 /* d2 = .A.C */
+ or.l %d7, %d2 /* d2 = BADC */
+
+ swap %d2
+ move.w %d2, (%a2)
+ swap %d2
+ move.w %d2, (%a2)
+ move.l %d4, %d0
+ lsl.l %d1, %d3
+ lsr.l #8, %d0
+ or.l %d0, %d3
+
+ /* byte swap d3 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d3, %d7 /* d7 = .B.D */
+ eor.l %d7, %d3 /* d3 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d3 /* d3 = .A.C */
+ or.l %d7, %d3 /* d3 = BADC */
+
+ swap %d3
+ move.w %d3, (%a2)
+ swap %d3
+ move.w %d3, (%a2)
+ move.l %d5, %d0
+ lsl.l %d1, %d4
+ lsr.l #8, %d0
+ or.l %d0, %d4
+
+ /* byte swap d4 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d4, %d7 /* d7 = .B.D */
+ eor.l %d7, %d4 /* d4 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d4 /* d4 = .A.C */
+ or.l %d7, %d4 /* d4 = BADC */
+
+ swap %d4
+ move.w %d4, (%a2)
+ swap %d4
+ move.w %d4, (%a2)
+ move.l %d6, %d0
+ lsl.l %d1, %d5
+ lsr.l #8, %d0
+ or.l %d0, %d5
+
+ /* byte swap d5 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d5, %d7 /* d7 = .B.D */
+ eor.l %d7, %d5 /* d5 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d5 /* d5 = .A.C */
+ or.l %d7, %d5 /* d5 = BADC */
+
+ swap %d5
+ move.w %d5, (%a2)
+ swap %d5
+ move.w %d5, (%a2)
+ move.l %d6, %d2
+ cmp.l %a0, %a1 /* run up to last line bound */
+ bhi.b .w_loop_u_line
+
+ lea.l (12, %a1), %a1 /* readjust for longword loop */
+ cmp.l %a0, %a1 /* any trailing longwords? */
+ bls.b .w_end_u_l2 /* no: skip loop */
+
+.w_loop_u_l2:
+ move.l (%a0)+, %d3
+ move.l %d3, %d4
+ lsl.l %d1, %d2
+ lsr.l #8, %d3
+ or.l %d3, %d2
+
+ /* byte swap d2 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d2, %d7 /* d7 = .B.D */
+ eor.l %d7, %d2 /* d2 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d2 /* d2 = .A.C */
+ or.l %d7, %d2 /* d2 = BADC */
+
+ swap %d2
+ move.w %d2, (%a2)
+ swap %d2
+ move.w %d2, (%a2)
+ move.l %d4, %d2
+ cmp.l %a0, %a1 /* run up to first line bound */
+ bhi.b .w_loop_u_l2
+
+.w_end_u_l2:
+ addq.l #2, %a1 /* back to final end address */
+ cmp.l %a0, %a1 /* one word left? */
+ bls.b .w_end_u_w2
+
+ swap %d2
+ move.w (%a0)+, %d2
+ move.l %d2, %d3
+ lsr.l #8, %d3
+
+ /* byte swap d3 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d3, %d7 /* d7 = .B.D */
+ eor.l %d7, %d3 /* d3 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d3 /* d3 = .A.C */
+ or.l %d7, %d3 /* d3 = BADC */
+
+ move.w %d3, (%a2)
+
+.w_end_u_w2:
+ lsl.l #8, %d2
+ move.b (%a0)+, %d2
+
+ /* byte swap d2 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d2, %d7 /* d7 = .B.D */
+ eor.l %d7, %d2 /* d2 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d2 /* d2 = .A.C */
+ or.l %d7, %d2 /* d2 = BADC */
+
+ move.w %d2, (%a2)
+ bra.w .w_exit
+
+ /* 16-bit aligned */
+.w_aligned:
+ btst.l #1, %d0
+ beq.b .w_end_a_w1
+
+ /* this has to be byte swaped */
+ /* copy initial word */
+ move.w (%a0)+, %d1
+
+ /* byte swap d1 */
+ move.l %a3, %d7 /* d7 = $00FF00FF */
+ and.l %d1, %d7 /* d7 = .B.D */
+ eor.l %d7, %d1 /* d1 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d1 /* d1 = .A.C */
+ or.l %d7, %d1 /* d1 = BADC */
+
+ move.w %d1, (%a2)
+
+
+.w_end_a_w1:
+ moveq.l #12, %d0
+ add.l %a0, %d0
+ and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
+ cmp.l %a0, %d0 /* any leading longwords? */
+ bls.b .w_end_a_l1 /* no: skip loop */
+
+.w_loop_a_l1:
+ move.l (%a0)+, %d1
+
+/* byte swap d1 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d1, %d7 /* d7 = .B.D */
+ eor.l %d7, %d1 /* d1 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d1 /* d1 = .A.C */
+ or.l %d7, %d1 /* d1 = BADC */
+
+ swap %d1
+ move.w %d1, (%a2)
+ swap %d1
+ move.w %d1, (%a2)
+ cmp.l %a0, %d0 /* run up to first line bound */
+ bhi.b .w_loop_a_l1
+
+.w_end_a_l1:
+ lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
+
+.w_loop_a_line:
+ movem.l (%a0), %d0-%d3
+
+/* byte swap d0-d3 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d0, %d7 /* d7 = .B.D */
+ eor.l %d7, %d0 /* d0 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d0 /* d0 = .A.C */
+ or.l %d7, %d0 /* d0 = BADC */
+
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d1, %d7 /* d7 = .B.D */
+ eor.l %d7, %d1 /* d1 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d1 /* d1 = .A.C */
+ or.l %d7, %d1 /* d1 = BADC */
+
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d2, %d7 /* d7 = .B.D */
+ eor.l %d7, %d2 /* d2 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d2 /* d2 = .A.C */
+ or.l %d7, %d2 /* d2 = BADC */
+
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d3, %d7 /* d7 = .B.D */
+ eor.l %d7, %d3 /* d3 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d3 /* d3 = .A.C */
+ or.l %d7, %d3 /* d3 = BADC */
+
+ lea.l (16, %a0), %a0
+ swap %d0
+ move.w %d0, (%a2)
+ swap %d0
+ move.w %d0, (%a2)
+ swap %d1
+ move.w %d1, (%a2)
+ swap %d1
+ move.w %d1, (%a2)
+ swap %d2
+ move.w %d2, (%a2)
+ swap %d2
+ move.w %d2, (%a2)
+ swap %d3
+ move.w %d3, (%a2)
+ swap %d3
+ move.w %d3, (%a2)
+ cmp.l %a0, %a1 /* run up to last line bound */
+ bhi.b .w_loop_a_line
+
+ lea.l (12, %a1), %a1 /* readjust for longword loop */
+ cmp.l %a0, %a1 /* any trailing longwords? */
+ bls.b .w_end_a_l2 /* no: skip loop */
+
+.w_loop_a_l2:
+ move.l (%a0)+, %d1
+
+/* byte swap d1 */
+ move.l %a3, %d7 /* d7 = 0x00FF00FF */
+ and.l %d1, %d7 /* d7 = .B.D */
+ eor.l %d7, %d1 /* d1 = A.C. */
+ lsl.l #8, %d7 /* d7 = B.D. */
+ lsr.l #8, %d1 /* d1 = .A.C */
+ or.l %d7, %d1 /* d1 = BADC */
+
+ swap %d1
+ move.w %d1, (%a2)
+ swap %d1
+ move.w %d1, (%a2)
+ cmp.l %a0, %a1 /* run up to first line bound */
+ bhi.b .w_loop_a_l2
+
+.w_end_a_l2:
+ addq.l #2, %a1 /* back to final end address */
+ cmp.l %a0, %a1 /* one word left? */
+ bls.b .w_end_a_w2
+
+/* this has to be byte swaped */
+/* copy final word */
+ move.w (%a0)+, %d0
+ move.l %a3, %d7
+ and.l %d0, %d7
+ eor.l %d7, %d0
+ lsl.l #8, %d7
+ lsr.l #8, %d0
+ or.l %d7, %d0
+ move.w %d0, (%a2)
+
+.w_end_a_w2:
+
+.w_exit:
+ movem.l (%sp), %d2-%d7/%a2-%a3
+ lea.l (32, %sp), %sp
+ rts
+
+.w_end:
+ .size copy_write_sectors,.w_end-copy_write_sectors
+#endif
diff --git a/firmware/target/coldfire/mpio/ata-mpio.c b/firmware/target/coldfire/mpio/ata-mpio.c
new file mode 100644
index 0000000000..ca1c9b1bc6
--- /dev/null
+++ b/firmware/target/coldfire/mpio/ata-mpio.c
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "cpu.h"
+#include <stdbool.h>
+#include "kernel.h"
+#include "system.h"
+#include "power.h"
+#include "ata-target.h"
+
+void ata_reset(void)
+{
+ /* GPIO19 */
+ and_l(~(1<<19), &GPIO_OUT);
+ sleep(1); /* > 25us */
+
+ or_l((1<<19), &GPIO_OUT);
+ sleep(1); /* > 25us */
+}
+
+void ata_enable(bool on)
+{
+ (void)on;
+}
+
+/* to be fixed */
+bool ata_is_coldstart(void)
+{
+ return true;
+}
+
+void ata_device_init(void)
+{
+ /* ATA reset line config */
+ or_l((1<<19), &GPIO_OUT);
+ or_l((1<<19), &GPIO_ENABLE);
+ or_l((1<<19), &GPIO_FUNCTION);
+}
diff --git a/firmware/target/coldfire/mpio/ata-target.h b/firmware/target/coldfire/mpio/ata-target.h
new file mode 100644
index 0000000000..1fa4c5af41
--- /dev/null
+++ b/firmware/target/coldfire/mpio/ata-target.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+#ifndef ATA_TARGET_H
+#define ATA_TARGET_H
+
+/* asm optimised read & write loops - we skip this for now*/
+#define ATA_OPTIMIZED_READING
+//#define ATA_OPTIMIZED_WRITING
+
+#define SWAP_WORDS
+
+#define ATA_IOBASE 0x20000000
+#define ATA_DATA (*((volatile unsigned short*)(ATA_IOBASE + 0x20)))
+#define ATA_CONTROL (*((volatile unsigned short*)(ATA_IOBASE + 0x1c)))
+
+#define ATA_ERROR (*((volatile unsigned short*)(ATA_IOBASE + 0x22)))
+#define ATA_NSECTOR (*((volatile unsigned short*)(ATA_IOBASE + 0x24)))
+#define ATA_SECTOR (*((volatile unsigned short*)(ATA_IOBASE + 0x26)))
+#define ATA_LCYL (*((volatile unsigned short*)(ATA_IOBASE + 0x28)))
+#define ATA_HCYL (*((volatile unsigned short*)(ATA_IOBASE + 0x2a)))
+#define ATA_SELECT (*((volatile unsigned short*)(ATA_IOBASE + 0x2c)))
+#define ATA_COMMAND (*((volatile unsigned short*)(ATA_IOBASE + 0x2e)))
+
+
+#define STATUS_BSY 0x80
+#define STATUS_RDY 0x40
+#define STATUS_DF 0x20
+#define STATUS_DRQ 0x08
+#define STATUS_ERR 0x01
+
+#define ERROR_ABRT 0x04
+#define ERROR_IDNF 0x10
+
+#define WRITE_PATTERN1 0xa5
+#define WRITE_PATTERN2 0x5a
+#define WRITE_PATTERN3 0xaa
+#define WRITE_PATTERN4 0x55
+
+#define READ_PATTERN1 0xa5
+#define READ_PATTERN2 0x5a
+#define READ_PATTERN3 0xaa
+#define READ_PATTERN4 0x55
+
+#define READ_PATTERN1_MASK 0xff
+#define READ_PATTERN2_MASK 0xff
+#define READ_PATTERN3_MASK 0xff
+#define READ_PATTERN4_MASK 0xff
+
+#define SET_REG(reg,val) reg = (val)
+#define SET_16BITREG(reg,val) reg = (val)
+
+void ata_reset(void);
+void ata_enable(bool on);
+void ata_device_init(void);
+bool ata_is_coldstart(void);
+
+void copy_read_sectors(unsigned char* buf, int wordcount);
+//void copy_write_sectors(const unsigned char* buf, int wordcount);
+#endif
diff --git a/firmware/target/coldfire/mpio/audio-mpio.c b/firmware/target/coldfire/mpio/audio-mpio.c
new file mode 100644
index 0000000000..28c6419171
--- /dev/null
+++ b/firmware/target/coldfire/mpio/audio-mpio.c
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+#include "system.h"
+#include "cpu.h"
+#include "audio.h"
+#include "sound.h"
+
+void audio_set_output_source(int source)
+{
+
+ (void)source;
+ int level = set_irq_level(DMA_IRQ_LEVEL);
+
+ /* PDOR3 */
+ IIS2CONFIG = (IIS2CONFIG & ~(7 << 8)) | (3 << 8);
+
+ restore_irq(level);
+}
+
+void audio_input_mux(int source, unsigned flags)
+{
+ (void)source;
+ (void)flags;
+
+ switch(source)
+ {
+ case AUDIO_SRC_FMRADIO:
+ break;
+ }
+ /* empty stub */
+}
diff --git a/firmware/target/coldfire/mpio/boot.lds b/firmware/target/coldfire/mpio/boot.lds
new file mode 100644
index 0000000000..2b086586ad
--- /dev/null
+++ b/firmware/target/coldfire/mpio/boot.lds
@@ -0,0 +1,81 @@
+#include "config.h"
+
+ENTRY(start)
+OUTPUT_FORMAT(elf32-m68k)
+STARTUP(target/coldfire/crt0.o)
+
+#define DRAMSIZE (MEMORYSIZE * 0x100000)
+
+#define DRAMORIG 0x31000000
+#define IRAMORIG 0x10000000
+#define IRAMSIZE 0x18000
+#define FLASHORIG 0x000e0000
+#define FLASHSIZE 0x1f800
+
+MEMORY
+{
+ DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
+ IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
+ FLASH : ORIGIN = FLASHORIG, LENGTH = FLASHSIZE
+}
+
+SECTIONS
+{
+ .vectors :
+ {
+ _datacopy = .;
+ } > FLASH
+
+ .data : AT ( _datacopy )
+ {
+ _datastart = .;
+ KEEP(*(.resetvectors));
+ *(.resetvectors);
+ KEEP(*(.vectors));
+ *(.vectors);
+ . = ALIGN(0x200);
+ *(.icode)
+ *(.irodata)
+ *(.idata)
+ *(.data*)
+ . = ALIGN(0x4);
+ _dataend = .;
+ . = ALIGN(0x10); /* Maintain proper alignment for .text section */
+ } > IRAM
+
+ /* TRICK ALERT! Newer versions of the linker don't allow output sections
+ to overlap even if one of them is empty, so advance the location pointer
+ "by hand" */
+ .text LOADADDR(.data) + SIZEOF(.data) :
+ {
+ *(.init.text)
+ *(.text*)
+ . = ALIGN(0x4);
+ } > FLASH
+
+ .rodata :
+ {
+ *(.rodata*)
+ . = ALIGN(0x4);
+ _iramcopy = .;
+ } > FLASH
+
+ .stack :
+ {
+ *(.stack)
+ _stackbegin = .;
+ stackbegin = .;
+ . += 0x2000;
+ _stackend = .;
+ stackend = .;
+ } > IRAM
+
+ .bss DRAMORIG+0x800000:
+ {
+ _edata = .;
+ *(.ibss)
+ *(.bss*)
+ *(COMMON)
+ _end = .;
+ } > DRAM
+}
diff --git a/firmware/target/coldfire/mpio/boot.lds.flash b/firmware/target/coldfire/mpio/boot.lds.flash
new file mode 100644
index 0000000000..2b086586ad
--- /dev/null
+++ b/firmware/target/coldfire/mpio/boot.lds.flash
@@ -0,0 +1,81 @@
+#include "config.h"
+
+ENTRY(start)
+OUTPUT_FORMAT(elf32-m68k)
+STARTUP(target/coldfire/crt0.o)
+
+#define DRAMSIZE (MEMORYSIZE * 0x100000)
+
+#define DRAMORIG 0x31000000
+#define IRAMORIG 0x10000000
+#define IRAMSIZE 0x18000
+#define FLASHORIG 0x000e0000
+#define FLASHSIZE 0x1f800
+
+MEMORY
+{
+ DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
+ IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
+ FLASH : ORIGIN = FLASHORIG, LENGTH = FLASHSIZE
+}
+
+SECTIONS
+{
+ .vectors :
+ {
+ _datacopy = .;
+ } > FLASH
+
+ .data : AT ( _datacopy )
+ {
+ _datastart = .;
+ KEEP(*(.resetvectors));
+ *(.resetvectors);
+ KEEP(*(.vectors));
+ *(.vectors);
+ . = ALIGN(0x200);
+ *(.icode)
+ *(.irodata)
+ *(.idata)
+ *(.data*)
+ . = ALIGN(0x4);
+ _dataend = .;
+ . = ALIGN(0x10); /* Maintain proper alignment for .text section */
+ } > IRAM
+
+ /* TRICK ALERT! Newer versions of the linker don't allow output sections
+ to overlap even if one of them is empty, so advance the location pointer
+ "by hand" */
+ .text LOADADDR(.data) + SIZEOF(.data) :
+ {
+ *(.init.text)
+ *(.text*)
+ . = ALIGN(0x4);
+ } > FLASH
+
+ .rodata :
+ {
+ *(.rodata*)
+ . = ALIGN(0x4);
+ _iramcopy = .;
+ } > FLASH
+
+ .stack :
+ {
+ *(.stack)
+ _stackbegin = .;
+ stackbegin = .;
+ . += 0x2000;
+ _stackend = .;
+ stackend = .;
+ } > IRAM
+
+ .bss DRAMORIG+0x800000:
+ {
+ _edata = .;
+ *(.ibss)
+ *(.bss*)
+ *(COMMON)
+ _end = .;
+ } > DRAM
+}
diff --git a/firmware/target/coldfire/mpio/boot.lds.iram b/firmware/target/coldfire/mpio/boot.lds.iram
new file mode 100644
index 0000000000..769e1027ab
--- /dev/null
+++ b/firmware/target/coldfire/mpio/boot.lds.iram
@@ -0,0 +1,81 @@
+#include "config.h"
+
+ENTRY(start)
+OUTPUT_FORMAT(elf32-m68k)
+STARTUP(target/coldfire/crt0.o)
+
+#define DRAMSIZE (MEMORYSIZE * 0x100000)
+
+#define DRAMORIG 0x31000000
+#define IRAMORIG 0x10000000
+#define IRAMSIZE 0x18000
+#define FLASHORIG 0x000e0000
+#define FLASHSIZE 0x1f800
+
+MEMORY
+{
+ DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
+ IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
+ FLASH : ORIGIN = FLASHORIG, LENGTH = FLASHSIZE
+}
+
+SECTIONS
+{
+ .vectors :
+ {
+ _datacopy = .;
+ } > IRAM
+
+ .data : AT ( _datacopy )
+ {
+ _datastart = .;
+ KEEP(*(.resetvectors));
+ *(.resetvectors);
+ KEEP(*(.vectors));
+ *(.vectors);
+ . = ALIGN(0x200);
+ *(.icode)
+ *(.irodata)
+ *(.idata)
+ *(.data*)
+ . = ALIGN(0x4);
+ _dataend = .;
+ . = ALIGN(0x10); /* Maintain proper alignment for .text section */
+ } > IRAM
+
+ /* TRICK ALERT! Newer versions of the linker don't allow output sections
+ to overlap even if one of them is empty, so advance the location pointer
+ "by hand" */
+ .text LOADADDR(.data) + SIZEOF(.data) :
+ {
+ *(.init.text)
+ *(.text*)
+ . = ALIGN(0x4);
+ } > IRAM
+
+ .rodata :
+ {
+ *(.rodata*)
+ . = ALIGN(0x4);
+ _iramcopy = .;
+ } > IRAM
+
+ .stack :
+ {
+ *(.stack)
+ _stackbegin = .;
+ stackbegin = .;
+ . += 0x2000;
+ _stackend = .;
+ stackend = .;
+ } > IRAM
+
+ .bss DRAMORIG+0x800000:
+ {
+ _edata = .;
+ *(.ibss)
+ *(.bss*)
+ *(COMMON)
+ _end = .;
+ } > DRAM
+}
diff --git a/firmware/target/coldfire/mpio/button-target.h b/firmware/target/coldfire/mpio/button-target.h
new file mode 100644
index 0000000000..ae55612e56
--- /dev/null
+++ b/firmware/target/coldfire/mpio/button-target.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+#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);
+
+/* HD200 specific button codes */
+/* Main unit's buttons - flags as in original firmware*/
+#define BUTTON_PLAY 0x00000001
+
+#define BUTTON_PREV 0x00000004
+#define BUTTON_NEXT 0x00000002
+#define BUTTON_VOL_UP 0x00000008
+#define BUTTON_VOL_DOWN 0x00000010
+#define BUTTON_REC 0x00000020
+#define BUTTON_SELECT 0x00002000
+
+#define BUTTON_LEFT BUTTON_PREV
+#define BUTTON_RIGHT BUTTON_NEXT
+#define BUTTON_ON BUTTON_PLAY
+#define BUTTON_REMOTE 0x0
+
+#define BUTTON_MAIN (BUTTON_PLAY|BUTTON_PREV|BUTTON_NEXT|BUTTON_VOL_UP|\
+ BUTTON_VOL_DOWN|BUTTON_REC|BUTTON_SELECT)
+
+#define POWEROFF_BUTTON BUTTON_PLAY
+#define POWEROFF_COUNT 30
+
+#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/coldfire/mpio/fmradio_i2c-mpio.c b/firmware/target/coldfire/mpio/fmradio_i2c-mpio.c
new file mode 100644
index 0000000000..a687c13200
--- /dev/null
+++ b/firmware/target/coldfire/mpio/fmradio_i2c-mpio.c
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ * Physical interface of the Philips TEA5767 in iAudio M3
+ *
+ * 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"
+
+#if (CONFIG_TUNER & TEA5767)
+
+#include "i2c-coldfire.h"
+#include "fmradio_i2c.h"
+
+int fmradio_i2c_write(unsigned char address, const unsigned char* buf,
+ int count)
+{
+ return i2c_write(I2C_IFACE_1, address, buf, count);
+}
+
+int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
+{
+ return i2c_read(I2C_IFACE_1, address, buf, count);
+}
+
+#endif
diff --git a/firmware/target/coldfire/mpio/hd200/adc-hd200.c b/firmware/target/coldfire/mpio/hd200/adc-hd200.c
new file mode 100644
index 0000000000..8bf96436bf
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd200/adc-hd200.c
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "cpu.h"
+#include "system.h"
+#include "kernel.h"
+#include "thread.h"
+#include "adc.h"
+
+volatile unsigned short adc_data[NUM_ADC_CHANNELS] IBSS_ATTR;
+
+/* Reading takes 4096 adclk ticks
+ * We do read one channel at once
+ *
+ * state FCPU Fbus Fadc bus/Fadc Fchannelread
+ * default 11.2896 MHz 5.6448 MHz 5.6448 MHz 2 172.2656 Hz
+ * normal 45.1584 MHz 22.5792 MHz 2.8224 MHz 8 172.2656 Hz
+ * max 124.1856 MHz 62.0928 MHz 1.9404 MHz 32 118.4326 Hz
+ */
+
+void ADC(void) __attribute__ ((interrupt_handler,section(".icode")));
+void ADC(void)
+{
+ static unsigned char channel;
+ /* read current value */
+ adc_data[(channel & 0x03)] = ADVALUE;
+
+ /* switch channel
+ *
+ * set source remark
+ * ADCONFIG is 16bit wide so we have to shift data by 16bits left
+ * thats why we shift <<24 instead of <<8
+ */
+
+ channel++;
+
+ and_l(~(3<<24),&ADCONFIG);
+ or_l( (((channel & 0x03) << 8 )|(1<<7))<<16, &ADCONFIG);
+
+}
+
+unsigned short adc_scan(int channel)
+{
+ /* maybe we can drop &0x03 part */
+ return adc_data[(channel&0x03)];
+}
+
+void adc_init(void)
+{
+ /* GPIO38 GPIO39 */
+ and_l(~((1<<6)|(1<<7)), &GPIO1_FUNCTION);
+
+ /* ADOUT_SEL = 01
+ * SOURCE SELECT = 000
+ * CLEAR INTERRUPT FLAG
+ * ENABLE INTERRUPT = 1
+ * ADOUT_DRIVE = 00
+ * ADCLK_SEL = 011 (busclk/8)
+ */
+
+ ADCONFIG = (1<<10)|(1<<7)|(1<<6)|(1<<1)|(1<<0);
+
+ /* ADC interrupt level 4.0 */
+ or_l((4<<28), &INTPRI8);
+}
diff --git a/firmware/target/coldfire/mpio/hd200/adc-target.h b/firmware/target/coldfire/mpio/hd200/adc-target.h
new file mode 100644
index 0000000000..2e61065695
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd200/adc-target.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+
+#ifndef _ADC_TARGET_H_
+#define _ADC_TARGET_H_
+
+#define NUM_ADC_CHANNELS 4
+
+#define ADC_BUTTONS 1
+#define ADC_REMOTE 0
+#define ADC_BATTERY 2
+#define ADC_REMOTEDETECT 3
+#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
+
+/* Force a scan now */
+unsigned short adc_scan(int channel);
+
+static inline unsigned short adc_read(int channel)
+{
+ return adc_scan(channel);
+}
+
+#endif /* _ADC_TARGET_H_ */
diff --git a/firmware/target/coldfire/mpio/hd200/backlight-hd200.c b/firmware/target/coldfire/mpio/hd200/backlight-hd200.c
new file mode 100644
index 0000000000..783376c91e
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd200/backlight-hd200.c
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "cpu.h"
+#include "kernel.h"
+#include "system.h"
+#include "backlight.h"
+#include "backlight-target.h"
+#include "lcd.h"
+
+static bool _backlight_on = false;
+static int _brightness = DEFAULT_BRIGHTNESS_SETTING;
+
+/* Returns the current state of the backlight (true=ON, false=OFF). */
+bool _backlight_init(void)
+{
+ and_l(~(1<<28),&GPIO_OUT);
+ or_l((1<<28),&GPIO_FUNCTION);
+ or_l((1<<28),&GPIO_ENABLE);
+ return true;
+}
+
+void _backlight_hw_on(void)
+{
+
+ if (_backlight_on)
+ return;
+
+ _backlight_set_brightness(_brightness);
+ _backlight_on = true;
+
+}
+
+void _backlight_hw_off(void)
+{
+ /* GPIO28 low */
+ and_l(~(1<<28),&GPIO_OUT);
+ _backlight_on = false;
+}
+
+void _backlight_set_brightness(int val)
+{
+ unsigned char i;
+
+ and_l(~(1<<28),&GPIO_OUT);
+ sleep(4);
+
+ for (i=0;i<val;i++)
+ {
+ or_l((1<<28),&GPIO_OUT);
+ and_l(~(1<<28),&GPIO_OUT);
+ }
+
+ or_l((1<<28),&GPIO_OUT);
+
+ _brightness = val;
+}
+
+void _remote_backlight_on(void)
+{
+ /* I don't have remote to play with */
+}
+
+void _remote_backlight_off(void)
+{
+ /* I don't have remote to play with */
+}
diff --git a/firmware/target/coldfire/mpio/hd200/backlight-target.h b/firmware/target/coldfire/mpio/hd200/backlight-target.h
new file mode 100644
index 0000000000..0080ccac08
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd200/backlight-target.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+#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);
+void _backlight_set_brightness(int val);
+
+#define _backlight_on() _backlight_hw_on()
+#define _backlight_off() _backlight_hw_off()
+#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
diff --git a/firmware/target/coldfire/mpio/hd200/button-hd200.c b/firmware/target/coldfire/mpio/hd200/button-hd200.c
new file mode 100644
index 0000000000..b40c3324e1
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd200/button-hd200.c
@@ -0,0 +1,123 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "cpu.h"
+#include "system.h"
+#include "button.h"
+#include "backlight.h"
+#include "adc.h"
+
+void button_init_device(void)
+{
+ /* Set GPIO36, GPIO56 as general purpose inputs */
+ or_l((1<<4)|(1<<24),&GPIO1_FUNCTION);
+ and_l(~((1<<4)|(1<<24)),&GPIO1_ENABLE);
+}
+
+bool button_hold(void)
+{
+ /* GPIO36 active high */
+ return (GPIO1_READ & (1<<4))?true:false;
+}
+
+
+/*
+ * Get button pressed from hardware
+ */
+int button_read_device(void)
+{
+ int btn = BUTTON_NONE;
+ int data = 0;
+ static bool hold_button = false;
+
+ /* for moving average filter */
+ static unsigned short button_filter[4];
+ static unsigned char index;
+
+ bool hold_button_old;
+
+ /* normal buttons */
+ hold_button_old = hold_button;
+ hold_button = button_hold();
+
+
+#ifndef BOOTLOADER
+ if (hold_button != hold_button_old)
+ backlight_hold_changed(hold_button);
+#endif
+
+ if (!hold_button)
+ {
+
+ /* simple moving average filter with 4 item window */
+ button_filter[index&0x03] = adc_scan(ADC_BUTTONS);
+ index++;
+
+ data = (button_filter[0]+button_filter[1] \
+ +button_filter[2]+button_filter[3])>>2;
+
+
+ if (data < 2250) // valid button
+ {
+ if (data < 900) /* middle */
+ {
+ if (data < 500)
+ {
+ if (data > 200)
+ /* 200 - 500 */
+ btn = BUTTON_REC;
+ }
+ else /* 900 - 500 */
+ btn = BUTTON_VOL_DOWN;
+ }
+ else /* 2250 - 900 */
+ {
+ if (data < 1600)
+ {
+ /* 1600 - 900 */
+ if (data < 1200)
+ /* 1200 - 900 */
+ btn = BUTTON_VOL_UP;
+ else /* 1600 - 1200 */
+ btn = BUTTON_NEXT;
+ }
+ else /* 1600 - 2250 */
+ {
+ if (data < 1900)
+ /* 1900 - 1600 */
+ btn = BUTTON_PREV;
+ else /* 1900 - 2250 */
+ btn = BUTTON_SELECT;
+ }
+ }
+ }
+ }
+
+
+ data = GPIO1_READ;
+
+ /* GPIO56 active high main PLAY/PAUSE/ON */
+ if (!hold_button && ((data & (1<<24))))
+ btn |= BUTTON_PLAY;
+
+ return btn;
+}
diff --git a/firmware/target/coldfire/mpio/hd200/lcd-as-hd200.S b/firmware/target/coldfire/mpio/hd200/lcd-as-hd200.S
new file mode 100644
index 0000000000..add9f694de
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd200/lcd-as-hd200.S
@@ -0,0 +1,103 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "cpu.h"
+
+
+#define LCD_BASE_ADDRESS 0xf0000000
+
+ .section .icode,"ax",@progbits
+
+ .align 2
+ .global lcd_write_command
+ .type lcd_write_command,@function
+
+lcd_write_command:
+ move.l (4, %sp), %d0
+ move.w %d0, LCD_BASE_ADDRESS /* data is 1byte but CF uses word
+ * transfers only */
+ rts
+.wc_end:
+ .size lcd_write_command,.wc_end-lcd_write_command
+
+
+ .align 2
+ .global lcd_write_command_e
+ .type lcd_write_command_e,@function
+
+lcd_write_command_e:
+ lea.l LCD_BASE_ADDRESS, %a0
+
+ move.l (4, %sp), %d0 /* Command */
+ move.w %d0, (%a0)
+ move.l (8, %sp), %d0 /* Data */
+ move.w %d0, (%a0) /* Write to LCD */
+
+ rts
+.wce_end:
+ .size lcd_write_command_e,.wce_end-lcd_write_command_e
+
+
+ .align 2
+ .global lcd_write_data
+ .type lcd_write_data,@function
+
+/* PIXELFORMAT = VERTICAL_INTERLEAVED
+ * this means that data is packed verticaly in 8 pixels columns
+ * first byte is lsb of 2bit color in column
+ * second byte is msb of 2bit color in column
+ * so one word of data equals 8 pixels i 2bits color depth packed
+ * verticaly
+ */
+lcd_write_data:
+ movem.l (4, %sp), %a0 /* Data pointer */
+ move.l (8, %sp), %d0 /* Length i in words */
+ lea LCD_BASE_ADDRESS+2, %a1 /* LCD data port address */
+
+ btst #0, %d0 /* longwords multiply? */
+ beq .l_write
+
+.w_write:
+ move.w (%a0)+, %d1 /* load data 3 cycles*/
+ move.w %d1, (%a1) /* first byte 1 cycle*/
+ lsr.l #8, %d1 /* load second byte 1 cycle*/
+ move.w %d1, (%a1) /* transfer 1 cycle*/
+ subq.l #1, %d0 /* decrement counter 1 cycle*/
+ beq .write_end
+
+.l_write:
+ move.l (%a0)+, %d1 /* load data 2 cycles*/
+ swap %d1 /* 1 cycle */
+ move.w %d1, (%a1) /* first byte 1 cycle*/
+ lsr.l #8, %d1 /* 1 cycle */
+ move.w %d1, (%a1) /* second byte 1 cycle*/
+ lsr.l #8, %d1 /* 1 cycle */
+ move.w %d1, (%a1) /* third byte 1 cycle*/
+ lsr.l #8, %d1 /* 1 cycle */
+ move.w %d1, (%a1) /* forth byte 1 cycle*/
+ subq.l #2, %d0 /* decrement counter 1 cycle*/
+ bne .l_write
+
+.write_end:
+ rts
+ .size lcd_write_data,.wd_end-lcd_write_data
+
diff --git a/firmware/target/coldfire/mpio/hd200/lcd-hd200.c b/firmware/target/coldfire/mpio/hd200/lcd-hd200.c
new file mode 100644
index 0000000000..8cb9e8e087
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd200/lcd-hd200.c
@@ -0,0 +1,241 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+
+#include "system.h"
+#include "kernel.h"
+#include "lcd.h"
+
+/*** definitions ***/
+/* TOMATO LSI 0350 - definitions and slightly tweaked functions
+ * taken from lcd-remote-iaudio.c
+ */
+
+#define LCD_SET_DUTY_RATIO 0x48
+#define LCD_SELECT_ADC 0xa0
+#define LCD_SELECT_SHL 0xc0
+#define LCD_SET_COM0 0x44
+#define LCD_OSC_ON 0xab
+#define LCD_SELECT_DCDC 0x64
+#define LCD_SELECT_RES 0x20
+#define LCD_SET_VOLUME 0x81
+#define LCD_SET_BIAS 0x50
+#define LCD_CONTROL_POWER 0x28
+#define LCD_DISPLAY_ON 0xae
+#define LCD_SET_INITLINE 0x40
+#define LCD_SET_COLUMN 0x10
+#define LCD_SET_PAGE 0xb0
+#define LCD_SET_GRAY 0x88
+#define LCD_SET_PWM_FRC 0x90
+#define LCD_SET_POWER_SAVE 0xa8
+#define LCD_REVERSE 0xa6
+#define LCD_RESET 0xe2
+
+/* cached settings */
+static bool cached_invert = false;
+static bool cached_flip = false;
+static int cached_contrast = DEFAULT_CONTRAST_SETTING;
+bool lcd_initialized = false;
+
+/*** hardware configuration ***/
+int lcd_default_contrast(void)
+{
+ return DEFAULT_CONTRAST_SETTING;
+}
+
+void lcd_powersave(bool on)
+{
+/* What is the point of having else construct here? */
+ if(lcd_initialized) {
+ if (on)
+ lcd_write_command(LCD_SET_POWER_SAVE | 1);
+ else
+ lcd_write_command(LCD_SET_POWER_SAVE | 1);
+ }
+}
+
+void lcd_set_contrast(int val)
+{
+ if (val < MIN_CONTRAST_SETTING)
+ val = MIN_CONTRAST_SETTING;
+ else if (val > MAX_CONTRAST_SETTING)
+ val = MAX_CONTRAST_SETTING;
+
+ cached_contrast = val;
+ if(lcd_initialized)
+ lcd_write_command_e(LCD_SET_VOLUME, val);
+}
+
+void lcd_set_invert_display(bool yesno)
+{
+ cached_invert = yesno;
+ if(lcd_initialized)
+ lcd_write_command(LCD_REVERSE | yesno);
+
+}
+
+/* turn the display upside down (call lcd_update() afterwards) */
+void lcd_set_flip(bool yesno)
+{
+ cached_flip = yesno;
+ if(lcd_initialized)
+ {
+ if(yesno)
+ {
+ lcd_write_command(LCD_SELECT_ADC | 1);
+ lcd_write_command(LCD_SELECT_SHL | 0);
+ lcd_write_command_e(LCD_SET_COM0, 0);
+ }
+ else
+ {
+ lcd_write_command(LCD_SELECT_ADC | 0);
+ lcd_write_command(LCD_SELECT_SHL | 8);
+ lcd_write_command_e(LCD_SET_COM0, 0);
+ }
+ }
+
+}
+
+void lcd_shutdown(void)
+{
+ /* Set power save -> Power OFF (VDD - VSS) .. that's it */
+ if (lcd_initialized)
+ lcd_write_command(LCD_SET_POWER_SAVE | 1);
+}
+
+void lcd_init_device(void)
+{
+ and_l(~0x00000800, &GPIO_FUNCTION); /* CS3 line */
+
+ /* LCD Reset GPO34 */
+ or_l(0x00000004, &GPIO1_ENABLE); /* set as output */
+ or_l(0x00000004, &GPIO1_FUNCTION); /* switch to secondary function - GPIO */
+
+ and_l(~0x00000004, &GPIO1_OUT); /* RESET low */
+ sleep(1); /* delay at least 1000 ns */
+ or_l(0x00000004, &GPIO1_OUT); /* RESET high */
+ sleep(1);
+
+ /* parameters setup taken from original firmware */
+ lcd_write_command(LCD_RESET);
+ lcd_write_command_e(LCD_SET_DUTY_RATIO,0x80); /* 1/128 */
+ lcd_write_command(LCD_OSC_ON);
+ lcd_write_command(LCD_SELECT_DCDC | 3); /* DC/DC 6xboost */
+ lcd_write_command(LCD_SELECT_RES | 7); /* Regulator resistor: 7.2 */
+ lcd_write_command(LCD_SET_BIAS | 6); /* 1/11 */
+ lcd_write_command(LCD_SET_PWM_FRC | 6); /* 3FRC + 12PWM */
+ lcd_write_command_e(LCD_SET_GRAY | 0, 0x00);
+ lcd_write_command_e(LCD_SET_GRAY | 1, 0x00);
+ lcd_write_command_e(LCD_SET_GRAY | 2, 0x0c);
+ lcd_write_command_e(LCD_SET_GRAY | 3, 0x00);
+ lcd_write_command_e(LCD_SET_GRAY | 4, 0xc4);
+ lcd_write_command_e(LCD_SET_GRAY | 5, 0x00);
+ lcd_write_command_e(LCD_SET_GRAY | 6, 0xcc);
+ lcd_write_command_e(LCD_SET_GRAY | 7, 0x00);
+
+ lcd_write_command(LCD_CONTROL_POWER | 7); /* All circuits ON */
+ lcd_write_command(LCD_DISPLAY_ON | 1); /* display on */
+
+ /* Ok we are ready */
+ lcd_initialized = true;
+
+ lcd_set_flip(cached_flip);
+ lcd_set_contrast(cached_contrast);
+ lcd_set_invert_display(cached_invert);
+
+ lcd_update();
+}
+
+/* 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;
+ if(!lcd_initialized)
+ return;
+
+ for(y = 0;y < LCD_FBHEIGHT;y++)
+ {
+ lcd_write_command(LCD_SET_PAGE | y);
+ lcd_write_command_e(LCD_SET_COLUMN, 0);
+ 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;
+
+ if (!lcd_initialized)
+ return;
+
+
+ /* 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;
+
+ /* Copy specified rectange bitmap to hardware */
+ for (; y <= ymax; y++)
+ {
+ lcd_write_command(LCD_SET_PAGE | y );
+ lcd_write_command_e(LCD_SET_COLUMN | ((x >> 4) & 0xf), x & 0x0f);
+ lcd_write_data (&lcd_framebuffer[y][x], width);
+ }
+
+}
+
+void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
+ int x, int by, int width, int bheight, int stride)
+{
+ (void)values;
+ (void)phases;
+ (void)x;
+ (void)by;
+ (void)width;
+ (void)bheight;
+ (void)stride;
+ /* empty stub */
+}
+
+void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
+ int bheight, int stride)
+{
+ (void)data;
+ (void)x;
+ (void)by;
+ (void)width;
+ (void)bheight;
+ (void)stride;
+ /* empty stub */
+}
diff --git a/firmware/target/coldfire/mpio/hd200/power-hd200.c b/firmware/target/coldfire/mpio/hd200/power-hd200.c
new file mode 100644
index 0000000000..dd8576b9e4
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd200/power-hd200.c
@@ -0,0 +1,113 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "cpu.h"
+#include <stdbool.h>
+#include "kernel.h"
+#include "system.h"
+#include "lcd.h"
+#include "power.h"
+
+#if CONFIG_TUNER
+bool tuner_power(bool status)
+{
+ (void)status;
+ if (status)
+ {
+ and_l(~(1<<17), &GPIO1_OUT);
+ }
+ else
+ {
+ or_l((1<<17), &GPIO1_OUT);
+ }
+
+ return status;
+}
+#endif /* #if CONFIG_TUNER */
+
+void power_init(void)
+{
+ /* GPIO53 has to be high - low resets device */
+ /* GPIO49 is FM related */
+ or_l((1<<21)|(1<<17), &GPIO1_OUT);
+ or_l((1<<21)|(1<<17), &GPIO1_ENABLE);
+ or_l((1<<21)|(1<<17)|(1<<14), &GPIO1_FUNCTION);
+
+ and_l(~(1<<15), &GPIO_OUT);
+ or_l((1<<15),&GPIO_ENABLE);
+ or_l((1<<15),&GPIO_FUNCTION);
+
+ or_l((1<<23), &GPIO_OUT);
+ and_l(~(1<<23), &GPIO_ENABLE);
+ or_l((1<<23), &GPIO_FUNCTION);
+
+#ifndef BOOTLOADER
+ /* The boot loader controls the power */
+ ide_power_enable(true);
+#endif
+}
+
+unsigned int power_input_status(void)
+{
+ unsigned int status = POWER_INPUT_NONE;
+/* GPIO46 is AC plug detect (low = AC plugged) */
+ if (!(GPIO1_READ & (1<<14)))
+ status |= POWER_INPUT_MAIN_CHARGER;
+
+ return status;
+}
+
+/* Returns true if the unit is charging the batteries. */
+bool charging_state(void)
+{
+ if (!(GPIO1_READ & (1<<14)))
+ return (GPIO_READ & (1<<30) )?false:true;
+ else
+ return false;
+}
+
+void ide_power_enable(bool on)
+{
+ (void)on;
+ if (on)
+ and_l(~(1<<31),&GPIO_OUT);
+ else
+ or_l((1<<31),&GPIO_OUT);
+
+ or_l((1<<31),&GPIO_ENABLE);
+ or_l((1<<31),&GPIO_FUNCTION);
+
+}
+
+bool ide_powered(void)
+{
+ return true;
+}
+
+void power_off(void)
+{
+ lcd_shutdown();
+ set_irq_level(DISABLE_INTERRUPTS);
+ and_l(~(1<<21), &GPIO1_OUT); /* pull KEEPACT low */
+ asm("halt");
+ while(1);
+}
diff --git a/firmware/target/coldfire/mpio/hd200/powermgmt-hd200.c b/firmware/target/coldfire/mpio/hd200/powermgmt-hd200.c
new file mode 100644
index 0000000000..23a0bac927
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd200/powermgmt-hd200.c
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+#include "adc.h"
+#include "powermgmt.h"
+
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+ 3700
+};
+
+const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
+{
+ 3650
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
+const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
+{
+ /* from OF and measurements voltage range is 3.7-4.1 V */
+ { 3700, 3740, 3780, 3820, 3860, 3900, 3940, 3980, 4020, 4060, 4100 }
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+const unsigned short percent_to_volt_charge[11] =
+{
+ /* values measured over one full charging cycle */
+ 3540, 3860, 3930, 3980, 4000, 4020, 4040, 4080, 4130, 4180, 4230 /* LiPo */
+};
+
+/* 3.33V as reference */
+#define BATTERY_SCALE_FACTOR 3330
+
+
+/* Returns battery voltage from ADC [millivolts] */
+unsigned int battery_adc_voltage(void)
+{
+ return (adc_read(ADC_BATTERY) * BATTERY_SCALE_FACTOR) >> 11;
+}
+
diff --git a/firmware/target/coldfire/mpio/hd200/system-hd200.c b/firmware/target/coldfire/mpio/hd200/system-hd200.c
new file mode 100644
index 0000000000..06628c0835
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd200/system-hd200.c
@@ -0,0 +1,125 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "cpu.h"
+#include "kernel.h"
+#include "system.h"
+#include "power.h"
+#include "timer.h"
+
+/* Settings for all possible clock frequencies (with properly working timers)
+ *
+ * xxx_REFRESH_TIMER below
+ * system.h, CPUFREQ_xxx_MULT |
+ * | |
+ * V V
+ * PLLCR & Rftim. IDECONFIG1/IDECONFIG2
+ * CPUCLK/Hz MULT ~0x70c00000 16MB CSCR0 CSCR1 CS2Pre CS2Post CS2Wait
+ * -------------------------------------------------------------------------
+ * 11289600 1 0x00000200 4 0x0180 0x0180 1 1 0
+ * 22579200 2 0x05028049 10 0x0180 0x0180 1 1 0
+ * 33868800 3 0x03024049 15 0x0180 0x0180 1 1 0
+ * 45158400 4 0x05028045 21 0x0180 0x0180 1 1 0
+ * 56448000 5 0x02028049 26 0x0580 0x0580 2 1 0
+ * 67737600 6 0x03024045 32 0x0580 0x0980 2 1 0
+ * 79027200 7 0x0302a045 37 0x0580 0x0d80 2 1 0
+ * 90316800 8 0x03030045 43 0x0980 0x0d80 2 1 0
+ * 101606400 9 0x01024049 48 0x0980 0x1180 2 1 0
+ * 112896000 10 0x01028049 54 0x0980 0x1580 3 1 0
+ * 124185600 11 0x0102c049 59 0x0980 0x1180 3 1 1
+ */
+
+#define MAX_REFRESH_TIMER 59
+#define NORMAL_REFRESH_TIMER 21
+#define DEFAULT_REFRESH_TIMER 4
+
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+void set_cpu_frequency (long) __attribute__ ((section (".icode")));
+void set_cpu_frequency(long frequency)
+#else
+void cf_set_cpu_frequency (long) __attribute__ ((section (".icode")));
+void cf_set_cpu_frequency(long frequency)
+#endif
+{
+ switch(frequency)
+ {
+ case CPUFREQ_MAX:
+ DCR = (0x8200 | DEFAULT_REFRESH_TIMER);
+ /* Refresh timer for bypass frequency */
+ PLLCR &= ~1; /* Bypass mode */
+ timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false);
+ PLLCR = 0x0102c049 | (PLLCR & 0x70C00000);
+ CSCR0 = 0x00001180; /* Flash: 4 wait states */
+ CSCR3 = 0x00001180; /* LCD: 4 wait states */
+ while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
+ This may take up to 10ms! */
+ timers_adjust_prescale(CPUFREQ_MAX_MULT, true);
+ DCR = (0x8200 | MAX_REFRESH_TIMER); /* Refresh timer */
+ cpu_frequency = CPUFREQ_MAX;
+ IDECONFIG1 = (1<<28)|(1<<20)|(1<<18)|(1<<13)|(3<<10);
+ /* BUFEN2 enable on /CS2 | CS2Post 1 clock| CS2Pre 3 clocks*/
+ IDECONFIG2 = (1<<18)|(1<<16)|(1<<8)|(1<<0); /* TA /CS2 enable + CS2wait */
+
+ and_l(~(0x07<<16), &ADCONFIG);
+ or_l(((1<<7)|(1<<2)|(1<<0))<<16, &ADCONFIG); /* adclk = busclk/32 */
+
+ break;
+
+ case CPUFREQ_NORMAL:
+ DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER;
+ /* Refresh timer for bypass frequency */
+ PLLCR &= ~1; /* Bypass mode */
+ timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false);
+ PLLCR = 0x05028045 | (PLLCR & 0x70C00000);
+ CSCR0 = 0x00000580; /* Flash: 1 wait state */
+ CSCR3 = 0x00000980; /* LCD: 0 wait states */
+ while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
+ This may take up to 10ms! */
+ timers_adjust_prescale(CPUFREQ_NORMAL_MULT, true);
+ DCR = (0x8000 | NORMAL_REFRESH_TIMER); /* Refresh timer */
+ cpu_frequency = CPUFREQ_NORMAL;
+ IDECONFIG1 = (1<<28)|(1<<20)|(1<<18)|(1<<13)|(1<<10);
+ IDECONFIG2 = (1<<18)|(1<<16);
+
+ and_l(~(0x07<<16), &ADCONFIG);
+ or_l(((1<<7)|(1<<1)|(1<<0))<<16, &ADCONFIG); /* adclk = busclk/8 */
+
+ break;
+ default:
+ DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER;
+ /* Refresh timer for bypass frequency */
+ PLLCR &= ~1; /* Bypass mode */
+ timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, true);
+ /* Power down PLL, but keep CLSEL and CRSEL */
+ PLLCR = 0x00000200 | (PLLCR & 0x70C00000);
+ CSCR0 = 0x00000180; /* Flash: 0 wait states */
+ CSCR3 = 0x00000980; /* LCD: 0 wait states */
+ DCR = (0x8000 | DEFAULT_REFRESH_TIMER); /* Refresh timer */
+ cpu_frequency = CPUFREQ_DEFAULT;
+ IDECONFIG1 = (1<<28)|(1<<20)|(1<<18)|(1<<13)|(1<<10);
+ IDECONFIG2 = (1<<18)|(1<<16);
+
+ and_l(~(0x07<<16), &ADCONFIG);
+ or_l(((1<<7)|(1<<0))<<16, &ADCONFIG); /* adclk = busclk/2 */
+
+ break;
+ }
+}
diff --git a/firmware/target/coldfire/mpio/hd200/usb-hd200.c b/firmware/target/coldfire/mpio/hd200/usb-hd200.c
new file mode 100644
index 0000000000..8f348b8038
--- /dev/null
+++ b/firmware/target/coldfire/mpio/hd200/usb-hd200.c
@@ -0,0 +1,81 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Copyright (C) 2010 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.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include <stdbool.h>
+#include "cpu.h"
+#include "system.h"
+#include "kernel.h"
+#include "usb.h"
+
+void usb_init_device(void)
+{
+ /* GPIO42 is USB detect input
+ * but it also serves as MCLK2 for DAC
+ */
+ and_l(~(1<<4), &GPIO1_OUT);
+ or_l((1<<4)|(1<<18), &GPIO1_ENABLE); /* GPIO36 GPIO50 */
+ or_l((1<<4)|(1<<18), &GPIO1_FUNCTION);
+
+ /* GPIO22 GPIO30*/
+ /* GPIO31 has to be low to ATA work */
+ or_l((1<<22)|(1<<30), &GPIO_OUT);
+ or_l((1<<22)|(1<<30)|(1<<31), &GPIO_ENABLE);
+ or_l((1<<22)|(1<<30)|(1<<31), &GPIO_FUNCTION);
+}
+
+int usb_detect(void)
+{
+ /* GPIO42 active low*/
+ return (GPIO1_READ & (1<<10)) ? USB_EXTRACTED : USB_INSERTED;
+}
+
+void usb_enable(bool on)
+{
+
+ if(on)
+ {
+ or_l((1<<18),&GPIO1_OUT); /* GPIO50 high */
+
+ and_l(~(1<<30),&GPIO_OUT); /* GPIO30 low */
+ /* GPIO36 low delay GPIO36 high delay */
+ and_l(~(1<<4),&GPIO1_OUT);
+ or_l((1<<4),&GPIO1_OUT);
+
+ and_l(~(1<<18),&GPIO1_OUT); /* GPIO50 low */
+ sleep(HZ/5); /* delay 200 ms */
+ and_l(~(1<<22),&GPIO_OUT); /* GPIO22 low */
+ }
+ else
+ {
+ /* GPIO36 low delay GPIO36 high delay */
+ and_l(~(1<<4),&GPIO1_OUT);
+ sleep(HZ/100);
+ or_l((1<<4),&GPIO1_OUT);
+ sleep(HZ/100);
+
+ or_l((1<<22),&GPIO_OUT); /* GPIO22 high */
+ or_l((1<<30),&GPIO_OUT); /* GPIO30 high */
+
+ and_l(~(1<<4),&GPIO1_OUT); /* GPIO36 low */
+
+ //or_l((1<<18),&GPIO1_OUT); /* GPIO50 high */
+ }
+}
diff --git a/firmware/target/coldfire/wmcodec-coldfire.c b/firmware/target/coldfire/wmcodec-coldfire.c
new file mode 100644
index 0000000000..4403b9a2a2
--- /dev/null
+++ b/firmware/target/coldfire/wmcodec-coldfire.c
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id:$
+ *
+ * Coldfire specific code for Wolfson audio codecs based on
+ * wmcodec-pp.c
+ *
+ * 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 "audiohw.h"
+#include "i2c-coldfire.h"
+#include "i2s.h"
+#include "wmcodec.h"
+
+#if defined(MPIO_HD200)
+#define I2C_CODEC_ADDRESS 0x34
+#define I2C_IFACE I2C_IFACE_1
+#endif
+
+void audiohw_init(void)
+{
+ audiohw_preinit();
+}
+
+void wmcodec_write(int reg, int data)
+{
+ unsigned char wmdata[2];
+ wmdata[0] = (reg << 1) | ((data & 0x100)>>8);
+ wmdata[1] = data & 0xff;
+ i2c_write(I2C_IFACE,I2C_CODEC_ADDRESS,wmdata,2);
+ return;
+}