diff --git a/hal/msm8974/hw_info.c b/hal/msm8974/hw_info.c index 128e4afe..59bdb562 100644 --- a/hal/msm8974/hw_info.c +++ b/hal/msm8974/hw_info.c @@ -125,7 +125,9 @@ static const snd_device_t helicon_skuab_variant_devices[] = { static void update_hardware_info_8084(struct hardware_info *hw_info, const char *snd_card_name) { - if (!strcmp(snd_card_name, "apq8084-taiko-mtp-snd-card")) { + if (!strcmp(snd_card_name, "apq8084-taiko-mtp-snd-card") || + !strncmp(snd_card_name, "apq8084-taiko-i2s-mtp-snd-card", + sizeof("apq8084-taiko-i2s-mtp-snd-card"))) { strlcpy(hw_info->type, "mtp", sizeof(hw_info->type)); strlcpy(hw_info->name, "apq8084", sizeof(hw_info->name)); hw_info->snd_devices = NULL; @@ -137,6 +139,13 @@ static void update_hardware_info_8084(struct hardware_info *hw_info, const char hw_info->snd_devices = (snd_device_t *)taiko_apq8084_CDP_variant_devices; hw_info->num_snd_devices = ARRAY_SIZE(taiko_apq8084_CDP_variant_devices); strlcpy(hw_info->dev_extn, "-cdp", sizeof(hw_info->dev_extn)); + } else if (!strncmp(snd_card_name, "apq8084-taiko-i2s-cdp-snd-card", + sizeof("apq8084-taiko-i2s-cdp-snd-card"))) { + strlcpy(hw_info->type, " cdp", sizeof(hw_info->type)); + strlcpy(hw_info->name, "apq8084", sizeof(hw_info->name)); + hw_info->snd_devices = NULL; + hw_info->num_snd_devices = 0; + strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn)); } else if (!strcmp(snd_card_name, "apq8084-taiko-liquid-snd-card")) { strlcpy(hw_info->type , " liquid", sizeof(hw_info->type)); strlcpy(hw_info->name, "apq8084", sizeof(hw_info->type)); diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c index 4161d871..b88d86f3 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 @@ struct platform_data { 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 @@ static int set_echo_reference(struct mixer *mixer, const char* ec_ref) 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 @@ static struct csd_data *open_csd_client() __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 @@ static struct csd_data *open_csd_client() __func__, dlerror()); goto error; } else { - csd->init(); + csd->init(i2s_ext_modem); } } return csd; @@ -557,7 +573,23 @@ static void platform_csd_init(struct platform_data *plat_data) 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 @@ void *platform_init(struct audio_device *adev) 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 @@ void *platform_init(struct audio_device *adev) } /* 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 @@ int platform_stop_voice_call(void *platform, uint32_t vsid) 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; diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h index e80d3f1f..e2ec8220 100644 --- a/hal/msm8974/platform.h +++ b/hal/msm8974/platform.h @@ -221,7 +221,7 @@ enum { #define LIB_CSD_CLIENT "libcsd-client.so" /* CSD-CLIENT related functions */ -typedef int (*init_t)(); +typedef int (*init_t)(bool); typedef int (*deinit_t)(); typedef int (*disable_device_t)(); typedef int (*enable_device_config_t)(int, int); @@ -235,6 +235,7 @@ typedef int (*start_playback_t)(uint32_t); typedef int (*stop_playback_t)(uint32_t); typedef int (*start_record_t)(uint32_t, int); typedef int (*stop_record_t)(uint32_t); +typedef int (*get_sample_rate_t)(uint32_t *); /* CSD Client structure */ struct csd_data { void *csd_client; @@ -252,6 +253,7 @@ struct csd_data { stop_playback_t stop_playback; start_record_t start_record; stop_record_t stop_record; + get_sample_rate_t get_sample_rate; }; #endif // QCOM_AUDIO_PLATFORM_H diff --git a/hal/platform_api.h b/hal/platform_api.h index 81291a22..2ec6b50d 100644 --- a/hal/platform_api.h +++ b/hal/platform_api.h @@ -44,6 +44,7 @@ int platform_start_voice_call(void *platform, uint32_t vsid); int platform_stop_voice_call(void *platform, uint32_t vsid); int platform_set_voice_volume(void *platform, int volume); int platform_set_mic_mute(void *platform, bool state); +int platform_get_sample_rate(void *platform, uint32_t *rate); snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices); snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device); int platform_set_hdmi_channels(void *platform, int channel_count); @@ -63,7 +64,7 @@ int platform_update_usecase_from_source(int source, audio_usecase_t usecase); bool platform_listen_update_status(snd_device_t snd_device); /* From platform_info_parser.c */ -int platform_info_init(void); +int platform_info_init(const char *filename); struct audio_offload_info_t; uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info); diff --git a/hal/platform_info.c b/hal/platform_info.c index 8f561071..85a05eb9 100644 --- a/hal/platform_info.c +++ b/hal/platform_info.c @@ -38,7 +38,6 @@ #include "platform_api.h" #include -#define PLATFORM_INFO_XML_PATH "/system/etc/audio_platform_info.xml" #define BUF_SIZE 1024 static void process_device(const XML_Char **attr) @@ -52,20 +51,20 @@ static void process_device(const XML_Char **attr) index = platform_get_snd_device_index((char *)attr[1]); if (index < 0) { - ALOGE("%s: Device %s in %s not found, no ACDB ID set!", - __func__, attr[1], PLATFORM_INFO_XML_PATH); + ALOGE("%s: Device %s in platform info xml not found, no ACDB ID set!", + __func__, attr[1]); goto done; } if (strcmp(attr[2], "acdb_id") != 0) { - ALOGE("%s: Device %s in %s has no acdb_id, no ACDB ID set!", - __func__, attr[1], PLATFORM_INFO_XML_PATH); + ALOGE("%s: Device %s in platform info xml has no acdb_id, no ACDB ID set!", + __func__, attr[1]); goto done; } if(platform_set_snd_device_acdb_id(index, atoi((char *)attr[3])) < 0) { - ALOGE("%s: Device %s in %s, ACDB ID %d was not set!", - __func__, attr[1], PLATFORM_INFO_XML_PATH, atoi((char *)attr[3])); + ALOGE("%s: Device %s in platform info xml ACDB ID %d was not set!", + __func__, attr[1], atoi((char *)attr[3])); goto done; } @@ -91,7 +90,7 @@ static void end_tag(void *userdata, const XML_Char *tag_name) } -int platform_info_init(void) +int platform_info_init(const char *filename) { XML_Parser parser; FILE *file; @@ -99,10 +98,10 @@ int platform_info_init(void) int bytes_read; void *buf; - file = fopen(PLATFORM_INFO_XML_PATH, "r"); + file = fopen(filename, "r"); if (!file) { ALOGD("%s: Failed to open %s, using defaults.", - __func__, PLATFORM_INFO_XML_PATH); + __func__, filename); ret = -ENODEV; goto done; } @@ -134,7 +133,7 @@ int platform_info_init(void) if (XML_ParseBuffer(parser, bytes_read, bytes_read == 0) == XML_STATUS_ERROR) { ALOGE("%s: XML_ParseBuffer failed, for %s", - __func__, PLATFORM_INFO_XML_PATH); + __func__, filename); ret = -EINVAL; goto err_free_parser; } diff --git a/hal/voice.c b/hal/voice.c index 28d44db8..1c3ab383 100644 --- a/hal/voice.c +++ b/hal/voice.c @@ -106,6 +106,7 @@ int start_call(struct audio_device *adev, audio_usecase_t usecase_id) int i, ret = 0; struct audio_usecase *uc_info; int pcm_dev_rx_id, pcm_dev_tx_id; + uint32_t sample_rate = 8000; struct voice_session *session = NULL; struct pcm_config voice_config = pcm_config_voice_call; @@ -133,6 +134,13 @@ int start_call(struct audio_device *adev, audio_usecase_t usecase_id) ret = -EIO; goto error_start_voice; } + ret = platform_get_sample_rate(adev->platform, &sample_rate); + if (ret < 0) { + ALOGE("platform_get_sample_rate error %d\n", ret); + } else { + voice_config.rate = sample_rate; + } + ALOGD("voice_config.rate %d\n", voice_config.rate); ALOGV("%s: Opening PCM playback device card_id(%d) device_id(%d)", __func__, adev->snd_card, pcm_dev_rx_id);