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

Commit c0fe4c14 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "hal: add support for SWB codec for BT SCO device"

parents 31a053a5 12c29504
Loading
Loading
Loading
Loading
+259 −39
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@
#define MEDIA_FMT_LDAC                                     0x00013224
#define MEDIA_FMT_MP3                                      0x00010BE9
#define MEDIA_FMT_APTX_ADAPTIVE                            0x00013204
#define MEDIA_FMT_APTX_AD_SPEECH                           0x00013208
#define MEDIA_FMT_AAC_AOT_LC                               2
#define MEDIA_FMT_AAC_AOT_SBR                              5
#define MEDIA_FMT_AAC_AOT_PS                               29
@@ -85,6 +86,7 @@
#define MIXER_SAMPLE_RATE_DEFAULT  "BT SampleRate"
#define MIXER_AFE_IN_CHANNELS      "AFE Input Channels"
#define MIXER_ABR_TX_FEEDBACK_PATH "A2DP_SLIM7_UL_HL Switch"
#define MIXER_ABR_RX_FEEDBACK_PATH "SCO_SLIM7_DL_HL Switch"
#define MIXER_SET_FEEDBACK_CHANNEL "BT set feedback channel"
#define MIXER_SINK_SAMPLE_RATE     "BT_TX SampleRate"
#define MIXER_AFE_SINK_CHANNELS    "AFE Output Channels"
@@ -125,6 +127,9 @@
// Slimbus Tx sample rate for ABR feedback channel
#define ABR_TX_SAMPLE_RATE             "KHZ_8"

// Slimbus Tx sample rate for APTX AD SPEECH
#define SPEECH_TX_SAMPLE_RATE             "KHZ_96"

// Purpose ID for Inter Module Communication (IMC) in AFE
#define IMC_PURPOSE_ID_BT_INFO         0x000132E2

@@ -134,8 +139,13 @@
// Instance identifier for A2DP
#define MAX_INSTANCE_ID                (UINT32_MAX / 2)

// Instance identifier for SWB
#define APTX_AD_SPEECH_INSTANCE_ID                 37

#define SAMPLING_RATE_96K               96000
#define SAMPLING_RATE_48K               48000
#define SAMPLING_RATE_441K              44100
#define SAMPLING_RATE_32K               32000
#define CH_STEREO                       2
#define CH_MONO                         1
#define SOURCE 0
@@ -172,6 +182,7 @@ typedef enum {
    CODEC_TYPE_LDAC = AUDIO_FORMAT_LDAC, // 0x23000000UL
    CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
    CODEC_TYPE_APTX_AD = 620756992u, // 0x25000000UL
    CODEC_TYPE_APTX_AD_SPEECH = 637534208u, //0x26000000UL
    CODEC_TYPE_PCM = AUDIO_FORMAT_PCM_16_BIT, // 0x1u
}codec_t;

@@ -236,6 +247,11 @@ typedef enum {
    IMC_ENABLE,
} imc_status_t;

typedef enum {
    SWAP_DISABLE,
    SWAP_ENABLE,
} swap_status_t;

typedef enum {
    MTU_SIZE,
    PEAK_BIT_RATE,
@@ -265,6 +281,8 @@ struct a2dp_abr_config {
    bool abr_started;
    /* ABR Tx path pcm handle */
    struct pcm *abr_tx_handle;
    /* ABR Rx path pcm handle */
    struct pcm *abr_rx_handle;
    /* ABR Inter Module Communication (IMC) instance ID */
    uint32_t imc_instance;
};
@@ -319,6 +337,7 @@ struct a2dp_data {
    uint32_t dec_channels;
    bool a2dp_sink_started;
    int  a2dp_sink_total_active_session_requests;
    bool swb_configured;
};

struct a2dp_data a2dp;
@@ -400,6 +419,18 @@ struct abr_dec_cfg_t {
    struct imc_dec_enc_info imc_info;
} __attribute__ ((packed));

struct aptx_ad_speech_mode_cfg_t
{
    uint32_t mode;
    uint32_t swapping;
} __attribute__ ((packed));

/* Structure for SWB voice dec config */
struct aptx_ad_speech_dec_cfg_t {
    struct abr_dec_cfg_t abr_cfg;
    struct aptx_ad_speech_mode_cfg_t speech_mode;
} __attribute__ ((packed));

/* START of DSP configurable structures
 * These values should match with DSP interface defintion
 */
@@ -546,6 +577,15 @@ struct aptx_ad_enc_cfg_t
    struct abr_enc_cfg_t abr_cfg;
} __attribute__ ((packed));

