From aecc204cd9816405a48eb92c15b3f5d1307337d9 Mon Sep 17 00:00:00 2001 From: UtkarshGupta Date: Mon, 10 Mar 2014 14:12:59 +0530 Subject: i9300: audio: update hal Brings the audio in line with i9305, n7100, n7105 Fixes various issues. Only bug left now is audio stutter in real racing 3 which is probably due to the lovely hwcomposer. Change-Id: I67b0df685e4175b248d2f75608c47cb2bfe85527 --- audio/audio_hw.c | 155 +++++++++++++++++++++++++++++++++++-------------------- audio/audio_hw.h | 39 +++++++------- 2 files changed, 118 insertions(+), 76 deletions(-) mode change 100755 => 100644 audio/audio_hw.c (limited to 'audio') diff --git a/audio/audio_hw.c b/audio/audio_hw.c old mode 100755 new mode 100644 index 3b269f9..64ca452 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -73,7 +73,7 @@ struct pcm_config pcm_config_capture = { struct pcm_config pcm_config_vx = { .channels = 2, - .rate = VX_NB_SAMPLING_RATE, + .rate = VX_WB_SAMPLING_RATE, .period_size = 160, .period_count = 2, .format = PCM_FORMAT_S16_LE, @@ -96,6 +96,8 @@ struct m0_audio_device { int in_device; struct pcm *pcm_modem_dl; struct pcm *pcm_modem_ul; + struct pcm *pcm_bt_dl; + struct pcm *pcm_bt_ul; int in_call; float voice_volume; struct m0_stream_in *active_input; @@ -207,7 +209,7 @@ static void in_update_aux_channels(struct m0_stream_in *in, effect_handle_t effe /* The enable flag when 0 makes the assumption that enums are disabled by * "Off" and integers/booleans by 0 */ -static int set_voicecall_route_by_array(struct mixer *mixer, struct route_setting *route, +static int set_bigroute_by_array(struct mixer *mixer, struct route_setting *route, int enable) { struct mixer_ctl *ctl; @@ -312,7 +314,6 @@ static int set_route_by_array(struct mixer *mixer, struct route_setting *route, void select_devices(struct m0_audio_device *adev) { int i; - if (adev->active_out_device == adev->out_device && adev->active_in_device == adev->in_device) return; @@ -351,17 +352,21 @@ void select_devices(struct m0_audio_device *adev) static int start_call(struct m0_audio_device *adev) { - ALOGE("Opening modem PCMs"); + ALOGV("Opening modem PCMs"); int bt_on; bt_on = adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO; - pcm_config_vx.rate = adev->wb_amr ? VX_WB_SAMPLING_RATE : VX_NB_SAMPLING_RATE; + + if (bt_on) { + /* use amr-nb for bluetooth */ + pcm_config_vx.rate = VX_NB_SAMPLING_RATE; + } else { + pcm_config_vx.rate = adev->wb_amr ? VX_WB_SAMPLING_RATE : VX_NB_SAMPLING_RATE; + } /* Open modem PCM channels */ if (adev->pcm_modem_dl == NULL) { - if (bt_on) - adev->pcm_modem_dl = pcm_open(CARD_DEFAULT, PORT_BT, PCM_OUT, &pcm_config_vx); - else + ALOGD("Opening PCM modem DL stream"); adev->pcm_modem_dl = pcm_open(CARD_DEFAULT, PORT_MODEM, PCM_OUT, &pcm_config_vx); if (!pcm_is_ready(adev->pcm_modem_dl)) { ALOGE("cannot open PCM modem DL stream: %s", pcm_get_error(adev->pcm_modem_dl)); @@ -370,6 +375,7 @@ static int start_call(struct m0_audio_device *adev) } if (adev->pcm_modem_ul == NULL) { + ALOGD("Opening PCM modem UL stream"); adev->pcm_modem_ul = pcm_open(CARD_DEFAULT, PORT_MODEM, PCM_IN, &pcm_config_vx); if (!pcm_is_ready(adev->pcm_modem_ul)) { ALOGE("cannot open PCM modem UL stream: %s", pcm_get_error(adev->pcm_modem_ul)); @@ -377,34 +383,88 @@ static int start_call(struct m0_audio_device *adev) } } + ALOGD("Starting PCM modem streams"); pcm_start(adev->pcm_modem_dl); pcm_start(adev->pcm_modem_ul); + /* Open bluetooth PCM channels */ + if (bt_on) { + ALOGV("Opening bluetooth PCMs"); + + if (adev->pcm_bt_dl == NULL) { + ALOGD("Opening PCM bluetooth DL stream"); + adev->pcm_bt_dl = pcm_open(CARD_DEFAULT, PORT_BT, PCM_OUT, &pcm_config_vx); + if (!pcm_is_ready(adev->pcm_bt_dl)) { + ALOGE("cannot open PCM bluetooth DL stream: %s", pcm_get_error(adev->pcm_bt_dl)); + goto err_open_dl; + } + } + + if (adev->pcm_bt_ul == NULL) { + ALOGD("Opening PCM bluetooth UL stream"); + adev->pcm_bt_ul = pcm_open(CARD_DEFAULT, PORT_BT, PCM_IN, &pcm_config_vx); + if (!pcm_is_ready(adev->pcm_bt_ul)) { + ALOGE("cannot open PCM bluetooth UL stream: %s", pcm_get_error(adev->pcm_bt_ul)); + goto err_open_ul; + } + } + ALOGD("Starting PCM bluetooth streams"); + pcm_start(adev->pcm_bt_dl); + pcm_start(adev->pcm_bt_ul); + } + return 0; err_open_ul: pcm_close(adev->pcm_modem_ul); adev->pcm_modem_ul = NULL; + pcm_close(adev->pcm_bt_ul); + adev->pcm_bt_ul = NULL; err_open_dl: pcm_close(adev->pcm_modem_dl); adev->pcm_modem_dl = NULL; + pcm_close(adev->pcm_bt_dl); + adev->pcm_bt_dl = NULL; return -ENOMEM; } static void end_call(struct m0_audio_device *adev) { - ALOGE("Closing modem PCMs"); - pcm_stop(adev->pcm_modem_dl); - pcm_stop(adev->pcm_modem_ul); - pcm_close(adev->pcm_modem_dl); - pcm_close(adev->pcm_modem_ul); + int bt_on; + bt_on = adev->out_device & AUDIO_DEVICE_OUT_ALL_SCO; + + if (adev->pcm_modem_dl != NULL) { + ALOGD("Stopping modem DL PCM"); + pcm_stop(adev->pcm_modem_dl); + ALOGV("Closing modem DL PCM"); + pcm_close(adev->pcm_modem_dl); + } + if (adev->pcm_modem_ul != NULL) { + ALOGD("Stopping modem UL PCM"); + pcm_stop(adev->pcm_modem_ul); + ALOGV("Closing modem UL PCM"); + pcm_close(adev->pcm_modem_ul); + } adev->pcm_modem_dl = NULL; adev->pcm_modem_ul = NULL; - /* re-enable +30db boost on mics */ - mixer_ctl_set_value(adev->mixer_ctls.mixinl_in1l_volume, 0, 1); - mixer_ctl_set_value(adev->mixer_ctls.mixinl_in2l_volume, 0, 1); + if (bt_on) { + if (adev->pcm_bt_dl != NULL) { + ALOGD("Stopping bluetooth DL PCM"); + pcm_stop(adev->pcm_bt_dl); + ALOGV("Closing bluetooth DL PCM"); + pcm_close(adev->pcm_bt_dl); + } + if (adev->pcm_bt_ul != NULL) { + ALOGD("Stopping bluetooth UL PCM"); + pcm_stop(adev->pcm_bt_ul); + ALOGV("Closing bluetooth UL PCM"); + pcm_close(adev->pcm_bt_ul); + } + } + adev->pcm_bt_dl = NULL; + adev->pcm_bt_ul = NULL; } static void set_eq_filter(struct m0_audio_device *adev) @@ -438,7 +498,7 @@ static void set_incall_device(struct m0_audio_device *adev) device_type = SOUND_AUDIO_PATH_HANDSET; break; case AUDIO_DEVICE_OUT_SPEAKER: - case AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET: + case AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET: case AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET: case AUDIO_DEVICE_OUT_AUX_DIGITAL: device_type = SOUND_AUDIO_PATH_SPEAKER; @@ -532,21 +592,10 @@ static void select_mode(struct m0_audio_device *adev) adev->in_call, adev->mode); if (adev->in_call) { adev->in_call = 0; + ril_set_call_clock_sync(&adev->ril, SOUND_CLOCK_STOP); end_call(adev); force_all_standby(adev); - - ALOGD("%s: set voicecall route: voicecall_default_disable", __func__); - set_voicecall_route_by_array(adev->mixer, voicecall_default_disable, 1); - ALOGD("%s: set voicecall route: default_input_disable", __func__); - set_voicecall_route_by_array(adev->mixer, default_input_disable, 1); - ALOGD("%s: set voicecall route: headset_input_disable", __func__); - set_voicecall_route_by_array(adev->mixer, headset_input_disable, 1); - ALOGD("%s: set voicecall route: bt_disable", __func__); - set_voicecall_route_by_array(adev->mixer, bt_disable, 1); - select_output_device(adev); - //Force Input Standby - adev->in_device = AUDIO_DEVICE_NONE; select_input_device(adev); } } @@ -632,57 +681,51 @@ static void select_output_device(struct m0_audio_device *adev) if (headset_on || headphone_on || speaker_on || earpiece_on) { ALOGD("%s: set voicecall route: voicecall_default", __func__); - set_voicecall_route_by_array(adev->mixer, voicecall_default, 1); + set_bigroute_by_array(adev->mixer, voicecall_default, 1); } else { ALOGD("%s: set voicecall route: voicecall_default_disable", __func__); - set_voicecall_route_by_array(adev->mixer, voicecall_default_disable, 1); + set_bigroute_by_array(adev->mixer, voicecall_default_disable, 1); } if (speaker_on || earpiece_on || headphone_on) { ALOGD("%s: set voicecall route: default_input", __func__); - set_voicecall_route_by_array(adev->mixer, default_input, 1); + set_bigroute_by_array(adev->mixer, default_input, 1); } else { ALOGD("%s: set voicecall route: default_input_disable", __func__); - set_voicecall_route_by_array(adev->mixer, default_input_disable, 1); + set_bigroute_by_array(adev->mixer, default_input_disable, 1); } if (headset_on) { ALOGD("%s: set voicecall route: headset_input", __func__); - set_voicecall_route_by_array(adev->mixer, headset_input, 1); + set_bigroute_by_array(adev->mixer, headset_input, 1); } else { ALOGD("%s: set voicecall route: headset_input_disable", __func__); - set_voicecall_route_by_array(adev->mixer, headset_input_disable, 1); + set_bigroute_by_array(adev->mixer, headset_input_disable, 1); } if (bt_on) { - // bt uses a different port (PORT_BT) for playback, reopen the pcms - end_call(adev); - start_call(adev); ALOGD("%s: set voicecall route: bt_input", __func__); - set_voicecall_route_by_array(adev->mixer, bt_input, 1); + set_bigroute_by_array(adev->mixer, bt_input, 1); ALOGD("%s: set voicecall route: bt_output", __func__); - set_voicecall_route_by_array(adev->mixer, bt_output, 1); + set_bigroute_by_array(adev->mixer, bt_output, 1); } else { ALOGD("%s: set voicecall route: bt_disable", __func__); - set_voicecall_route_by_array(adev->mixer, bt_disable, 1); + set_bigroute_by_array(adev->mixer, bt_disable, 1); } - set_incall_device(adev); } } static void select_input_device(struct m0_audio_device *adev) { - int input_device = AUDIO_DEVICE_BIT_IN | adev->in_device; - - switch(input_device) { + switch(adev->in_device) { case AUDIO_DEVICE_IN_BUILTIN_MIC: ALOGD("%s: AUDIO_DEVICE_IN_BUILTIN_MIC", __func__); break; case AUDIO_DEVICE_IN_BACK_MIC: - ALOGD("%s: AUDIO_DEVICE_IN_BACK_MIC | AUDIO_DEVICE_IN_BUILTIN_MIC", __func__); // Force use both mics for video recording adev->in_device = (AUDIO_DEVICE_IN_BACK_MIC | AUDIO_DEVICE_IN_BUILTIN_MIC) & ~AUDIO_DEVICE_BIT_IN; + ALOGD("%s: AUDIO_DEVICE_IN_BACK_MIC and AUDIO_DEVICE_IN_BUILTIN_MIC", __func__); break; case AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET: ALOGD("%s: AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET", __func__); @@ -2544,12 +2587,12 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) ALOGE("%s: enabling two mic control", __func__); ril_set_two_mic_control(&adev->ril, AUDIENCE, TWO_MIC_SOLUTION_ON); /* sub mic */ - set_voicecall_route_by_array(adev->mixer, noise_suppression, 1); + set_bigroute_by_array(adev->mixer, noise_suppression, 1); } else { ALOGE("%s: disabling two mic control", __func__); ril_set_two_mic_control(&adev->ril, AUDIENCE, TWO_MIC_SOLUTION_OFF); /* sub mic */ - set_voicecall_route_by_array(adev->mixer, noise_suppression_disable, 1); + set_bigroute_by_array(adev->mixer, noise_suppression_disable, 1); } } @@ -2772,8 +2815,8 @@ static const struct { { AUDIO_DEVICE_OUT_SPEAKER, "speaker" }, { AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE, "headphone" }, { AUDIO_DEVICE_OUT_EARPIECE, "earpiece" }, - { AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, "dock" }, - { AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, "dock" }, + { AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, "analogue-dock" }, + { AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, "digital-dock" }, { AUDIO_DEVICE_OUT_ALL_SCO, "sco-out" }, { AUDIO_DEVICE_OUT_AUX_DIGITAL, "aux-digital" }, @@ -3021,6 +3064,10 @@ static int adev_open(const hw_module_t* module, const char* name, return -EINVAL; } + /* +30db boost for mics */ + adev->mixer_ctls.mixinl_in1l_volume = mixer_get_ctl_by_name(adev->mixer, "MIXINL IN1L Volume"); + adev->mixer_ctls.mixinl_in2l_volume = mixer_get_ctl_by_name(adev->mixer, "MIXINL IN2L Volume"); + ret = adev_config_parse(adev); if (ret != 0) goto err_mixer; @@ -3029,15 +3076,13 @@ static int adev_open(const hw_module_t* module, const char* name, pthread_mutex_lock(&adev->lock); adev->mode = AUDIO_MODE_NORMAL; adev->out_device = AUDIO_DEVICE_OUT_SPEAKER; - adev->in_device = AUDIO_DEVICE_NONE; + adev->in_device = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN; select_devices(adev); - /* +30db boost for mics */ - adev->mixer_ctls.mixinl_in1l_volume = mixer_get_ctl_by_name(adev->mixer, "MIXINL IN1L Volume"); - adev->mixer_ctls.mixinl_in2l_volume = mixer_get_ctl_by_name(adev->mixer, "MIXINL IN2L Volume"); - adev->pcm_modem_dl = NULL; adev->pcm_modem_ul = NULL; + adev->pcm_bt_dl = NULL; + adev->pcm_bt_ul = NULL; adev->voice_volume = 1.0f; adev->tty_mode = TTY_MODE_OFF; adev->bluetooth_nrec = true; diff --git a/audio/audio_hw.h b/audio/audio_hw.h index f882959..ae7905e 100644 --- a/audio/audio_hw.h +++ b/audio/audio_hw.h @@ -118,8 +118,6 @@ struct route_setting }; struct route_setting voicecall_default[] = { - { .ctl_name = "AIF2DACL Source", .intval = 0, }, - { .ctl_name = "AIF2DACR Source", .intval = 0, }, { .ctl_name = "AIF2 Mode", .intval = 0, }, { .ctl_name = "DAC1L Mixer AIF1.1 Switch", .intval = 1, }, { .ctl_name = "DAC1R Mixer AIF1.1 Switch", .intval = 1, }, @@ -130,20 +128,20 @@ struct route_setting voicecall_default[] = { }; struct route_setting voicecall_default_disable[] = { - { .ctl_name = "AIF2DACL Source", .intval = 0, }, - { .ctl_name = "AIF2DACR Source", .intval = 1, }, { .ctl_name = "AIF2 Mode", .intval = 0, }, { .ctl_name = "DAC1L Mixer AIF2 Switch", .intval = 0, }, { .ctl_name = "DAC1R Mixer AIF2 Switch", .intval = 0, }, { .ctl_name = "AIF2DAC Mux", .strval = "AIF3DACDAT", }, { .ctl_name = "Main Mic Switch", .intval = 0, }, { .ctl_name = "MIXINL IN1L Switch", .intval = 0, }, + { .ctl_name = "Sub Mic Switch", .intval = 0, }, + { .ctl_name = "MIXINR IN1R Switch", .intval = 0, }, { .ctl_name = NULL, }, }; struct route_setting default_input[] = { { .ctl_name = "Main Mic Switch", .intval = 1, }, - { .ctl_name = "IN1L Volume", .intval = 30, }, + { .ctl_name = "IN1L Volume", .intval = 28, }, { .ctl_name = "MIXINL IN1L Switch", .intval = 1, }, { .ctl_name = "MIXINL IN1L Volume", .intval = 0, }, { .ctl_name = "AIF1ADC1 HPF Mode", .intval = 0, }, @@ -153,7 +151,7 @@ struct route_setting default_input[] = { struct route_setting default_input_disable[] = { { .ctl_name = "Main Mic Switch", .intval = 0, }, - { .ctl_name = "IN1L Volume", .intval = 22, }, + { .ctl_name = "IN1L Volume", .intval = 4, }, { .ctl_name = "MIXINL IN1L Switch", .intval = 0, }, { .ctl_name = "AIF1ADC1 HPF Switch", .intval = 0, }, { .ctl_name = NULL, }, @@ -165,7 +163,6 @@ struct route_setting noise_suppression[] = { { .ctl_name = "MIXINR IN1R Switch", .intval = 1, }, { .ctl_name = "MIXINR IN1R Volume", .intval = 0, }, { .ctl_name = "AIF1ADCR Source", .intval = 1, }, - { .ctl_name = "AIF2ADCR Source", .intval = 1, }, { .ctl_name = NULL, }, }; @@ -181,15 +178,14 @@ struct route_setting headset_input[] = { { .ctl_name = "MIXINL IN1L Switch", .intval = 0, }, { .ctl_name = "MIXINR IN1R Switch", .intval = 0, }, { .ctl_name = "Headset Mic Switch", .intval = 1, }, - { .ctl_name = "IN2L Volume", .intval = 30, }, + { .ctl_name = "IN2L Volume", .intval = 18, }, { .ctl_name = "MIXINL IN2L Switch", .intval = 1, }, { .ctl_name = "MIXINL IN2L Volume", .intval = 0, }, - { .ctl_name = "AIF1ADC1 HPF Mode", .intval = 0, }, + { .ctl_name = "AIF1ADC1 HPF Mode", .intval = 1, }, { .ctl_name = "AIF1ADC1 HPF Switch", .intval = 1, }, { .ctl_name = "AIF1ADC1 Volume", .intval = 96, }, { .ctl_name = "AIF1ADCL Source", .intval = 0, }, { .ctl_name = "AIF1ADCR Source", .intval = 0, }, - { .ctl_name = "AIF2ADCL Source", .intval = 0, }, { .ctl_name = NULL, }, }; @@ -202,24 +198,23 @@ struct route_setting headset_input_disable[] = { }; struct route_setting bt_output[] = { + { .ctl_name = "AIF1DAC1 Volume", .intval = 96, }, + { .ctl_name = "AIF1 Boost Volume", .intval = 0, }, + { .ctl_name = "DAC2 Volume", .intval = 96, }, + { .ctl_name = "AIF2ADC Volume", .intval = 96, }, { .ctl_name = "DAC1L Mixer AIF1.1 Switch", .intval = 1, }, { .ctl_name = "DAC1R Mixer AIF1.1 Switch", .intval = 1, }, { .ctl_name = "AIF3ADC Mux", .intval = 1, }, { .ctl_name = "AIF2DAC2L Mixer AIF1.1 Switch", .intval = 1, }, { .ctl_name = "AIF2DAC2R Mixer AIF1.1 Switch", .intval = 1, }, { .ctl_name = "AIF2DAC Volume", .intval = 96, }, - { .ctl_name = "DAC2 Volume", .intval = 96, }, - { .ctl_name = "AIF2ADC Volume", .intval = 96, }, - { .ctl_name = "Speaker Mixer Volume", .intval = 1, }, - { .ctl_name = "MIXINL IN2L Volume", .intval = 1, }, - { .ctl_name = "IN1L Volume", .intval = 25, }, - { .ctl_name = "IN1R Volume", .intval = 25, }, - { .ctl_name = "Speaker Boost Volume", .intval = 4, }, + { .ctl_name = "MIXINL IN1L Volume", .intval = 1, }, + { .ctl_name = "IN1L Volume", .intval = 28, }, + { .ctl_name = "IN1R Volume", .intval = 28, }, { .ctl_name = "LINEOUT1N Switch", .intval = 0, }, { .ctl_name = "LINEOUT1P Switch", .intval = 0, }, - { .ctl_name = "AIF2DACR Source", .intval = 0, }, { .ctl_name = "AIF1ADC1 HPF Switch", .intval = 0, }, - { .ctl_name = "AIF2ADC HPF Mode", .intval = 1, }, + { .ctl_name = "AIF2ADC HPF Mode", .intval = 3, }, { .ctl_name = "AIF2ADC HPF Switch", .intval = 1, }, { .ctl_name = "AIF2DAC Mux", .strval = "AIF2DACDAT", }, { .ctl_name = "AIF2DAC2R Mixer AIF2 Switch", .intval = 1, }, @@ -231,8 +226,6 @@ struct route_setting bt_input[] = { { .ctl_name = "AIF2ADC Mux", .intval = 1, }, { .ctl_name = "AIF1ADCL Source", .intval = 0, }, { .ctl_name = "AIF1ADCR Source", .intval = 1, }, - { .ctl_name = "AIF2ADCL Source", .intval = 0, }, - { .ctl_name = "AIF2ADCR Source", .intval = 1, }, { .ctl_name = "DAC1L Mixer AIF2 Switch", .intval = 1, }, { .ctl_name = "DAC1R Mixer AIF2 Switch", .intval = 1, }, { .ctl_name = "AIF1ADC1R Mixer AIF2 Switch", .intval = 1, }, @@ -243,6 +236,10 @@ struct route_setting bt_input[] = { }; struct route_setting bt_disable[] = { + { .ctl_name = "AIF1DAC1 Volume", .intval = 96, }, + { .ctl_name = "AIF1 Boost Volume", .intval = 0, }, + { .ctl_name = "DAC2 Volume", .intval = 96, }, + { .ctl_name = "AIF2ADC Volume", .intval = 96, }, { .ctl_name = "AIF2ADC Mux", .intval = 0, }, { .ctl_name = "MIXINL IN2L Volume", .intval = 0, }, { .ctl_name = "LINEOUT1N Switch", .intval = 1, }, -- cgit v1.1