Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a16ad7e authored by Helen Zeng's avatar Helen Zeng
Browse files

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
parent 008aebd1
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -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));
+61 −6
Original line number Diff line number Diff line
@@ -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;
+3 −1
Original line number Diff line number Diff line
@@ -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
+2 −1
Original line number Diff line number Diff line
@@ -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);
+10 −11
Original line number Diff line number Diff line
@@ -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;
        }
Loading