1
0
Fork 0
forked from len0rd/rockbox

Add MPIO HD200 port - new files

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25725 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Marcin Bukat 2010-04-26 21:40:16 +00:00
parent b09d3aec39
commit 28d54c6016
29 changed files with 3756 additions and 0 deletions

View file

@ -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 = .;
}
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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 */
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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_ */

View file

@ -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

View file

@ -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);
}

View file

@ -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_ */

View file

@ -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 */
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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 */
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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 */
}
}

View file

@ -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;
}