/* APTX AD SPEECH structure */
struct aptx_ad_speech_enc_cfg_t
{
    struct custom_enc_cfg_t  custom_cfg;
    /* Information to set up IMC between decoder and encoder */
    struct imc_dec_enc_info imc_info;
    struct aptx_ad_speech_mode_cfg_t speech_mode;
} __attribute__ ((packed));

struct ldac_specific_enc_cfg_t
{
    uint32_t      bit_rate;
@@ -715,7 +755,9 @@ static void update_offload_codec_capabilities()
static int stop_abr()
{
    struct mixer_ctl *ctl_abr_tx_path = NULL;
    struct mixer_ctl *ctl_abr_rx_path = NULL;
    struct mixer_ctl *ctl_set_bt_feedback_channel = NULL;
    int ret = 0;

    /* This function can be used if !abr_started for clean up */
    ALOGV("%s: enter", __func__);
@@ -725,6 +767,10 @@ static int stop_abr()
        pcm_close(a2dp.abr_config.abr_tx_handle);
        a2dp.abr_config.abr_tx_handle = NULL;
    }
    if (a2dp.abr_config.abr_rx_handle != NULL) {
        pcm_close(a2dp.abr_config.abr_rx_handle);
        a2dp.abr_config.abr_rx_handle = NULL;
    }
    a2dp.abr_config.abr_started = false;
    a2dp.abr_config.imc_instance = 0;

@@ -733,11 +779,10 @@ static int stop_abr()
                                        MIXER_SET_FEEDBACK_CHANNEL);
    if (!ctl_set_bt_feedback_channel) {
        ALOGE("%s: ERROR Set usecase mixer control not identifed", __func__);
        return -ENOSYS;
    }
    if (mixer_ctl_set_value(ctl_set_bt_feedback_channel, 0, 0) != 0) {
        ret = -ENOSYS;
    } else if (mixer_ctl_set_value(ctl_set_bt_feedback_channel, 0, 0) != 0) {
        ALOGE("%s: Failed to set BT usecase", __func__);
        return -ENOSYS;
        ret = -ENOSYS;
    }

    // Reset ABR Tx feedback path
@@ -746,19 +791,31 @@ static int stop_abr()
                                        MIXER_ABR_TX_FEEDBACK_PATH);
    if (!ctl_abr_tx_path) {
        ALOGE("%s: ERROR ABR Tx feedback path mixer control not identifed", __func__);
        return -ENOSYS;
    }
    if (mixer_ctl_set_value(ctl_abr_tx_path, 0, 0) != 0) {
        ret = -ENOSYS;
    } else if (mixer_ctl_set_value(ctl_abr_tx_path, 0, 0) != 0) {
        ALOGE("%s: Failed to set ABR Tx feedback path", __func__);
        return -ENOSYS;
        ret = -ENOSYS;
    }

   return 0;
    // Reset ABR Rx feedback path
    ALOGV("%s: Disable ABR Rx feedback path", __func__);
    ctl_abr_rx_path = mixer_get_ctl_by_name(a2dp.adev->mixer,
                                        MIXER_ABR_RX_FEEDBACK_PATH);
    if (!ctl_abr_rx_path) {
        ALOGE("%s: ERROR ABR Rx feedback path mixer control not identifed", __func__);
        ret = -ENOSYS;
    } else if (mixer_ctl_set_value(ctl_abr_rx_path, 0, 0) != 0) {
        ALOGE("%s: Failed to set ABR Rx feedback path", __func__);
        ret = -ENOSYS;
    }

   return ret;
}

