Merge "hal: add support for I2S based external modem"

This commit is contained in:
Linux Build Service Account 2014-03-06 14:09:27 -08:00 committed by Gerrit - the friendly Code Review server
commit 6a4a6b572e
6 changed files with 94 additions and 20 deletions

View File

@ -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));

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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);