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 #ifdef AUDIOHW_HAVE_BASS
37 [SOUND_BASS
] = {"dB", 0, 1, -24, 24, 0},
39 #ifdef AUDIOHW_HAVE_TREBLE
40 [SOUND_TREBLE
] = {"dB", 0, 1, -24, 24, 0},
42 [SOUND_BALANCE
] = {"%", 0, 1,-100, 100, 0},
43 [SOUND_CHANNELS
] = {"", 0, 1, 0, 5, 0},
44 [SOUND_STEREO_WIDTH
] = {"%", 0, 5, 0, 250, 100},
46 [SOUND_LEFT_GAIN
] = {"dB", 1, 1, 0, 31, 23},
47 [SOUND_RIGHT_GAIN
] = {"dB", 1, 1, 0, 31, 23},
48 [SOUND_MIC_GAIN
] = {"dB", 1, 1, 0, 1, 1},
53 static unsigned short codec_volume
;
54 static unsigned short codec_base_gain
;
55 static unsigned short codec_mic_gain
;
56 static int HP_register_value
;
58 static bool HP_on_off_flag
;
60 static void i2s_codec_reset(void)
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
|
64 ICDC_CDCCR1_SUSPD
| ICDC_CDCCR1_RST
);
66 REG_ICDC_CDCCR1
= (ICDC_CDCCR1_SW2ON
| ICDC_CDCCR1_PDVR
| ICDC_CDCCR1_PDVRA
| ICDC_CDCCR1_VRCGL
|
67 ICDC_CDCCR1_VRCGH
| ICDC_CDCCR1_HPOV0
| ICDC_CDCCR1_PDHPM
| ICDC_CDCCR1_PDHP
);
70 static void i2s_codec_init(void)
77 __i2s_internal_codec();
82 __aic_disable_byteswap();
83 __aic_disable_unsignadj();
84 __aic_disable_mono2stereo();
88 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_SUSPD
| ICDC_CDCCR1_RST
);
90 REG_ICDC_CDCCR2
= ( ICDC_CDCCR2_AINVOL(23) | ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_44
)
91 | ICDC_CDCCR2_HPVOL(ICDC_CDCCR2_HPVOL_0
));
94 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_PDVR
| ICDC_CDCCR1_VRCGL
| ICDC_CDCCR1_VRCGH
);
95 REG_ICDC_CDCCR1
|= (ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_HPCG
);
98 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_PDVRA
| ICDC_CDCCR1_HPCG
| ICDC_CDCCR1_PDHPM
| ICDC_CDCCR1_PDHP
);
102 /* CDCCR1.ELININ=0, CDCCR1.EMIC=0, CDCCR1.EADC=0, CDCCR1.SW1ON=0, CDCCR1.EDAC=1, CDCCR1.SW2ON=1, CDCCR1.HPMUTE=0 */
103 REG_ICDC_CDCCR1
= (REG_ICDC_CDCCR1
& ~(ICDC_CDCCR1_ELININ
| ICDC_CDCCR1_EMIC
| ICDC_CDCCR1_EADC
|
104 ICDC_CDCCR1_SW1ON
| ICDC_CDCCR1_HPMUTE
)) | (ICDC_CDCCR1_EDAC
105 | ICDC_CDCCR1_SW2ON
);
107 HP_on_off_flag
= 1; /* HP is on */
111 static void i2s_codec_set_mic(unsigned short v
) /* 0 <= v <= 100 */
117 codec_mic_gain
= 31 * v
/100;
119 REG_ICDC_CDCCR2
= ((REG_ICDC_CDCCR2
& ~(0x1f << 16)) | (codec_mic_gain
<< 16));
122 static void i2s_codec_set_base(unsigned short v
) /* 0 <= v <= 100 */
131 if(v
>= 25 && v
< 50)
133 if(v
>= 50 && v
< 75)
135 if(v
>= 75 && v
<= 100)
138 REG_ICDC_CDCCR2
= ((REG_ICDC_CDCCR2
& ~(0x3 << 4)) | (codec_base_gain
<< 4));
141 static void i2s_codec_set_volume(unsigned short v
) /* 0 <= v <= 100 */
150 if(v
>= 25 && v
< 50)
152 if(v
>= 50 && v
< 75)
154 if(v
>= 75 && v
<= 100)
157 REG_ICDC_CDCCR2
= ((REG_ICDC_CDCCR2
& ~(0x3)) | codec_volume
);
160 static unsigned short i2s_codec_get_bass(void)
165 if(codec_base_gain
== 0)
167 if(codec_base_gain
== 1)
169 if(codec_base_gain
== 2)
171 if(codec_base_gain
== 3)
180 static unsigned short i2s_codec_get_mic(void)
184 val
= 100 * codec_mic_gain
/ 31;
191 static unsigned short i2s_codec_get_volume(void)
196 if(codec_volume
== 0)
198 if(codec_volume
== 1)
200 if(codec_volume
== 2)
202 if(codec_volume
== 3)
211 static unsigned long HP_register_value
;
212 static void HP_turn_on(void)
216 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_SUSPD
| ICDC_CDCCR1_RST
); //set suspend 0
219 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_PDVR
| ICDC_CDCCR1_VRCGL
| ICDC_CDCCR1_VRCGH
);
220 REG_ICDC_CDCCR1
|= (ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_HPCG
);
223 REG_ICDC_CDCCR1
&= ~(ICDC_CDCCR1_PDVRA
| ICDC_CDCCR1_HPCG
| ICDC_CDCCR1_PDHPM
| ICDC_CDCCR1_PDHP
);
226 HP_register_value
= REG_ICDC_CDCCR1
;
229 /*REG_ICDC_CDCCR1 &= 0xfffffffc;
231 REG_ICDC_CDCCR1 |= 0x00040400;
233 REG_ICDC_CDCCR1 &= 0xfffbfbff;
235 REG_ICDC_CDCCR1 &= 0xffe5fcff;
236 REG_ICDC_CDCCR1 |= 0x01000000;
238 REG_ICDC_CDCCR1 &= 0xfffeffff;
240 HP_register_value = REG_ICDC_CDCCR1;*/
246 static void HP_turn_off(void)
250 REG_ICDC_CDCCR1
= HP_register_value
;
251 REG_ICDC_CDCCR1
|= 0x001b0300;
252 REG_ICDC_CDCCR1
&= 0xfeffffff;
255 REG_ICDC_CDCCR1
|= 0x00000002;//set suspend 1
259 REG_ICDC_CDCCR1 = HP_register_value;
260 REG_ICDC_CDCCR1 |= 0x001b0300;
261 REG_ICDC_CDCCR1 &= 0xfeffffff;
263 REG_ICDC_CDCCR1 |= 0x00000400;
265 REG_ICDC_CDCCR1 &= 0xfffffdff;
267 REG_ICDC_CDCCR1 |= 0x00000002;*/
273 static void audiohw_mute(bool mute
)
276 REG_ICDC_CDCCR1
|= ICDC_CDCCR1_HPMUTE
;
278 REG_ICDC_CDCCR1
&= ~ICDC_CDCCR1_HPMUTE
;
281 void audiohw_preinit(void)
285 void audiohw_postinit(void)
291 void audiohw_init(void)
296 void audiohw_set_volume(int v
)
301 unsigned int codec_volume
= ICDC_CDCCR2_HPVOL(v
/ 20);
303 if((REG_ICDC_CDCCR2
& ICDC_CDCCR2_HPVOL(0x3)) != codec_volume
)
304 REG_ICDC_CDCCR2
= (REG_ICDC_CDCCR2
& ~ICDC_CDCCR2_HPVOL(0x3)) | codec_volume
;
308 void audiohw_set_frequency(int freq
)
315 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_8
);
318 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_11
);
321 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_12
);
324 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_16
);
327 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_22
);
330 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_24
);
333 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_32
);
336 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_44
);
339 speed
= ICDC_CDCCR2_SMPR(ICDC_CDCCR2_SMPR_48
);
345 if((REG_ICDC_CDCCR2
& ICDC_CDCCR2_SMPR(0xF)) != speed
)
346 REG_ICDC_CDCCR2
= (REG_ICDC_CDCCR2
& ~ICDC_CDCCR2_SMPR(0xF)) | speed
;
349 int audio_channels
= 2;
350 int audio_output_source
= AUDIO_SRC_PLAYBACK
;
352 void audio_set_output_source(int source
)
354 if((unsigned)source
>= AUDIO_NUM_SOURCES
)
355 source
= AUDIO_SRC_PLAYBACK
;
357 audio_output_source
= source
;
358 } /* audio_set_output_source */
360 void audio_input_mux(int source
, unsigned flags
)
362 static int last_source
= AUDIO_SRC_PLAYBACK
;
363 static bool last_recording
= false;
364 bool recording
= flags
& SRCF_RECORDING
;
368 default: /* playback - no recording */
369 source
= AUDIO_SRC_PLAYBACK
;
370 case AUDIO_SRC_PLAYBACK
:
372 if(source
!= last_source
)
373 REG_ICDC_CDCCR1
= (REG_ICDC_CDCCR1
& ~(ICDC_CDCCR1_ELININ
| ICDC_CDCCR1_EMIC
| ICDC_CDCCR1_EADC
| ICDC_CDCCR1_SW1ON
| ICDC_CDCCR1_HPMUTE
))
374 | (ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_SW2ON
);
377 #if INPUT_SRC_CAPS & SRC_CAP_MIC
378 case AUDIO_SRC_MIC
: /* recording only */
380 if(source
!= last_source
)
381 REG_ICDC_CDCCR1
= (REG_ICDC_CDCCR1
& ~(ICDC_CDCCR1_ELININ
| ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_SW2ON
| ICDC_CDCCR1_HPMUTE
))
382 | (ICDC_CDCCR1_EADC
| ICDC_CDCCR1_SW1ON
| ICDC_CDCCR1_EMIC
);
386 #if INPUT_SRC_CAPS & SRC_CAP_FMRADIO
387 case AUDIO_SRC_FMRADIO
: /* recording and playback */
390 if(source
== last_source
&& recording
== last_recording
)
393 last_recording
= recording
;
396 REG_ICDC_CDCCR1
= (REG_ICDC_CDCCR1
& ~(ICDC_CDCCR1_EMIC
| ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_SW2ON
| ICDC_CDCCR1_HPMUTE
))
397 | (ICDC_CDCCR1_EADC
| ICDC_CDCCR1_SW1ON
| ICDC_CDCCR1_ELININ
);
399 REG_ICDC_CDCCR1
= (REG_ICDC_CDCCR1
& ~(ICDC_CDCCR1_EMIC
| ICDC_CDCCR1_EDAC
| ICDC_CDCCR1_EADC
|
400 ICDC_CDCCR1_SW2ON
| ICDC_CDCCR1_HPMUTE
)) | (ICDC_CDCCR1_SW1ON
| ICDC_CDCCR1_ELININ
);
405 last_source
= source
;
406 } /* audio_input_mux */