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

Commit dd208e3b authored by Luca Stefani's avatar Luca Stefani
Browse files

Merge tag 'android-9.0.0_r16' into lineage-16.0

Android 9.0.0 Release 16 (PQ1A.181105.017.A1)

* tag 'android-9.0.0_r16':
  hal: Add ABR enabled flag to LDAC config
  hal: add sdm710 to the list of supproted platforms
  audio: fix static noise on speaker path when enable incall-music
  hal: enable audio_hw flag for sdm710 platform
  hal: Configure frame size of AAC encoded output
  visualizer: Pass sound card and capture device from audio HAL
  A2DP set_parameter: return correct status value
  hal: speaker protect: Add deinit function to clean up
  audio: Add a build flag to enable cirrus speaker calibration.
  hal: Reset A2DP backend before SCO is started
  audio: Load maxx_conf.ini by snd factor
  audio: Notify sthal of pending record as part of device enable
  hal: poll for SLPI subsystem status
  audio: hal: check routing after stop_output_stream
  audio: fix app type's acdb transfer to kernel driver

Change-Id: I178b3880bbe9b162b6367dc0f27b639c5bc6de15
parents 4de33494 a384019d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ ifeq ($(call my-dir),$(call project-path-for,qcom-audio))

# TODO:  Find a better way to separate build configs for ADP vs non-ADP devices
ifneq ($(TARGET_BOARD_AUTO),true)
  ifneq ($(filter msm8960 msm8226 msm8x26 msm8x84 msm8084 msm8992 msm8994 msm8996 msm8909 msm8952 msm8998 sdm845,$(TARGET_BOARD_PLATFORM)),)
  ifneq ($(filter msm8960 msm8226 msm8x26 msm8x84 msm8084 msm8992 msm8994 msm8996 msm8909 msm8952 msm8998 sdm845 sdm710,$(TARGET_BOARD_PLATFORM)),)

    MY_LOCAL_PATH := $(call my-dir)

+9 −2
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
ifneq ($(filter msm8960,$(TARGET_BOARD_PLATFORM)),)
  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2"
endif
ifneq ($(filter msm8974 msm8226 msm8084 msm8992 msm8994 msm8996 msm8998 sdm845,$(TARGET_BOARD_PLATFORM)),)
ifneq ($(filter msm8974 msm8226 msm8084 msm8992 msm8994 msm8996 msm8998 sdm845 sdm710,$(TARGET_BOARD_PLATFORM)),)
  # B-family platform uses msm8974 code base
  AUDIO_PLATFORM = msm8974
ifneq ($(filter msm8974,$(TARGET_BOARD_PLATFORM)),)
@@ -55,6 +55,13 @@ ifneq ($(filter sdm845,$(TARGET_BOARD_PLATFORM)),)
  LOCAL_CFLAGS += -DINCALL_STEREO_CAPTURE_ENABLED
  MULTIPLE_HW_VARIANTS_ENABLED := true
endif
ifneq ($(filter sdm710,$(TARGET_BOARD_PLATFORM)),)
  LOCAL_CFLAGS := -DPLATFORM_SDM710
  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
  LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
  LOCAL_CFLAGS += -DINCALL_STEREO_CAPTURE_ENABLED
  MULTIPLE_HW_VARIANTS_ENABLED := true
endif
endif

ifneq ($(filter msm8916 msm8909 msm8952,$(TARGET_BOARD_PLATFORM)),)
@@ -171,7 +178,7 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD)),true)
    LOCAL_SRC_FILES += audio_extn/a2dp.c
endif

ifneq ($(filter msm8992 msm8994 msm8996 msm8998 sdm845,$(TARGET_BOARD_PLATFORM)),)
ifneq ($(filter msm8992 msm8994 msm8996 msm8998 sdm845 sdm710,$(TARGET_BOARD_PLATFORM)),)
  # push codec/mad calibration to HW dep node
  # applicable to msm8992/8994 or newer platforms
  LOCAL_CFLAGS += -DHWDEP_CAL_ENABLED
+92 −46
Original line number Diff line number Diff line
@@ -159,6 +159,11 @@ typedef enum {
    IMC_ENABLE,
} imc_status_t;

