diff options
-rw-r--r-- | firmware/target/arm/as3525/pcm-as3525.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c index bdd6a4eca1..bddc8b9f5e 100644 --- a/firmware/target/arm/as3525/pcm-as3525.c +++ b/firmware/target/arm/as3525/pcm-as3525.c | |||
@@ -134,20 +134,35 @@ void pcm_postinit(void) | |||
134 | audiohw_postinit(); | 134 | audiohw_postinit(); |
135 | } | 135 | } |
136 | 136 | ||
137 | static unsigned mclk_divider(void) | 137 | /* divider is 9 bits but the highest one (for 8kHz) fit in 8 bits */ |
138 | static const unsigned char divider[SAMPR_NUM_FREQ] = { | ||
139 | [HW_FREQ_96] = ((AS3525_MCLK_FREQ/128 + SAMPR_96/2) / SAMPR_96) - 1, | ||
140 | [HW_FREQ_88] = ((AS3525_MCLK_FREQ/128 + SAMPR_88/2) / SAMPR_88) - 1, | ||
141 | [HW_FREQ_64] = ((AS3525_MCLK_FREQ/128 + SAMPR_64/2) / SAMPR_64) - 1, | ||
142 | [HW_FREQ_48] = ((AS3525_MCLK_FREQ/128 + SAMPR_48/2) / SAMPR_48) - 1, | ||
143 | [HW_FREQ_44] = ((AS3525_MCLK_FREQ/128 + SAMPR_44/2) / SAMPR_44) - 1, | ||
144 | [HW_FREQ_32] = ((AS3525_MCLK_FREQ/128 + SAMPR_32/2) / SAMPR_32) - 1, | ||
145 | [HW_FREQ_24] = ((AS3525_MCLK_FREQ/128 + SAMPR_24/2) / SAMPR_24) - 1, | ||
146 | [HW_FREQ_22] = ((AS3525_MCLK_FREQ/128 + SAMPR_22/2) / SAMPR_22) - 1, | ||
147 | [HW_FREQ_16] = ((AS3525_MCLK_FREQ/128 + SAMPR_16/2) / SAMPR_16) - 1, | ||
148 | [HW_FREQ_12] = ((AS3525_MCLK_FREQ/128 + SAMPR_12/2) / SAMPR_12) - 1, | ||
149 | [HW_FREQ_11] = ((AS3525_MCLK_FREQ/128 + SAMPR_11/2) / SAMPR_11) - 1, | ||
150 | [HW_FREQ_8 ] = ((AS3525_MCLK_FREQ/128 + SAMPR_8 /2) / SAMPR_8 ) - 1, | ||
151 | }; | ||
152 | |||
153 | static inline unsigned char mclk_divider(void) | ||
138 | { | 154 | { |
139 | /* TODO : use a table ? */ | 155 | return divider[pcm_fsel]; |
140 | return (((AS3525_MCLK_FREQ/128) + (pcm_sampr/2)) / pcm_sampr) - 1; | ||
141 | } | 156 | } |
142 | 157 | ||
143 | void pcm_dma_apply_settings(void) | 158 | void pcm_dma_apply_settings(void) |
144 | { | 159 | { |
145 | int cgu_audio = CGU_AUDIO; /* read register */ | 160 | int cgu_audio = CGU_AUDIO; /* read register */ |
146 | cgu_audio &= ~(3 << 0); /* clear i2sout MCLK_SEL */ | 161 | cgu_audio &= ~(3 << 0); /* clear i2sout MCLK_SEL */ |
147 | cgu_audio |= (AS3525_MCLK_SEL << 0); /* set i2sout MCLK_SEL */ | 162 | cgu_audio |= (AS3525_MCLK_SEL << 0); /* set i2sout MCLK_SEL */ |
148 | cgu_audio &= ~(511 << 2); /* clear i2sout divider */ | 163 | cgu_audio &= ~(0x1ff << 2); /* clear i2sout divider */ |
149 | cgu_audio |= mclk_divider() << 2; /* set new i2sout divider */ | 164 | cgu_audio |= mclk_divider() << 2; /* set new i2sout divider */ |
150 | CGU_AUDIO = cgu_audio; /* write back register */ | 165 | CGU_AUDIO = cgu_audio; /* write back register */ |
151 | } | 166 | } |
152 | 167 | ||
153 | size_t pcm_get_bytes_waiting(void) | 168 | size_t pcm_get_bytes_waiting(void) |
@@ -281,12 +296,12 @@ void pcm_rec_dma_close(void) | |||
281 | 296 | ||
282 | void pcm_rec_dma_init(void) | 297 | void pcm_rec_dma_init(void) |
283 | { | 298 | { |
284 | int cgu_audio = CGU_AUDIO; /* read register */ | 299 | int cgu_audio = CGU_AUDIO; /* read register */ |
285 | cgu_audio &= ~(3 << 12); /* clear i2sin MCLK_SEL */ | 300 | cgu_audio &= ~(3 << 12); /* clear i2sin MCLK_SEL */ |
286 | cgu_audio |= (AS3525_MCLK_SEL << 12); /* set i2sin MCLK_SEL */ | 301 | cgu_audio |= (AS3525_MCLK_SEL << 12); /* set i2sin MCLK_SEL */ |
287 | cgu_audio &= ~(511 << 14); /* clear i2sin divider */ | 302 | cgu_audio &= ~(0x1ff << 14); /* clear i2sin divider */ |
288 | cgu_audio |= mclk_divider() << 14; /* set new i2sin divider */ | 303 | cgu_audio |= mclk_divider() << 14; /* set new i2sin divider */ |
289 | CGU_AUDIO = cgu_audio; /* write back register */ | 304 | CGU_AUDIO = cgu_audio; /* write back register */ |
290 | 305 | ||
291 | /* i2c clk src = I2SOUTIF, sdata src = AFE, | 306 | /* i2c clk src = I2SOUTIF, sdata src = AFE, |
292 | * data valid at positive edge of SCLK */ | 307 | * data valid at positive edge of SCLK */ |