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

Commit c497a3ca authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "hal: add voice call support on apq8084"

parents abca4b12 d9d9ff34
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ endif
ifneq ($(filter msm8226,$(TARGET_BOARD_PLATFORM)),)
  LOCAL_CFLAGS := -DPLATFORM_MSM8x26
endif
ifneq ($(filter apq8084,$(TARGET_BOARD_PLATFORM)),)
  LOCAL_CFLAGS := -DPLATFORM_APQ8084
endif
endif

LOCAL_SRC_FILES := \
+216 −13
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ struct audio_block_header
    int length;
};

/* Audio calibration related functions */
typedef void (*acdb_deallocate_t)();
typedef int  (*acdb_init_t)();
typedef void (*acdb_send_audio_cal_t)(int, int);
@@ -93,6 +94,7 @@ struct platform_data {
    acdb_send_voice_cal_t acdb_send_voice_cal;

    void *hw_info;
    struct csd_data *csd;
};

static const int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -293,8 +295,133 @@ static int set_echo_reference(struct mixer *mixer, const char* ec_ref)
    return 0;
}

static struct csd_data *open_csd_client()
{
    struct csd_data *csd = calloc(1, sizeof(struct csd_data));

    csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
    if (csd->csd_client == NULL) {
        ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
        goto error;
    } else {
        ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);

        csd->deinit = (deinit_t)dlsym(csd->csd_client,
                                             "csd_client_deinit");
        if (csd->deinit == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
                  dlerror());
            goto error;
        }
        csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
                                             "csd_client_disable_device");
        if (csd->disable_device == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_disable_device",
                  __func__, dlerror());
            goto error;
        }
        csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
                                             "csd_client_enable_device");
        if (csd->enable_device == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_enable_device",
                  __func__, dlerror());
            goto error;
        }
        csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
                                             "csd_client_start_voice");
        if (csd->start_voice == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_start_voice",
                  __func__, dlerror());
            goto error;
        }
        csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
                                             "csd_client_stop_voice");
        if (csd->stop_voice == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_stop_voice",
                  __func__, dlerror());
            goto error;
        }
        csd->volume = (volume_t)dlsym(csd->csd_client,
                                             "csd_client_volume");
        if (csd->volume == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_volume",
                  __func__, dlerror());
            goto error;
        }
        csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
                                             "csd_client_mic_mute");
        if (csd->mic_mute == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_mic_mute",
                  __func__, dlerror());
            goto error;
        }
        csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
                                             "csd_client_slow_talk");
        if (csd->slow_talk == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_slow_talk",
                  __func__, dlerror());
            goto error;
        }
        csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
                                             "csd_client_start_playback");
        if (csd->start_playback == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_start_playback",
                  __func__, dlerror());
            goto error;
        }
        csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
                                             "csd_client_stop_playback");
        if (csd->stop_playback == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_stop_playback",
                  __func__, dlerror());
            goto error;
        }
        csd->start_record = (start_record_t)dlsym(csd->csd_client,
                                             "csd_client_start_record");
        if (csd->start_record == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_start_record",
                  __func__, dlerror());
            goto error;
        }
        csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
                                             "csd_client_stop_record");
        if (csd->stop_record == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_stop_record",
                  __func__, dlerror());
            goto error;
        }
        csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");

        if (csd->init == NULL) {
            ALOGE("%s: dlsym error %s for csd_client_init",
                  __func__, dlerror());
            goto error;
        } else {
            csd->init();
        }
    }
    return csd;

error:
    free(csd);
    csd = NULL;
    return csd;
}

void close_csd_client(struct csd_data *csd)
{
    if (csd != NULL) {
        csd->deinit();
        dlclose(csd->csd_client);
        free(csd);
        csd = NULL;
    }
}

void *platform_init(struct audio_device *adev)
{
    char platform[PROPERTY_VALUE_MAX];
    char baseband[PROPERTY_VALUE_MAX];
    char value[PROPERTY_VALUE_MAX];
    struct platform_data *my_data;
    int retry_num = 0;
@@ -391,6 +518,17 @@ void *platform_init(struct audio_device *adev)
            my_data->acdb_init();
    }

    /* If platform is apq8084 and baseband is MDM, load CSD Client specific
     * symbols. Voice call is handled by MDM and apps processor talks to
     * MDM through CSD Client
     */
    property_get("ro.board.platform", platform, "");
    property_get("ro.baseband", baseband, "");
    if (!strncmp("apq8084", platform, sizeof("apq8084")) &&
        !strncmp("mdm", baseband, sizeof("mdm"))) {
         my_data->csd = open_csd_client();
    }

    /* init usb */
    audio_extn_usb_init(adev);

@@ -405,6 +543,8 @@ void platform_deinit(void *platform)
    struct platform_data *my_data = (struct platform_data *)platform;

    hw_info_deinit(my_data->hw_info);
    close_csd_client(my_data->csd);

    free(platform);
    /* deinit usb */
    audio_extn_usb_deinit();