typedef enum {
    MTU_SIZE,
    PEAK_BIT_RATE,
} frame_control_type_t;

/* PCM config for ABR Feedback hostless front end */
static struct pcm_config pcm_config_abr = {
    .channels = 1,
@@ -288,12 +293,25 @@ struct imc_dec_enc_info {
    uint32_t comm_instance;
};

/* Structure to control frame size of AAC encoded frames. */
struct aac_frame_size_control_t {
    /* Type of frame size control: MTU_SIZE / PEAK_BIT_RATE*/
    uint32_t ctl_type;
    /* Control value
     * MTU_SIZE: MTU size in bytes
     * PEAK_BIT_RATE: Peak bitrate in bits per second.
     */
    uint32_t ctl_value;
};

/* Structure used for ABR config of AFE encoder and decoder. */
struct abr_enc_cfg_t {
    /* Link quality level to bitrate mapping info sent to DSP. */
    struct quality_level_to_bitrate_info mapping_info;
    /* Information to set up IMC between decoder and encoder */
    struct imc_dec_enc_info imc_info;
    /* Flag to indicate whether ABR is enabled */
    bool is_abr_enabled;
}  __attribute__ ((packed));

/* Structure to send configuration for decoder introduced
@@ -310,10 +328,7 @@ struct abr_dec_cfg_t {
 * These values should match with DSP interface defintion
 */

/* AAC encoder configuration structure. */
typedef struct aac_enc_cfg_t aac_enc_cfg_t;

struct aac_enc_cfg_t {
struct aac_cfg_blk_t {
    /* Encoder media format for AAC */
    uint32_t      enc_format;

@@ -333,6 +348,14 @@ struct aac_enc_cfg_t {
    uint32_t      sample_rate;
} __attribute__ ((packed));

/* AAC encoder configuration structure. */
typedef struct aac_enc_cfg_t aac_enc_cfg_t;

struct aac_enc_cfg_t {
    struct aac_cfg_blk_t aac_cfg;
    struct aac_frame_size_control_t frame_ctl;
} __attribute__ ((packed));

/* SBC encoder configuration structure. */
typedef struct sbc_enc_cfg_t sbc_enc_cfg_t;

@@ -493,6 +516,7 @@ typedef struct {
    uint32_t sampling_rate;
    uint32_t bitrate;
    uint32_t bits_per_sample;
    struct aac_frame_size_control_t frame_ctl;
} audio_aac_encoder_config;

/* Information about Bluetooth LDAC encoder configuration
@@ -807,7 +831,7 @@ static int a2dp_set_backend_cfg()
    }

    // Set Tx backend sample rate
    if (a2dp.abr_config.is_abr_enabled)
    if (a2dp.abr_config.is_abr_enabled) {
        rate_str = ABR_TX_SAMPLE_RATE;

        ALOGV("%s: set backend tx sample rate = %s", __func__, rate_str);
@@ -822,6 +846,7 @@ static int a2dp_set_backend_cfg()
                                        __func__, rate_str);
            return -ENOSYS;
        }
    }

    // Configure AFE input channels
    switch (a2dp.enc_channels) {
@@ -901,6 +926,7 @@ static int a2dp_reset_backend_cfg()
        return -ENOSYS;
    }

    if (a2dp.abr_config.is_abr_enabled) {
        ctl_sample_rate_tx = mixer_get_ctl_by_name(a2dp.adev->mixer,
                                            MIXER_SAMPLE_RATE_TX);
        if (!ctl_sample_rate_tx) {
@@ -911,6 +937,7 @@ static int a2dp_reset_backend_cfg()
            ALOGE("%s: Failed to reset Tx backend sample rate = %s", __func__, rate_str);
            return -ENOSYS;
        }
    }

    // Reset AFE input channels
    ALOGV("%s: reset AFE input channels = %s", __func__, in_channels);
@@ -1184,23 +1211,25 @@ static bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
        goto exit;
    }
    memset(&aac_dsp_cfg, 0x0, sizeof(aac_dsp_cfg));
    aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC;
    aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate;
    aac_dsp_cfg.sample_rate = aac_bt_cfg->sampling_rate;
    aac_dsp_cfg.aac_cfg.enc_format = ENC_MEDIA_FMT_AAC;
    aac_dsp_cfg.aac_cfg.bit_rate = aac_bt_cfg->bitrate;
    aac_dsp_cfg.aac_cfg.sample_rate = aac_bt_cfg->sampling_rate;
    switch (aac_bt_cfg->enc_mode) {
        case 0:
            aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
            aac_dsp_cfg.aac_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
            break;
        case 2:
            aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
            aac_dsp_cfg.aac_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
            break;
        case 1:
        default:
            aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
            aac_dsp_cfg.aac_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
            break;
    }
    aac_dsp_cfg.aac_fmt_flag = aac_bt_cfg->format_flag;
    aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels;
    aac_dsp_cfg.aac_cfg.aac_fmt_flag = aac_bt_cfg->format_flag;
    aac_dsp_cfg.aac_cfg.channel_cfg = aac_bt_cfg->channels;
    aac_dsp_cfg.frame_ctl.ctl_type = aac_bt_cfg->frame_ctl.ctl_type;
    aac_dsp_cfg.frame_ctl.ctl_value = aac_bt_cfg->frame_ctl.ctl_value;
    ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg,
                              sizeof(aac_dsp_cfg));
    if (ret != 0) {
@@ -1218,7 +1247,7 @@ static bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
    a2dp.enc_sampling_rate = aac_bt_cfg->sampling_rate;
    a2dp.enc_channels = aac_bt_cfg->channels;
    ALOGV("%s: Successfully updated AAC enc format with sampling rate: %d channels:%d",
           __func__, aac_dsp_cfg.sample_rate, aac_dsp_cfg.channel_cfg);
           __func__, aac_dsp_cfg.aac_cfg.sample_rate, aac_dsp_cfg.aac_cfg.channel_cfg);
exit:
    return is_configured;
}
@@ -1269,6 +1298,7 @@ static bool configure_ldac_enc_format(audio_ldac_encoder_config *ldac_bt_cfg)
        ldac_dsp_cfg.abr_cfg.imc_info.enable = IMC_ENABLE;
        ldac_dsp_cfg.abr_cfg.imc_info.purpose = IMC_PURPOSE_ID_BT_INFO;
        ldac_dsp_cfg.abr_cfg.imc_info.comm_instance = a2dp.abr_config.imc_instance;
        ldac_dsp_cfg.abr_cfg.is_abr_enabled = ldac_bt_cfg->is_abr_enabled;
    }

    ret = mixer_ctl_set_array(ldac_enc_data, (void *)&ldac_dsp_cfg,
@@ -1457,6 +1487,15 @@ static int reset_a2dp_dec_config_params()
    return ret;
}

static void reset_a2dp_config() {
    reset_a2dp_enc_config_params();
    reset_a2dp_dec_config_params();
    a2dp_reset_backend_cfg();
    if (a2dp.abr_config.is_abr_enabled && a2dp.abr_config.abr_started)
        stop_abr();
    a2dp.abr_config.is_abr_enabled = false;
}

int audio_extn_a2dp_stop_playback()
{
    int ret = 0;
@@ -1479,12 +1518,8 @@ int audio_extn_a2dp_stop_playback()
            ALOGE("%s: stop stream to Bluetooth IPC lib failed", __func__);
        else
            ALOGV("%s: stop steam to Bluetooth IPC lib successful", __func__);
        reset_a2dp_enc_config_params();
        reset_a2dp_dec_config_params();
        a2dp_reset_backend_cfg();
        if (a2dp.abr_config.is_abr_enabled && a2dp.abr_config.abr_started)
            stop_abr();
        a2dp.abr_config.is_abr_enabled = false;
        if (!a2dp.a2dp_suspended)
            reset_a2dp_config();
        a2dp.a2dp_started = false;
    }
    ALOGD("%s: Stop A2DP playback total active sessions :%d", __func__,
@@ -1495,13 +1530,14 @@ int audio_extn_a2dp_stop_playback()
int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig)
{
     int ret = 0, val;
     int status = 0;
     char value[32] = {0};
     struct audio_usecase *uc_info;
     struct listnode *node;

     if (a2dp.is_a2dp_offload_enabled == false) {
        ALOGV("%s: No supported encoders identified,ignoring A2DP setparam", __func__);
        ret = -EINVAL;
        status = -EINVAL;
        goto param_handled;
     }

@@ -1549,8 +1585,7 @@ int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig)
                        pthread_mutex_lock(&a2dp.adev->lock);
                    }
                }
                reset_a2dp_enc_config_params();
                reset_a2dp_dec_config_params();
                reset_a2dp_config();
                if (a2dp.audio_stream_suspend) {
                   a2dp.audio_stream_suspend();
                }
@@ -1580,12 +1615,23 @@ int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig)
                if (a2dp.a2dp_total_active_session_request > 0) {
                    ALOGD("%s: Calling Bluetooth IPC lib start post suspend state", __func__);
                    if (a2dp.audio_stream_start) {
                        ret =  a2dp.audio_stream_start();
                        if (ret != 0) {
                        status =  a2dp.audio_stream_start();
                        if (status != 0) {
                            ALOGE("%s: Bluetooth controller start failed", __func__);
                            a2dp.a2dp_started = false;
                        } else {
                            if (!configure_a2dp_encoder_format()) {
                                ALOGE("%s: Encoder params configuration failed post suspend", __func__);
                                a2dp.a2dp_started = false;
                                status = -ETIMEDOUT;
                            }
                        }
                    }
                    if (a2dp.a2dp_started) {
                        a2dp_set_backend_cfg();
                        if (a2dp.abr_config.is_abr_enabled)
                            start_abr();
                    }
                }
                list_for_each(node, &a2dp.adev->usecase_list) {
                    uc_info = node_to_item(node, struct audio_usecase, list);
@@ -1613,7 +1659,7 @@ int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig)

param_handled:
     ALOGV("%s: end of A2DP setparam", __func__);
     return ret;
     return status;
}

void audio_extn_a2dp_set_handoff_mode(bool is_on)
+3 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ void audio_extn_set_snd_card_split(const char* in_snd_card_name);
#define audio_extn_spkr_prot_stop_processing(snd_device)     (0)
#define audio_extn_spkr_prot_is_enabled() (false)
#define audio_extn_get_spkr_prot_snd_device(snd_device) (snd_device)
#define audio_extn_spkr_prot_deinit(adev)       (0)
#else
void audio_extn_spkr_prot_init(void *adev);
int audio_extn_spkr_prot_start_processing(snd_device_t snd_device);
@@ -49,6 +50,8 @@ void audio_extn_spkr_prot_stop_processing(snd_device_t snd_device);
bool audio_extn_spkr_prot_is_enabled();
int audio_extn_get_spkr_prot_snd_device(snd_device_t snd_device);
void audio_extn_spkr_prot_calib_cancel(void *adev);
void audio_extn_spkr_prot_deinit(void *adev);

#endif

#ifndef HFP_ENABLED
+106 −2
Original line number Diff line number Diff line
@@ -155,7 +155,11 @@ static struct pcm_config pcm_config_cirrus_rx = {

static struct cirrus_playback_session handle;

#ifdef CIRRUS_FACTORY_CALIBRATION
static void *audio_extn_cirrus_calibration_thread();
#else
static void *audio_extn_cirrus_config_thread();
#endif

#ifdef ENABLE_CIRRUS_DETECTION
static void *audio_extn_cirrus_failure_detect_thread();
@@ -175,11 +179,30 @@ void audio_extn_spkr_prot_init(void *adev) {

    pthread_mutex_init(&handle.fb_prot_mutex, NULL);

#ifdef CIRRUS_FACTORY_CALIBRATION
    (void)pthread_create(&handle.calibration_thread,
                (const pthread_attr_t *) NULL,
                audio_extn_cirrus_calibration_thread, &handle);
#else
    (void)pthread_create(&handle.calibration_thread,
                (const pthread_attr_t *) NULL,
                audio_extn_cirrus_config_thread, &handle);
#endif
}

void audio_extn_spkr_prot_deinit(void *adev __unused) {
    ALOGV("%s: Entry", __func__);

#ifdef ENABLE_CIRRUS_DETECTION
    pthread_join(handle.failure_detect_thread, NULL);
#endif
    pthread_join(handle.calibration_thread, NULL);
    pthread_mutex_destroy(&handle.fb_prot_mutex);

    ALOGV("%s: Exit", __func__);
}

#ifdef CIRRUS_FACTORY_CALIBRATION
static int audio_extn_cirrus_run_calibration() {
    struct audio_device *adev = handle.adev_handle;
    struct crus_sp_ioctl_header header;
@@ -282,7 +305,6 @@ static int audio_extn_cirrus_run_calibration() {
        if (ret < 0)
            goto exit;

#ifdef ENABLED_CIRRUS_WRITE_CAL_FILE
        cal_file = fopen(CRUS_CAL_FILE, "wb");
        if (cal_file == NULL) {
            ALOGE("%s: Cannot create Cirrus SP calibration file (%s)",
@@ -305,7 +327,6 @@ static int audio_extn_cirrus_run_calibration() {

        ALOGI("%s: Cirrus calibration file successfully written",
              __func__);
#endif
    }

    header.size = sizeof(header);
@@ -531,6 +552,89 @@ exit:
    return NULL;
}

#else
static void *audio_extn_cirrus_config_thread(void) {
    struct audio_device *adev = handle.adev_handle;
    struct crus_sp_ioctl_header header;
    struct cirrus_cal_result_t result;
    struct mixer_ctl *ctl_config = NULL;
    FILE *cal_file = NULL;
    int ret = 0, dev_file = -1;

    ALOGI("%s: ++", __func__);

    memset(&result, 0, sizeof(result));

    dev_file = open(CRUS_SP_FILE, O_RDWR | O_NONBLOCK);
    if (dev_file < 0) {
        ALOGE("%s: Failed to open Cirrus Playback IOCTL (%d)",
              __func__, dev_file);
        ret = -EINVAL;
        goto exit;
    }

    cal_file = fopen(CRUS_CAL_FILE, "r");
    if (cal_file) {
        ret = fread(&result, sizeof(result), 1, cal_file);

        if (ret != 1) {
            ALOGE("%s: Cirrus SP calibration file cannot be read , read size: %lu file error: %d",
                 __func__, (unsigned long)ret * sizeof(result), ferror(cal_file));
            ret = -EINVAL;
            goto exit;
        }
    }

    header.size = sizeof(header);
    header.module_id = CRUS_MODULE_ID_TX;
    header.param_id = 0;
    header.data_length = sizeof(result);
    header.data = &result;

    ret = ioctl(dev_file, CRUS_SP_IOCTL_SET_CALIB, &header);

    if (ret < 0) {
        ALOGE("%s: Cirrus SP calibration IOCTL failure", __func__);
        goto exit;
    }

    ctl_config = mixer_get_ctl_by_name(adev->mixer,
                       CRUS_SP_LOAD_CONF_MIXER);
    if (!ctl_config) {
        ALOGE("%s: Could not get ctl for mixer commands", __func__);
        ret = -EINVAL;
        goto exit;
    }

    ret = mixer_ctl_set_value(ctl_config, 0, 2);
    if (ret < 0) {
        ALOGE("%s load tx config failed", __func__);
        goto exit;
    }

    ret = mixer_ctl_set_value(ctl_config, 0, 1);
    if (ret < 0) {
        ALOGE("%s load rx config failed", __func__);
        goto exit;
    }

    ret = mixer_ctl_set_value(ctl_config, 0, 0);
    if (ret < 0) {
        ALOGE("%s set idle state failed", __func__);
        goto exit;
    }

exit:
    if (dev_file >= 0)
        close(dev_file);
    if (cal_file)
        fclose(cal_file);

    ALOGI("%s: ret: %d --", __func__, ret);
    return NULL;
}
#endif

#ifdef ENABLE_CIRRUS_DETECTION
void *audio_extn_cirrus_failure_detect_thread() {
    struct audio_device *adev = handle.adev_handle;
Loading