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 /firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c | |
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
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c')
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c | 115 |
1 files changed, 59 insertions, 56 deletions
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) |