3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 #include <ubi_uboot.h>
30 #include "sound_common.h"
32 #define pr_fmt(fmt) "[sound: htc ]" fmt
34 #define snd_dbg(fmt,args...) pr_info(fmt ,##args)
36 #define snd_dbg(fmt,args...)
40 SOUND_DIGITAL_LOOP = 0x01,
41 SOUND_ANALOG_LOOP = 0x02,
45 SOUND_MAIN_MIC = 0x01,
47 SOUND_HEADSET_MIC = 0x04,
54 SOUND_EARPIECE = 0x02,
55 SOUND_HEADPHONE = 0x04,
56 SOUND_SPEAKER2 = 0x08,
59 static inline char *_2str(int enable)
61 return enable ? "enable" : "disable";
64 static inline int is_analog_loop(int loop)
66 return loop & SOUND_ANALOG_LOOP;
69 static int speaker_pa_enable(int on)
71 sprd_inter_speaker_pa(on);
75 static int hp_pa_enable(int on)
77 #ifdef CONFIG_SOUND_CODEC_SPRD_V3
78 sprd_inter_headphone_pa(on);
83 static int audio_codec(int enable, int loop, int drv_in, int drv_out)
85 static int s_loop = 0;
86 static int s_drv_in = 0;
87 static int s_drv_out = 0;
88 static int s_enable = 0;
89 static int s_adc_power = 0;
90 static int s_dac_power = 0;
91 int adc_need_power_on = 0;
92 int dac_need_power_on = 0;
102 printf("force disable all\n");
108 s_drv_out |= drv_out;
109 if (loop != s_loop) {
111 ("warnning: had some other loop path enable\n");
113 if (drv_in != s_drv_in) {
115 ("warnning: had some other driver in opened\n");
117 if (drv_out != s_drv_out) {
119 ("warnning: had some other driver out opened\n");
124 s_drv_out &= ~drv_out;
125 if ((s_drv_in == 0) && (s_drv_out != 0)) {
127 ("warnning: can't loop by driver in all disable\n");
128 drv_out |= s_drv_out;
133 if ((s_drv_out == 0) && (s_drv_in != 0)) {
135 ("warnning: can't loop by driver out all disable\n");
144 adc_need_power_on = 1;
147 dac_need_power_on = 1;
151 if (adc_need_power_on != s_adc_power) {
154 if (!is_analog_loop(loop)) {
155 adcl_digital_switch(enable);
156 adcr_digital_switch(enable);
158 s_adc_power = adc_need_power_on;
161 if (dac_need_power_on != s_dac_power) {
162 if (!is_analog_loop(loop)) {
163 dacl_digital_switch(enable);
164 dacr_digital_switch(enable);
166 s_dac_power = dac_need_power_on;
170 if (drv_in & SOUND_MAIN_MIC) {
171 printf("main mic %s\n", _2str(enable));
172 mic_bias_enable(SPRD_CODEC_MIC_BIAS, enable);
173 mixer_set(ID_FUN(SPRD_CODEC_MAIN_MIC, SPRD_CODEC_LEFT), enable);
174 mixer_set(ID_FUN(SPRD_CODEC_MAIN_MIC, SPRD_CODEC_RIGHT),
177 if (drv_in & SOUND_AUX_MIC) {
178 printf("aux mic %s\n", _2str(enable));
179 mic_bias_enable(SPRD_CODEC_AUXMIC_BIAS, enable);
180 mixer_set(ID_FUN(SPRD_CODEC_AUX_MIC, SPRD_CODEC_LEFT), enable);
181 mixer_set(ID_FUN(SPRD_CODEC_AUX_MIC, SPRD_CODEC_RIGHT), enable);
183 if (drv_in & SOUND_HEADSET_MIC) {
184 printf("headset mic %s\n", _2str(enable));
185 mixer_set(ID_FUN(SPRD_CODEC_HP_MIC, SPRD_CODEC_LEFT), enable);
186 mixer_set(ID_FUN(SPRD_CODEC_HP_MIC, SPRD_CODEC_RIGHT), enable);
188 if (drv_in & SOUND_AIL) {
189 printf("analog left signal %s\n", _2str(enable));
190 mixer_set(ID_FUN(SPRD_CODEC_AIL, SPRD_CODEC_LEFT), enable);
191 mixer_set(ID_FUN(SPRD_CODEC_AIL, SPRD_CODEC_RIGHT), enable);
193 if (drv_in & SOUND_AIR) {
194 printf("analog right signal %s\n", _2str(enable));
195 mixer_set(ID_FUN(SPRD_CODEC_AIR, SPRD_CODEC_LEFT), enable);
196 mixer_set(ID_FUN(SPRD_CODEC_AIR, SPRD_CODEC_RIGHT), enable);
200 pga_enable(SPRD_CODEC_PGA_ADCL, 0x0A, enable);
201 pga_enable(SPRD_CODEC_PGA_ADCR, 0x0A, enable);
204 if (drv_out & SOUND_SPEAKER) {
205 printf("speaker %s\n", _2str(enable));
207 if (is_analog_loop(loop)) {
208 mixer_set(ID_FUN(SPRD_CODEC_SPK_ADCL, SPRD_CODEC_LEFT),
210 mixer_set(ID_FUN(SPRD_CODEC_SPK_ADCR, SPRD_CODEC_LEFT),
213 mixer_set(ID_FUN(SPRD_CODEC_SPK_DACL, SPRD_CODEC_LEFT),
215 mixer_set(ID_FUN(SPRD_CODEC_SPK_DACR, SPRD_CODEC_LEFT),
218 pga_enable(SPRD_CODEC_PGA_SPKL, 0x03, enable);
219 speaker_pa_enable(enable);
221 if (drv_out & SOUND_EARPIECE) {
222 printf("earpiece %s\n", _2str(enable));
224 if (is_analog_loop(loop)) {
225 printf("[err]earpiece can't support analog loop\n");
228 (SPRD_CODEC_EAR_DACL, SPRD_CODEC_LEFT),
231 pga_enable(SPRD_CODEC_PGA_EAR, 0x0F, enable);
233 if (drv_out & SOUND_HEADPHONE) {
234 printf("headphone %s\n", _2str(enable));
236 if (is_analog_loop(loop)) {
237 mixer_set(ID_FUN(SPRD_CODEC_HP_ADCL, SPRD_CODEC_LEFT),
239 mixer_set(ID_FUN(SPRD_CODEC_HP_ADCR, SPRD_CODEC_RIGHT),
242 mixer_set(ID_FUN(SPRD_CODEC_HP_DACL, SPRD_CODEC_LEFT),
244 mixer_set(ID_FUN(SPRD_CODEC_HP_DACR, SPRD_CODEC_RIGHT),
247 pga_enable(SPRD_CODEC_PGA_HPL, 0x0C, enable);
248 pga_enable(SPRD_CODEC_PGA_HPR, 0x0C, enable);
249 hp_pa_enable(enable);
251 if (drv_out & SOUND_SPEAKER2) {
252 printf("speaker2 %s\n", _2str(enable));
254 if (is_analog_loop(loop)) {
255 mixer_set(ID_FUN(SPRD_CODEC_SPK_ADCL, SPRD_CODEC_RIGHT),
257 mixer_set(ID_FUN(SPRD_CODEC_SPK_ADCR, SPRD_CODEC_RIGHT),
260 mixer_set(ID_FUN(SPRD_CODEC_SPK_DACL, SPRD_CODEC_RIGHT),
262 mixer_set(ID_FUN(SPRD_CODEC_SPK_DACR, SPRD_CODEC_RIGHT),
265 pga_enable(SPRD_CODEC_PGA_SPKR, 0x03, enable);
272 if (adc_need_power_on != s_adc_power) {
273 if (!is_analog_loop(loop)) {
274 adcl_digital_switch(enable);
275 adcr_digital_switch(enable);
279 s_adc_power = adc_need_power_on;
282 if (dac_need_power_on != s_dac_power) {
283 if (!is_analog_loop(loop)) {
284 dacl_digital_switch(enable);
285 dacr_digital_switch(enable);
287 s_dac_power = dac_need_power_on;
291 if (enable == s_enable) {
294 if (enable && loop) {
295 printf("%s audio loop\n", _2str(enable));
296 if (!is_analog_loop(loop)) {
297 sprd_codec_digital_loop(enable);
301 if ((s_drv_in == 0) && (s_drv_out == 0)) {
302 printf("%s audio loop\n", _2str(enable));
303 if (!is_analog_loop(loop)) {
304 sprd_codec_digital_loop(enable);
313 int do_audio_codec(cmd_tbl_t * cmdtp, int flag, int argc, char *const argv[])
316 int loop = SOUND_DIGITAL_LOOP;
317 int drv_in = SOUND_MAIN_MIC;
318 int drv_out = SOUND_SPEAKER;
321 return cmd_usage(cmdtp);
323 enable = simple_strtoul(argv[1], NULL, 16);
325 if (!((enable == 0xA) || (enable == 0xD) || (enable == 0xE))) {
326 printf("enable or disable? please refer:\n");
327 return cmd_usage(cmdtp);
331 drv_in = simple_strtoul(argv[2], NULL, 16);
333 drv_out = simple_strtoul(argv[3], NULL, 16);
335 loop = simple_strtoul(argv[4], NULL, 16);
338 return audio_codec(enable, loop, drv_in, drv_out);
341 #ifdef CONFIG_SOUND_DAI_VBC_R2P0
342 /* audio pin mux function */
344 static int audio_iis_fm(int enable, int port, int drv_out)
347 if (ret = arch_audio_pin_func_i2s_port(port, 0)) {
348 printf("error iis port %d\n", port);
351 printf("iis port %d\n", port);
352 arch_audio_i2s_port_sys_sel(port, I2S_PORT_SYS_SEL_VBC);
354 ret = audio_codec(enable, 0, 0, drv_out);
355 sprd_codec_pcm_set_sample_rate(1, 32000);
356 sprd_codec_pcm_set_sample_rate(0, 32000);
365 vbc_startup(SNDRV_PCM_STREAM_PLAYBACK);
366 vbc_startup(SNDRV_PCM_STREAM_CAPTURE);
368 vbc_dac0_fm_mixer(1);
369 vbc_dac1_fm_mixer(1);
370 vbc_trigger(SNDRV_PCM_STREAM_PLAYBACK, enable);
371 vbc_trigger(SNDRV_PCM_STREAM_CAPTURE, enable);
373 vbc_trigger(SNDRV_PCM_STREAM_PLAYBACK, enable);
374 vbc_trigger(SNDRV_PCM_STREAM_CAPTURE, enable);
375 vbc_dac0_fm_mixer(0);
376 vbc_dac1_fm_mixer(0);
378 vbc_shutdown(SNDRV_PCM_STREAM_PLAYBACK);
379 vbc_shutdown(SNDRV_PCM_STREAM_CAPTURE);
386 int do_audio_iis_fm(cmd_tbl_t * cmdtp, int flag, int argc, char *const argv[])
390 int drv_out = SOUND_SPEAKER;
393 return cmd_usage(cmdtp);
395 enable = simple_strtoul(argv[1], NULL, 16);
397 if (!((enable == 0xA) || (enable == 0xD) || (enable == 0xE))) {
398 printf("enable or disable? please refer:\n");
399 return cmd_usage(cmdtp);
403 port = simple_strtoul(argv[2], NULL, 16);
405 drv_out = simple_strtoul(argv[3], NULL, 16);
408 return audio_iis_fm(enable, port, drv_out);
412 int do_func(cmd_tbl_t * cmdtp, int flag, int argc, char *const argv[])
419 U_BOOT_CMD(audio_codec, 5, 1, do_audio_codec,
420 "switch audio analog route",
422 " - switch audio analog route, switch many driver in/out\n"
423 "audio_codec enable [driver_in] [driver_out] [loop]\n"
424 " enable - enable or diable audio loop\n"
427 " a - force all disable\n"
428 " driver_in - select driver in\n"
429 " 0x01 - main mic(d)\n"
431 " 0x04 - headset mic\n"
434 " driver_out- select driver out\n"
435 " 0x01 - speaker(d)\n"
437 " 0x04 - headphone\n"
439 " loop - select loop\n"
440 " 0x01 - digital loop(d)\n"
441 " 0x02 - analog loop\n"
444 #ifdef CONFIG_SOUND_DAI_VBC_R2P0
445 U_BOOT_CMD(audio_iis_fm, 4, 1, do_audio_iis_fm,
446 "select iis port to play fm",
448 " - select iis port to play fm with vbc fm mixer\n"
449 "audio_iis_fm enable [port] [driver_out]\n"
450 " enable - enable or diable audio loop\n"
453 " a - force all disable\n"
454 " port - select iis port\n"
458 " 3 - iis port 3(d)\n"
459 " driver_out- select driver out\n"
460 " 0x01 - speaker(d)\n"
462 " 0x04 - headphone\n"