summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-09-13 19:34:16 +0000
committerJens Arnold <amiconn@rockbox.org>2008-09-13 19:34:16 +0000
commit6938083e4f45164c20d5c081839f37635cbcd6cd (patch)
treea41c635a1528ab4dfa01e6a5986e50613f3ba15b
parentc487c01d4626eb5f7aa07654829722f42695ffa6 (diff)
downloadrockbox-6938083e4f45164c20d5c081839f37635cbcd6cd.tar.gz
rockbox-6938083e4f45164c20d5c081839f37635cbcd6cd.zip
iPod Video: Fix playback after recording (FS #7402). Implement recording gain adjustment. * Enable timeout for zero-crossing detection (SLOWCLK), avoids hanging volume/ gain due to DC offsets.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18509 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/audio/wm8758.c246
-rw-r--r--firmware/export/wm8758.h304
-rw-r--r--firmware/sound.c4
-rw-r--r--firmware/target/arm/pcm-pp.c3
-rw-r--r--firmware/target/arm/wmcodec-pp.c6
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 */
53unsigned int eq1_reg; 53static unsigned short eq1_reg = EQ1_EQ3DMODE | EQ_GAIN_VALUE(0);
54unsigned int eq5_reg; 54static 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 */
57int tenthdb2master(int db) 57int 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 */ 66int sound_val2phys(int setting, int value)
75int 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 */ 87void audiohw_mute(bool mute)
93void 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*/ 96void 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); 119void 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
125void audiohw_set_master_vol(int vol_l, int vol_r) 127void 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
132void audiohw_set_lineout_vol(int vol_l, int vol_r) 134void 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
139void audiohw_set_mixer_vol(int channel1, int channel2)
140{
141 (void)channel1;
142 (void)channel2;
143} 139}
144 140
145void audiohw_set_bass(int value) 141void 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
151void audiohw_set_bass_cutoff(int value) 147void 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
157void audiohw_set_treble(int value) 153void 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
169void 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 */
182void audiohw_close(void) 166void 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 */
194void audiohw_set_nsorder(int order) 175void 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
221void audiohw_enable_recording(bool source_mic) 200void 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
269void audiohw_disable_recording(void) { 220void 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
279void audiohw_set_recvol(int left, int right, int type) { 228void 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
286void audiohw_set_monitor(bool enable) { 246void 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);
37extern void audiohw_set_nsorder(int order); 37extern void audiohw_set_nsorder(int order);
38extern void audiohw_set_sample_rate(int sampling_control); 38extern 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)
630int sound_val2phys(int setting, int value) 630int 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)
106void audiohw_postinit(void) 108void audiohw_postinit(void)
107{ 109{
108} 110}