hal: add DSDA support on APQ targets
-This change adds DSDA support for APQ based targets
where external modem is used for voice calls.
-Add new CSD API to support local call hold.
Change-Id: I7743a1df43dc1abac4e325ff104ec1bb64c9e12b
diff --git a/hal/Android.mk b/hal/Android.mk
index 73ae361..5f1c028 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -43,6 +43,8 @@
LOCAL_SRC_FILES += audio_extn/audio_extn.c \
audio_extn/utils.c
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PCM_OFFLOAD)),true)
LOCAL_CFLAGS += -DPCM_OFFLOAD_ENABLED
@@ -89,8 +91,7 @@
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MULTI_VOICE_SESSIONS)),true)
LOCAL_CFLAGS += -DMULTI_VOICE_SESSION_ENABLED
LOCAL_SRC_FILES += voice_extn/voice_extn.c
- LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
- LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_INCALL_MUSIC)),true)
LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
endif
@@ -108,8 +109,6 @@
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SPKR_PROTECTION)),true)
LOCAL_CFLAGS += -DSPKR_PROT_ENABLED
LOCAL_SRC_FILES += audio_extn/spkr_protection.c
- LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
- LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
endif
ifdef MULTIPLE_HW_VARIANTS_ENABLED
@@ -124,8 +123,6 @@
ifeq ($(strip $(DOLBY_DDP)),true)
LOCAL_CFLAGS += -DDS1_DOLBY_DDP_ENABLED
- LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
- LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_SRC_FILES += audio_extn/dolby.c
endif
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index d10566d..bd1b235 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -628,6 +628,8 @@
{
snd_device_t out_snd_device = SND_DEVICE_NONE;
snd_device_t in_snd_device = SND_DEVICE_NONE;
+ snd_device_t prev_out_snd_device = SND_DEVICE_NONE;
+ snd_device_t prev_in_snd_device = SND_DEVICE_NONE;
struct audio_usecase *usecase = NULL;
struct audio_usecase *vc_usecase = NULL;
struct audio_usecase *voip_usecase = NULL;
@@ -723,7 +725,9 @@
* and enable both RX and TX devices though one of them is same as current
* device.
*/
- if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL) {
+ if ((usecase->type == VOICE_CALL) &&
+ (usecase->in_snd_device != SND_DEVICE_NONE) &&
+ (usecase->out_snd_device != SND_DEVICE_NONE)) {
status = platform_switch_voice_call_device_pre(adev->platform);
}
@@ -742,10 +746,13 @@
* New device information should be sent to modem before enabling
* the devices to reduce in-call device switch time.
*/
- if (usecase->type == VOICE_CALL)
+ if ((usecase->type == VOICE_CALL) &&
+ (usecase->in_snd_device != SND_DEVICE_NONE) &&
+ (usecase->out_snd_device != SND_DEVICE_NONE)) {
status = platform_switch_voice_call_enable_device_config(adev->platform,
out_snd_device,
in_snd_device);
+ }
/* Enable new sound devices */
if (out_snd_device != SND_DEVICE_NONE) {
@@ -764,6 +771,12 @@
out_snd_device,
in_snd_device);
+ /* Cache the current usecase devices. This is required to avoid
+ * sending device enable command to the external modem.
+ */
+ prev_in_snd_device = usecase->in_snd_device;
+ prev_out_snd_device = usecase->out_snd_device;
+
usecase->in_snd_device = in_snd_device;
usecase->out_snd_device = out_snd_device;
@@ -773,10 +786,13 @@
* Enable device command should be sent to modem only after
* enabling voice call mixer controls
*/
- if (usecase->type == VOICE_CALL)
+ if ((usecase->type == VOICE_CALL) &&
+ (prev_in_snd_device != SND_DEVICE_NONE) &&
+ (prev_out_snd_device != SND_DEVICE_NONE)) {
status = platform_switch_voice_call_usecase_route_post(adev->platform,
out_snd_device,
in_snd_device);
+ }
ALOGD("%s: done",__func__);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 6e52779..5bd37ee 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <dlfcn.h>
+#include <sys/ioctl.h>
#include <cutils/log.h>
#include <cutils/properties.h>
#include <cutils/str_parms.h>
@@ -551,6 +552,14 @@
__func__, dlerror());
goto error;
}
+ csd->set_lch = (set_lch_t)dlsym(csd->csd_client, "csd_client_set_lch");
+ if (csd->set_lch == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_set_lch",
+ __func__, dlerror());
+ /* Ignore the error as this is not mandatory function for
+ * basic voice call to work.
+ */
+ }
csd->start_record = (start_record_t)dlsym(csd->csd_client,
"csd_client_start_record");
if (csd->start_record == NULL) {
@@ -1853,6 +1862,20 @@
return ret;
}
+int platform_update_lch(void *platform, struct voice_session *session,
+ enum voice_lch_mode lch_mode)
+{
+ int ret = 0;
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if ((my_data->csd != NULL) && (my_data->csd->set_lch != NULL))
+ ret = my_data->csd->set_lch(session->vsid, lch_mode);
+ else
+ ret = pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode);
+
+ return ret;
+}
+
void platform_get_parameters(void *platform,
struct str_parms *query,
struct str_parms *reply)
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index f12697c..4ab5394 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -19,6 +19,7 @@
#ifndef QCOM_AUDIO_PLATFORM_H
#define QCOM_AUDIO_PLATFORM_H
+#include <sound/voice_params.h>
enum {
FLUENCE_NONE,
@@ -205,6 +206,7 @@
typedef int (*stop_voice_t)(uint32_t);
typedef int (*start_playback_t)(uint32_t);
typedef int (*stop_playback_t)(uint32_t);
+typedef int (*set_lch_t)(uint32_t, enum voice_lch_mode);
typedef int (*start_record_t)(uint32_t, int);
typedef int (*stop_record_t)(uint32_t);
/* CSD Client structure */
@@ -222,6 +224,7 @@
stop_voice_t stop_voice;
start_playback_t start_playback;
stop_playback_t stop_playback;
+ set_lch_t set_lch;
start_record_t start_record;
stop_record_t stop_record;
};
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 13f5473..fd62256 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -895,6 +895,14 @@
return -ENOSYS;
}
+int platform_update_lch(void *platform __unused,
+ struct voice_session *session __unused,
+ enum voice_lch_mode lch_mode __unused)
+{
+ LOGE("%s: Not implemented", __func__);
+ return -ENOSYS;
+}
+
/* Delay in Us */
int64_t platform_render_latency(audio_usecase_t usecase)
{
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 52c6fec..9accd1b 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <dlfcn.h>
+#include <sys/ioctl.h>
#include <cutils/log.h>
#include <cutils/properties.h>
#include <cutils/str_parms.h>
@@ -563,6 +564,14 @@
__func__, dlerror());
goto error;
}
+ csd->set_lch = (set_lch_t)dlsym(csd->csd_client, "csd_client_set_lch");
+ if (csd->set_lch == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_set_lch",
+ __func__, dlerror());
+ /* Ignore the error as this is not mandatory function for
+ * basic voice call to work.
+ */
+ }
csd->start_record = (start_record_t)dlsym(csd->csd_client,
"csd_client_start_record");
if (csd->start_record == NULL) {
@@ -2044,6 +2053,20 @@
return ret;
}
+int platform_update_lch(void *platform, struct voice_session *session,
+ enum voice_lch_mode lch_mode)
+{
+ int ret = 0;
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if ((my_data->csd != NULL) && (my_data->csd->set_lch != NULL))
+ ret = my_data->csd->set_lch(session->vsid, lch_mode);
+ else
+ ret = pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode);
+
+ return ret;
+}
+
void platform_get_parameters(void *platform,
struct str_parms *query,
struct str_parms *reply)
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 956e395..19f37c7 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -19,6 +19,7 @@
#ifndef QCOM_AUDIO_PLATFORM_H
#define QCOM_AUDIO_PLATFORM_H
+#include <sound/voice_params.h>
enum {
FLUENCE_NONE,
@@ -190,13 +191,15 @@
#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 14
#elif PLATFORM_MSM8x26
#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 16
+#elif PLATFORM_APQ8084
+#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 34
#else
#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 35
#endif
#define SPKR_PROT_CALIB_RX_PCM_DEVICE 5
#ifdef PLATFORM_APQ8084
-#define SPKR_PROT_CALIB_TX_PCM_DEVICE 33
+#define SPKR_PROT_CALIB_TX_PCM_DEVICE 35
#else
#define SPKR_PROT_CALIB_TX_PCM_DEVICE 25
#endif
@@ -302,6 +305,7 @@
typedef int (*stop_voice_t)(uint32_t);
typedef int (*start_playback_t)(uint32_t);
typedef int (*stop_playback_t)(uint32_t);
+typedef int (*set_lch_t)(uint32_t, enum voice_lch_mode);
typedef int (*start_record_t)(uint32_t, int);
typedef int (*stop_record_t)(uint32_t);
typedef int (*get_sample_rate_t)(uint32_t *);
@@ -320,6 +324,7 @@
stop_voice_t stop_voice;
start_playback_t start_playback;
stop_playback_t stop_playback;
+ set_lch_t set_lch;
start_record_t start_record;
stop_record_t stop_record;
get_sample_rate_t get_sample_rate;
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 66b090e..6c64073 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -19,6 +19,7 @@
#ifndef AUDIO_PLATFORM_API_H
#define AUDIO_PLATFORM_API_H
+#include <sound/voice_params.h>
void *platform_init(struct audio_device *adev);
void platform_deinit(void *platform);
@@ -63,6 +64,8 @@
int platform_stop_incall_recording_usecase(void *platform);
int platform_start_incall_music_usecase(void *platform);
int platform_stop_incall_music_usecase(void *platform);
+int platform_update_lch(void *platform, struct voice_session *session,
+ enum voice_lch_mode lch_mode);
/* returns the latency for a usecase in Us */
int64_t platform_render_latency(audio_usecase_t usecase);
int platform_update_usecase_from_source(int source, audio_usecase_t usecase);
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index ea25a4b..b73eb31 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -187,11 +187,11 @@
case CALL_LOCAL_HOLD:
ALOGD("%s: LOCAL_HOLD -> ACTIVE vsid:%x", __func__, session->vsid);
lch_mode = VOICE_LCH_STOP;
- if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) {
- ALOGE("LOCAL_HOLD -> ACTIVE failed");
- } else {
+ ret = platform_update_lch(adev->platform, session, lch_mode);
+ if (ret < 0)
+ ALOGE("%s: lch mode update failed, ret = %d", __func__, ret);
+ else
session->state.current = session->state.new;
- }
break;
default:
@@ -239,11 +239,11 @@
case CALL_LOCAL_HOLD:
ALOGD("%s: CALL_LOCAL_HOLD -> HOLD vsid:%x", __func__, session->vsid);
lch_mode = VOICE_LCH_STOP;
- if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) {
- ALOGE("LOCAL_HOLD -> HOLD failed");
- } else {
+ ret = platform_update_lch(adev->platform, session, lch_mode);
+ if (ret < 0)
+ ALOGE("%s: lch mode update failed, ret = %d", __func__, ret);
+ else
session->state.current = session->state.new;
- }
break;
default:
@@ -261,11 +261,11 @@
ALOGD("%s: ACTIVE/CALL_HOLD -> LOCAL_HOLD vsid:%x", __func__,
session->vsid);
lch_mode = VOICE_LCH_START;
- if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) {
- ALOGE("LOCAL_HOLD -> HOLD failed");
- } else {
+ ret = platform_update_lch(adev->platform, session, lch_mode);
+ if (ret < 0)
+ ALOGE("%s: lch mode update failed, ret = %d", __func__, ret);
+ else
session->state.current = session->state.new;
- }
break;
default: