Merge "hal: fix compilation issues with audio FM extention"
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index 61c21d2..fcf5eb0 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -35,6 +35,7 @@
#define AUDIO_PARAMETER_KEY_HANDLE_FM "handle_fm"
#define AUDIO_PARAMETER_KEY_FM_VOLUME "fm_volume"
#define AUDIO_PARAMETER_KEY_REC_PLAY_CONC "rec_play_conc_on"
+#define FM_LOOPBACK_DRAIN_TIME_MS 2
static struct pcm_config pcm_config_fm = {
.channels = 2,
@@ -65,7 +66,7 @@
.scard_state = SND_CARD_STATE_ONLINE,
};
-static int32_t fm_set_volume(struct audio_device *adev, float value)
+static int32_t fm_set_volume(struct audio_device *adev, float value, bool persist)
{
int32_t vol, ret = 0;
struct mixer_ctl *ctl;
@@ -82,7 +83,8 @@
value = 1.0;
}
vol = lrint((value * 0x2000) + 0.5);
- fmmod.fm_volume = value;
+ if (persist)
+ fmmod.fm_volume = value;
if (!fmmod.is_fm_running) {
ALOGV("%s: FM not active, ignoring set_fm_volume call", __func__);
@@ -202,7 +204,7 @@
pcm_start(fmmod.fm_pcm_tx);
fmmod.is_fm_running = true;
- fm_set_volume(adev, fmmod.fm_volume);
+ fm_set_volume(adev, fmmod.fm_volume, false);
ALOGD("%s: exit: status(%d)", __func__, ret);
return 0;
@@ -263,8 +265,11 @@
adev->primary_output->devices = val & ~AUDIO_DEVICE_OUT_FM;
fm_start(adev);
} else if (!(val & AUDIO_DEVICE_OUT_FM)
- && fmmod.is_fm_running == true)
+ && fmmod.is_fm_running == true) {
+ fm_set_volume(adev, 0, false);
+ usleep(FM_LOOPBACK_DRAIN_TIME_MS*1000);
fm_stop(adev);
+ }
}
}
@@ -278,7 +283,7 @@
goto exit;
}
ALOGD("%s: set_fm_volume usecase", __func__);
- fm_set_volume(adev, vol);
+ fm_set_volume(adev, vol, true);
}
#ifdef RECORD_PLAY_CONCURRENCY
@@ -293,7 +298,7 @@
ALOGD("Record play concurrency OFF Forcing FM device reroute");
select_devices(adev, USECASE_AUDIO_PLAYBACK_FM);
- fm_set_volume(adev,fmmod.fm_volume);
+ fm_set_volume(adev, fmmod.fm_volume, false);
}
#endif
exit:
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 308a6a8..6af23f1 100755
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -915,6 +915,8 @@
if (out_snd_device == usecase->out_snd_device &&
in_snd_device == usecase->in_snd_device) {
+ audio_extn_dolby_set_endpoint(adev);
+ audio_extn_dolby_ds2_set_endpoint(adev);
return 0;
}
@@ -2958,6 +2960,12 @@
} else {
ALOGV("%s:: inserting OFFLOAD_USECASE", __func__);
out->usecase = get_offload_usecase(adev);
+
+ out->stream.set_callback = out_set_callback;
+ out->stream.pause = out_pause;
+ out->stream.resume = out_resume;
+ out->stream.drain = out_drain;
+ out->stream.flush = out_flush;
}
if (config->offload_info.channel_mask)
out->channel_mask = config->offload_info.channel_mask;
@@ -2968,11 +2976,6 @@
format = out->format = config->offload_info.format;
out->sample_rate = config->offload_info.sample_rate;
- out->stream.set_callback = out_set_callback;
- out->stream.pause = out_pause;
- out->stream.resume = out_resume;
- out->stream.drain = out_drain;
- out->stream.flush = out_flush;
out->bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
if (audio_extn_is_dolby_format(config->offload_info.format))
diff --git a/policy_hal/Android.mk b/policy_hal/Android.mk
index 4385f1a..9fb49ac 100644
--- a/policy_hal/Android.mk
+++ b/policy_hal/Android.mk
@@ -59,6 +59,10 @@
LOCAL_CFLAGS += -DAUDIO_EXTN_AFE_PROXY_ENABLED
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FM_POWER_OPT)),true)
+LOCAL_CFLAGS += -DFM_POWER_OPT
+endif
+
LOCAL_MODULE := libaudiopolicymanager
include $(BUILD_SHARED_LIBRARY)
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index b69968f..70f8d1e 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -250,6 +250,23 @@
audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
updateCallRouting(newDevice);
}
+
+#ifdef FM_POWER_OPT
+ // handle FM device connection state to trigger FM AFE loopback
+ if(device == AUDIO_DEVICE_OUT_FM && hasPrimaryOutput()) {
+ audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
+ if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
+ mPrimaryOutput->changeRefCount(AUDIO_STREAM_MUSIC, 1);
+ newDevice = newDevice | AUDIO_DEVICE_OUT_FM;
+ } else {
+ mPrimaryOutput->changeRefCount(AUDIO_STREAM_MUSIC, -1);
+ }
+ AudioParameter param = AudioParameter();
+ param.addInt(String8("handle_fm"), (int)newDevice);
+ mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString());
+ }
+#endif /* FM_POWER_OPT end */
+
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
@@ -1228,6 +1245,13 @@
mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
mLastVoiceVolume = voiceVolume;
}
+#ifdef FM_POWER_OPT
+ } else if (stream == AUDIO_STREAM_MUSIC && hasPrimaryOutput() &&
+ outputDesc == mPrimaryOutput) {
+ AudioParameter param = AudioParameter();
+ param.addFloat(String8("fm_volume"), Volume::DbToAmpl(volumeDb));
+ mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString(), delayMs);
+#endif /* FM_POWER_OPT end */
}
return NO_ERROR;