static int start_abr()
{
    struct mixer_ctl *ctl_abr_tx_path = NULL;
    struct mixer_ctl *ctl_abr_rx_path = NULL;
    struct mixer_ctl *ctl_set_bt_feedback_channel = NULL;
    int abr_device_id;
    int ret = 0;
@@ -792,11 +849,11 @@ static int start_abr()
                                        MIXER_SET_FEEDBACK_CHANNEL);
    if (!ctl_set_bt_feedback_channel) {
        ALOGE("%s: ERROR Set usecase mixer control not identifed", __func__);
        return -ENOSYS;
        goto fail;
    }
    if (mixer_ctl_set_value(ctl_set_bt_feedback_channel, 0, 1) != 0) {
        ALOGE("%s: Failed to set BT usecase", __func__);
        return -ENOSYS;
        goto fail;
    }

    // Open hostless front end and prepare ABR Tx path
@@ -806,19 +863,60 @@ static int start_abr()
        a2dp.abr_config.abr_tx_handle = pcm_open(a2dp.adev->snd_card,
                                                 abr_device_id, PCM_IN,
                                                 &pcm_config_abr);
        if (a2dp.abr_config.abr_tx_handle == NULL ||
            !pcm_is_ready(a2dp.abr_config.abr_tx_handle))
        if (a2dp.abr_config.abr_tx_handle == NULL) {
            ALOGE("%s: Can't open abr tx device", __func__);
            goto fail;
        }
    ret = pcm_start(a2dp.abr_config.abr_tx_handle);
    if (ret < 0)
        if (!(pcm_is_ready(a2dp.abr_config.abr_tx_handle) &&
              !pcm_start(a2dp.abr_config.abr_tx_handle))) {
            ALOGE("%s: tx: %s", __func__, pcm_get_error(a2dp.abr_config.abr_tx_handle));
            goto fail;
        }
    }

    // Enable Slimbus 7 Rx feedback path for HD Voice use case
    if (a2dp.bt_encoder_format == CODEC_TYPE_APTX_AD_SPEECH) {
        ALOGV("%s: Enable ABR Rx feedback path", __func__);
        ctl_abr_rx_path = mixer_get_ctl_by_name(a2dp.adev->mixer,
                                            MIXER_ABR_RX_FEEDBACK_PATH);
        if (!ctl_abr_rx_path) {
            ALOGE("%s: ERROR ABR Rx feedback path mixer control not identifed", __func__);
            goto fail;
        }
        if (mixer_ctl_set_value(ctl_abr_rx_path, 0, 1) != 0) {
            ALOGE("%s: Failed to set ABR Rx feedback path", __func__);
            goto fail;
        }

        if (mixer_ctl_set_value(ctl_set_bt_feedback_channel, 0, 1) != 0) {
            ALOGE("%s: Failed to set BT usecase", __func__);
            goto fail;
        }

        // Open hostless front end and prepare ABR Rx path
        abr_device_id = fp_platform_get_pcm_device_id(USECASE_AUDIO_A2DP_ABR_FEEDBACK,
                                                   PCM_PLAYBACK);
        if (!a2dp.abr_config.abr_rx_handle) {
            a2dp.abr_config.abr_rx_handle = pcm_open(a2dp.adev->snd_card,
                                                     abr_device_id, PCM_OUT,
                                                     &pcm_config_abr);
            if (a2dp.abr_config.abr_rx_handle == NULL) {
                ALOGE("%s: Can't open abr rx device", __func__);
                goto fail;
            }
            if (!(pcm_is_ready(a2dp.abr_config.abr_rx_handle) &&
                  !pcm_start(a2dp.abr_config.abr_rx_handle))) {
                ALOGE("%s: rx: %s", __func__, pcm_get_error(a2dp.abr_config.abr_rx_handle));
                goto fail;
            }
        }
    }

    a2dp.abr_config.abr_started = true;

    return ret;

