diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/audio/wm8721.c (renamed from firmware/drivers/audio/wm8731l.c) | 126 | ||||
-rw-r--r-- | firmware/drivers/audio/wm8731.c | 324 |
2 files changed, 327 insertions, 123 deletions
diff --git a/firmware/drivers/audio/wm8731l.c b/firmware/drivers/audio/wm8721.c index 94efc535e2..9b58454ca8 100644 --- a/firmware/drivers/audio/wm8731l.c +++ b/firmware/drivers/audio/wm8721.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Driver for WM8731L audio codec | 10 | * Driver for WM8721 audio codec |
11 | * | 11 | * |
12 | * Based on code from the ipodlinux project - http://ipodlinux.org/ | 12 | * Based on code from the ipodlinux project - http://ipodlinux.org/ |
13 | * Adapted for Rockbox in January 2006 | 13 | * Adapted for Rockbox in January 2006 |
@@ -46,11 +46,6 @@ const struct sound_settings_info audiohw_settings[] = { | |||
46 | [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, | 46 | [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, |
47 | [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, | 47 | [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, |
48 | [SOUND_STEREO_WIDTH] = {"%", 0, 1, 0, 255, 100}, | 48 | [SOUND_STEREO_WIDTH] = {"%", 0, 1, 0, 255, 100}, |
49 | #ifdef HAVE_RECORDING | ||
50 | [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0}, | ||
51 | [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, | ||
52 | [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, | ||
53 | #endif | ||
54 | }; | 49 | }; |
55 | 50 | ||
56 | /* convert tenth of dB volume (-730..60) to master volume register value */ | 51 | /* convert tenth of dB volume (-730..60) to master volume register value */ |
@@ -118,13 +113,8 @@ void audiohw_enable_output(bool enable) | |||
118 | 113 | ||
119 | codec_set_active(0x0); | 114 | codec_set_active(0x0); |
120 | 115 | ||
121 | #ifdef HAVE_WM8721 | ||
122 | /* DACSEL=1 */ | 116 | /* DACSEL=1 */ |
123 | wmcodec_write(0x4, 0x10); | 117 | wmcodec_write(0x4, 0x10); |
124 | #elif defined HAVE_WM8731 | ||
125 | /* DACSEL=1, BYPASS=1 */ | ||
126 | wmcodec_write(0x4, 0x18); | ||
127 | #endif | ||
128 | 118 | ||
129 | /* set power register to POWEROFF=0 on OUTPD=0, DACPD=0 */ | 119 | /* set power register to POWEROFF=0 on OUTPD=0, DACPD=0 */ |
130 | wmcodec_write(PWRMGMT, 0x67); | 120 | wmcodec_write(PWRMGMT, 0x67); |
@@ -133,7 +123,7 @@ void audiohw_enable_output(bool enable) | |||
133 | /* IWL=00(16 bit) FORMAT=10(I2S format) */ | 123 | /* IWL=00(16 bit) FORMAT=10(I2S format) */ |
134 | wmcodec_write(AINTFCE, 0x42); | 124 | wmcodec_write(AINTFCE, 0x42); |
135 | 125 | ||
136 | audiohw_set_sample_rate(WM8731L_44100HZ); | 126 | audiohw_set_sample_rate(WM8721_USB24_44100HZ); |
137 | 127 | ||
138 | /* set the volume to -6dB */ | 128 | /* set the volume to -6dB */ |
139 | wmcodec_write(LOUTVOL, IPOD_PCM_LEVEL); | 129 | wmcodec_write(LOUTVOL, IPOD_PCM_LEVEL); |
@@ -145,16 +135,8 @@ void audiohw_enable_output(bool enable) | |||
145 | /* 5. Set DACMU = 0 to soft-un-mute the audio DACs. */ | 135 | /* 5. Set DACMU = 0 to soft-un-mute the audio DACs. */ |
146 | wmcodec_write(DACCTRL, 0x0); | 136 | wmcodec_write(DACCTRL, 0x0); |
147 | 137 | ||
148 | #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) | ||
149 | /* We need to enable bit 4 of GPIOL for output for sound on H10 */ | ||
150 | GPIOL_OUTPUT_VAL |= 0x10; | ||
151 | #endif | ||
152 | audiohw_mute(0); | 138 | audiohw_mute(0); |
153 | } else { | 139 | } else { |
154 | #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) | ||
155 | /* We need to disable bit 4 of GPIOL to disable sound on H10 */ | ||
156 | GPIOL_OUTPUT_VAL &= ~0x10; | ||
157 | #endif | ||
158 | audiohw_mute(1); | 140 | audiohw_mute(1); |
159 | } | 141 | } |
160 | } | 142 | } |
@@ -166,32 +148,13 @@ int audiohw_set_master_vol(int vol_l, int vol_r) | |||
166 | /* 1111001 == 0dB */ | 148 | /* 1111001 == 0dB */ |
167 | /* 0110000 == -73dB */ | 149 | /* 0110000 == -73dB */ |
168 | /* 0101111 == mute (0x2f) */ | 150 | /* 0101111 == mute (0x2f) */ |
169 | |||
170 | wmcodec_write(LOUTVOL, VOLUME_ZC_WAIT | vol_l); | 151 | wmcodec_write(LOUTVOL, VOLUME_ZC_WAIT | vol_l); |
171 | wmcodec_write(ROUTVOL, VOLUME_ZC_WAIT | vol_r); | 152 | wmcodec_write(ROUTVOL, VOLUME_ZC_WAIT | vol_r); |
172 | 153 | ||
173 | return 0; | 154 | return 0; |
174 | } | 155 | } |
175 | 156 | ||
176 | int audiohw_set_mixer_vol(int channel1, int channel2) | 157 | /* Nice shutdown of WM8721 codec */ |
177 | { | ||
178 | (void)channel1; | ||
179 | (void)channel2; | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | void audiohw_set_bass(int value) | ||
185 | { | ||
186 | (void)value; | ||
187 | } | ||
188 | |||
189 | void audiohw_set_treble(int value) | ||
190 | { | ||
191 | (void)value; | ||
192 | } | ||
193 | |||
194 | /* Nice shutdown of WM8731 codec */ | ||
195 | void audiohw_close(void) | 158 | void audiohw_close(void) |
196 | { | 159 | { |
197 | /* set DACMU=1 DEEMPH=0 */ | 160 | /* set DACMU=1 DEEMPH=0 */ |
@@ -225,86 +188,3 @@ void audiohw_set_sample_rate(int sampling_control) | |||
225 | wmcodec_write(SAMPCTRL, sampling_control); | 188 | wmcodec_write(SAMPCTRL, sampling_control); |
226 | codec_set_active(0x1); | 189 | codec_set_active(0x1); |
227 | } | 190 | } |
228 | |||
229 | void audiohw_enable_recording(bool source_mic) | ||
230 | { | ||
231 | static int line_level = 0x17; | ||
232 | static int mic_boost = true; | ||
233 | codec_set_active(0x0); | ||
234 | |||
235 | /* set BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 | ||
236 | * LRP=0 IWL=00(16 bit) FORMAT=10(I2S format) */ | ||
237 | wmcodec_write(AINTFCE, 0x42); | ||
238 | |||
239 | wmcodec_write(LOUTVOL, 0x0); /* headphone mute left */ | ||
240 | wmcodec_write(ROUTVOL, 0x0); /* headphone mute right */ | ||
241 | |||
242 | |||
243 | if(source_mic){ | ||
244 | wmcodec_write(LINVOL, 0x80); /* line in mute left */ | ||
245 | wmcodec_write(RINVOL, 0x80); /* line in mute right */ | ||
246 | |||
247 | |||
248 | if (mic_boost) { | ||
249 | wmcodec_write(AAPCTRL, 0x5); /* INSEL=mic, MIC_BOOST=enable */ | ||
250 | } else { | ||
251 | wmcodec_write(AAPCTRL, 0x4); /* INSEL=mic */ | ||
252 | } | ||
253 | } else { | ||
254 | if (line_level == 0) { | ||
255 | wmcodec_write(LINVOL, 0x80); | ||
256 | wmcodec_write(RINVOL, 0x80); | ||
257 | } else { | ||
258 | wmcodec_write(LINVOL, line_level); | ||
259 | wmcodec_write(RINVOL, line_level); | ||
260 | } | ||
261 | wmcodec_write(AAPCTRL, 0xa); /* BY PASS, mute mic, INSEL=line in */ | ||
262 | } | ||
263 | |||
264 | /* disable ADC high pass filter, mute dac */ | ||
265 | wmcodec_write(DACCTRL, 0x9); | ||
266 | |||
267 | /* power on (PWR_OFF=0) */ | ||
268 | if(source_mic){ | ||
269 | /* CLKOUTPD OSCPD OUTPD DACPD LINEINPD */ | ||
270 | wmcodec_write(PWRMGMT, 0x79); | ||
271 | } else { | ||
272 | wmcodec_write(PWRMGMT, 0x7a); /* MICPD */ | ||
273 | } | ||
274 | |||
275 | codec_set_active(0x1); | ||
276 | } | ||
277 | |||
278 | void audiohw_disable_recording(void) | ||
279 | { | ||
280 | /* set DACMU=1 DEEMPH=0 */ | ||
281 | wmcodec_write(DACCTRL, 0x8); | ||
282 | |||
283 | /* ACTIVE=0 */ | ||
284 | codec_set_active(0x0); | ||
285 | |||
286 | /* line in mute left & right*/ | ||
287 | wmcodec_write(LINVOL, 0x80); | ||
288 | wmcodec_write(RINVOL, 0x80); | ||
289 | |||
290 | /* set DACSEL=0, MUTEMIC=1 */ | ||
291 | wmcodec_write(AAPCTRL, 0x2); | ||
292 | |||
293 | /* set POWEROFF=0 OUTPD=0 DACPD=1 */ | ||
294 | wmcodec_write(PWRMGMT, 0x6f); | ||
295 | |||
296 | /* set POWEROFF=1 OUTPD=1 DACPD=1 */ | ||
297 | wmcodec_write(PWRMGMT, 0xff); | ||
298 | } | ||
299 | |||
300 | void audiohw_set_recvol(int left, int right, int type) | ||
301 | { | ||
302 | (void)left; | ||
303 | (void)right; | ||
304 | (void)type; | ||
305 | } | ||
306 | |||
307 | void audiohw_set_monitor(int enable) | ||
308 | { | ||
309 | (void)enable; | ||
310 | } | ||
diff --git a/firmware/drivers/audio/wm8731.c b/firmware/drivers/audio/wm8731.c new file mode 100644 index 0000000000..2e1a978777 --- /dev/null +++ b/firmware/drivers/audio/wm8731.c | |||
@@ -0,0 +1,324 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Driver for WM8731L audio codec | ||
11 | * | ||
12 | * Based on code from the ipodlinux project - http://ipodlinux.org/ | ||
13 | * Adapted for Rockbox in January 2006 | ||
14 | * | ||
15 | * Original file: linux/arch/armnommu/mach-ipod/audio.c | ||
16 | * | ||
17 | * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org) | ||
18 | * | ||
19 | * All files in this archive are subject to the GNU General Public License. | ||
20 | * See the file COPYING in the source tree root for full license agreement. | ||
21 | * | ||
22 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
23 | * KIND, either express or implied. | ||
24 | * | ||
25 | ****************************************************************************/ | ||
26 | #include "config.h" | ||
27 | #include "logf.h" | ||
28 | #include "system.h" | ||
29 | #include "string.h" | ||
30 | #include "audio.h" | ||
31 | |||
32 | #include "wmcodec.h" | ||
33 | #include "audiohw.h" | ||
34 | #include "i2s.h" | ||
35 | |||
36 | const struct sound_settings_info audiohw_settings[] = { | ||
37 | [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25}, | ||
38 | /* HAVE_SW_TONE_CONTROLS */ | ||
39 | [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, | ||
40 | [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, | ||
41 | [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, | ||
42 | [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, | ||
43 | [SOUND_STEREO_WIDTH] = {"%", 0, 1, 0, 255, 100}, | ||
44 | #ifdef HAVE_RECORDING | ||
45 | [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23}, | ||
46 | [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23}, | ||
47 | [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 0}, | ||
48 | #endif | ||
49 | }; | ||
50 | |||
51 | /* Init values/shadows | ||
52 | * Ignore bit 8 since that only specifies "both" for updating | ||
53 | * gains */ | ||
54 | static unsigned char wm8731_regs[7] = | ||
55 | { | ||
56 | [LINVOL] = LINVOL_LINMUTE, | ||
57 | [RINVOL] = RINVOL_RINMUTE, | ||
58 | [LOUTVOL] = ROUTVOL_RZCEN, | ||
59 | [ROUTVOL] = ROUTVOL_RZCEN, | ||
60 | [AAPCTRL] = AAPCTRL_MUTEMIC | AAPCTRL_DACSEL, | ||
61 | [DAPCTRL] = DAPCTRL_DACMU | DAPCTRL_DEEMP_44KHz | DAPCTRL_ADCHPD, | ||
62 | [PDCTRL] = PDCTRL_LINEINPD | PDCTRL_MICPD | PDCTRL_ADCPD | | ||
63 | PDCTRL_OUTPD | PDCTRL_OSCPD | PDCTRL_CLKOUTPD, | ||
64 | }; | ||
65 | |||
66 | static void wm8731_write(int reg, unsigned val) | ||
67 | { | ||
68 | wm8731_regs[reg] = (unsigned char)val; | ||
69 | wmcodec_write(reg, val); | ||
70 | } | ||
71 | |||
72 | static void wm8731_write_and(int reg, unsigned bits) | ||
73 | { | ||
74 | wm8731_write(reg, wm8731_regs[reg] & bits); | ||
75 | } | ||
76 | |||
77 | static void wm8731_write_or(int reg, unsigned bits) | ||
78 | { | ||
79 | wm8731_write(reg, wm8731_regs[reg] | bits); | ||
80 | } | ||
81 | |||
82 | /* convert tenth of dB volume (-730..60) to master volume register value */ | ||
83 | int tenthdb2master(int db) | ||
84 | { | ||
85 | /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ | ||
86 | /* 1111111 == +6dB (0x7f) */ | ||
87 | /* 1111001 == 0dB (0x79) */ | ||
88 | /* 0110000 == -73dB (0x30 */ | ||
89 | /* 0101111 == mute (0x2f) */ | ||
90 | |||
91 | if (db < VOLUME_MIN) { | ||
92 | return 0x2f; | ||
93 | } else { | ||
94 | return((db/10)+0x30+73); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | /* convert tenth of dB volume (-780..0) to mixer volume register value */ | ||
99 | int tenthdb2mixer(int db) | ||
100 | { | ||
101 | if (db < -660) /* 1.5 dB steps */ | ||
102 | return (2640 - db) / 15; | ||
103 | else if (db < -600) /* 0.75 dB steps */ | ||
104 | return (990 - db) * 2 / 15; | ||
105 | else if (db < -460) /* 0.5 dB steps */ | ||
106 | return (460 - db) / 5; | ||
107 | else /* 0.25 dB steps */ | ||
108 | return -db * 2 / 5; | ||
109 | } | ||
110 | |||
111 | int sound_val2phys(int setting, int value) | ||
112 | { | ||
113 | int result; | ||
114 | |||
115 | switch(setting) | ||
116 | { | ||
117 | case SOUND_LEFT_GAIN: | ||
118 | case SOUND_RIGHT_GAIN: | ||
119 | result = (value - 23) * 15; | ||
120 | break; | ||
121 | case SOUND_MIC_GAIN: | ||
122 | result = value * 200; | ||
123 | break; | ||
124 | default: | ||
125 | result = value; | ||
126 | break; | ||
127 | } | ||
128 | |||
129 | return result; | ||
130 | } | ||
131 | |||
132 | void audiohw_mute(bool mute) | ||
133 | { | ||
134 | if (mute) { | ||
135 | /* Set DACMU = 1 to soft-mute the audio DACs. */ | ||
136 | wm8731_write_or(DAPCTRL, DAPCTRL_DACMU); | ||
137 | } else { | ||
138 | /* Set DACMU = 0 to soft-un-mute the audio DACs. */ | ||
139 | wm8731_write_and(DAPCTRL, ~DAPCTRL_DACMU); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static void codec_set_active(int active) | ||
144 | { | ||
145 | /* set active to 0x0 or 0x1 */ | ||
146 | wmcodec_write(ACTIVECTRL, active ? ACTIVECTRL_ACTIVE : 0); | ||
147 | } | ||
148 | |||
149 | void audiohw_preinit(void) | ||
150 | { | ||
151 | i2s_reset(); | ||
152 | |||
153 | /* POWER UP SEQUENCE */ | ||
154 | /* 1) Switch on power supplies. By default the WM8731 is in Standby Mode, | ||
155 | * the DAC is digitally muted and the Audio Interface and Outputs are | ||
156 | * all OFF. */ | ||
157 | wmcodec_write(RESET, RESET_RESET); | ||
158 | |||
159 | /* 2) Set all required bits in the Power Down register (0Ch) to '0'; | ||
160 | * EXCEPT the OUTPD bit, this should be set to '1' (Default). */ | ||
161 | wm8731_write(PDCTRL, wm8731_regs[PDCTRL]); | ||
162 | |||
163 | /* 3) Set required values in all other registers except 12h (Active). */ | ||
164 | wmcodec_write(AINTFCE, AINTFCE_FORMAT_I2S | AINTFCE_IWL_16BIT | | ||
165 | AINTFCE_MS); | ||
166 | wm8731_write(AAPCTRL, wm8731_regs[AAPCTRL]); | ||
167 | wm8731_write(DAPCTRL, wm8731_regs[DAPCTRL]); | ||
168 | wmcodec_write(SAMPCTRL, WM8731_USB24_44100HZ); | ||
169 | |||
170 | /* 5) The last write of the sequence should be setting OUTPD to '0' | ||
171 | * (active) in register 0Ch, enabling the DAC signal path, free | ||
172 | * of any significant power-up noise. */ | ||
173 | wm8731_write_and(PDCTRL, ~PDCTRL_OUTPD); | ||
174 | } | ||
175 | |||
176 | void audiohw_postinit(void) | ||
177 | { | ||
178 | sleep(HZ); | ||
179 | |||
180 | /* 4) Set the ‘Active’ bit in register 12h. */ | ||
181 | codec_set_active(true); | ||
182 | |||
183 | audiohw_mute(false); | ||
184 | |||
185 | #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) | ||
186 | /* We need to enable bit 4 of GPIOL for output for sound on H10 */ | ||
187 | GPIOL_OUTPUT_VAL |= 0x10; | ||
188 | #endif | ||
189 | } | ||
190 | |||
191 | int audiohw_set_master_vol(int vol_l, int vol_r) | ||
192 | { | ||
193 | /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ | ||
194 | /* 1111111 == +6dB */ | ||
195 | /* 1111001 == 0dB */ | ||
196 | /* 0110000 == -73dB */ | ||
197 | /* 0101111 == mute (0x2f) */ | ||
198 | wm8731_write(LOUTVOL, LOUTVOL_LZCEN | (vol_l & LOUTVOL_LHPVOL_MASK)); | ||
199 | wm8731_write(ROUTVOL, ROUTVOL_RZCEN | (vol_r & ROUTVOL_RHPVOL_MASK)); | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | /* Nice shutdown of WM8731 codec */ | ||
204 | void audiohw_close(void) | ||
205 | { | ||
206 | /* POWER DOWN SEQUENCE */ | ||
207 | /* 1) Set the OUTPD bit to '1' (power down). */ | ||
208 | wm8731_write_or(PDCTRL, PDCTRL_OUTPD); | ||
209 | /* 2) Remove the WM8731 supplies. */ | ||
210 | } | ||
211 | |||
212 | void audiohw_set_nsorder(int order) | ||
213 | { | ||
214 | static const unsigned char deemp[4] = | ||
215 | { | ||
216 | DAPCTRL_DEEMP_DISABLE, | ||
217 | DAPCTRL_DEEMP_32KHz, | ||
218 | DAPCTRL_DEEMP_44KHz, | ||
219 | DAPCTRL_DEEMP_48KHz | ||
220 | }; | ||
221 | |||
222 | if ((unsigned)order >= ARRAYLEN(deemp)) | ||
223 | order = 0; | ||
224 | |||
225 | wm8731_write(DAPCTRL, | ||
226 | (wm8731_regs[DAPCTRL] & ~DAPCTRL_DEEMP_MASK) | deemp[order]); | ||
227 | } | ||
228 | |||
229 | void audiohw_set_sample_rate(int sampling_control) | ||
230 | { | ||
231 | codec_set_active(false); | ||
232 | wmcodec_write(SAMPCTRL, sampling_control); | ||
233 | codec_set_active(true); | ||
234 | } | ||
235 | |||
236 | void audiohw_enable_recording(bool source_mic) | ||
237 | { | ||
238 | codec_set_active(false); | ||
239 | |||
240 | wm8731_regs[PDCTRL] &= ~PDCTRL_ADCPD; | ||
241 | wm8731_regs[PDCTRL] |= PDCTRL_DACPD; | ||
242 | wm8731_regs[AAPCTRL] &= ~AAPCTRL_DACSEL; | ||
243 | |||
244 | if (source_mic) { | ||
245 | wm8731_write_or(LINVOL, LINVOL_LINMUTE); | ||
246 | wm8731_write_or(RINVOL, RINVOL_RINMUTE); | ||
247 | wm8731_regs[PDCTRL] &= ~PDCTRL_MICPD; | ||
248 | wm8731_regs[PDCTRL] |= PDCTRL_LINEINPD; | ||
249 | wm8731_regs[AAPCTRL] |= AAPCTRL_INSEL | AAPCTRL_SIDETONE; | ||
250 | wm8731_regs[AAPCTRL] &= ~AAPCTRL_MUTEMIC; | ||
251 | } else { | ||
252 | wm8731_regs[PDCTRL] |= PDCTRL_MICPD; | ||
253 | wm8731_regs[PDCTRL] &= ~PDCTRL_LINEINPD; | ||
254 | wm8731_regs[AAPCTRL] |= AAPCTRL_MUTEMIC | AAPCTRL_BYPASS; | ||
255 | wm8731_regs[AAPCTRL] &= ~(AAPCTRL_INSEL | AAPCTRL_SIDETONE); | ||
256 | } | ||
257 | |||
258 | wm8731_write(PDCTRL, wm8731_regs[PDCTRL]); | ||
259 | wm8731_write(AAPCTRL, wm8731_regs[AAPCTRL]); | ||
260 | |||
261 | if (!source_mic) { | ||
262 | wm8731_regs[AAPCTRL] |= AAPCTRL_INSEL | AAPCTRL_SIDETONE; | ||
263 | wm8731_regs[AAPCTRL] &= ~(AAPCTRL_MUTEMIC | AAPCTRL_BYPASS); | ||
264 | } else { | ||
265 | wm8731_write_and(LINVOL, ~LINVOL_LINMUTE); | ||
266 | wm8731_write_and(RINVOL, ~RINVOL_RINMUTE); | ||
267 | } | ||
268 | |||
269 | codec_set_active(true); | ||
270 | } | ||
271 | |||
272 | void audiohw_disable_recording(void) | ||
273 | { | ||
274 | codec_set_active(false); | ||
275 | |||
276 | /* Mute inputs */ | ||
277 | wm8731_write_or(LINVOL, LINVOL_LINMUTE); | ||
278 | wm8731_write_or(RINVOL, RINVOL_RINMUTE); | ||
279 | wm8731_write_or(AAPCTRL, AAPCTRL_MUTEMIC); | ||
280 | |||
281 | /* Turn off input analog audio paths */ | ||
282 | wm8731_regs[AAPCTRL] &= ~(AAPCTRL_BYPASS | AAPCTRL_SIDETONE); | ||
283 | wm8731_write(AAPCTRL, wm8731_regs[AAPCTRL]); | ||
284 | |||
285 | /* Set power config */ | ||
286 | wm8731_regs[PDCTRL] &= ~PDCTRL_DACPD; | ||
287 | wm8731_regs[PDCTRL] |= PDCTRL_MICPD | PDCTRL_LINEINPD | | ||
288 | PDCTRL_ADCPD; | ||
289 | wm8731_write(PDCTRL, wm8731_regs[PDCTRL]); | ||
290 | |||
291 | /* Select DAC */ | ||
292 | wm8731_write_or(AAPCTRL, AAPCTRL_DACSEL); | ||
293 | |||
294 | codec_set_active(true); | ||
295 | } | ||
296 | |||
297 | void audiohw_set_recvol(int left, int right, int type) | ||
298 | { | ||
299 | switch (type) | ||
300 | { | ||
301 | case AUDIO_GAIN_MIC: | ||
302 | if (left > 0) { | ||
303 | wm8731_write_or(AAPCTRL, AAPCTRL_MIC_BOOST); | ||
304 | } | ||
305 | else { | ||
306 | wm8731_write_and(AAPCTRL, ~AAPCTRL_MIC_BOOST); | ||
307 | } | ||
308 | break; | ||
309 | case AUDIO_GAIN_LINEIN: | ||
310 | wm8731_regs[LINVOL] &= ~LINVOL_MASK; | ||
311 | wm8731_write(LINVOL, wm8731_regs[LINVOL] | (left & LINVOL_MASK)); | ||
312 | wm8731_regs[RINVOL] &= ~RINVOL_MASK; | ||
313 | wm8731_write(RINVOL, wm8731_regs[RINVOL] | (right & RINVOL_MASK)); | ||
314 | break; | ||
315 | default: | ||
316 | return; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | void audiohw_set_monitor(int enable) | ||
321 | { | ||
322 | /* TODO: Implement for FM monitoring */ | ||
323 | (void)enable; | ||
324 | } | ||