summaryrefslogtreecommitdiffstats
path: root/firmware/target/mips
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2009-05-26 22:57:49 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2009-05-26 22:57:49 +0000
commita0458dac2b14d4ec50dc2d65d26005a58b6a5581 (patch)
treec4dde20b8140e5c49e31af75b0d8226de2520aa3 /firmware/target/mips
parent83eb479732879e9852064644942ca36a7fd986a9 (diff)
downloadrockbox-a0458dac2b14d4ec50dc2d65d26005a58b6a5581.tar.gz
rockbox-a0458dac2b14d4ec50dc2d65d26005a58b6a5581.zip
Fix audio on Onda VX747
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21097 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/mips')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/codec-jz4740.c93
-rw-r--r--firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c115
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-target.h4
3 files changed, 109 insertions, 103 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
index 44d291f312..6a0b6ae340 100644
--- a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c
@@ -26,7 +26,7 @@
/* TODO */
const struct sound_settings_info audiohw_settings[] = {
- [SOUND_VOLUME] = {"dB", 0, 1, -73, 6, -20},
+ [SOUND_VOLUME] = {"dB", 0, 2, 0, 6, 0},
/* HAVE_SW_TONE_CONTROLS */
[SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
[SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
@@ -62,40 +62,39 @@ static void i2s_codec_init(void)
{
__cpm_start_aic1();
__cpm_start_aic2();
-
+
__aic_enable();
-
+
__i2s_internal_codec();
__i2s_as_slave();
__i2s_select_i2s();
__aic_select_i2s();
-
+
__aic_disable_byteswap();
__aic_disable_unsignadj();
__aic_disable_mono2stereo();
-
+
i2s_codec_reset();
-
- //REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(ICDC_CDCCR2_AINVOL_DB(0)) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48)
+
+ REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST);
+
REG_ICDC_CDCCR2 = ( ICDC_CDCCR2_AINVOL(14) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_44)
| ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_0));
-
- REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST);
mdelay(15);
REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_PDVR | ICDC_CDCCR1_VRCGL | ICDC_CDCCR1_VRCGH);
REG_ICDC_CDCCR1 |= (ICDC_CDCCR1_EDAC | ICDC_CDCCR1_HPCG);
-
+
mdelay(600);
REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_HPCG | ICDC_CDCCR1_PDHPM | ICDC_CDCCR1_PDHP);
-
+
mdelay(2);
-
+
/* CDCCR1.ELININ=0, CDCCR1.EMIC=0, CDCCR1.EADC=0, CDCCR1.SW1ON=0, CDCCR1.EDAC=1, CDCCR1.SW2ON=1, CDCCR1.HPMUTE=0 */
REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_ELININ | ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EADC |
ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_HPMUTE)) | (ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_SW2ON);
-
+
HP_on_off_flag = 1; /* HP is on */
}
@@ -111,7 +110,7 @@ static void i2s_codec_set_mic(unsigned short v) /* 0 <= v <= 100 */
REG_ICDC_CDCCR2 = ((REG_ICDC_CDCCR2 & ~(0x1f << 16)) | (codec_mic_gain << 16));
}
-static void i2s_codec_set_bass(unsigned short v) /* 0 <= v <= 100 */
+static void i2s_codec_set_base(unsigned short v) /* 0 <= v <= 100 */
{
v &= 0xff;
@@ -200,6 +199,7 @@ static unsigned short i2s_codec_get_volume(void)
return val;
}
+static unsigned long HP_register_value;
static void HP_turn_on(void)
{
//see 1.3.4.1
@@ -261,11 +261,41 @@ static void HP_turn_off(void)
}
#endif
-static void i2s_codec_set_samplerate(unsigned int rate)
+void audiohw_mute(bool mute)
+{
+ if(mute)
+ REG_ICDC_CDCCR1 |= ICDC_CDCCR1_HPMUTE;
+ else
+ REG_ICDC_CDCCR1 &= ~ICDC_CDCCR1_HPMUTE;
+}
+
+void audiohw_preinit(void)
+{
+}
+
+void audiohw_postinit(void)
+{
+ audiohw_mute(false);
+ //HP_turn_on();
+}
+
+void audiohw_init(void)
+{
+ i2s_codec_init();
+}
+
+void audiohw_set_volume(int v)
+{
+ /* 0 <= v <= 60 */
+ unsigned int codec_volume = v / 20;
+ REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_HPVOL(0x3)) | ICDC_CDCCR2_HPVOL(codec_volume);
+}
+
+void audiohw_set_frequency(int freq)
{
unsigned int speed;
-
- switch (rate)
+
+ switch(freq)
{
case 8000:
speed = ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_8);
@@ -297,33 +327,6 @@ static void i2s_codec_set_samplerate(unsigned int rate)
default:
return;
}
- REG_ICDC_CDCCR2 &= ~ICDC_CDCCR2_SMPR(0xF);
- REG_ICDC_CDCCR2 |= speed;
-}
-void audiohw_mute(bool mute)
-{
- if(mute)
- REG_ICDC_CDCCR1 |= ICDC_CDCCR1_HPMUTE;
- else
- REG_ICDC_CDCCR1 &= ~ICDC_CDCCR1_HPMUTE;
-}
-
-void audiohw_preinit(void)
-{
-}
-
-void audiohw_postinit(void)
-{
- audiohw_mute(false);
-}
-
-void audiohw_init(void)
-{
- i2s_codec_init();
-}
-
-void audiohw_set_frequency(int freq)
-{
- i2s_codec_set_samplerate(freq);
+ REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_SMPR(0xF)) | speed;
}
diff --git a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
index 11a5e6d8c0..05c89be158 100644
--- a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c
@@ -37,12 +37,15 @@ static void* playback_address;
void pcm_postinit(void)
{
audiohw_postinit();
-
+
/* playback sample: 16 bits burst: 16 bytes */
__i2s_set_iss_sample_size(16);
__i2s_set_oss_sample_size(16);
- __i2s_set_transmit_trigger(16 - 4);
- __i2s_set_receive_trigger(4);
+ __i2s_set_transmit_trigger(10);
+ __i2s_set_receive_trigger(1);
+
+ /* Flush FIFO */
+ __aic_flush_fifo();
}
void pcm_play_dma_init(void)
@@ -50,7 +53,7 @@ void pcm_play_dma_init(void)
/* TODO */
system_enable_irq(DMA_IRQ(DMA_AIC_TX_CHANNEL));
-
+
/* Initialize default register values. */
audiohw_init();
}
@@ -63,30 +66,39 @@ void pcm_dma_apply_settings(void)
static void play_start_pcm(void)
{
- /* Prefill FIFO */
- REG_AIC_DR = 0;
- REG_AIC_DR = 0;
- REG_AIC_DR = 0;
- REG_AIC_DR = 0;
-
- __i2s_enable_transmit_dma();
- __i2s_enable_replay();
-
+ __aic_enable_transmit_dma();
+ __aic_enable_replay();
+
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN;
- REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) |= DMAC_DCMD_TIE;
-
+
playback_started = true;
}
+static inline void set_dma(const void *addr, size_t size)
+{
+ logf("%x %x %d %d %x", (unsigned int)addr, size, (REG_AIC_SR>>24) & 0x20, (REG_AIC_SR>>8) & 0x20, REG_AIC_SR & 0xF);
+
+ //__dcache_writeback_all();
+ REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = DMAC_DCCSR_NDES;
+ REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)addr);
+ REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR);
+ REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) = size / 16;
+ REG_DMAC_DRSR(DMA_AIC_TX_CHANNEL) = DMAC_DRSR_RS_AICOUT;
+ REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) = (DMAC_DCMD_SAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DWDH_16 | DMAC_DCMD_TIE |
+ DMAC_DCMD_RDIL_IGN);
+
+ playback_address = (void*)addr;
+}
+
static void play_stop_pcm(void)
{
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) | DMAC_DCCSR_HLT) & ~DMAC_DCCSR_EN;
-
+
dma_disable();
-
- __i2s_disable_transmit_dma();
- __i2s_disable_replay();
-
+
+ __aic_disable_transmit_dma();
+ __aic_disable_replay();
+
playback_started = false;
}
@@ -94,56 +106,47 @@ void pcm_play_dma_start(const void *addr, size_t size)
{
dma_enable();
- __dcache_writeback_all();
- REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = DMAC_DCCSR_NDES;
- REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)addr);
- REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR);
- REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) = size;
- REG_DMAC_DRSR(DMA_AIC_TX_CHANNEL) = DMAC_DRSR_RS_AICOUT;
- REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) = (DMAC_DCMD_SAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DWDH_16);
-
- playback_address = (void*)addr;
+ set_dma(addr, size);
play_start_pcm();
}
-static void play_dma_callback(void)
+static inline void play_dma_callback(void)
{
unsigned char *start;
size_t size = 0;
-
pcm_callback_for_more(&start, &size);
- if(size != 0)
+
+ if(LIKELY(size > 0))
{
- __dcache_writeback_all();
- REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = DMAC_DCCSR_NDES;
- REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)start);
- REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR);
- REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) = size;
- REG_DMAC_DRSR(DMA_AIC_TX_CHANNEL) = DMAC_DRSR_RS_AICOUT;
- REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) = (DMAC_DCMD_SAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DWDH_16);
+ set_dma(start, size);
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN;
- REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) |= DMAC_DCMD_TIE;
- return;
}
-
- /* Error, callback missing or no more DMA to do */
- pcm_play_dma_stop();
- pcm_play_dma_stopped_callback();
+ else
+ {
+ /* Error, callback missing or no more DMA to do */
+ pcm_play_dma_stop();
+ pcm_play_dma_stopped_callback();
+ }
}
void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void)
{
if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_AR)
+ {
+ logf("PCM DMA address error");
REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_AR;
+ }
- if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_CT)
- REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_CT;
+ if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_HLT)
+ {
+ logf("PCM DMA halt");
+ REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_HLT;
+ }
- if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & (DMAC_DCCSR_TT | DMAC_DCCSR_HLT))
+ if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_TT)
{
- REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~(DMAC_DCCSR_TT | DMAC_DCCSR_HLT);
- REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_EN;
+ REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_TT;
play_dma_callback();
}
}
@@ -151,7 +154,7 @@ void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void)
size_t pcm_get_bytes_waiting(void)
{
if(playback_started)
- return REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) & ~3;
+ return (REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) * 16) & ~3;
else
return 0;
}
@@ -161,8 +164,8 @@ const void * pcm_play_dma_get_peak_buffer(int *count)
/* TODO */
if(playback_started)
{
- *count = REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL);
- return (void*)(playback_address + ((REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) + 2) & ~3));
+ *count = REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) >> 2;
+ return (void*)(playback_address + ((REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL)*16 + 2) & ~3));
}
else
{
@@ -174,7 +177,7 @@ const void * pcm_play_dma_get_peak_buffer(int *count)
void pcm_play_dma_stop(void)
{
play_stop_pcm();
-
+
/* TODO */
}
@@ -191,9 +194,9 @@ void pcm_play_unlock(void)
void pcm_play_dma_pause(bool pause)
{
if(pause)
- play_stop_pcm();
+ REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_EN;
else
- play_start_pcm();
+ REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN;
}
void audiohw_close(void)
diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h
index 08c3aeddb6..b2d960ef54 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/system-target.h
@@ -86,10 +86,10 @@ void mdelay(unsigned int msec);
void dma_enable(void);
void dma_disable(void);
-#define DMA_LCD_CHANNEL 0
+#define DMA_AIC_TX_CHANNEL 0
#define DMA_NAND_CHANNEL 1
#define DMA_USB_CHANNEL 2
-#define DMA_AIC_TX_CHANNEL 3
+#define DMA_LCD_CHANNEL 3
#define XDMA_CALLBACK(n) DMA ## n
#define DMA_CALLBACK(n) XDMA_CALLBACK(n)