fail:
    ALOGE("%s: %s", __func__, pcm_get_error(a2dp.abr_config.abr_tx_handle));
    stop_abr();
    return -ENOSYS;
}
@@ -965,6 +1063,7 @@ static int close_a2dp_output()
    a2dp.abr_config.abr_started = false;
    a2dp.abr_config.imc_instance = 0;
    a2dp.abr_config.abr_tx_handle = NULL;
    a2dp.abr_config.abr_rx_handle = NULL;
    a2dp.bt_state_source = A2DP_STATE_DISCONNECTED;

    return 0;
@@ -1079,9 +1178,12 @@ static bool a2dp_set_backend_cfg(uint8_t direction)

        if (direction == SOURCE) {
            /* Set Tx backend sample rate */
            if (a2dp.abr_config.is_abr_enabled)
            if (a2dp.abr_config.is_abr_enabled) {
                if (a2dp.bt_encoder_format == CODEC_TYPE_APTX_AD_SPEECH)
                    rate_str = SPEECH_TX_SAMPLE_RATE;
                else
                    rate_str = ABR_TX_SAMPLE_RATE;

            }
            ALOGD("%s: set backend tx sample rate = %s", __func__, rate_str);
            ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
                                            MIXER_SOURCE_SAMPLE_RATE_TX);
@@ -1282,7 +1384,7 @@ static int a2dp_reset_backend_cfg(uint8_t direction)
            ALOGE("%s: Failed to reset backend sample rate = %s", __func__, rate_str);
            return -ENOSYS;
        }

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

        ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
