diff options
author | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2009-05-26 22:57:49 +0000 |
---|---|---|
committer | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2009-05-26 22:57:49 +0000 |
commit | a0458dac2b14d4ec50dc2d65d26005a58b6a5581 (patch) | |
tree | c4dde20b8140e5c49e31af75b0d8226de2520aa3 | |
parent | 83eb479732879e9852064644942ca36a7fd986a9 (diff) | |
download | rockbox-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
-rw-r--r-- | firmware/export/config-ondavx747.h | 6 | ||||
-rw-r--r-- | firmware/export/jz4740-codec.h | 4 | ||||
-rw-r--r-- | firmware/export/jz4740.h | 2 | ||||
-rw-r--r-- | firmware/sound.c | 2 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/codec-jz4740.c | 93 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c | 115 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/system-target.h | 4 |
7 files changed, 114 insertions, 112 deletions
diff --git a/firmware/export/config-ondavx747.h b/firmware/export/config-ondavx747.h index 176a35f4e9..b603e02c2b 100644 --- a/firmware/export/config-ondavx747.h +++ b/firmware/export/config-ondavx747.h | |||
@@ -122,6 +122,9 @@ | |||
122 | /* Define this if you have the Jz4740 internal codec */ | 122 | /* Define this if you have the Jz4740 internal codec */ |
123 | #define HAVE_JZ4740_CODEC | 123 | #define HAVE_JZ4740_CODEC |
124 | 124 | ||
125 | /* has no tone controls, so we use the software ones */ | ||
126 | #define HAVE_SW_TONE_CONTROLS | ||
127 | |||
125 | /* define the bitmask of hardware sample rates */ | 128 | /* define the bitmask of hardware sample rates */ |
126 | #define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \ | 129 | #define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \ |
127 | SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \ | 130 | SAMPR_CAP_24 | SAMPR_CAP_22 | SAMPR_CAP_16 | \ |
@@ -131,9 +134,6 @@ | |||
131 | 134 | ||
132 | #define NEED_ADC_CLOSE 1 | 135 | #define NEED_ADC_CLOSE 1 |
133 | 136 | ||
134 | /* has no tone controls, so we use the software ones */ | ||
135 | //#define HAVE_SW_TONE_CONTROLS | ||
136 | |||
137 | #define BATTERY_CAPACITY_DEFAULT 1250 /* default battery capacity */ | 137 | #define BATTERY_CAPACITY_DEFAULT 1250 /* default battery capacity */ |
138 | #define BATTERY_CAPACITY_MIN 500 /* min. capacity selectable */ | 138 | #define BATTERY_CAPACITY_MIN 500 /* min. capacity selectable */ |
139 | #define BATTERY_CAPACITY_MAX 2500 /* max. capacity selectable */ | 139 | #define BATTERY_CAPACITY_MAX 2500 /* max. capacity selectable */ |
diff --git a/firmware/export/jz4740-codec.h b/firmware/export/jz4740-codec.h index e8751b5141..c98bfba602 100644 --- a/firmware/export/jz4740-codec.h +++ b/firmware/export/jz4740-codec.h | |||
@@ -21,11 +21,7 @@ | |||
21 | #ifndef __JZ4740_CODEC_H_ | 21 | #ifndef __JZ4740_CODEC_H_ |
22 | #define __JZ4740_CODEC_H_ | 22 | #define __JZ4740_CODEC_H_ |
23 | 23 | ||
24 | /* TODO */ | ||
25 | #define VOLUME_MIN -730 | 24 | #define VOLUME_MIN -730 |
26 | #define VOLUME_MAX 60 | 25 | #define VOLUME_MAX 60 |
27 | 26 | ||
28 | int tenthdb2master(int db); | ||
29 | void audiohw_set_headphone_vol(int vol_l, int vol_r); | ||
30 | |||
31 | #endif /* __JZ4740_CODEC_H_ */ | 27 | #endif /* __JZ4740_CODEC_H_ */ |
diff --git a/firmware/export/jz4740.h b/firmware/export/jz4740.h index 7ddec364a6..3bf34bd342 100644 --- a/firmware/export/jz4740.h +++ b/firmware/export/jz4740.h | |||
@@ -1310,8 +1310,6 @@ | |||
1310 | #define ICDC_CDCCR2_MICBG(n) ((n & 0x3) << 4) | 1310 | #define ICDC_CDCCR2_MICBG(n) ((n & 0x3) << 4) |
1311 | #define ICDC_CDCCR2_HPVOL(n) ((n & 0x3) << 0) | 1311 | #define ICDC_CDCCR2_HPVOL(n) ((n & 0x3) << 0) |
1312 | 1312 | ||
1313 | #define ICDC_CDCCR2_AINVOL_DB(n) ((n+34.5)/1.5) | ||
1314 | |||
1315 | #define ICDC_CDCCR2_SMPR_8 (0) | 1313 | #define ICDC_CDCCR2_SMPR_8 (0) |
1316 | #define ICDC_CDCCR2_SMPR_11 (1) | 1314 | #define ICDC_CDCCR2_SMPR_11 (1) |
1317 | #define ICDC_CDCCR2_SMPR_12 (2) | 1315 | #define ICDC_CDCCR2_SMPR_12 (2) |
diff --git a/firmware/sound.c b/firmware/sound.c index 0e16c5a3a9..bca98b039c 100644 --- a/firmware/sound.c +++ b/firmware/sound.c | |||
@@ -264,6 +264,8 @@ static void set_prescaled_volume(void) | |||
264 | 264 | ||
265 | #elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985) | 265 | #elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985) |
266 | audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r)); | 266 | audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r)); |
267 | #elif defined(HAVE_JZ4740_CODEC) | ||
268 | audiohw_set_volume(current_volume); | ||
267 | #endif | 269 | #endif |
268 | } | 270 | } |
269 | #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */ | 271 | #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */ |
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 @@ | |||
26 | 26 | ||
27 | /* TODO */ | 27 | /* TODO */ |
28 | const struct sound_settings_info audiohw_settings[] = { | 28 | const struct sound_settings_info audiohw_settings[] = { |
29 | [SOUND_VOLUME] = {"dB", 0, 1, -73, 6, -20}, | 29 | [SOUND_VOLUME] = {"dB", 0, 2, 0, 6, 0}, |
30 | /* HAVE_SW_TONE_CONTROLS */ | 30 | /* HAVE_SW_TONE_CONTROLS */ |
31 | [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, | 31 | [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, |
32 | [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, | 32 | [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, |
@@ -62,40 +62,39 @@ static void i2s_codec_init(void) | |||
62 | { | 62 | { |
63 | __cpm_start_aic1(); | 63 | __cpm_start_aic1(); |
64 | __cpm_start_aic2(); | 64 | __cpm_start_aic2(); |
65 | 65 | ||
66 | __aic_enable(); | 66 | __aic_enable(); |
67 | 67 | ||
68 | __i2s_internal_codec(); | 68 | __i2s_internal_codec(); |
69 | __i2s_as_slave(); | 69 | __i2s_as_slave(); |
70 | __i2s_select_i2s(); | 70 | __i2s_select_i2s(); |
71 | __aic_select_i2s(); | 71 | __aic_select_i2s(); |
72 | 72 | ||
73 | __aic_disable_byteswap(); | 73 | __aic_disable_byteswap(); |
74 | __aic_disable_unsignadj(); | 74 | __aic_disable_unsignadj(); |
75 | __aic_disable_mono2stereo(); | 75 | __aic_disable_mono2stereo(); |
76 | 76 | ||
77 | i2s_codec_reset(); | 77 | i2s_codec_reset(); |
78 | 78 | ||
79 | //REG_ICDC_CDCCR2 = (ICDC_CDCCR2_AINVOL(ICDC_CDCCR2_AINVOL_DB(0)) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48) | 79 | REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST); |
80 | |||
80 | REG_ICDC_CDCCR2 = ( ICDC_CDCCR2_AINVOL(14) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_44) | 81 | REG_ICDC_CDCCR2 = ( ICDC_CDCCR2_AINVOL(14) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_44) |
81 | | ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_0)); | 82 | | ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_0)); |
82 | |||
83 | REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_SUSPD | ICDC_CDCCR1_RST); | ||
84 | 83 | ||
85 | mdelay(15); | 84 | mdelay(15); |
86 | REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_PDVR | ICDC_CDCCR1_VRCGL | ICDC_CDCCR1_VRCGH); | 85 | REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_PDVR | ICDC_CDCCR1_VRCGL | ICDC_CDCCR1_VRCGH); |
87 | REG_ICDC_CDCCR1 |= (ICDC_CDCCR1_EDAC | ICDC_CDCCR1_HPCG); | 86 | REG_ICDC_CDCCR1 |= (ICDC_CDCCR1_EDAC | ICDC_CDCCR1_HPCG); |
88 | 87 | ||
89 | mdelay(600); | 88 | mdelay(600); |
90 | REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_HPCG | ICDC_CDCCR1_PDHPM | ICDC_CDCCR1_PDHP); | 89 | REG_ICDC_CDCCR1 &= ~(ICDC_CDCCR1_PDVRA | ICDC_CDCCR1_HPCG | ICDC_CDCCR1_PDHPM | ICDC_CDCCR1_PDHP); |
91 | 90 | ||
92 | mdelay(2); | 91 | mdelay(2); |
93 | 92 | ||
94 | /* CDCCR1.ELININ=0, CDCCR1.EMIC=0, CDCCR1.EADC=0, CDCCR1.SW1ON=0, CDCCR1.EDAC=1, CDCCR1.SW2ON=1, CDCCR1.HPMUTE=0 */ | 93 | /* CDCCR1.ELININ=0, CDCCR1.EMIC=0, CDCCR1.EADC=0, CDCCR1.SW1ON=0, CDCCR1.EDAC=1, CDCCR1.SW2ON=1, CDCCR1.HPMUTE=0 */ |
95 | REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_ELININ | ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EADC | | 94 | REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_ELININ | ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EADC | |
96 | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_HPMUTE)) | (ICDC_CDCCR1_EDAC | 95 | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_HPMUTE)) | (ICDC_CDCCR1_EDAC |
97 | | ICDC_CDCCR1_SW2ON); | 96 | | ICDC_CDCCR1_SW2ON); |
98 | 97 | ||
99 | HP_on_off_flag = 1; /* HP is on */ | 98 | HP_on_off_flag = 1; /* HP is on */ |
100 | } | 99 | } |
101 | 100 | ||
@@ -111,7 +110,7 @@ static void i2s_codec_set_mic(unsigned short v) /* 0 <= v <= 100 */ | |||
111 | REG_ICDC_CDCCR2 = ((REG_ICDC_CDCCR2 & ~(0x1f << 16)) | (codec_mic_gain << 16)); | 110 | REG_ICDC_CDCCR2 = ((REG_ICDC_CDCCR2 & ~(0x1f << 16)) | (codec_mic_gain << 16)); |
112 | } | 111 | } |
113 | 112 | ||
114 | static void i2s_codec_set_bass(unsigned short v) /* 0 <= v <= 100 */ | 113 | static void i2s_codec_set_base(unsigned short v) /* 0 <= v <= 100 */ |
115 | { | 114 | { |
116 | v &= 0xff; | 115 | v &= 0xff; |
117 | 116 | ||
@@ -200,6 +199,7 @@ static unsigned short i2s_codec_get_volume(void) | |||
200 | return val; | 199 | return val; |
201 | } | 200 | } |
202 | 201 | ||
202 | static unsigned long HP_register_value; | ||
203 | static void HP_turn_on(void) | 203 | static void HP_turn_on(void) |
204 | { | 204 | { |
205 | //see 1.3.4.1 | 205 | //see 1.3.4.1 |
@@ -261,11 +261,41 @@ static void HP_turn_off(void) | |||
261 | } | 261 | } |
262 | #endif | 262 | #endif |
263 | 263 | ||
264 | static void i2s_codec_set_samplerate(unsigned int rate) | 264 | void audiohw_mute(bool mute) |
265 | { | ||
266 | if(mute) | ||
267 | REG_ICDC_CDCCR1 |= ICDC_CDCCR1_HPMUTE; | ||
268 | else | ||
269 | REG_ICDC_CDCCR1 &= ~ICDC_CDCCR1_HPMUTE; | ||
270 | } | ||
271 | |||
272 | void audiohw_preinit(void) | ||
273 | { | ||
274 | } | ||
275 | |||
276 | void audiohw_postinit(void) | ||
277 | { | ||
278 | audiohw_mute(false); | ||
279 | //HP_turn_on(); | ||
280 | } | ||
281 | |||
282 | void audiohw_init(void) | ||
283 | { | ||
284 | i2s_codec_init(); | ||
285 | } | ||
286 | |||
287 | void audiohw_set_volume(int v) | ||
288 | { | ||
289 | /* 0 <= v <= 60 */ | ||
290 | unsigned int codec_volume = v / 20; | ||
291 | REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_HPVOL(0x3)) | ICDC_CDCCR2_HPVOL(codec_volume); | ||
292 | } | ||
293 | |||
294 | void audiohw_set_frequency(int freq) | ||
265 | { | 295 | { |
266 | unsigned int speed; | 296 | unsigned int speed; |
267 | 297 | ||
268 | switch (rate) | 298 | switch(freq) |
269 | { | 299 | { |
270 | case 8000: | 300 | case 8000: |
271 | speed = ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_8); | 301 | speed = ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_8); |
@@ -297,33 +327,6 @@ static void i2s_codec_set_samplerate(unsigned int rate) | |||
297 | default: | 327 | default: |
298 | return; | 328 | return; |
299 | } | 329 | } |
300 | REG_ICDC_CDCCR2 &= ~ICDC_CDCCR2_SMPR(0xF); | ||
301 | REG_ICDC_CDCCR2 |= speed; | ||
302 | } | ||
303 | 330 | ||
304 | void audiohw_mute(bool mute) | 331 | REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_SMPR(0xF)) | speed; |
305 | { | ||
306 | if(mute) | ||
307 | REG_ICDC_CDCCR1 |= ICDC_CDCCR1_HPMUTE; | ||
308 | else | ||
309 | REG_ICDC_CDCCR1 &= ~ICDC_CDCCR1_HPMUTE; | ||
310 | } | ||
311 | |||
312 | void audiohw_preinit(void) | ||
313 | { | ||
314 | } | ||
315 | |||
316 | void audiohw_postinit(void) | ||
317 | { | ||
318 | audiohw_mute(false); | ||
319 | } | ||
320 | |||
321 | void audiohw_init(void) | ||
322 | { | ||
323 | i2s_codec_init(); | ||
324 | } | ||
325 | |||
326 | void audiohw_set_frequency(int freq) | ||
327 | { | ||
328 | i2s_codec_set_samplerate(freq); | ||
329 | } | 332 | } |
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; | |||
37 | void pcm_postinit(void) | 37 | void pcm_postinit(void) |
38 | { | 38 | { |
39 | audiohw_postinit(); | 39 | audiohw_postinit(); |
40 | 40 | ||
41 | /* playback sample: 16 bits burst: 16 bytes */ | 41 | /* playback sample: 16 bits burst: 16 bytes */ |
42 | __i2s_set_iss_sample_size(16); | 42 | __i2s_set_iss_sample_size(16); |
43 | __i2s_set_oss_sample_size(16); | 43 | __i2s_set_oss_sample_size(16); |
44 | __i2s_set_transmit_trigger(16 - 4); | 44 | __i2s_set_transmit_trigger(10); |
45 | __i2s_set_receive_trigger(4); | 45 | __i2s_set_receive_trigger(1); |
46 | |||
47 | /* Flush FIFO */ | ||
48 | __aic_flush_fifo(); | ||
46 | } | 49 | } |
47 | 50 | ||
48 | void pcm_play_dma_init(void) | 51 | void pcm_play_dma_init(void) |
@@ -50,7 +53,7 @@ void pcm_play_dma_init(void) | |||
50 | /* TODO */ | 53 | /* TODO */ |
51 | 54 | ||
52 | system_enable_irq(DMA_IRQ(DMA_AIC_TX_CHANNEL)); | 55 | system_enable_irq(DMA_IRQ(DMA_AIC_TX_CHANNEL)); |
53 | 56 | ||
54 | /* Initialize default register values. */ | 57 | /* Initialize default register values. */ |
55 | audiohw_init(); | 58 | audiohw_init(); |
56 | } | 59 | } |
@@ -63,30 +66,39 @@ void pcm_dma_apply_settings(void) | |||
63 | 66 | ||
64 | static void play_start_pcm(void) | 67 | static void play_start_pcm(void) |
65 | { | 68 | { |
66 | /* Prefill FIFO */ | 69 | __aic_enable_transmit_dma(); |
67 | REG_AIC_DR = 0; | 70 | __aic_enable_replay(); |
68 | REG_AIC_DR = 0; | 71 | |
69 | REG_AIC_DR = 0; | ||
70 | REG_AIC_DR = 0; | ||
71 | |||
72 | __i2s_enable_transmit_dma(); | ||
73 | __i2s_enable_replay(); | ||
74 | |||
75 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN; | 72 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN; |
76 | REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) |= DMAC_DCMD_TIE; | 73 | |
77 | |||
78 | playback_started = true; | 74 | playback_started = true; |
79 | } | 75 | } |
80 | 76 | ||
77 | static inline void set_dma(const void *addr, size_t size) | ||
78 | { | ||
79 | logf("%x %x %d %d %x", (unsigned int)addr, size, (REG_AIC_SR>>24) & 0x20, (REG_AIC_SR>>8) & 0x20, REG_AIC_SR & 0xF); | ||
80 | |||
81 | //__dcache_writeback_all(); | ||
82 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = DMAC_DCCSR_NDES; | ||
83 | REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)addr); | ||
84 | REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR); | ||
85 | REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) = size / 16; | ||
86 | REG_DMAC_DRSR(DMA_AIC_TX_CHANNEL) = DMAC_DRSR_RS_AICOUT; | ||
87 | 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 | | ||
88 | DMAC_DCMD_RDIL_IGN); | ||
89 | |||
90 | playback_address = (void*)addr; | ||
91 | } | ||
92 | |||
81 | static void play_stop_pcm(void) | 93 | static void play_stop_pcm(void) |
82 | { | 94 | { |
83 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) | DMAC_DCCSR_HLT) & ~DMAC_DCCSR_EN; | 95 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) | DMAC_DCCSR_HLT) & ~DMAC_DCCSR_EN; |
84 | 96 | ||
85 | dma_disable(); | 97 | dma_disable(); |
86 | 98 | ||
87 | __i2s_disable_transmit_dma(); | 99 | __aic_disable_transmit_dma(); |
88 | __i2s_disable_replay(); | 100 | __aic_disable_replay(); |
89 | 101 | ||
90 | playback_started = false; | 102 | playback_started = false; |
91 | } | 103 | } |
92 | 104 | ||
@@ -94,56 +106,47 @@ void pcm_play_dma_start(const void *addr, size_t size) | |||
94 | { | 106 | { |
95 | dma_enable(); | 107 | dma_enable(); |
96 | 108 | ||
97 | __dcache_writeback_all(); | 109 | set_dma(addr, size); |
98 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = DMAC_DCCSR_NDES; | ||
99 | REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)addr); | ||
100 | REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR); | ||
101 | REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) = size; | ||
102 | REG_DMAC_DRSR(DMA_AIC_TX_CHANNEL) = DMAC_DRSR_RS_AICOUT; | ||
103 | REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) = (DMAC_DCMD_SAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DWDH_16); | ||
104 | |||
105 | playback_address = (void*)addr; | ||
106 | play_start_pcm(); | 110 | play_start_pcm(); |
107 | } | 111 | } |
108 | 112 | ||
109 | 113 | ||
110 | static void play_dma_callback(void) | 114 | static inline void play_dma_callback(void) |
111 | { | 115 | { |
112 | unsigned char *start; | 116 | unsigned char *start; |
113 | size_t size = 0; | 117 | size_t size = 0; |
114 | |||
115 | pcm_callback_for_more(&start, &size); | 118 | pcm_callback_for_more(&start, &size); |
116 | if(size != 0) | 119 | |
120 | if(LIKELY(size > 0)) | ||
117 | { | 121 | { |
118 | __dcache_writeback_all(); | 122 | set_dma(start, size); |
119 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) = DMAC_DCCSR_NDES; | ||
120 | REG_DMAC_DSAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)start); | ||
121 | REG_DMAC_DTAR(DMA_AIC_TX_CHANNEL) = PHYSADDR((unsigned long)AIC_DR); | ||
122 | REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) = size; | ||
123 | REG_DMAC_DRSR(DMA_AIC_TX_CHANNEL) = DMAC_DRSR_RS_AICOUT; | ||
124 | REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) = (DMAC_DCMD_SAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DWDH_16); | ||
125 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN; | 123 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN; |
126 | REG_DMAC_DCMD(DMA_AIC_TX_CHANNEL) |= DMAC_DCMD_TIE; | ||
127 | return; | ||
128 | } | 124 | } |
129 | 125 | else | |
130 | /* Error, callback missing or no more DMA to do */ | 126 | { |
131 | pcm_play_dma_stop(); | 127 | /* Error, callback missing or no more DMA to do */ |
132 | pcm_play_dma_stopped_callback(); | 128 | pcm_play_dma_stop(); |
129 | pcm_play_dma_stopped_callback(); | ||
130 | } | ||
133 | } | 131 | } |
134 | 132 | ||
135 | void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void) | 133 | void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void) |
136 | { | 134 | { |
137 | if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_AR) | 135 | if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_AR) |
136 | { | ||
137 | logf("PCM DMA address error"); | ||
138 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_AR; | 138 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_AR; |
139 | } | ||
139 | 140 | ||
140 | if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_CT) | 141 | if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_HLT) |
141 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_CT; | 142 | { |
143 | logf("PCM DMA halt"); | ||
144 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_HLT; | ||
145 | } | ||
142 | 146 | ||
143 | if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & (DMAC_DCCSR_TT | DMAC_DCCSR_HLT)) | 147 | if (REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) & DMAC_DCCSR_TT) |
144 | { | 148 | { |
145 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~(DMAC_DCCSR_TT | DMAC_DCCSR_HLT); | 149 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_TT; |
146 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_EN; | ||
147 | play_dma_callback(); | 150 | play_dma_callback(); |
148 | } | 151 | } |
149 | } | 152 | } |
@@ -151,7 +154,7 @@ void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void) | |||
151 | size_t pcm_get_bytes_waiting(void) | 154 | size_t pcm_get_bytes_waiting(void) |
152 | { | 155 | { |
153 | if(playback_started) | 156 | if(playback_started) |
154 | return REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) & ~3; | 157 | return (REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) * 16) & ~3; |
155 | else | 158 | else |
156 | return 0; | 159 | return 0; |
157 | } | 160 | } |
@@ -161,8 +164,8 @@ const void * pcm_play_dma_get_peak_buffer(int *count) | |||
161 | /* TODO */ | 164 | /* TODO */ |
162 | if(playback_started) | 165 | if(playback_started) |
163 | { | 166 | { |
164 | *count = REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL); | 167 | *count = REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) >> 2; |
165 | return (void*)(playback_address + ((REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL) + 2) & ~3)); | 168 | return (void*)(playback_address + ((REG_DMAC_DTCR(DMA_AIC_TX_CHANNEL)*16 + 2) & ~3)); |
166 | } | 169 | } |
167 | else | 170 | else |
168 | { | 171 | { |
@@ -174,7 +177,7 @@ const void * pcm_play_dma_get_peak_buffer(int *count) | |||
174 | void pcm_play_dma_stop(void) | 177 | void pcm_play_dma_stop(void) |
175 | { | 178 | { |
176 | play_stop_pcm(); | 179 | play_stop_pcm(); |
177 | 180 | ||
178 | /* TODO */ | 181 | /* TODO */ |
179 | } | 182 | } |
180 | 183 | ||
@@ -191,9 +194,9 @@ void pcm_play_unlock(void) | |||
191 | void pcm_play_dma_pause(bool pause) | 194 | void pcm_play_dma_pause(bool pause) |
192 | { | 195 | { |
193 | if(pause) | 196 | if(pause) |
194 | play_stop_pcm(); | 197 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) &= ~DMAC_DCCSR_EN; |
195 | else | 198 | else |
196 | play_start_pcm(); | 199 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN; |
197 | } | 200 | } |
198 | 201 | ||
199 | void audiohw_close(void) | 202 | 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); | |||
86 | void dma_enable(void); | 86 | void dma_enable(void); |
87 | void dma_disable(void); | 87 | void dma_disable(void); |
88 | 88 | ||
89 | #define DMA_LCD_CHANNEL 0 | 89 | #define DMA_AIC_TX_CHANNEL 0 |
90 | #define DMA_NAND_CHANNEL 1 | 90 | #define DMA_NAND_CHANNEL 1 |
91 | #define DMA_USB_CHANNEL 2 | 91 | #define DMA_USB_CHANNEL 2 |
92 | #define DMA_AIC_TX_CHANNEL 3 | 92 | #define DMA_LCD_CHANNEL 3 |
93 | 93 | ||
94 | #define XDMA_CALLBACK(n) DMA ## n | 94 | #define XDMA_CALLBACK(n) DMA ## n |
95 | #define DMA_CALLBACK(n) XDMA_CALLBACK(n) | 95 | #define DMA_CALLBACK(n) XDMA_CALLBACK(n) |