hal: add support for I2S based external modem
There are specific xml files used for I2S based external modem.
Add check to load the correct xml file.
For I2S based external modem, voice sample rate can be 8k or
16k based on vocoder type. Call csd client api to get the
correct sample rate to configure voice call.
Change-Id: Ie9799336620f49a890355be74fe1830eb348cabe
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 4161d87..b88d86f 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -36,6 +36,11 @@
#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
+#define MIXER_XML_PATH_I2S "/system/etc/mixer_paths_i2s.xml"
+
+#define PLATFORM_INFO_XML_PATH "/system/etc/audio_platform_info.xml"
+#define PLATFORM_INFO_XML_PATH_I2S "/system/etc/audio_platform_info_i2s.xml"
+
#define LIB_ACDB_LOADER "libacdbloader.so"
#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
@@ -109,6 +114,7 @@
int fluence_type;
int btsco_sample_rate;
bool slowtalk;
+ bool is_i2s_ext_modem;
/* Audio calibration related functions */
void *acdb_handle;
int voice_feature_set;
@@ -410,7 +416,7 @@
return 0;
}
-static struct csd_data *open_csd_client()
+static struct csd_data *open_csd_client(bool i2s_ext_modem)
{
struct csd_data *csd = calloc(1, sizeof(struct csd_data));
@@ -512,6 +518,16 @@
__func__, dlerror());
goto error;
}
+
+ csd->get_sample_rate = (get_sample_rate_t)dlsym(csd->csd_client,
+ "csd_client_get_sample_rate");
+ if (csd->get_sample_rate == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_get_sample_rate",
+ __func__, dlerror());
+
+ goto error;
+ }
+
csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
if (csd->init == NULL) {
@@ -519,7 +535,7 @@
__func__, dlerror());
goto error;
} else {
- csd->init();
+ csd->init(i2s_ext_modem);
}
}
return csd;
@@ -557,7 +573,23 @@
ALOGD("%s: num_modems %d\n", __func__, mdm_detect_info.num_modems);
if (mdm_detect_info.num_modems > 0)
- plat_data->csd = open_csd_client();
+ plat_data->csd = open_csd_client(plat_data->is_i2s_ext_modem);
+}
+
+static bool platform_is_i2s_ext_modem(const char *snd_card_name,
+ struct platform_data *plat_data)
+{
+ plat_data->is_i2s_ext_modem = false;
+
+ if (!strncmp(snd_card_name, "apq8084-taiko-i2s-mtp-snd-card",
+ sizeof("apq8084-taiko-i2s-mtp-snd-card")) ||
+ !strncmp(snd_card_name, "apq8084-taiko-i2s-cdp-snd-card",
+ sizeof("apq8084-taiko-i2s-cdp-snd-card"))) {
+ plat_data->is_i2s_ext_modem = true;
+ }
+ ALOGV("%s, is_i2s_ext_modem:%d",__func__, plat_data->is_i2s_ext_modem);
+
+ return plat_data->is_i2s_ext_modem;
}
void *platform_init(struct audio_device *adev)
@@ -593,10 +625,16 @@
if (!my_data->hw_info) {
ALOGE("%s: Failed to init hardware info", __func__);
} else {
- if (audio_extn_read_xml(adev, snd_card_num, MIXER_XML_PATH,
- MIXER_XML_PATH_AUXPCM) == -ENOSYS)
+ if (platform_is_i2s_ext_modem(snd_card_name, my_data)) {
+ ALOGD("%s: Call MIXER_XML_PATH_I2S", __func__);
+
+ adev->audio_route = audio_route_init(snd_card_num,
+ MIXER_XML_PATH_I2S);
+ } else if (audio_extn_read_xml(adev, snd_card_num, MIXER_XML_PATH,
+ MIXER_XML_PATH_AUXPCM) == -ENOSYS) {
adev->audio_route = audio_route_init(snd_card_num,
MIXER_XML_PATH);
+ }
if (!adev->audio_route) {
ALOGE("%s: Failed to init audio route controls, aborting.",
__func__);
@@ -695,7 +733,10 @@
}
/* Initialize ACDB ID's */
- platform_info_init();
+ if (my_data->is_i2s_ext_modem)
+ platform_info_init(PLATFORM_INFO_XML_PATH_I2S);
+ else
+ platform_info_init(PLATFORM_INFO_XML_PATH);
/* load csd client */
platform_csd_init(my_data);
@@ -971,6 +1012,20 @@
return ret;
}
+int platform_get_sample_rate(void *platform, uint32_t *rate)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ int ret = 0;
+
+ if ((my_data->csd != NULL) && my_data->is_i2s_ext_modem) {
+ ret = my_data->csd->get_sample_rate(rate);
+ if (ret < 0) {
+ ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret);
+ }
+ }
+ return ret;
+}
+
int platform_set_voice_volume(void *platform, int volume)
{
struct platform_data *my_data = (struct platform_data *)platform;