@@ -1707,7 +1810,7 @@ static int update_aptx_dsp_config_v1(struct custom_enc_cfg_t *aptx_dsp_cfg,
bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
{
    struct mixer_ctl *ctl_enc_data = NULL;
    int mixer_size;
    int mixer_size = 0;
    bool is_configured = false;
    int ret = 0;
    int sample_rate_backup;
@@ -2209,7 +2312,7 @@ int a2dp_start_playback()
        return -ENOSYS;
    }

    if (a2dp.a2dp_source_suspended == true) {
    if (a2dp.a2dp_source_suspended || a2dp.swb_configured) {
        //session will be restarted after suspend completion
        ALOGD("a2dp start requested during suspend state");
        return -ENOSYS;
@@ -2434,6 +2537,16 @@ static void reset_a2dp_sink_dec_config_params()
    }
}

static void reset_codec_config()
{
    reset_a2dp_enc_config_params();
    reset_a2dp_source_dec_config_params();
    a2dp_reset_backend_cfg(SOURCE);
    if (a2dp.abr_config.is_abr_enabled && a2dp.abr_config.abr_started)
        stop_abr();
    a2dp.abr_config.is_abr_enabled = false;
}

int a2dp_stop_playback()
{
    int ret =0;
@@ -2456,14 +2569,9 @@ int a2dp_stop_playback()
            ALOGE("stop stream to BT IPC lib failed");
        else
            ALOGV("stop steam to BT IPC lib successful");
        reset_a2dp_enc_config_params();
        reset_a2dp_source_dec_config_params();
        a2dp_reset_backend_cfg(SOURCE);
        if (a2dp.abr_config.is_abr_enabled && a2dp.abr_config.abr_started)
            stop_abr();
        a2dp.abr_config.is_abr_enabled = false;
        if (!a2dp.a2dp_source_suspended && !a2dp.swb_configured)
            reset_codec_config();
        a2dp.a2dp_source_started = false;
        a2dp_reset_backend_cfg(SOURCE);
    }
    if (!a2dp.a2dp_source_total_active_session_requests)
       a2dp.a2dp_source_started = false;
@@ -2578,8 +2686,8 @@ int a2dp_set_parameters(struct str_parms *parms, bool *reconfig)
                        pthread_mutex_lock(&a2dp.adev->lock);
                    }
                }
                reset_a2dp_enc_config_params();
                reset_a2dp_source_dec_config_params();
                if (!a2dp.swb_configured)
                    reset_codec_config();
                if (a2dp.audio_source_suspend)
                   a2dp.audio_source_suspend();
            } else if (a2dp.a2dp_source_suspended == true) {
@@ -2699,8 +2807,11 @@ void a2dp_init(void *adev,
  a2dp.abr_config.abr_started = false;
  a2dp.abr_config.imc_instance = 0;
  a2dp.abr_config.abr_tx_handle = NULL;
  a2dp.abr_config.abr_rx_handle = NULL;
  a2dp.is_tws_mono_mode_on = false;
  a2dp_source_init();
  a2dp.swb_configured = false;

  // init function pointers
  fp_platform_get_pcm_device_id =
              init_config.fp_platform_get_pcm_device_id;
@@ -2802,3 +2913,112 @@ int a2dp_get_parameters(struct str_parms *query,

    return 0;
}


bool configure_aptx_ad_speech_enc_fmt() {
    struct mixer_ctl *ctl_enc_data = NULL;
    int mixer_size = 0;
    int ret = 0;
    struct aptx_ad_speech_enc_cfg_t aptx_dsp_cfg;

    ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
    if (!ctl_enc_data) {
        ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
        return false;
    }

    /* Initialize dsp configuration params */
    memset(&aptx_dsp_cfg, 0x0, sizeof(struct aptx_ad_speech_enc_cfg_t));
    aptx_dsp_cfg.custom_cfg.enc_format = MEDIA_FMT_APTX_AD_SPEECH;
    aptx_dsp_cfg.custom_cfg.sample_rate = SAMPLING_RATE_32K;
    aptx_dsp_cfg.custom_cfg.num_channels = CH_MONO;
    aptx_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
    aptx_dsp_cfg.imc_info.direction = IMC_RECEIVE;
    aptx_dsp_cfg.imc_info.enable = IMC_ENABLE;
    aptx_dsp_cfg.imc_info.purpose = IMC_PURPOSE_ID_BT_INFO;
    aptx_dsp_cfg.imc_info.comm_instance = APTX_AD_SPEECH_INSTANCE_ID;
    aptx_dsp_cfg.speech_mode.mode = a2dp.adev->swb_speech_mode;
    aptx_dsp_cfg.speech_mode.swapping = SWAP_ENABLE;

    /* Configure AFE DSP configuration */
    mixer_size = sizeof(struct aptx_ad_speech_enc_cfg_t);
    ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
                  mixer_size);
    if (ret != 0) {
        ALOGE("%s: Failed to set SWB encoder config", __func__);
        return false;
    }

    /* Configure AFE Input Bit Format as PCM_16 */
    ret = a2dp_set_bit_format(DEFAULT_ENCODER_BIT_FORMAT);
    if (ret != 0) {
        ALOGE("%s: Failed to set SWB bit format", __func__);
        return false;
    }

    return true;
}

bool configure_aptx_ad_speech_dec_fmt()
{
    struct mixer_ctl *ctl_dec_data = NULL;
    struct aptx_ad_speech_dec_cfg_t dec_cfg;
    int ret = 0;

    ctl_dec_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_SOURCE_DEC_CONFIG_BLOCK);
    if (!ctl_dec_data) {
        ALOGE("%s: ERROR codec config data mixer control not identifed", __func__);
        return false;
    }
    memset(&dec_cfg, 0x0, sizeof(dec_cfg));
    dec_cfg.abr_cfg.dec_format = MEDIA_FMT_APTX_AD_SPEECH;
    dec_cfg.abr_cfg.imc_info.direction = IMC_TRANSMIT;
    dec_cfg.abr_cfg.imc_info.enable = IMC_ENABLE;
    dec_cfg.abr_cfg.imc_info.purpose = IMC_PURPOSE_ID_BT_INFO;
    dec_cfg.abr_cfg.imc_info.comm_instance = APTX_AD_SPEECH_INSTANCE_ID;
    dec_cfg.speech_mode.mode = a2dp.adev->swb_speech_mode;
    dec_cfg.speech_mode.swapping = SWAP_ENABLE;

    ret = mixer_ctl_set_array(ctl_dec_data, &dec_cfg,
                              sizeof(dec_cfg));
    if (ret != 0) {
        ALOGE("%s: Failed to set decoder config", __func__);
        return false;
    }
      return true;
}

