From 28d54c6016459ffe93c0be2efea7de27c38d783c Mon Sep 17 00:00:00 2001 From: Marcin Bukat Date: Mon, 26 Apr 2010 21:40:16 +0000 Subject: Add MPIO HD200 port - new files git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25725 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/coldfire/mpio/app.lds | 145 ++++ firmware/target/coldfire/mpio/ata-as-mpio.S | 757 +++++++++++++++++++++ firmware/target/coldfire/mpio/ata-mpio.c | 57 ++ firmware/target/coldfire/mpio/ata-target.h | 77 +++ firmware/target/coldfire/mpio/audio-mpio.c | 49 ++ firmware/target/coldfire/mpio/boot.lds | 81 +++ firmware/target/coldfire/mpio/boot.lds.flash | 81 +++ firmware/target/coldfire/mpio/boot.lds.iram | 81 +++ firmware/target/coldfire/mpio/button-target.h | 55 ++ firmware/target/coldfire/mpio/fmradio_i2c-mpio.c | 40 ++ firmware/target/coldfire/mpio/hd200/adc-hd200.c | 84 +++ firmware/target/coldfire/mpio/hd200/adc-target.h | 41 ++ .../target/coldfire/mpio/hd200/backlight-hd200.c | 86 +++ .../target/coldfire/mpio/hd200/backlight-target.h | 35 + firmware/target/coldfire/mpio/hd200/button-hd200.c | 123 ++++ firmware/target/coldfire/mpio/hd200/lcd-as-hd200.S | 103 +++ firmware/target/coldfire/mpio/hd200/lcd-hd200.c | 241 +++++++ firmware/target/coldfire/mpio/hd200/power-hd200.c | 113 +++ .../target/coldfire/mpio/hd200/powermgmt-hd200.c | 59 ++ firmware/target/coldfire/mpio/hd200/system-hd200.c | 125 ++++ firmware/target/coldfire/mpio/hd200/usb-hd200.c | 81 +++ firmware/target/coldfire/wmcodec-coldfire.c | 52 ++ 22 files changed, 2566 insertions(+) create mode 100644 firmware/target/coldfire/mpio/app.lds create mode 100644 firmware/target/coldfire/mpio/ata-as-mpio.S create mode 100644 firmware/target/coldfire/mpio/ata-mpio.c create mode 100644 firmware/target/coldfire/mpio/ata-target.h create mode 100644 firmware/target/coldfire/mpio/audio-mpio.c create mode 100644 firmware/target/coldfire/mpio/boot.lds create mode 100644 firmware/target/coldfire/mpio/boot.lds.flash create mode 100644 firmware/target/coldfire/mpio/boot.lds.iram create mode 100644 firmware/target/coldfire/mpio/button-target.h create mode 100644 firmware/target/coldfire/mpio/fmradio_i2c-mpio.c create mode 100644 firmware/target/coldfire/mpio/hd200/adc-hd200.c create mode 100644 firmware/target/coldfire/mpio/hd200/adc-target.h create mode 100644 firmware/target/coldfire/mpio/hd200/backlight-hd200.c create mode 100644 firmware/target/coldfire/mpio/hd200/backlight-target.h create mode 100644 firmware/target/coldfire/mpio/hd200/button-hd200.c create mode 100644 firmware/target/coldfire/mpio/hd200/lcd-as-hd200.S create mode 100644 firmware/target/coldfire/mpio/hd200/lcd-hd200.c create mode 100644 firmware/target/coldfire/mpio/hd200/power-hd200.c create mode 100644 firmware/target/coldfire/mpio/hd200/powermgmt-hd200.c create mode 100644 firmware/target/coldfire/mpio/hd200/system-hd200.c create mode 100644 firmware/target/coldfire/mpio/hd200/usb-hd200.c create mode 100644 firmware/target/coldfire/wmcodec-coldfire.c (limited to 'firmware/target') 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 +#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 +#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 ) \___| < | \_\ ( <_> > < < + * 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 +#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 +#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; +} -- cgit v1.2.3