@@ -499,7 +639,18 @@ int platform_send_audio_calibration(void *platform, snd_device_t snd_device)

int platform_switch_voice_call_device_pre(void *platform)
{
    return 0;
    struct platform_data *my_data = (struct platform_data *)platform;
    int ret = 0;

    if (my_data->csd != NULL) {
        /* This must be called before disabling mixer controls on APQ side */
        ret = my_data->csd->disable_device();
        if (ret < 0) {
            ALOGE("%s: csd_client_disable_device, failed, error %d",
                  __func__, ret);
        }
    }
    return ret;
}

int platform_switch_voice_call_device_post(void *platform,
@@ -508,13 +659,14 @@ int platform_switch_voice_call_device_post(void *platform,
{
    struct platform_data *my_data = (struct platform_data *)platform;
    int acdb_rx_id, acdb_tx_id;
    int ret = 0;

    if (my_data->acdb_send_voice_cal == NULL) {
        ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
    } else {
    acdb_rx_id = acdb_device_table[out_snd_device];
    acdb_tx_id = acdb_device_table[in_snd_device];

    if (my_data->acdb_send_voice_cal == NULL) {
        ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
    } else {
        if (acdb_rx_id > 0 && acdb_tx_id > 0)
            my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
        else
@@ -522,17 +674,48 @@ int platform_switch_voice_call_device_post(void *platform,
                  acdb_rx_id, acdb_tx_id);
    }

    return 0;
    if (my_data->csd != NULL) {
        if (acdb_rx_id > 0 || acdb_tx_id > 0) {
            ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
                                              my_data->adev->acdb_settings);
            if (ret < 0) {
                ALOGE("%s: csd_enable_device, failed, error %d",
                      __func__, ret);
            }
        } else {
            ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
                  acdb_rx_id, acdb_tx_id);
        }
    }
    return ret;
}

int platform_start_voice_call(void *platform)
int platform_start_voice_call(void *platform, uint32_t vsid)
{
    return 0;
    struct platform_data *my_data = (struct platform_data *)platform;
    int ret = 0;

    if (my_data->csd != NULL) {
        ret = my_data->csd->start_voice(vsid);
        if (ret < 0) {
            ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
        }
    }
    return ret;
}

int platform_stop_voice_call(void *platform)
int platform_stop_voice_call(void *platform, uint32_t vsid)
{
    return 0;
    struct platform_data *my_data = (struct platform_data *)platform;
    int ret = 0;

    if (my_data->csd != NULL) {
        ret = my_data->csd->stop_voice(vsid);
        if (ret < 0) {
            ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
        }
    }
    return ret;
}

int platform_set_voice_volume(void *platform, int volume)
@@ -541,7 +724,7 @@ int platform_set_voice_volume(void *platform, int volume)
    struct audio_device *adev = my_data->adev;
    struct mixer_ctl *ctl;
    const char *mixer_ctl_name = "Voice Rx Gain";
    int vol_index = 0;
    int vol_index = 0, ret = 0;
    uint32_t set_values[ ] = {0,
                              ALL_SESSION_VSID,
                              DEFAULT_VOLUME_RAMP_DURATION_MS};
@@ -561,7 +744,13 @@ int platform_set_voice_volume(void *platform, int volume)
    ALOGV("Setting voice volume index: %d", set_values[0]);
    mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));

    return 0;
    if (my_data->csd != NULL) {
        ret = my_data->csd->volume(ALL_SESSION_VSID, volume);
        if (ret < 0) {
            ALOGE("%s: csd_volume error %d", __func__, ret);
        }
    }
    return ret;
}

int platform_set_mic_mute(void *platform, bool state)
@@ -570,6 +759,7 @@ int platform_set_mic_mute(void *platform, bool state)
    struct audio_device *adev = my_data->adev;
    struct mixer_ctl *ctl;
    const char *mixer_ctl_name = "Voice Tx Mute";
    int ret = 0;
    uint32_t set_values[ ] = {0,
                              ALL_SESSION_VSID,
                              DEFAULT_VOLUME_RAMP_DURATION_MS};
@@ -584,9 +774,15 @@ int platform_set_mic_mute(void *platform, bool state)
        }
        ALOGV("Setting voice mute state: %d", state);
        mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
    }

    return 0;
        if (my_data->csd != NULL) {
            ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state);
            if (ret < 0) {
                ALOGE("%s: csd_mic_mute error %d", __func__, ret);
            }
        }
    }
    return ret;
}

snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
@@ -1076,6 +1272,13 @@ static int platform_set_slowtalk(struct platform_data *my_data, bool state)
        my_data->slowtalk = state;
    }

    if (my_data->csd != NULL) {
        ret = my_data->csd->slow_talk(ALL_SESSION_VSID, state);
        if (ret < 0) {
            ALOGE("%s: csd_client_disable_device, failed, error %d",
                  __func__, ret);
        }
    }
    return ret;
}

