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
This commit is contained in:
parent
008aebd15a
commit
6a16ad7ed0
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "platform_api.h"
|
||||
#include <platform.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue