use correct define for gigabeat fx to enable lineout (was broken in r29588)
[maemo-rb.git] / firmware / drivers / audio / wm8751.c
blobc37341ef2682a6c0aeb50a3c5a3fa90e0facff5b
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Driver for WM8751 audio codec
12 * Based on code from the ipodlinux project - http://ipodlinux.org/
13 * Adapted for Rockbox in December 2005
15 * Original file: linux/arch/armnommu/mach-ipod/audio.c
17 * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
25 * KIND, either express or implied.
27 ****************************************************************************/
28 #include "kernel.h"
29 #include "wmcodec.h"
30 #include "audio.h"
31 #include "audiohw.h"
32 #include "system.h"
34 const struct sound_settings_info audiohw_settings[] = {
35 [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25},
36 [SOUND_BASS] = {"dB", 1, 15, -60, 90, 0},
37 [SOUND_TREBLE] = {"dB", 1, 15, -60, 90, 0},
38 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
39 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
40 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
41 #ifdef HAVE_RECORDING
42 /* -17.25dB to 30.0dB in 0.75dB increments 64 steps*/
43 [SOUND_LEFT_GAIN] = {"dB", 2, 75, -1725, 3000, 0},
44 [SOUND_RIGHT_GAIN] = {"dB", 2, 75, -1725, 3000, 0},
45 [SOUND_MIC_GAIN] = {"dB", 2, 75, -1725, 3000, 3000},
46 #endif
47 #ifdef AUDIOHW_HAVE_BASS_CUTOFF
48 [SOUND_BASS_CUTOFF] = {"Hz", 0, 70, 130, 200, 200},
49 #endif
50 #ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
51 [SOUND_TREBLE_CUTOFF] = {"kHz", 0, 4, 4, 8, 4},
52 #endif
53 #ifdef AUDIOHW_HAVE_DEPTH_3D
54 [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0},
55 #endif
58 static uint16_t wmcodec_regs[WM_NUM_REGS] =
60 [0 ... WM_NUM_REGS-1] = 0x200, /* set invalid data in gaps */
61 #ifdef HAVE_WM8750
62 [LINVOL] = 0x097,
63 [RINVOL] = 0x097,
64 #endif
65 [LOUT1] = 0x079,
66 [ROUT1] = 0x079,
67 [DACCTRL] = 0x008,
68 [AINTFCE] = 0x00a,
69 [CLOCKING] = 0x000,
70 [LEFTGAIN] = 0x0ff,
71 [RIGHTGAIN] = 0x0ff,
72 [BASSCTRL] = 0x00f,
73 [TREBCTRL] = 0x00f,
74 /* [RESET] */
75 #ifdef HAVE_WM8750
76 [ENHANCE_3D] = 0x000,
77 [ALC1] = 0x07b,
78 [ALC2] = 0x000,
79 [ALC3] = 0x032,
80 [NGAT] = 0x000,
81 [LADCVOL] = 0x0c3,
82 [RADCVOL] = 0x0c3,
83 #endif
84 [ADDITIONAL1] = 0x0c0,
85 [ADDITIONAL2] = 0x000,
86 [PWRMGMT1] = 0x000,
87 [PWRMGMT2] = 0x000,
88 [ADDITIONAL3] = 0x000,
89 #ifdef HAVE_WM8750
90 [ADCIM] = 0x000,
91 [ADCL] = 0x000,
92 [ADCR] = 0x000,
93 #endif
94 [LEFTMIX1] = 0x050,
95 [LEFTMIX2] = 0x050,
96 [RIGHTMIX1] = 0x050,
97 [RIGHTMIX2] = 0x050,
98 [MONOMIX1] = 0x050,
99 [MONOMIX2] = 0x050,
100 [LOUT2] = 0x079,
101 [ROUT2] = 0x079,
102 [MONOOUT] = 0x079
105 /* global prescaler vars */
106 static int prescalertone = 0;
107 static int prescaler3d = 0;
109 static void wmcodec_set_reg(unsigned int reg, unsigned int val)
111 if (reg >= WM_NUM_REGS || (wmcodec_regs[reg] & 0x200))
112 /* invalid register */
113 return;
115 wmcodec_regs[reg] = val & 0x1ff;
116 wmcodec_write(reg, wmcodec_regs[reg]);
119 static void wmcodec_set_bits(unsigned int reg, unsigned int bits)
121 wmcodec_set_reg(reg, wmcodec_regs[reg] | bits);
124 static void wmcodec_clear_bits(unsigned int reg, unsigned int bits)
126 wmcodec_set_reg(reg, wmcodec_regs[reg] & ~bits);
129 static void wmcodec_set_masked(unsigned int reg, unsigned int val,
130 unsigned int mask )
132 wmcodec_set_reg(reg, (wmcodec_regs[reg] & ~mask) | val);
135 /* convert tenth of dB volume (-730..60) to master volume register value */
136 int tenthdb2master(int db)
138 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
139 /* 1111111 == +6dB (0x7f) */
140 /* 1111001 == 0dB (0x79) */
141 /* 0110000 == -73dB (0x30) */
142 /* 0101111..0000000 == mute (<= 0x2f) */
143 if (db < VOLUME_MIN)
144 return 0x0;
145 else
146 return (db / 10) + 73 + 0x30;
149 static int tone_tenthdb2hw(int value)
151 /* -6.0db..+0db..+9.0db step 1.5db - translate -60..+0..+90 step 15
152 to 10..6..0 step -1.
154 value = 10 - (value + 60) / 15;
156 if (value == 6)
157 value = 0xf; /* 0db -> off */
159 return value;
162 #ifdef AUDIOHW_HAVE_BASS_CUTOFF
163 void audiohw_set_bass_cutoff(int val)
165 if ( val == 130 )
166 wmcodec_clear_bits(BASSCTRL, BASSCTRL_BC);
167 else
168 wmcodec_set_bits(BASSCTRL, BASSCTRL_BC);
171 #endif
173 #ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
174 void audiohw_set_treble_cutoff(int val)
176 if ( val == 8 )
177 wmcodec_clear_bits(TREBCTRL, TREBCTRL_TC);
178 else
179 wmcodec_set_bits(TREBCTRL, TREBCTRL_TC);
181 #endif
183 #ifdef HAVE_RECORDING
184 static int recvol2hw(int value)
186 /* -1725 to 3000 => 0 ... 23 ... 63 */
187 return ((4 * value) / 300) + 23;
189 #endif
191 int sound_val2phys(int setting, int value)
193 int result;
195 switch (setting)
197 #ifdef AUDIOHW_HAVE_DEPTH_3D
198 case SOUND_DEPTH_3D:
199 result = (100 * value + 8) / 15;
200 break;
201 #endif
202 default:
203 result = value;
206 return result;
209 static void audiohw_mute(bool mute)
211 /* Mute: Set DACMU = 1 to soft-mute the audio DACs. */
212 /* Unmute: Set DACMU = 0 to soft-un-mute the audio DACs. */
213 if (mute)
214 wmcodec_set_bits(DACCTRL, DACCTRL_DACMU);
215 else
216 wmcodec_clear_bits(DACCTRL, DACCTRL_DACMU);
219 /* Reset and power up the WM8751 */
220 void audiohw_preinit(void)
222 #ifdef MROBE_100
223 /* controls headphone ouput */
224 GPIOL_ENABLE |= 0x10;
225 GPIOL_OUTPUT_EN |= 0x10;
226 GPIOL_OUTPUT_VAL |= 0x10; /* disable */
227 #endif
229 #ifdef MPIO_HD200
230 /* control headphone output
231 * disabled on startup
233 and_l(~(1<<25),&GPIO1_OUT);
234 or_l((1<<25), &GPIO1_ENABLE);
235 or_l((1<<25), &GPIO1_FUNCTION);
236 #endif
239 * 1. Switch on power supplies.
240 * By default the WM8751 is in Standby Mode, the DAC is
241 * digitally muted and the Audio Interface, Line outputs
242 * and Headphone outputs are all OFF (DACMU = 1 Power
243 * Management registers 1 and 2 are all zeros).
246 wmcodec_write(RESET, RESET_RESET); /*Reset*/
248 /* 2. Enable Vmid and VREF. */
249 wmcodec_set_bits(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_5K);
251 #ifdef CODEC_SLAVE
252 wmcodec_set_bits(AINTFCE,AINTFCE_WL_16 | AINTFCE_FORMAT_I2S);
253 #else
254 /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */
255 /* IWL=00(16 bit) FORMAT=10(I2S format) */
256 wmcodec_set_bits(AINTFCE, AINTFCE_MS | AINTFCE_WL_16 |
257 AINTFCE_FORMAT_I2S);
258 #endif
259 /* Set default samplerate */
261 audiohw_set_frequency(HW_FREQ_DEFAULT);
264 /* Enable DACs and audio output after a short delay */
265 void audiohw_postinit(void)
267 /* From app notes: allow Vref to stabilize to reduce clicks */
268 sleep(HZ);
270 #ifdef AUDIOHW_HAVE_DEPTH_3D
271 wmcodec_set_bits(ENHANCE_3D, ENHANCE_3D_MODE3D_PLAYBACK);
272 #endif
274 /* 3. Enable DACs as required. */
275 wmcodec_set_bits(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR);
277 /* 4. Enable line and / or headphone output buffers as required. */
278 #if defined(GIGABEAT_F)
279 /* headphones + line-out */
280 wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 |
281 PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2);
282 #else
283 /* headphones */
284 wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
285 #endif
287 /* Full -0dB on the DACS */
288 wmcodec_set_bits(LEFTGAIN, 0xff);
289 wmcodec_set_bits(RIGHTGAIN, RIGHTGAIN_RDVU | 0xff);
291 /* Enable Thermal shutdown, Timeout when zero-crossing in use,
292 * set analog bias for 3.3V, monomix to DACR
294 wmcodec_set_reg(ADDITIONAL1, ADDITIONAL1_TSDEN | ADDITIONAL1_TOEN |
295 ADDITIONAL1_DMONOMIX_LLRR | ADDITIONAL1_VSEL_DEFAULT);
298 /* Enable zero-crossing in out stage */
299 wmcodec_set_bits(LOUT1, LOUT1_LO1ZC);
300 wmcodec_set_bits(ROUT1, ROUT1_RO1ZC);
301 wmcodec_set_bits(LOUT2, LOUT2_LO2ZC);
302 wmcodec_set_bits(ROUT2, ROUT2_RO2ZC);
304 /* route signal from DAC to mixers */
305 wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LD2LO);
306 wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RD2RO);
308 #ifdef TOSHIBA_GIGABEAT_F
309 #ifdef HAVE_HARDWARE_BEEP
310 /* Single-ended mono input */
311 wmcodec_set_reg(MONOMIX1, 0x00);
313 /* Route mono input to both outputs at 0dB */
314 wmcodec_set_reg(LEFTMIX2, LEFTMIX2_MI2LO | LEFTMIX2_MI2LOVOL(2));
315 wmcodec_set_reg(RIGHTMIX1, RIGHTMIX1_MI2RO | RIGHTMIX1_MI2ROVOL(2));
316 #endif
317 #endif
319 /* lower power consumption */
320 wmcodec_set_masked(PWRMGMT1, PWRMGMT1_VMIDSEL_50K,
321 PWRMGMT1_VMIDSEL_MASK);
323 audiohw_mute(false);
325 #ifdef MROBE_100
326 /* enable headphone output */
327 GPIOL_OUTPUT_VAL &= ~0x10;
328 GPIOL_OUTPUT_EN |= 0x10;
329 #endif
331 #ifdef MPIO_HD200
332 /* enable headphone output */
333 or_l((1<<25),&GPIO1_OUT);
334 #endif
337 void audiohw_set_master_vol(int vol_l, int vol_r)
339 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
340 /* 1111111 == +6dB */
341 /* 1111001 == 0dB */
342 /* 0110000 == -73dB */
343 /* 0101111 == mute (0x2f) */
345 wmcodec_set_masked(LOUT1, LOUT1_LOUT1VOL(vol_l),
346 LOUT1_LOUT1VOL_MASK);
347 wmcodec_set_masked(ROUT1, ROUT1_RO1VU | ROUT1_ROUT1VOL(vol_r),
348 ROUT1_ROUT1VOL_MASK);
351 #ifdef TOSHIBA_GIGABEAT_F
352 void audiohw_set_lineout_vol(int vol_l, int vol_r)
354 wmcodec_set_masked(LOUT2, LOUT2_LOUT2VOL(vol_l),
355 LOUT2_LOUT2VOL_MASK);
356 wmcodec_set_masked(ROUT2, ROUT2_RO2VU | ROUT2_ROUT2VOL(vol_r),
357 ROUT2_ROUT2VOL_MASK);
359 #endif
361 void audiohw_set_bass(int value)
363 wmcodec_set_masked(BASSCTRL,
364 BASSCTRL_BASS(tone_tenthdb2hw(value)),
365 BASSCTRL_BASS_MASK);
368 void audiohw_set_treble(int value)
370 wmcodec_set_masked(TREBCTRL, TREBCTRL_TREB(tone_tenthdb2hw(value)),
371 TREBCTRL_TREB_MASK);
374 static void sync_prescaler(void)
376 int prescaler;
377 prescaler = prescalertone + prescaler3d;
379 /* attenuate in 0.5dB steps (0dB - -127dB) */
380 wmcodec_set_reg(LEFTGAIN, 0xff - (prescaler & LEFTGAIN_LDACVOL));
381 wmcodec_set_reg(RIGHTGAIN, RIGHTGAIN_RDVU |
382 (0xff - (prescaler & RIGHTGAIN_RDACVOL)));
385 void audiohw_set_prescaler(int value)
387 prescalertone = 3 * value / 15; /* value in tdB */
388 sync_prescaler();
391 /* Nice shutdown of WM8751 codec */
392 void audiohw_close(void)
394 /* 1. Set DACMU = 1 to soft-mute the audio DACs. */
395 audiohw_mute(true);
397 #ifdef MPIO_HD200
398 /* disable headphone out */
399 and_l(~(1<<25), &GPIO1_OUT);
400 #endif
402 /* 2. Disable all output buffers. */
403 wmcodec_set_reg(PWRMGMT2, 0x0);
405 /* 3. Switch off the power supplies. */
406 wmcodec_set_reg(PWRMGMT1, 0x0);
409 /* According to datasheet of WM8750
410 * clocking setup is needed in both slave and master mode
412 void audiohw_set_frequency(int fsel)
414 (void)fsel;
415 static const unsigned char srctrl_table[HW_NUM_FREQ] =
417 HW_HAVE_11_([HW_FREQ_11] = CODEC_SRCTRL_11025HZ,)
418 HW_HAVE_22_([HW_FREQ_22] = CODEC_SRCTRL_22050HZ,)
419 HW_HAVE_44_([HW_FREQ_44] = CODEC_SRCTRL_44100HZ,)
420 HW_HAVE_88_([HW_FREQ_88] = CODEC_SRCTRL_88200HZ,)
423 if ((unsigned)fsel >= HW_NUM_FREQ)
424 fsel = HW_FREQ_DEFAULT;
426 wmcodec_set_reg(CLOCKING, srctrl_table[fsel]);
429 #ifdef HAVE_WM8750
430 #ifdef AUDIOHW_HAVE_DEPTH_3D
431 /* Set the depth of the 3D effect */
432 void audiohw_set_depth_3d(int val)
434 if (val > 0)
436 wmcodec_set_bits(ENHANCE_3D, ENHANCE_3D_3DEN);
437 wmcodec_set_masked(ENHANCE_3D, ENHANCE_3D_DEPTH(val),
438 ENHANCE_3D_DEPTH_MASK);
440 else
442 wmcodec_clear_bits(ENHANCE_3D, ENHANCE_3D_3DEN);
445 /* -4 dB @ full setting
446 * this gives approximately constant volume on setting change
447 * and prevents clipping (at least on my HD300)
449 prescaler3d = 8*val / 15;
450 sync_prescaler();
452 #endif
454 #ifdef HAVE_RECORDING
455 #if 0
456 static void audiohw_set_ngat(int ngath, int type, bool enable)
458 /* This function controls Noise gate function
459 * of the codec. This can only run in conjunction
460 * with ALC
463 if(enable)
464 wmcodec_set_reg(NGAT, NGAT_NGG(type) |
465 NGAT_NGTH(ngath) | NGAT_NGAT);
466 else
467 wmcodec_clear_bits(NGAT, NGAT_NGAT);
471 static void audiohw_set_alc(unsigned char level, /* signal level at ADC */
472 bool zc, /* zero cross detection */
473 unsigned char hold, /* hold time */
474 unsigned char decay, /* decay time */
475 unsigned char attack, /* attack time */
476 bool enable) /* hw function on/off */
478 if(enable)
480 wmcodec_set_reg(ALC1, ALC1_ALCSEL_STEREO | ALC1_MAXGAIN(0x07) |
481 ALC1_ALCL(level));
482 wmcodec_set_reg(ALC2, zc?ALC2_ALCZC:0 | ALC2_HLD(hold));
483 wmcodec_set_reg(ALC3, ALC3_DCY(decay) | ALC3_ATK(attack));
485 else
487 wmcodec_set_masked(ALC1, ALC1_ALCSEL_DISABLED, ALC1_ALCSEL_MASK);
490 #endif
492 void audiohw_set_recsrc(int source, bool recording)
494 /* INPUT1 - FM radio
495 * INPUT2 - Line-in
496 * INPUT3 - MIC
498 * if recording == false we use analog bypass from input
499 * turn off ADC, PGA to save power
500 * turn on output buffer(s)
502 * if recording == true we route input signal to PGA
503 * and monitoring picks up signal after PGA and ADC
504 * turn on ADC, PGA, DAC, output buffer(s)
507 switch(source)
509 case AUDIO_SRC_PLAYBACK:
510 audiohw_mute(true);
512 /* mute PGA, disable all audio paths but DAC and output stage*/
513 wmcodec_set_bits(LINVOL, LINVOL_LINMUTE); /* Mute */
514 wmcodec_set_bits(RINVOL, RINVOL_RINMUTE); /* Mute */
516 wmcodec_clear_bits(PWRMGMT2, PWRMGMT2_OUT3 | PWRMGMT2_MOUT |
517 PWRMGMT2_ROUT2 | PWRMGMT2_LOUT2);
519 /* route DAC signal to output mixer, disable INPUT routing */
520 wmcodec_clear_bits(LEFTMIX1, LEFTMIX1_LI2LO);
521 wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LD2LO);
522 wmcodec_clear_bits(RIGHTMIX2, RIGHTMIX2_RI2RO);
523 wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RD2RO);
525 /* unmute DAC */
526 audiohw_mute(false);
527 break;
529 case AUDIO_SRC_FMRADIO:
530 if(recording)
532 audiohw_mute(true);
533 /* Turn on PGA and ADC */
534 wmcodec_set_bits(PWRMGMT1, PWRMGMT1_AINL | PWRMGMT1_AINR |
535 PWRMGMT1_ADCL | PWRMGMT1_ADCR);
537 /* Setup input source for PGA as INPUT1 */
538 wmcodec_set_masked(ADCL, ADCL_LINSEL_LINPUT1, ADCL_LINSEL_MASK);
539 wmcodec_set_masked(ADCR, ADCR_RINSEL_RINPUT1, ADCR_RINSEL_MASK);
541 /* turn off ALC and NGAT as OF do */
543 audiohw_set_alc(0x00, false, 0x00, 0x00, 0x00, false);
544 audiohw_set_ngat(0x00, 0x00, false);
547 /* setup output digital data
548 * default is LADC -> LDATA, RADC -> RDATA
549 * so we don't touch this
552 /* skip: power up DAC and output stage as its never powered down
553 wmcodec_set_bits(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
554 PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
557 /* route DAC signal to output mixer, disable INPUT routing */
558 wmcodec_clear_bits(LEFTMIX1, LEFTMIX1_LI2LO);
559 wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LD2LO);
560 wmcodec_clear_bits(RIGHTMIX2, RIGHTMIX2_RI2RO);
561 wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RD2RO);
563 audiohw_mute(false);
565 else
567 audiohw_mute(true);
569 /* turn off ADC, PGA */
570 wmcodec_clear_bits(PWRMGMT1, PWRMGMT1_AINL | PWRMGMT1_AINR |
571 PWRMGMT1_ADCL | PWRMGMT1_ADCR);
573 /* setup monitor mode by routing input signal to outmix
574 * at 0dB volume
576 wmcodec_set_masked(LEFTMIX1, LEFTMIX1_LI2LOVOL(0x20),
577 LEFTMIX1_LI2LOVOL_MASK);
578 wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LI2LO |
579 LEFTMIX1_LMIXSEL_LINPUT1 |
580 LEFTMIX1_LD2LO);
581 wmcodec_set_masked(RIGHTMIX2, RIGHTMIX2_RI2ROVOL(0x20),
582 RIGHTMIX2_RI2ROVOL_MASK);
583 wmcodec_set_bits(RIGHTMIX1, RIGHTMIX1_RMIXSEL_RINPUT1);
584 wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RI2RO |
585 RIGHTMIX2_RD2RO);
587 audiohw_mute(false);
589 break;
591 #if (INPUT_SRC_CAPS & SRC_CAP_LINEIN)
592 case AUDIO_SRC_LINEIN:
593 audiohw_mute(true);
595 /* Turn on PGA, ADC */
596 wmcodec_set_bits(PWRMGMT1, PWRMGMT1_AINL | PWRMGMT1_AINR |
597 PWRMGMT1_ADCL | PWRMGMT1_ADCR);
599 /* Setup input source for PGA as INPUT2
600 * MICBOOST disabled
602 wmcodec_set_masked(ADCL, ADCL_LINSEL_LINPUT2, ADCL_LINSEL_MASK);
603 wmcodec_set_masked(ADCR, ADCR_RINSEL_RINPUT2, ADCR_RINSEL_MASK);
605 /* setup ALC and NGAT as OF do */
606 /* level, zc, hold, decay, attack, enable */
607 /* audiohw_set_alc(0x0b, true, 0x00, 0x03, 0x02, true); */
608 /* ngath, type, enable */
609 /* audiohw_set_ngat(0x08, 0x02, true); */
611 /* setup output digital data
612 * default is LADC -> LDATA, RADC -> RDATA
613 * so we don't touch this
616 /* route DAC signal to output mixer, disable INPUT routing */
617 wmcodec_clear_bits(LEFTMIX1, LEFTMIX1_LI2LO);
618 wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LD2LO);
619 wmcodec_clear_bits(RIGHTMIX2, RIGHTMIX2_RI2RO);
620 wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RD2RO);
622 #if !defined(MPIO_HD300)
623 /* HD300 uses the same socket for headphones and line-in */
624 audiohw_mute(false);
625 #endif
626 break;
627 #endif
628 #if (INPUT_SRC_CAPS & SRC_CAP_MIC)
629 case AUDIO_SRC_MIC:
630 audiohw_mute(true);
632 /* Turn on PGA and ADC */
633 wmcodec_set_bits(PWRMGMT1, PWRMGMT1_AINL | PWRMGMT1_AINR |
634 PWRMGMT1_ADCL | PWRMGMT1_ADCR);
636 /* Setup input source for PGA as INPUT3
637 * MICBOOST disabled
639 wmcodec_set_masked(ADCL, ADCL_LINSEL_LINPUT3, ADCL_LINSEL_MASK);
640 wmcodec_set_masked(ADCR, ADCR_RINSEL_RINPUT3, ADCR_RINSEL_MASK);
642 /* setup ALC and NGAT as OF do */
643 /* level, zc, hold, decay, attack, enable */
644 /* audiohw_set_alc(0x0f, false, 0x00, 0x05, 0x02, true); */
645 /* ngath, type, enable */
646 /* audiohw_set_ngat(0x1f, 0x00, true); */
648 /* setup output digital data
649 * default is LADC -> LDATA, RADC -> RDATA
650 * so we don't touch this
653 /* route DAC signal to output mixer, disable INPUT routing */
654 wmcodec_clear_bits(LEFTMIX1, LEFTMIX1_LI2LO);
655 wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LD2LO);
656 wmcodec_clear_bits(RIGHTMIX2, RIGHTMIX2_RI2RO);
657 wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RD2RO);
659 audiohw_mute(false);
660 break;
661 #endif
662 } /* switch(source) */
665 /* Setup PGA gain */
666 void audiohw_set_recvol(int vol_l, int vol_r, int type)
668 wmcodec_set_reg(LINVOL, LINVOL_LIZC | LINVOL_LINVOL(recvol2hw(vol_l)));
670 if (type == AUDIO_GAIN_MIC)
671 wmcodec_set_reg(RINVOL, RINVOL_RIVU | RINVOL_RIZC |
672 RINVOL_RINVOL(recvol2hw(vol_l)));
673 else
674 wmcodec_set_reg(RINVOL, RINVOL_RIVU | RINVOL_RIZC |
675 RINVOL_RINVOL(recvol2hw(vol_r)));
677 #endif /* HAVE_RECORDING */
678 #endif /* HAVE_WM8750 */