int sco_start_configuration()
{
    ALOGD("sco_start_configuration start");

    if (!a2dp.swb_configured) {
        a2dp.bt_encoder_format = CODEC_TYPE_APTX_AD_SPEECH;
        /* Configure AFE codec*/
        if (configure_aptx_ad_speech_enc_fmt() &&
            configure_aptx_ad_speech_dec_fmt()) {
            ALOGD("%s: SCO enc/dec configured successfully", __func__);
        } else {
            ALOGE("%s: failed to send SCO configuration", __func__);
            return -ETIMEDOUT;
        }
        /* Configure backend*/
        a2dp.enc_sampling_rate = SAMPLING_RATE_96K;
        a2dp.enc_channels = CH_MONO;
        a2dp.abr_config.is_abr_enabled = true;
        a2dp_set_backend_cfg(SOURCE);
        /* Start abr*/
        start_abr();
        a2dp.swb_configured = true;
    }
    return 0;
}

void sco_reset_configuration()
{
    ALOGD("sco_reset_configuration start");

    reset_codec_config();
    a2dp.bt_encoder_format = CODEC_TYPE_INVALID;
    a2dp.swb_configured = false;
}
+26 −0
Original line number Diff line number Diff line
@@ -3791,6 +3791,13 @@ static a2dp_start_capture_t a2dp_start_capture;
typedef int (*a2dp_stop_capture_t)();
static a2dp_stop_capture_t a2dp_stop_capture;

typedef int (*sco_start_configuration_t)();
static sco_start_configuration_t sco_start_configuration;

typedef void (*sco_reset_configuration_t)();
static sco_reset_configuration_t sco_reset_configuration;


int a2dp_offload_feature_init(bool is_feature_enabled)
{
    ALOGD("%s: Called with feature %s", __func__,
@@ -3842,6 +3849,15 @@ int a2dp_offload_feature_init(bool is_feature_enabled)
            ALOGE("%s: dlsym failed", __func__);
            goto feature_disabled;
        }
        // initialize APIs for SWB extension
        if (!(sco_start_configuration =
                 (sco_start_configuration_t)dlsym(a2dp_lib_handle, "sco_start_configuration")) ||
             !(sco_reset_configuration =
                 (sco_reset_configuration_t)dlsym(a2dp_lib_handle, "sco_reset_configuration"))) {
            ALOGE("%s: dlsym failed for swb APIs", __func__);
            sco_start_configuration = NULL;
            sco_reset_configuration = NULL;
        }
        ALOGD("%s:: ---- Feature A2DP_OFFLOAD is Enabled ----", __func__);
        return 0;
    }
@@ -3965,6 +3981,16 @@ int audio_extn_a2dp_stop_capture()
    return (a2dp_stop_capture ? a2dp_stop_capture() : 0);
}

int audio_extn_sco_start_configuration()
{
    return (sco_start_configuration? sco_start_configuration() : 0);
}

void audio_extn_sco_reset_configuration()
{
    return (sco_reset_configuration? sco_reset_configuration() : 0);
}

// END: A2DP_OFFLOAD =====================================================================