+49 −10
Original line number Diff line number Diff line
@@ -157,35 +157,74 @@ enum {
#define AUDIO_CAPTURE_PERIOD_DURATION_MSEC 20
#define AUDIO_CAPTURE_PERIOD_COUNT 2

#define DEVICE_NAME_MAX_SIZE 128
#define HW_INFO_ARRAY_MAX_SIZE 32

#define DEEP_BUFFER_PCM_DEVICE 0
#define AUDIO_RECORD_PCM_DEVICE 0
#define MULTIMEDIA2_PCM_DEVICE 1
#define VOICE_CALL_PCM_DEVICE 2
#define FM_PLAYBACK_PCM_DEVICE 5
#define FM_CAPTURE_PCM_DEVICE  6
#define INCALL_MUSIC_UPLINK_PCM_DEVICE 1
#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 16
#define SPKR_PROT_CALIB_RX_PCM_DEVICE 5
#define SPKR_PROT_CALIB_TX_PCM_DEVICE 22
#define PLAYBACK_OFFLOAD_DEVICE 9

#ifdef PLATFORM_MSM8610
#define LOWLATENCY_PCM_DEVICE 12
#else
#define LOWLATENCY_PCM_DEVICE 15
#endif

#ifdef PLATFORM_MSM8x26
#define VOICE_CALL_PCM_DEVICE 2
#define VOICE2_CALL_PCM_DEVICE 14
#define VOLTE_CALL_PCM_DEVICE 17
#define QCHAT_CALL_PCM_DEVICE 18
#elif PLATFORM_APQ8084
#define VOICE_CALL_PCM_DEVICE 20
#define VOICE2_CALL_PCM_DEVICE 13
#define VOLTE_CALL_PCM_DEVICE 21
#define QCHAT_CALL_PCM_DEVICE 06
#else
#define VOICE_CALL_PCM_DEVICE 2
#define VOICE2_CALL_PCM_DEVICE 13
#define VOLTE_CALL_PCM_DEVICE 14
#define QCHAT_CALL_PCM_DEVICE 20
#endif

#define PLAYBACK_OFFLOAD_DEVICE 9

#ifdef PLATFORM_MSM8610
#define LOWLATENCY_PCM_DEVICE 12
#else
#define LOWLATENCY_PCM_DEVICE 15
#endif
#define LIB_CSD_CLIENT "libcsd-client.so"
/* CSD-CLIENT related functions */
typedef int (*init_t)();
typedef int (*deinit_t)();
typedef int (*disable_device_t)();
typedef int (*enable_device_t)(int, int, uint32_t);
typedef int (*volume_t)(uint32_t, int);
typedef int (*mic_mute_t)(uint32_t, int);
typedef int (*slow_talk_t)(uint32_t, uint8_t);
typedef int (*start_voice_t)(uint32_t);
typedef int (*stop_voice_t)(uint32_t);
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, int);
/* CSD Client structure */
struct csd_data {
    void *csd_client;
    init_t init;
    deinit_t deinit;
    disable_device_t disable_device;
    enable_device_t enable_device;
    volume_t volume;
    mic_mute_t mic_mute;
    slow_talk_t slow_talk;
    start_voice_t start_voice;
    stop_voice_t stop_voice;
    start_playback_t start_playback;
    stop_playback_t stop_playback;
    start_record_t start_record;
    stop_record_t stop_record;
};

#define DEVICE_NAME_MAX_SIZE 128
#define HW_INFO_ARRAY_MAX_SIZE 32
#endif // QCOM_AUDIO_PLATFORM_H
+2 −2
Original line number Diff line number Diff line
@@ -32,8 +32,8 @@ int platform_switch_voice_call_device_pre(void *platform);
int platform_switch_voice_call_device_post(void *platform,
                                           snd_device_t out_snd_device,
                                           snd_device_t in_snd_device);
int platform_start_voice_call(void *platform);
int platform_stop_voice_call(void *platform);
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);
snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices);
+2 −2
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ int stop_call(struct audio_device *adev, audio_usecase_t usecase_id)
    session = (struct voice_session *)voice_get_session_from_use_case(adev, usecase_id);
    session->state.current = CALL_INACTIVE;

    ret = platform_stop_voice_call(adev->platform);
    ret = platform_stop_voice_call(adev->platform, session->vsid);

    /* 1. Close the PCM devices */
    if (session->pcm_rx) {
@@ -166,7 +166,7 @@ int start_call(struct audio_device *adev, audio_usecase_t usecase_id)

    voice_set_volume(adev, adev->voice.volume);

    ret = platform_start_voice_call(adev->platform);
    ret = platform_start_voice_call(adev->platform, session->vsid);
    if (ret < 0) {
        ALOGE("%s: platform_start_voice_call error %d\n", __func__, ret);
        goto error_start_voice;