1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Maurus Cuelenaere
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
29 const struct sound_settings_info audiohw_settings
[] = {
30 #ifdef HAVE_SW_VOLUME_CONTROL
31 [SOUND_VOLUME
] = {"dB", 0, 1, SW_VOLUME_MIN
, 6, 0},
33 [SOUND_VOLUME
] = {"dB", 0, 1, 0, 6, 0},
35 /* HAVE_SW_TONE_CONTROLS */
36 [SOUND_BASS
] = {"dB", 0, 1, -24, 24, 0},
37 [SOUND_TREBLE
] = {"dB", 0, 1, -24, 24, 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},
42 [SOUND_LEFT_GAIN
] = {"dB", 1, 1, 0, 31, 23},
43 [SOUND_RIGHT_GAIN
] = {"dB", 1, 1, 0, 31, 23},
44 [SOUND_MIC_GAIN
] = {"dB", 1, 1, 0, 1, 1},
49 static unsigned short codec_volume
;
50 static unsigned short codec_base_gain
;
51 static unsigned short codec_mic_gain
;
52 static int HP_register_value
;
54 static bool HP_on_off_flag
;
56 static void i2s_codec_reset(void)
58 REG_ICDC_CDCCR1
= (ICDC_CDCCR1_SW2ON
| ICDC_CDCCR1_PDVR
| ICDC_CDCCR1_PDVRA
| ICDC_CDCCR1_VRCGL
|
59 ICDC_CDCCR1_VRCGH
| ICDC_CDCCR1_HPOV0
| ICDC_CDCCR1_PDHPM
| ICDC_CDCCR1_PDHP
|
60 ICDC_CDCCR1_SUSPD
| ICDC_CDCCR1_RST
);
62 REG_ICDC_CDCCR1
= (ICDC_CDCCR1_SW2ON
| ICDC_CDCCR1_PDVR
| ICDC_CDCCR1_PDVRA
| ICDC_CDCCR1_VRCGL
|
63 ICDC_CDCCR1_VRCGH
| ICDC_CDCCR1_HPOV0
| ICDC_CDCCR1_PDHPM
| ICDC_CDCCR1_PDHP
);
66 static void i2s_codec_init(void)
73 __i2s_internal_codec();
78 __aic_disable_byteswap();
79 __aic_disable_unsignadj();
80 __aic_disable_mono2stereo();
84 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_SUSPD
| ICDC_CDCCR1_RST
);
86 REG_ICDC_CDCCR2
= ( ICDC_CDCCR2_AINVOL(23) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_44
)
87 | ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_0
));
90 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_PDVR
| ICDC_CDCCR1_VRCGL
| ICDC_CDCCR1_VRCGH
);
91 REG_ICDC_CDCCR1
|= (ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_HPCG
);
94 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_PDVRA
| ICDC_CDCCR1_HPCG
| ICDC_CDCCR1_PDHPM
| ICDC_CDCCR1_PDHP
);
98 /* CDCCR1.ELININ=0, CDCCR1.EMIC=0, CDCCR1.EADC=0, CDCCR1.SW1ON=0, CDCCR1.EDAC=1, CDCCR1.SW2ON=1, CDCCR1.HPMUTE=0 */
99 REG_ICDC_CDCCR1
= (REG_ICDC_CDCCR1
& ~(ICDC_CDCCR1_ELININ
| ICDC_CDCCR1_EMIC
| ICDC_CDCCR1_EADC
|
100 ICDC_CDCCR1_SW1ON
| ICDC_CDCCR1_HPMUTE
)) | (ICDC_CDCCR1_EDAC
101 | ICDC_CDCCR1_SW2ON
);
103 HP_on_off_flag
= 1; /* HP is on */
107 static void i2s_codec_set_mic(unsigned short v
) /* 0 <= v <= 100 */
113 codec_mic_gain
= 31 * v
/100;
115 REG_ICDC_CDCCR2
= ((REG_ICDC_CDCCR2
& ~(0x1f << 16)) | (codec_mic_gain
<< 16));
118 static void i2s_codec_set_base(unsigned short v
) /* 0 <= v <= 100 */
127 if(v
>= 25 && v
< 50)
129 if(v
>= 50 && v
< 75)
131 if(v
>= 75 && v
<= 100)
134 REG_ICDC_CDCCR2
= ((REG_ICDC_CDCCR2
& ~(0x3 << 4)) | (codec_base_gain
<< 4));
137 static void i2s_codec_set_volume(unsigned short v
) /* 0 <= v <= 100 */
146 if(v
>= 25 && v
< 50)
148 if(v
>= 50 && v
< 75)
150 if(v
>= 75 && v
<= 100)
153 REG_ICDC_CDCCR2
= ((REG_ICDC_CDCCR2
& ~(0x3)) | codec_volume
);
156 static unsigned short i2s_codec_get_bass(void)
161 if(codec_base_gain
== 0)
163 if(codec_base_gain
== 1)
165 if(codec_base_gain
== 2)
167 if(codec_base_gain
== 3)
176 static unsigned short i2s_codec_get_mic(void)
180 val
= 100 * codec_mic_gain
/ 31;
187 static unsigned short i2s_codec_get_volume(void)
192 if(codec_volume
== 0)
194 if(codec_volume
== 1)
196 if(codec_volume
== 2)
198 if(codec_volume
== 3)
207 static unsigned long HP_register_value
;
208 static void HP_turn_on(void)
212 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_SUSPD
| ICDC_CDCCR1_RST
); //set suspend 0
215 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_PDVR
| ICDC_CDCCR1_VRCGL
| ICDC_CDCCR1_VRCGH
);
216 REG_ICDC_CDCCR1
|= (ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_HPCG
);
219 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_PDVRA
| ICDC_CDCCR1_HPCG
| ICDC_CDCCR1_PDHPM
| ICDC_CDCCR1_PDHP
);
222 HP_register_value
= REG_ICDC_CDCCR1
;
225 /*REG_ICDC_CDCCR1 &= 0xfffffffc;
227 REG_ICDC_CDCCR1 |= 0x00040400;
229 REG_ICDC_CDCCR1 &= 0xfffbfbff;
231 REG_ICDC_CDCCR1 &= 0xffe5fcff;
232 REG_ICDC_CDCCR1 |= 0x01000000;
234 REG_ICDC_CDCCR1 &= 0xfffeffff;
236 HP_register_value = REG_ICDC_CDCCR1;*/
242 static void HP_turn_off(void)
246 REG_ICDC_CDCCR1
= HP_register_value
;
247 REG_ICDC_CDCCR1
|= 0x001b0300;
248 REG_ICDC_CDCCR1
&= 0xfeffffff;
251 REG_ICDC_CDCCR1
|= 0x00000002;//set suspend 1
255 REG_ICDC_CDCCR1 = HP_register_value;
256 REG_ICDC_CDCCR1 |= 0x001b0300;
257 REG_ICDC_CDCCR1 &= 0xfeffffff;
259 REG_ICDC_CDCCR1 |= 0x00000400;
261 REG_ICDC_CDCCR1 &= 0xfffffdff;
263 REG_ICDC_CDCCR1 |= 0x00000002;*/
269 static void audiohw_mute(bool mute
)
272 REG_ICDC_CDCCR1
|= ICDC_CDCCR1_HPMUTE
;
274 REG_ICDC_CDCCR1
&= ~ICDC_CDCCR1_HPMUTE
;
277 void audiohw_preinit(void)
281 void audiohw_postinit(void)
287 void audiohw_init(void)
292 void audiohw_set_volume(int v
)
297 unsigned int codec_volume
= ICDC_CDCCR2_HPVOL(v
/ 20);
299 if((REG_ICDC_CDCCR2
& ICDC_CDCCR2_HPVOL(0x3)) != codec_volume
)
300 REG_ICDC_CDCCR2
= (REG_ICDC_CDCCR2
& ~ICDC_CDCCR2_HPVOL(0x3)) | codec_volume
;
304 void audiohw_set_frequency(int freq
)
311 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_8
);
314 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_11
);
317 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_12
);
320 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_16
);
323 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_22
);
326 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_24
);
329 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_32
);
332 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_44
);
335 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48
);
341 if((REG_ICDC_CDCCR2
& ICDC_CDCCR2_SMPR(0xF)) != speed
)
342 REG_ICDC_CDCCR2
= (REG_ICDC_CDCCR2
& ~ICDC_CDCCR2_SMPR(0xF)) | speed
;
345 int audio_channels
= 2;
346 int audio_output_source
= AUDIO_SRC_PLAYBACK
;
348 void audio_set_output_source(int source
)
350 if((unsigned)source
>= AUDIO_NUM_SOURCES
)
351 source
= AUDIO_SRC_PLAYBACK
;
353 audio_output_source
= source
;
354 } /* audio_set_output_source */
356 void audio_input_mux(int source
, unsigned flags
)
358 static int last_source
= AUDIO_SRC_PLAYBACK
;
359 static bool last_recording
= false;
360 bool recording
= flags
& SRCF_RECORDING
;
364 default: /* playback - no recording */
365 source
= AUDIO_SRC_PLAYBACK
;
366 case AUDIO_SRC_PLAYBACK
:
368 if(source
!= last_source
)
369 REG_ICDC_CDCCR1
= (REG_ICDC_CDCCR1
& ~(ICDC_CDCCR1_ELININ
| ICDC_CDCCR1_EMIC
| ICDC_CDCCR1_EADC
| ICDC_CDCCR1_SW1ON
| ICDC_CDCCR1_HPMUTE
))
370 | (ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_SW2ON
);
373 #if INPUT_SRC_CAPS & SRC_CAP_MIC
374 case AUDIO_SRC_MIC
: /* recording only */
376 if(source
!= last_source
)
377 REG_ICDC_CDCCR1
= (REG_ICDC_CDCCR1
& ~(ICDC_CDCCR1_ELININ
| ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_SW2ON
| ICDC_CDCCR1_HPMUTE
))
378 | (ICDC_CDCCR1_EADC
| ICDC_CDCCR1_SW1ON
| ICDC_CDCCR1_EMIC
);
382 #if INPUT_SRC_CAPS & SRC_CAP_FMRADIO
383 case AUDIO_SRC_FMRADIO
: /* recording and playback */
386 if(source
== last_source
&& recording
== last_recording
)
389 last_recording
= recording
;
392 REG_ICDC_CDCCR1
= (REG_ICDC_CDCCR1
& ~(ICDC_CDCCR1_EMIC
| ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_SW2ON
| ICDC_CDCCR1_HPMUTE
))
393 | (ICDC_CDCCR1_EADC
| ICDC_CDCCR1_SW1ON
| ICDC_CDCCR1_ELININ
);
395 REG_ICDC_CDCCR1
= (REG_ICDC_CDCCR1
& ~(ICDC_CDCCR1_EMIC
| ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_EADC
|
396 ICDC_CDCCR1_SW2ON
| ICDC_CDCCR1_HPMUTE
)) | (ICDC_CDCCR1_SW1ON
| ICDC_CDCCR1_ELININ
);
401 last_source
= source
;
402 } /* audio_input_mux */