diff options
-rw-r--r-- | firmware/drivers/audio/wm8758.c | 246 | ||||
-rw-r--r-- | firmware/export/wm8758.h | 304 | ||||
-rw-r--r-- | firmware/sound.c | 4 | ||||
-rw-r--r-- | firmware/target/arm/pcm-pp.c | 3 | ||||
-rw-r--r-- | firmware/target/arm/wmcodec-pp.c | 6 |
5 files changed, 367 insertions, 196 deletions
diff --git a/firmware/drivers/audio/wm8758.c b/firmware/drivers/audio/wm8758.c index 7918d03274..d698049a8b 100644 --- a/firmware/drivers/audio/wm8758.c +++ b/firmware/drivers/audio/wm8758.c | |||
@@ -41,117 +41,113 @@ const struct sound_settings_info audiohw_settings[] = { | |||
41 | [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, | 41 | [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, |
42 | [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, | 42 | [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, |
43 | #ifdef HAVE_RECORDING | 43 | #ifdef HAVE_RECORDING |
44 | [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0}, | 44 | [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 63, 16}, |
45 | [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, | 45 | [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 63, 16}, |
46 | [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, | 46 | [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 63, 16}, |
47 | #endif | 47 | #endif |
48 | [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1}, | 48 | [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1}, |
49 | [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, | 49 | [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1}, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | /* shadow registers */ | 52 | /* shadow registers */ |
53 | unsigned int eq1_reg; | 53 | static unsigned short eq1_reg = EQ1_EQ3DMODE | EQ_GAIN_VALUE(0); |
54 | unsigned int eq5_reg; | 54 | static unsigned short eq5_reg = EQ_GAIN_VALUE(0); |
55 | 55 | ||
56 | /* convert tenth of dB volume (-57..6) to master volume register value */ | 56 | /* convert tenth of dB volume (-57..6) to master volume register value */ |
57 | int tenthdb2master(int db) | 57 | int tenthdb2master(int db) |
58 | { | 58 | { |
59 | /* +6 to -57dB in 1dB steps == 64 levels = 6 bits */ | ||
60 | /* 0111111 == +6dB (0x3f) = 63) */ | ||
61 | /* 0111001 == 0dB (0x39) = 57) */ | ||
62 | /* 0000001 == -56dB (0x01) = */ | ||
63 | /* 0000000 == -57dB (0x00) */ | ||
64 | |||
65 | /* 1000000 == Mute (0x40) */ | ||
66 | |||
67 | if (db < VOLUME_MIN) { | 59 | if (db < VOLUME_MIN) { |
68 | return 0x40; | 60 | return 0x40; |
69 | } else { | 61 | } else { |
70 | return((db/10)+57); | 62 | return (db/10)+57; |
71 | } | 63 | } |
72 | } | 64 | } |
73 | 65 | ||
74 | /* convert tenth of dB volume (-780..0) to mixer volume register value */ | 66 | int sound_val2phys(int setting, int value) |
75 | int tenthdb2mixer(int db) | ||
76 | { | 67 | { |
77 | if (db < -660) /* 1.5 dB steps */ | 68 | int result; |
78 | return (2640 - db) / 15; | ||
79 | else if (db < -600) /* 0.75 dB steps */ | ||
80 | return (990 - db) * 2 / 15; | ||
81 | else if (db < -460) /* 0.5 dB steps */ | ||
82 | return (460 - db) / 5; | ||
83 | else /* 0.25 dB steps */ | ||
84 | return -db * 2 / 5; | ||
85 | } | ||
86 | 69 | ||
87 | #define IPOD_PCM_LEVEL 0x65 /* -6dB */ | 70 | switch(setting) |
71 | { | ||
72 | #ifdef HAVE_RECORDING | ||
73 | case SOUND_LEFT_GAIN: | ||
74 | case SOUND_RIGHT_GAIN: | ||
75 | case SOUND_MIC_GAIN: | ||
76 | result = ((value - 16) * 15) / 2; | ||
77 | break; | ||
78 | #endif | ||
79 | default: | ||
80 | result = value; | ||
81 | break; | ||
82 | } | ||
88 | 83 | ||
89 | //#define BASSCTRL 0x | 84 | return result; |
90 | //#define TREBCTRL 0x0b | 85 | } |
91 | 86 | ||
92 | /* Silently enable / disable audio output */ | 87 | void audiohw_mute(bool mute) |
93 | void audiohw_enable_output(bool enable) | ||
94 | { | 88 | { |
95 | if (enable) | 89 | if (mute) { |
96 | { | 90 | wmcodec_write(DACCTRL, DACCTRL_SOFTMUTE); |
97 | /* reset the I2S controller into known state */ | 91 | } else { |
98 | i2s_reset(); | 92 | wmcodec_write(DACCTRL, 0); |
99 | 93 | } | |
100 | /* TODO: Review the power-up sequence to prevent pops */ | 94 | } |
101 | 95 | ||
102 | wmcodec_write(RESET, 0x1ff); /*Reset*/ | 96 | void audiohw_preinit(void) |
103 | 97 | { | |
104 | wmcodec_write(PWRMGMT1, 0x2b); | 98 | i2s_reset(); |
105 | wmcodec_write(PWRMGMT2, 0x180); | ||
106 | wmcodec_write(PWRMGMT3, 0x6f); | ||
107 | 99 | ||
108 | wmcodec_write(AINTFCE, 0x10); | 100 | wmcodec_write(RESET, RESET_RESET); |
109 | wmcodec_write(CLKCTRL, 0x49); | ||
110 | 101 | ||
111 | wmcodec_write(OUTCTRL, 1); | 102 | wmcodec_write(PWRMGMT1, PWRMGMT1_PLLEN | PWRMGMT1_BIASEN |
103 | | PWRMGMT1_VMIDSEL_5K); | ||
104 | wmcodec_write(PWRMGMT2, PWRMGMT2_ROUT1EN | PWRMGMT2_LOUT1EN); | ||
105 | wmcodec_write(PWRMGMT3, PWRMGMT3_LOUT2EN | PWRMGMT3_ROUT2EN | ||
106 | | PWRMGMT3_RMIXEN | PWRMGMT3_LMIXEN | ||
107 | | PWRMGMT3_DACENR | PWRMGMT3_DACENL); | ||
108 | |||
109 | wmcodec_write(AINTFCE, AINTFCE_IWL_16BIT | AINTFCE_FORMAT_I2S); | ||
110 | wmcodec_write(OUTCTRL, OUTCTRL_VROI); | ||
111 | wmcodec_write(CLKCTRL, CLKCTRL_MS); /* WM8758 is clock master */ | ||
112 | 112 | ||
113 | /* The iPod can handle multiple frequencies, but fix at 44.1KHz | 113 | audiohw_set_sample_rate(WM8758_44100HZ); |
114 | for now */ | ||
115 | audiohw_set_sample_rate(WM8758_44100HZ); | ||
116 | 114 | ||
117 | wmcodec_write(LOUTMIX,0x1); /* Enable mixer */ | 115 | wmcodec_write(LOUTMIX, LOUTMIX_DACL2LMIX); |
118 | wmcodec_write(ROUTMIX,0x1); /* Enable mixer */ | 116 | wmcodec_write(ROUTMIX, ROUTMIX_DACR2RMIX); |
119 | audiohw_mute(0); | 117 | } |
120 | } else { | 118 | |
121 | audiohw_mute(1); | 119 | void audiohw_postinit(void) |
122 | } | 120 | { |
121 | wmcodec_write(PWRMGMT1, PWRMGMT1_PLLEN | PWRMGMT1_BIASEN | ||
122 | | PWRMGMT1_VMIDSEL_75K); | ||
123 | /* lower the VMID power consumption */ | ||
124 | audiohw_mute(false); | ||
123 | } | 125 | } |
124 | 126 | ||
125 | void audiohw_set_master_vol(int vol_l, int vol_r) | 127 | void audiohw_set_master_vol(int vol_l, int vol_r) |
126 | { | 128 | { |
127 | /* OUT1 */ | 129 | /* OUT1 */ |
128 | wmcodec_write(LOUT1VOL, 0x080 | vol_l); | 130 | wmcodec_write(LOUT1VOL, LOUT1VOL_LOUT1ZC | vol_l); |
129 | wmcodec_write(ROUT1VOL, 0x180 | vol_r); | 131 | wmcodec_write(ROUT1VOL, ROUT1VOL_OUT1VU | ROUT1VOL_ROUT1ZC | vol_r); |
130 | } | 132 | } |
131 | 133 | ||
132 | void audiohw_set_lineout_vol(int vol_l, int vol_r) | 134 | void audiohw_set_lineout_vol(int vol_l, int vol_r) |
133 | { | 135 | { |
134 | /* OUT2 */ | 136 | /* OUT2 */ |
135 | wmcodec_write(LOUT2VOL, vol_l); | 137 | wmcodec_write(LOUT2VOL, LOUT2VOL_LOUT2ZC | vol_l); |
136 | wmcodec_write(ROUT2VOL, 0x100 | vol_r); | 138 | wmcodec_write(ROUT2VOL, ROUT2VOL_OUT2VU | ROUT2VOL_ROUT2ZC | vol_r); |
137 | } | ||
138 | |||
139 | void audiohw_set_mixer_vol(int channel1, int channel2) | ||
140 | { | ||
141 | (void)channel1; | ||
142 | (void)channel2; | ||
143 | } | 139 | } |
144 | 140 | ||
145 | void audiohw_set_bass(int value) | 141 | void audiohw_set_bass(int value) |
146 | { | 142 | { |
147 | eq1_reg = (eq1_reg & ~EQ_GAIN_MASK) | EQ_GAIN_VALUE(value); | 143 | eq1_reg = (eq1_reg & ~EQ_GAIN_MASK) | EQ_GAIN_VALUE(value); |
148 | wmcodec_write(EQ1, 0x100 | eq1_reg); | 144 | wmcodec_write(EQ1, eq1_reg); |
149 | } | 145 | } |
150 | 146 | ||
151 | void audiohw_set_bass_cutoff(int value) | 147 | void audiohw_set_bass_cutoff(int value) |
152 | { | 148 | { |
153 | eq1_reg = (eq1_reg & ~EQ_CUTOFF_MASK) | EQ_CUTOFF_VALUE(value); | 149 | eq1_reg = (eq1_reg & ~EQ_CUTOFF_MASK) | EQ_CUTOFF_VALUE(value); |
154 | wmcodec_write(EQ1, 0x100 | eq1_reg); | 150 | wmcodec_write(EQ1, eq1_reg); |
155 | } | 151 | } |
156 | 152 | ||
157 | void audiohw_set_treble(int value) | 153 | void audiohw_set_treble(int value) |
@@ -166,31 +162,16 @@ void audiohw_set_treble_cutoff(int value) | |||
166 | wmcodec_write(EQ5, eq5_reg); | 162 | wmcodec_write(EQ5, eq5_reg); |
167 | } | 163 | } |
168 | 164 | ||
169 | void audiohw_mute(bool mute) | ||
170 | { | ||
171 | if (mute) | ||
172 | { | ||
173 | /* Set DACMU = 1 to soft-mute the audio DACs. */ | ||
174 | wmcodec_write(DACCTRL, 0x40); | ||
175 | } else { | ||
176 | /* Set DACMU = 0 to soft-un-mute the audio DACs. */ | ||
177 | wmcodec_write(DACCTRL, 0x0); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | /* Nice shutdown of WM8758 codec */ | 165 | /* Nice shutdown of WM8758 codec */ |
182 | void audiohw_close(void) | 166 | void audiohw_close(void) |
183 | { | 167 | { |
184 | audiohw_mute(1); | 168 | audiohw_mute(true); |
185 | |||
186 | wmcodec_write(PWRMGMT3, 0x0); | ||
187 | |||
188 | wmcodec_write(PWRMGMT1, 0x0); | ||
189 | 169 | ||
190 | wmcodec_write(PWRMGMT2, 0x40); | 170 | wmcodec_write(PWRMGMT3, 0); |
171 | wmcodec_write(PWRMGMT1, 0); | ||
172 | wmcodec_write(PWRMGMT2, PWRMGMT2_SLEEP); | ||
191 | } | 173 | } |
192 | 174 | ||
193 | /* Change the order of the noise shaper, 5th order is recommended above 32kHz */ | ||
194 | void audiohw_set_nsorder(int order) | 175 | void audiohw_set_nsorder(int order) |
195 | { | 176 | { |
196 | (void)order; | 177 | (void)order; |
@@ -202,89 +183,68 @@ void audiohw_set_sample_rate(int sampling_control) | |||
202 | /**** We force 44.1KHz for now. ****/ | 183 | /**** We force 44.1KHz for now. ****/ |
203 | (void)sampling_control; | 184 | (void)sampling_control; |
204 | 185 | ||
205 | /* set clock div */ | ||
206 | wmcodec_write(CLKCTRL, 1 | (0 << 2) | (2 << 5)); | ||
207 | |||
208 | /* setup PLL for MHZ=11.2896 */ | 186 | /* setup PLL for MHZ=11.2896 */ |
209 | wmcodec_write(PLLN, (1 << 4) | 0x7); | 187 | wmcodec_write(PLLN, PLLN_PLLPRESCALE | 0x7); |
210 | wmcodec_write(PLLK1, 0x21); | 188 | wmcodec_write(PLLK1, 0x21); |
211 | wmcodec_write(PLLK2, 0x161); | 189 | wmcodec_write(PLLK2, 0x161); |
212 | wmcodec_write(PLLK3, 0x26); | 190 | wmcodec_write(PLLK3, 0x26); |
213 | 191 | ||
214 | /* set clock div */ | 192 | /* set clock div */ |
215 | wmcodec_write(CLKCTRL, 1 | (1 << 2) | (2 << 5) | (1 << 8)); | 193 | wmcodec_write(CLKCTRL, CLKCTRL_CLKSEL | CLKCTRL_MCLKDIV_2 |
194 | | CLKCTRL_BCLKDIV_2 | CLKCTRL_MS); | ||
216 | 195 | ||
217 | /* set srate */ | 196 | wmcodec_write(ADDCTRL, ADDCTRL_SR_48kHz | ADDCTRL_SLOWCLKEN); |
218 | wmcodec_write(SRATECTRL, (0 << 1)); | 197 | /* SLOWCLK enabled for zero cross timeout to work */ |
219 | } | 198 | } |
220 | 199 | ||
221 | void audiohw_enable_recording(bool source_mic) | 200 | void audiohw_enable_recording(bool source_mic) |
222 | { | 201 | { |
223 | (void)source_mic; /* We only have a line-in (I think) */ | 202 | (void)source_mic; /* We only have a line-in (I think) */ |
224 | |||
225 | /* reset the I2S controller into known state */ | ||
226 | i2s_reset(); | ||
227 | |||
228 | wmcodec_write(RESET, 0x1ff); /*Reset*/ | ||
229 | 203 | ||
230 | wmcodec_write(PWRMGMT1, 0x2b); | 204 | wmcodec_write(PWRMGMT2, PWRMGMT2_ROUT1EN | PWRMGMT2_LOUT1EN |
231 | wmcodec_write(PWRMGMT2, 0x18f); /* Enable ADC - 0x0c enables left/right PGA input, and 0x03 turns on power to the ADCs */ | 205 | | PWRMGMT2_INPGAENR | PWRMGMT2_INPGAENL |
232 | wmcodec_write(PWRMGMT3, 0x6f); | 206 | | PWRMGMT2_ADCENR | PWRMGMT2_ADCENL); |
233 | 207 | ||
234 | wmcodec_write(AINTFCE, 0x10); | 208 | wmcodec_write(INCTRL, INCTRL_R2_2INPGA | INCTRL_L2_2INPGA); |
235 | wmcodec_write(CLKCTRL, 0x49); | ||
236 | 209 | ||
237 | wmcodec_write(OUTCTRL, 1); | 210 | wmcodec_write(LADCBOOST, LADCBOOST_L2_2BOOST(5)); |
238 | 211 | wmcodec_write(RADCBOOST, RADCBOOST_R2_2BOOST(5)); | |
239 | /* The iPod can handle multiple frequencies, but fix at 44.1KHz | ||
240 | for now */ | ||
241 | audiohw_set_sample_rate(WM8758_44100HZ); | ||
242 | |||
243 | wmcodec_write(INCTRL,0x44); /* Connect L2 and R2 inputs */ | ||
244 | |||
245 | /* Set L2/R2_2BOOSTVOL to 0db (bits 4-6) */ | ||
246 | /* 000 = disabled | ||
247 | 001 = -12dB | ||
248 | 010 = -9dB | ||
249 | 011 = -6dB | ||
250 | 100 = -3dB | ||
251 | 101 = 0dB | ||
252 | 110 = 3dB | ||
253 | 111 = 6dB | ||
254 | */ | ||
255 | wmcodec_write(LADCBOOST,0x50); | ||
256 | wmcodec_write(RADCBOOST,0x50); | ||
257 | |||
258 | /* Set L/R input PGA Volume to 0db */ | ||
259 | // wm8758_write(LINPGAVOL,0x3f); | ||
260 | // wm8758_write(RINPGAVOL,0x13f); | ||
261 | 212 | ||
262 | /* Enable monitoring */ | 213 | /* Enable monitoring */ |
263 | wmcodec_write(LOUTMIX,0x17); /* Enable output mixer - BYPL2LMIX @ 0db*/ | 214 | wmcodec_write(LOUTMIX, LOUTMIX_BYP2LMIXVOL(5) |
264 | wmcodec_write(ROUTMIX,0x17); /* Enable output mixer - BYPR2RMIX @ 0db*/ | 215 | | LOUTMIX_BYPL2LMIX | LOUTMIX_DACL2LMIX); |
265 | 216 | wmcodec_write(ROUTMIX, ROUTMIX_BYP2RMIXVOL(5) | |
266 | audiohw_mute(0); | 217 | | ROUTMIX_BYPR2RMIX | ROUTMIX_DACR2RMIX); |
267 | } | 218 | } |
268 | 219 | ||
269 | void audiohw_disable_recording(void) { | 220 | void audiohw_disable_recording(void) |
270 | audiohw_mute(1); | 221 | { |
271 | 222 | wmcodec_write(LOUTMIX, LOUTMIX_DACL2LMIX); | |
272 | wmcodec_write(PWRMGMT3, 0x0); | 223 | wmcodec_write(ROUTMIX, ROUTMIX_DACR2RMIX); |
273 | 224 | ||
274 | wmcodec_write(PWRMGMT1, 0x0); | 225 | wmcodec_write(PWRMGMT2, PWRMGMT2_ROUT1EN | PWRMGMT2_LOUT1EN); |
275 | |||
276 | wmcodec_write(PWRMGMT2, 0x40); | ||
277 | } | 226 | } |
278 | 227 | ||
279 | void audiohw_set_recvol(int left, int right, int type) { | 228 | void audiohw_set_recvol(int left, int right, int type) |
280 | 229 | { | |
281 | (void)left; | 230 | switch (type) |
282 | (void)right; | 231 | { |
283 | (void)type; | 232 | case AUDIO_GAIN_MIC: |
233 | right = left; | ||
234 | /* fall through */ | ||
235 | case AUDIO_GAIN_LINEIN: | ||
236 | wmcodec_write(LINPGAVOL, LINPGAVOL_INPGAZCL | ||
237 | | (left & LINPGAVOL_INPGAVOL_MASK)); | ||
238 | wmcodec_write(RINPGAVOL, RINPGAVOL_INPGAVU | RINPGAVOL_INPGAZCR | ||
239 | | (right & RINPGAVOL_INPGAVOL_MASK)); | ||
240 | break; | ||
241 | default: | ||
242 | return; | ||
243 | } | ||
284 | } | 244 | } |
285 | 245 | ||
286 | void audiohw_set_monitor(bool enable) { | 246 | void audiohw_set_monitor(bool enable) |
287 | 247 | { | |
288 | (void)enable; | 248 | (void)enable; |
289 | } | 249 | } |
290 | 250 | ||
diff --git a/firmware/export/wm8758.h b/firmware/export/wm8758.h index af0e22943d..e7f7906651 100644 --- a/firmware/export/wm8758.h +++ b/firmware/export/wm8758.h | |||
@@ -37,53 +37,261 @@ extern void audiohw_set_mixer_vol(int channel1, int channel2); | |||
37 | extern void audiohw_set_nsorder(int order); | 37 | extern void audiohw_set_nsorder(int order); |
38 | extern void audiohw_set_sample_rate(int sampling_control); | 38 | extern void audiohw_set_sample_rate(int sampling_control); |
39 | 39 | ||
40 | #define RESET 0x00 | 40 | #define RESET 0x00 |
41 | #define PWRMGMT1 0x01 | 41 | #define RESET_RESET 0x0 |
42 | #define PWRMGMT2 0x02 | 42 | |
43 | #define PWRMGMT3 0x03 | 43 | #define PWRMGMT1 0x01 |
44 | #define AINTFCE 0x04 | 44 | #define PWRMGMT1_VMIDSEL_OFF (0 << 0) |
45 | #define CLKCTRL 0x06 | 45 | #define PWRMGMT1_VMIDSEL_75K (1 << 0) |
46 | #define SRATECTRL 0x07 | 46 | #define PWRMGMT1_VMIDSEL_300K (2 << 0) |
47 | #define DACCTRL 0x0a | 47 | #define PWRMGMT1_VMIDSEL_5K (3 << 0) |
48 | #define INCTRL 0x2c | 48 | #define PWRMGMT1_BUFIOEN (1 << 2) |
49 | #define LINPGAVOL 0x2d | 49 | #define PWRMGMT1_BIASEN (1 << 3) |
50 | #define RINPGAVOL 0x2e | 50 | #define PWRMGMT1_MICBEN (1 << 4) |
51 | #define LADCBOOST 0x2f | 51 | #define PWRMGMT1_PLLEN (1 << 5) |
52 | #define RADCBOOST 0x30 | 52 | #define PWRMGMT1_OUT3MIXEN (1 << 6) |
53 | #define OUTCTRL 0x31 | 53 | #define PWRMGMT1_OUT4MIXEN (1 << 7) |
54 | #define LOUTMIX 0x32 | 54 | #define PWRMGMT1_BUFDCOPEN (1 << 8) |
55 | #define ROUTMIX 0x33 | 55 | |
56 | 56 | #define PWRMGMT2 0x02 | |
57 | #define LOUT1VOL 0x34 | 57 | #define PWRMGMT2_ADCENL (1 << 0) |
58 | #define ROUT1VOL 0x35 | 58 | #define PWRMGMT2_ADCENR (1 << 1) |
59 | #define LOUT2VOL 0x36 | 59 | #define PWRMGMT2_INPGAENL (1 << 2) |
60 | #define ROUT2VOL 0x37 | 60 | #define PWRMGMT2_INPGAENR (1 << 3) |
61 | 61 | #define PWRMGMT2_BOOSTENL (1 << 4) | |
62 | #define PLLN 0x24 | 62 | #define PWRMGMT2_BOOSTENR (1 << 5) |
63 | #define PLLK1 0x25 | 63 | #define PWRMGMT2_SLEEP (1 << 6) |
64 | #define PLLK2 0x26 | 64 | #define PWRMGMT2_LOUT1EN (1 << 7) |
65 | #define PLLK3 0x27 | 65 | #define PWRMGMT2_ROUT1EN (1 << 8) |
66 | 66 | ||
67 | #define EQ1 0x12 | 67 | #define PWRMGMT3 0x03 |
68 | #define EQ2 0x13 | 68 | #define PWRMGMT3_DACENL (1 << 0) |
69 | #define EQ3 0x14 | 69 | #define PWRMGMT3_DACENR (1 << 1) |
70 | #define EQ4 0x15 | 70 | #define PWRMGMT3_LMIXEN (1 << 2) |
71 | #define EQ5 0x16 | 71 | #define PWRMGMT3_RMIXEN (1 << 3) |
72 | #define EQ_GAIN_MASK 0x001f | 72 | #define PWRMGMT3_ROUT2EN (1 << 5) |
73 | #define EQ_CUTOFF_MASK 0x0060 | 73 | #define PWRMGMT3_LOUT2EN (1 << 6) |
74 | #define EQ_GAIN_VALUE(x) (((-x) + 12) & 0x1f) | 74 | #define PWRMGMT3_OUT3EN (1 << 7) |
75 | #define EQ_CUTOFF_VALUE(x) ((((x) - 1) & 0x03) << 5) | 75 | #define PWRMGMT3_OUT4EN (1 << 8) |
76 | 76 | ||
77 | /* Register settings for the supported samplerates: */ | 77 | #define AINTFCE 0x04 |
78 | #define WM8758_8000HZ 0x4d | 78 | #define AINTFCE_MONO (1 << 0) |
79 | #define WM8758_12000HZ 0x61 | 79 | #define AINTFCE_ALRSWAP (1 << 1) |
80 | #define WM8758_16000HZ 0x55 | 80 | #define AINTFCE_DLRSWAP (1 << 2) |
81 | #define WM8758_22050HZ 0x77 | 81 | #define AINTFCE_FORMAT_MSB_RJUST (0 << 3) |
82 | #define WM8758_24000HZ 0x79 | 82 | #define AINTFCE_FORMAT_MSB_LJUST (1 << 3) |
83 | #define WM8758_32000HZ 0x59 | 83 | #define AINTFCE_FORMAT_I2S (2 << 3) |
84 | #define WM8758_44100HZ 0x63 | 84 | #define AINTFCE_FORMAT_DSP (3 << 3) |
85 | #define WM8758_48000HZ 0x41 | 85 | #define AINTFCE_FORMAT_MASK (3 << 3) |
86 | #define WM8758_88200HZ 0x7f | 86 | #define AINTFCE_IWL_16BIT (0 << 5) |
87 | #define WM8758_96000HZ 0x5d | 87 | #define AINTFCE_IWL_20BIT (1 << 5) |
88 | #define AINTFCE_IWL_24BIT (2 << 5) | ||
89 | #define AINTFCE_IWL_32BIT (3 << 5) | ||
90 | #define AINTFCE_IWL_MASK (3 << 5) | ||
91 | #define AINTFCE_LRP (1 << 7) | ||
92 | #define AINTFCE_BCP (1 << 8) | ||
93 | |||
94 | #define COMPCTRL 0x05 /* unused */ | ||
95 | |||
96 | #define CLKCTRL 0x06 | ||
97 | #define CLKCTRL_MS (1 << 0) | ||
98 | #define CLKCTRL_BCLKDIV_1 (0 << 2) | ||
99 | #define CLKCTRL_BCLKDIV_2 (1 << 2) | ||
100 | #define CLKCTRL_BCLKDIV_4 (2 << 2) | ||
101 | #define CLKCTRL_BCLKDIV_8 (3 << 2) | ||
102 | #define CLKCTRL_BCLKDIV_16 (4 << 2) | ||
103 | #define CLKCTRL_BCLKDIV_32 (5 << 2) | ||
104 | #define CLKCTRL_MCLKDIV_1 (0 << 5) | ||
105 | #define CLKCTRL_MCLKDIV_1_5 (1 << 5) | ||
106 | #define CLKCTRL_MCLKDIV_2 (2 << 5) | ||
107 | #define CLKCTRL_MCLKDIV_3 (3 << 5) | ||
108 | #define CLKCTRL_MCLKDIV_4 (4 << 5) | ||
109 | #define CLKCTRL_MCLKDIV_6 (5 << 5) | ||
110 | #define CLKCTRL_MCLKDIV_8 (6 << 5) | ||
111 | #define CLKCTRL_MCLKDIV_12 (7 << 5) | ||
112 | #define CLKCTRL_CLKSEL (1 << 8) | ||
113 | |||
114 | #define ADDCTRL 0x07 | ||
115 | #define ADDCTRL_SLOWCLKEN (1 << 0) | ||
116 | #define ADDCTRL_SR_48kHz (0 << 1) | ||
117 | #define ADDCTRL_SR_32kHz (1 << 1) | ||
118 | #define ADDCTRL_SR_24kHz (2 << 1) | ||
119 | #define ADDCTRL_SR_16kHz (3 << 1) | ||
120 | #define ADDCTRL_SR_12kHz (4 << 1) | ||
121 | #define ADDCTRL_SR_8kHz (5 << 1) | ||
122 | #define ADDCTRL_SR_MASK (7 << 1) | ||
123 | |||
124 | /* unused */ | ||
125 | #define GPIOCTRL 0x08 | ||
126 | #define JACKDETECTCTRL1 0x09 | ||
127 | |||
128 | #define DACCTRL 0x0a | ||
129 | #define DACCTRL_DACLPOL (1 << 0) | ||
130 | #define DACCTRL_DACRPOL (1 << 1) | ||
131 | #define DACCTRL_AMUTE (1 << 2) | ||
132 | #define DACCTRL_DACOSR128 (1 << 3) | ||
133 | #define DACCTRL_SOFTMUTE (1 << 6) | ||
134 | |||
135 | #define LDACVOL 0x0b | ||
136 | #define LDACVOL_MASK 0xff | ||
137 | #define LDACVOL_DACVU (1 << 8) | ||
138 | |||
139 | #define RDACVOL 0x0c | ||
140 | #define RDACVOL_MASK 0xff | ||
141 | #define RDACVOL_DACVU (1 << 8) | ||
142 | |||
143 | #define JACKDETECTCTRL2 0x0d /* unused */ | ||
144 | |||
145 | #define ADCCTRL 0x0e | ||
146 | #define ADCCTRL_ADCLPOL (1 << 0) | ||
147 | #define ADCCTRL_ADCRPOL (1 << 1) | ||
148 | #define ADCCTRL_ADCOSR128 (1 << 3) | ||
149 | #define ADCCTRL_HPFCUT_MASK (7 << 4) | ||
150 | #define ADCCTRL_HPFAPP (1 << 7) | ||
151 | #define ADCCTRL_HPFEN (1 << 8) | ||
152 | |||
153 | #define LADCVOL 0x0f | ||
154 | #define LADCVOL_MASK 0xff | ||
155 | #define LADCVOL_ADCVU (1 << 8) | ||
156 | |||
157 | #define RADCVOL 0x10 | ||
158 | #define RADCVOL_MASK 0xff | ||
159 | #define RADCVOL_ADCVU (1 << 8) | ||
160 | |||
161 | #define EQ1 0x12 | ||
162 | #define EQ5 0x16 | ||
163 | /* note: the WM8983 used for reference has a true 5 band EQ, but the WM8758 | ||
164 | * does only have low shelf & high shelf (tested). Not sure about 3D mode. */ | ||
165 | #define EQ1_EQ3DMODE (1 << 8) | ||
166 | #define EQ_GAIN_MASK 0x1f | ||
167 | #define EQ_CUTOFF_MASK (3 << 5) | ||
168 | #define EQ_GAIN_VALUE(x) (((-x) + 12) & 0x1f) | ||
169 | #define EQ_CUTOFF_VALUE(x) ((((x) - 1) & 0x03) << 5) | ||
170 | |||
171 | /* unused */ | ||
172 | #define DACLIMITER1 0x18 | ||
173 | #define DACLIMITER2 0x19 | ||
174 | #define NOTCHFILTER1 0x1b | ||
175 | #define NOTCHFILTER2 0x1c | ||
176 | #define NOTCHFILTER3 0x1d | ||
177 | #define NOTCHFILTER4 0x1e | ||
178 | #define ALCCONTROL1 0x20 | ||
179 | #define ALCCONTROL2 0x21 | ||
180 | #define ALCCONTROL3 0x22 | ||
181 | #define NOISEGATE 0x23 | ||
182 | |||
183 | #define PLLN 0x24 | ||
184 | #define PLLN_PLLN_MASK 0x0f | ||
185 | #define PLLN_PLLPRESCALE (1 << 4) | ||
186 | |||
187 | #define PLLK1 0x25 | ||
188 | #define PLLK1_MASK 0x3f | ||
189 | |||
190 | #define PLLK2 0x26 | ||
191 | #define PLLK3 0x27 | ||
192 | |||
193 | #define THREEDCTRL 0x29 | ||
194 | #define THREEDCTRL_DEPTH3D_MASK 0x0f | ||
195 | |||
196 | #define OUT4TOADC 0x2a | ||
197 | #define OUT4TOADC_OUT1DEL (1 << 0) | ||
198 | #define OUT4TOADC_DELEN (1 << 1) | ||
199 | #define OUT4TOADC_POBCTRL (1 << 2) | ||
200 | #define OUT4TOADC_OUT4_2LNR (1 << 5) | ||
201 | #define OUT4TOADC_OUT4_ADCVOL_MASK (7 << 6) | ||
202 | |||
203 | #define BEEPCTRL 0x2b | ||
204 | #define BEEPCTRL_BEEPEN (1 << 0) | ||
205 | #define BEEPCTRL_BEEPVOL_MASK (7 << 1) | ||
206 | #define BEEPCTRL_INVROUT2 (1 << 4) | ||
207 | #define BEEPCTRL_MUTERPGA2INV (1 << 5) | ||
208 | #define BEEPCTRL_BYPR2LMIX (1 << 7) | ||
209 | #define BEEPCTRL_BYPL2RMIX (1 << 8) | ||
210 | |||
211 | #define INCTRL 0x2c | ||
212 | #define INCTRL_LIP2INPGA (1 << 0) | ||
213 | #define INCTRL_LIN2INPGA (1 << 1) | ||
214 | #define INCTRL_L2_2INPGA (1 << 2) | ||
215 | #define INCTRL_RIP2INPGA (1 << 4) | ||
216 | #define INCTRL_RIN2INPGA (1 << 5) | ||
217 | #define INCTRL_R2_2INPGA (1 << 6) | ||
218 | #define INCTRL_MBVSEL (1 << 8) | ||
219 | |||
220 | #define LINPGAVOL 0x2d | ||
221 | #define LINPGAVOL_INPGAVOL_MASK 0x3f | ||
222 | #define LINPGAVOL_INPGAMUTEL (1 << 6) | ||
223 | #define LINPGAVOL_INPGAZCL (1 << 7) | ||
224 | #define LINPGAVOL_INPGAVU (1 << 8) | ||
225 | |||
226 | #define RINPGAVOL 0x2e | ||
227 | #define RINPGAVOL_INPGAVOL_MASK 0x3f | ||
228 | #define RINPGAVOL_INPGAMUTER (1 << 6) | ||
229 | #define RINPGAVOL_INPGAZCR (1 << 7) | ||
230 | #define RINPGAVOL_INPGAVU (1 << 8) | ||
231 | |||
232 | #define LADCBOOST 0x2f | ||
233 | #define LADCBOOST_AUXL2BOOST_MASK (7 << 0) | ||
234 | #define LADCBOOST_L2_2BOOST_MASK (7 << 4) | ||
235 | #define LADCBOOST_L2_2BOOST(x) ((x) << 4) | ||
236 | #define LADCBOOST_PGABOOSTL (1 << 8) | ||
237 | |||
238 | #define RADCBOOST 0x30 | ||
239 | #define RADCBOOST_AUXR2BOOST_MASK (7 << 0) | ||
240 | #define RADCBOOST_R2_2BOOST_MASK (7 << 4) | ||
241 | #define RADCBOOST_R2_2BOOST(x) ((x) << 4) | ||
242 | #define RADCBOOST_PGABOOSTR (1 << 8) | ||
243 | |||
244 | #define OUTCTRL 0x31 | ||
245 | #define OUTCTRL_VROI (1 << 0) | ||
246 | #define OUTCTRL_TSDEN (1 << 1) | ||
247 | #define OUTCTRL_SPKBOOST (1 << 2) | ||
248 | #define OUTCTRL_OUT3BOOST (1 << 3) | ||
249 | #define OUTCTRL_OUT4BOOST (1 << 4) | ||
250 | #define OUTCTRL_DACR2LMIX (1 << 5) | ||
251 | #define OUTCTRL_DACL2RMIX (1 << 6) | ||
252 | |||
253 | #define LOUTMIX 0x32 | ||
254 | #define LOUTMIX_DACL2LMIX (1 << 0) | ||
255 | #define LOUTMIX_BYPL2LMIX (1 << 1) | ||
256 | #define LOUTMIX_BYP2LMIXVOL_MASK (7 << 2) | ||
257 | #define LOUTMIX_BYP2LMIXVOL(x) ((x) << 2) | ||
258 | #define LOUTMIX_AUXL2LMIX (1 << 5) | ||
259 | #define LOUTMIX_AUXLMIXVOL_MASK (7 << 6) | ||
260 | |||
261 | #define ROUTMIX 0x33 | ||
262 | #define ROUTMIX_DACR2RMIX (1 << 0) | ||
263 | #define ROUTMIX_BYPR2RMIX (1 << 1) | ||
264 | #define ROUTMIX_BYP2RMIXVOL_MASK (7 << 2) | ||
265 | #define ROUTMIX_BYP2RMIXVOL(x) ((x) << 2) | ||
266 | #define ROUTMIX_AUXR2RMIX (1 << 5) | ||
267 | #define ROUTMIX_AUXRMIXVOL_MASK (7 << 6) | ||
268 | |||
269 | #define LOUT1VOL 0x34 | ||
270 | #define LOUT1VOL_MASK 0x3f | ||
271 | #define LOUT1VOL_LOUT1MUTE (1 << 6) | ||
272 | #define LOUT1VOL_LOUT1ZC (1 << 7) | ||
273 | #define LOUT1VOL_OUT1VU (1 << 8) | ||
274 | |||
275 | #define ROUT1VOL 0x35 | ||
276 | #define ROUT1VOL_MASK 0x3f | ||
277 | #define ROUT1VOL_ROUT1MUTE (1 << 6) | ||
278 | #define ROUT1VOL_ROUT1ZC (1 << 7) | ||
279 | #define ROUT1VOL_OUT1VU (1 << 8) | ||
280 | |||
281 | #define LOUT2VOL 0x36 | ||
282 | #define LOUT2VOL_MASK 0x3f | ||
283 | #define LOUT2VOL_LOUT2MUTE (1 << 6) | ||
284 | #define LOUT2VOL_LOUT2ZC (1 << 7) | ||
285 | #define LOUT2VOL_OUT2VU (1 << 8) | ||
286 | |||
287 | #define ROUT2VOL 0x37 | ||
288 | #define ROUT2VOL_MASK 0x3f | ||
289 | #define ROUT2VOL_ROUT2MUTE (1 << 6) | ||
290 | #define ROUT2VOL_ROUT2ZC (1 << 7) | ||
291 | #define ROUT2VOL_OUT2VU (1 << 8) | ||
292 | |||
293 | |||
294 | /* Dummy definition, to be removed when the audio driver API gets reworked. */ | ||
295 | #define WM8758_44100HZ 0 | ||
88 | 296 | ||
89 | #endif /* _WM8758_H */ | 297 | #endif /* _WM8758_H */ |
diff --git a/firmware/sound.c b/firmware/sound.c index ab09c7e7bc..0a95562b22 100644 --- a/firmware/sound.c +++ b/firmware/sound.c | |||
@@ -625,8 +625,8 @@ void sound_set(int setting, int value) | |||
625 | sound_set_val(value); | 625 | sound_set_val(value); |
626 | } | 626 | } |
627 | 627 | ||
628 | #if (!defined(HAVE_AS3514) && !defined (HAVE_WM8731) && !defined (HAVE_WM8975) \ | 628 | #if (!defined(HAVE_AS3514) && !defined (HAVE_WM8731) && !defined(HAVE_WM8975) \ |
629 | && !defined(HAVE_TSC2100)) || defined(SIMULATOR) | 629 | && !defined(HAVE_WM8758) && !defined(HAVE_TSC2100)) || defined(SIMULATOR) |
630 | int sound_val2phys(int setting, int value) | 630 | int sound_val2phys(int setting, int value) |
631 | { | 631 | { |
632 | #if CONFIG_CODEC == MAS3587F | 632 | #if CONFIG_CODEC == MAS3587F |
diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c index e98054ab9e..38fd49165e 100644 --- a/firmware/target/arm/pcm-pp.c +++ b/firmware/target/arm/pcm-pp.c | |||
@@ -365,7 +365,8 @@ void pcm_play_dma_init(void) | |||
365 | /* Initialize default register values. */ | 365 | /* Initialize default register values. */ |
366 | audiohw_init(); | 366 | audiohw_init(); |
367 | 367 | ||
368 | #if !defined(HAVE_WM8731) && !defined(HAVE_WM8751) && !defined(HAVE_WM8975) | 368 | #if !defined(HAVE_WM8731) && !defined(HAVE_WM8751) && !defined(HAVE_WM8975) \ |
369 | && !defined(HAVE_WM8758) | ||
369 | /* Power on */ | 370 | /* Power on */ |
370 | audiohw_enable_output(true); | 371 | audiohw_enable_output(true); |
371 | /* Unmute the master channel (DAC should be at zero point now). */ | 372 | /* Unmute the master channel (DAC should be at zero point now). */ |
diff --git a/firmware/target/arm/wmcodec-pp.c b/firmware/target/arm/wmcodec-pp.c index 04cf238ac3..0d751f6b3f 100644 --- a/firmware/target/arm/wmcodec-pp.c +++ b/firmware/target/arm/wmcodec-pp.c | |||
@@ -96,13 +96,15 @@ void audiohw_init(void) { | |||
96 | #endif /* IPOD_1G2G/3G */ | 96 | #endif /* IPOD_1G2G/3G */ |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | #if defined(HAVE_WM8731) || defined(HAVE_WM8751) || defined(HAVE_WM8975) | 99 | #if defined(HAVE_WM8731) || defined(HAVE_WM8751) || defined(HAVE_WM8975) \ |
100 | || defined(HAVE_WM8758) | ||
100 | audiohw_preinit(); | 101 | audiohw_preinit(); |
101 | #endif | 102 | #endif |
102 | 103 | ||
103 | } | 104 | } |
104 | 105 | ||
105 | #if !defined(HAVE_WM8731) && !defined(HAVE_WM8751) && !defined(HAVE_WM8975) | 106 | #if !defined(HAVE_WM8731) && !defined(HAVE_WM8751) && !defined(HAVE_WM8975) \ |
107 | && !defined(HAVE_WM8758) | ||
106 | void audiohw_postinit(void) | 108 | void audiohw_postinit(void) |
107 | { | 109 | { |
108 | } | 110 | } |