#include "regs.h"
#include "common.h"
static void delay(int num);
struct {
unsigned int srcadd;
unsigned int dstadd;
unsigned int nnext;
unsigned int ctl0;
unsigned int ctl1;
}lli_next;
static void ac97_control_init(void)
{
GPDCON = 0x44444;
//Reset Codec and Controller Registers
AC_GLBCTRL |= 1;
delay(1);
AC_GLBCTRL &= ~0x1;
//Wake up codec from power down
AC_GLBCTRL |= 1 << 1;
delay(1);
AC_GLBCTRL &= ~(1 << 1);
//SYNC signal transfer to Codec
AC_GLBCTRL |= 1 << 2;
delay(1);
//Transfer data enable using AC-link
AC_GLBCTRL |= 1 << 3;
//READ ENABLE
AC_CODEC_CMD |= 1 << 23;
delay(1);
if((AC_GLBSTAT&0x7) == 0x3){
printf("ac97 controler is active ...\n");
}else{
printf("current state is %#x\n", AC_GLBSTAT&0x7);
}
}
inline static void set_cmmd(int reg, int val)
{
AC_CODEC_CMD = (reg << 16) | (val << 0);
delay(1);
}
inline static void wm9714_init(void)
{
//打开总音源,设置第一级音量
set_cmmd(0x0c, (0xf << 8) | (0xf << 0));
//当没有数字信号输入时DAC停止转换
set_cmmd(0x5c, 1 << 7);
//设置编解码器的抽样频率为44100HZ
set_cmmd(0x2a, (1 << 0));
set_cmmd(0x2c, 0xac44);
//选择耳机,喇叭的左右声道音源
set_cmmd(0x1c, (0x2 << 4) | (0x2 << 6) | (0x3 << 8) | (0x3 << 11));
//设置耳机,喇叭本身的音量为最大
set_cmmd(0x04, 0);
set_cmmd(0x02, 0);
//使能耳机被插入时的检测电路
set_cmmd(0x24, (1 << 4));
set_cmmd(0x5a, (0 << 6));
//打开编解码器各个电路模块的电源,开始工作
set_cmmd(0x26, 0);
set_cmmd(0x3c, 0);
set_cmmd(0x3e, 0);
}
void raise(void)
{
;
}
inline static void dma_init(unsigned long len, unsigned long ddr)
{
lli_next.srcadd = ddr;
lli_next.dstadd = (unsigned int)(&AC_PCMDATA);
lli_next.nnext = (unsigned int)&lli_next;
lli_next.ctl0 = ((1 << 26) | (1 << 25) | (2 << 21) | (2 << 18) | (1 << 15) | (1 << 12));
lli_next.ctl1 = (len + 3) >> 2;
SDMA_SEL |= 1 << 22;
DMACC0SrcAddr = ddr;
DMACC0DestAddr = (unsigned int)(&AC_PCMDATA);
DMACC0LLI = (unsigned int)&lli_next;
DMACC0Control0 = (1 << 26) | (1 << 25) | (2 << 21) | (2 << 18) | (1 << 15) | (1 << 12); //
DMACC0Control1 = (len + 3) >> 2;
DMACC0Configuration = (1 << 11) | (6 << 6) | (1 << 0);
}
inline static music_action(unsigned long len, unsigned long ddr)
{
ac97_control_init();
wm9714_init();
dma_init(len, ddr);
AC_GLBCTRL |= (2 << 12);
DMACConfiguration = 1;
}
inline static unsigned long get_len(void)
{
return *((unsigned long *)(AC97BUFFER + 0x28));
}
void play_music(void)
{
music_action(get_len(), AC97BUFFER);
}
static void delay(int num)
{
int i,j;
for(i = 0; i < num; i++){
for(j = 0; j < 10000; j++){
;
}
}
}