// START: HFP ======================================================================
+3 −0
Original line number Diff line number Diff line
@@ -313,6 +313,9 @@ bool audio_extn_a2dp_source_is_ready();
bool audio_extn_a2dp_source_is_suspended();
int audio_extn_a2dp_start_capture();
int audio_extn_a2dp_stop_capture();
int audio_extn_sco_start_configuration();
void audio_extn_sco_reset_configuration();


// --- Function pointers from audio_extn needed by A2DP_OFFLOAD
typedef int (*fp_check_a2dp_restore_t)(struct audio_device *,
+23 −1
Original line number Diff line number Diff line
@@ -1189,6 +1189,14 @@ int enable_snd_device(struct audio_device *adev,
            goto err;
        }

        if (((SND_DEVICE_OUT_BT_SCO_SWB == snd_device) ||
             (SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC == snd_device) ||
             (SND_DEVICE_IN_BT_SCO_MIC_SWB == snd_device)) &&
            (audio_extn_sco_start_configuration() < 0)) {
            ALOGE(" fail to configure sco control path ");
            goto err;
        }

        /* due to the possibility of calibration overwrite between listen
            and audio, notify listen hal before audio calibration is sent */
        audio_extn_sound_trigger_update_device_status(snd_device,
@@ -1281,7 +1289,14 @@ int disable_snd_device(struct audio_device *adev,
            audio_extn_a2dp_stop_playback();
        else if (snd_device == SND_DEVICE_IN_BT_A2DP)
            audio_extn_a2dp_stop_capture();
        else if ((snd_device == SND_DEVICE_OUT_HDMI) ||
        else if ((snd_device == SND_DEVICE_OUT_BT_SCO_SWB) ||
                 (snd_device == SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC) ||
                 (snd_device == SND_DEVICE_IN_BT_SCO_MIC_SWB)) {
            if ((adev->snd_dev_ref_cnt[SND_DEVICE_OUT_BT_SCO_SWB] == 0) &&
                (adev->snd_dev_ref_cnt[SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC] == 0) &&
                (adev->snd_dev_ref_cnt[SND_DEVICE_IN_BT_SCO_MIC_SWB] == 0))
                audio_extn_sco_reset_configuration();
       } else if ((snd_device == SND_DEVICE_OUT_HDMI) ||
                (snd_device == SND_DEVICE_OUT_DISPLAY_PORT))
            adev->is_channel_status_set = false;
        else if ((snd_device == SND_DEVICE_OUT_HEADPHONES) &&
@@ -7659,6 +7674,12 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
            adev->bt_wb_speech_enabled = false;
    }

    ret = str_parms_get_str(parms, "bt_swb", value, sizeof(value));
    if (ret >= 0) {
        val = atoi(value);
        adev->swb_speech_mode = val;
    }

    ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value, sizeof(value));
    if (ret >= 0) {
        val = atoi(value);
@@ -9104,6 +9125,7 @@ static int adev_open(const hw_module_t *module, const char *name,

    adev->enable_voicerx = false;
    adev->bt_wb_speech_enabled = false;
    adev->swb_speech_mode = SPEECH_MODE_INVALID;
    //initialize this to false for now,
    //this will be set to true through set param
    adev->vr_audio_mode_enabled = false;
+4 −0
Original line number Diff line number Diff line
@@ -85,6 +85,9 @@
#define ACDB_DEV_TYPE_OUT 1
#define ACDB_DEV_TYPE_IN 2

/* SCO SWB codec mode */
#define SPEECH_MODE_INVALID  0xFFFF

/* support positional and index masks to 8ch */
#define MAX_SUPPORTED_CHANNEL_MASKS (2 * FCC_8)
#define MAX_SUPPORTED_FORMATS 15
@@ -527,6 +530,7 @@ struct audio_device {
    unsigned int cur_hdmi_bit_width;
    unsigned int cur_wfd_channels;
    bool bt_wb_speech_enabled;
    unsigned int swb_speech_mode;
    bool allow_afe_proxy_usage;
    bool is_charging; // from battery listener
    bool mic_break_enabled;
Loading