Merge pi-dr1-dev to aosp-master
Change-Id: I8739f24b4a87116aa291fe06cc24ebd28135ad0e
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index d1671a8..797daee 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -159,6 +159,11 @@
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,6 +293,17 @@
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. */
@@ -310,10 +326,7 @@
* 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 +346,14 @@
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 +514,7 @@
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,20 +829,21 @@
}
// 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);
- ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
- MIXER_SAMPLE_RATE_TX);
- if (!ctl_sample_rate) {
- ALOGE("%s: ERROR backend sample rate mixer control not identifed", __func__);
- return -ENOSYS;
- }
- if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
- ALOGE("%s: Failed to set backend sample rate = %s",
- __func__, rate_str);
- return -ENOSYS;
+ ALOGV("%s: set backend tx sample rate = %s", __func__, rate_str);
+ ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
+ MIXER_SAMPLE_RATE_TX);
+ if (!ctl_sample_rate) {
+ ALOGE("%s: ERROR backend sample rate mixer control not identifed", __func__);
+ return -ENOSYS;
+ }
+ if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
+ ALOGE("%s: Failed to set backend sample rate = %s",
+ __func__, rate_str);
+ return -ENOSYS;
+ }
}
// Configure AFE input channels
@@ -901,15 +924,17 @@
return -ENOSYS;
}
- ctl_sample_rate_tx = mixer_get_ctl_by_name(a2dp.adev->mixer,
- MIXER_SAMPLE_RATE_TX);
- if (!ctl_sample_rate_tx) {
- ALOGE("%s: ERROR Tx backend sample rate mixer control not identifed", __func__);
- return -ENOSYS;
- }
- if (mixer_ctl_set_enum_by_string(ctl_sample_rate_tx, rate_str) != 0) {
- ALOGE("%s: Failed to reset Tx 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_SAMPLE_RATE_TX);
+ if (!ctl_sample_rate_tx) {
+ ALOGE("%s: ERROR Tx backend sample rate mixer control not identifed", __func__);
+ return -ENOSYS;
+ }
+ if (mixer_ctl_set_enum_by_string(ctl_sample_rate_tx, rate_str) != 0) {
+ ALOGE("%s: Failed to reset Tx backend sample rate = %s", __func__, rate_str);
+ return -ENOSYS;
+ }
}
// Reset AFE input channels
@@ -1184,23 +1209,25 @@
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 +1245,7 @@
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;
}
@@ -1457,6 +1484,15 @@
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 +1515,8 @@
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 +1527,14 @@
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 +1582,7 @@
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 +1612,23 @@
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 +1656,7 @@
param_handled:
ALOGV("%s: end of A2DP setparam", __func__);
- return ret;
+ return status;
}
void audio_extn_a2dp_set_handoff_mode(bool is_on)
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index b1c701d..1c28b6b 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -42,6 +42,7 @@
#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 @@
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
diff --git a/hal/audio_extn/cirrus_playback.c b/hal/audio_extn/cirrus_playback.c
index 21dbc10..25fe258 100644
--- a/hal/audio_extn/cirrus_playback.c
+++ b/hal/audio_extn/cirrus_playback.c
@@ -155,7 +155,11 @@
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 @@
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 @@
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 @@
ALOGI("%s: Cirrus calibration file successfully written",
__func__);
-#endif
}
header.size = sizeof(header);
@@ -531,6 +552,89 @@
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;
diff --git a/hal/audio_extn/maxxaudio.c b/hal/audio_extn/maxxaudio.c
index 9007da7..fc65332 100644
--- a/hal/audio_extn/maxxaudio.c
+++ b/hal/audio_extn/maxxaudio.c
@@ -37,7 +37,7 @@
#define PRESET_PATH "/vendor/etc"
#define MPS_BASE_STRING "default"
#define USER_PRESET_PATH ""
-#define CONFIG_PATH "/vendor/etc/maxx_conf.ini"
+#define CONFIG_BASE_STRING "maxx_conf"
#define CAL_PRESIST_STR "cal_persist"
#define CAL_SAMPLERATE_STR "cal_samplerate"
@@ -344,6 +344,7 @@
int ret = 0;
char lib_path[128] = {0};
char mps_path[128] = {0};
+ char cnf_path[128] = {0};
struct snd_card_split *snd_split_handle = NULL;
snd_split_handle = audio_extn_get_snd_card_split();
@@ -427,8 +428,17 @@
PRESET_PATH, MPS_BASE_STRING, snd_split_handle->form_factor);
}
+ /* get config files */
+ if (snd_split_handle == NULL) {
+ snprintf(cnf_path, sizeof(cnf_path), "%s/%s.ini",
+ PRESET_PATH, CONFIG_BASE_STRING);
+ } else {
+ snprintf(cnf_path, sizeof(cnf_path), "%s/%s_%s.ini",
+ PRESET_PATH, CONFIG_BASE_STRING, snd_split_handle->form_factor);
+ }
+
/* check file */
- if (access(mps_path, F_OK) < 0) {
+ if (access(mps_path, R_OK) < 0) {
ALOGW("%s: file %s isn't existed.", __func__, mps_path);
goto error;
} else
@@ -440,16 +450,18 @@
goto error;
}
*/
- if (access(CONFIG_PATH, F_OK) < 0) {
- ALOGW("%s: file %s isn't existed.", __func__, CONFIG_PATH);
+
+ if (access(cnf_path, R_OK) < 0) {
+ ALOGW("%s: file %s isn't existed.", __func__, cnf_path);
goto error;
- }
+ } else
+ ALOGD("%s: Loading ini file: %s", __func__, cnf_path);
/* init ma parameter */
if (my_data->ma_param_init(&g_ma_audio_cal_handle,
mps_path,
USER_PRESET_PATH, /* unused */
- CONFIG_PATH,
+ cnf_path,
&set_audio_cal)) {
if (!g_ma_audio_cal_handle) {
ALOGE("%s: ma parameters initialize failed", __func__);
diff --git a/hal/audio_extn/sndmonitor.c b/hal/audio_extn/sndmonitor.c
index 6e06d03..2e8fd43 100644
--- a/hal/audio_extn/sndmonitor.c
+++ b/hal/audio_extn/sndmonitor.c
@@ -51,6 +51,11 @@
#define MAX_CPE_SLEEP_RETRY 2
#define CPE_SLEEP_WAIT 100
+#define SPLI_STATE_PATH "/proc/wcd-spi-ac/svc-state"
+#define SLPI_MAGIC_NUM 0x3000
+#define MAX_SLPI_SLEEP_RETRY 2
+#define SLPI_SLEEP_WAIT_MS 100
+
#define MAX_SLEEP_RETRY 100
#define AUDIO_INIT_SLEEP_WAIT 100 /* 100 ms */
@@ -245,6 +250,31 @@
if (line)
free(line);
fclose(fp);
+
+ /* Add fd to query for SLPI status */
+ if (access(SPLI_STATE_PATH, R_OK) < 0) {
+ ALOGV("access to %s failed: %s", SPLI_STATE_PATH, strerror(errno));
+ } else {
+ tries = MAX_SLPI_SLEEP_RETRY;
+ ALOGV("Open %s", SPLI_STATE_PATH);
+ while (tries--) {
+ if ((fd = open(SPLI_STATE_PATH, O_RDONLY)) < 0) {
+ ALOGW("Open %s failed %s, retry", SPLI_STATE_PATH,
+ strerror(errno));
+ usleep(SLPI_SLEEP_WAIT_MS * 1000);
+ continue;
+ }
+ break;
+ }
+ if (fd >= 0) {
+ ret = add_new_sndcard(SLPI_MAGIC_NUM, fd);
+ if (ret != 0)
+ close(fd);
+ else
+ num_cards++;
+ }
+ }
+
ALOGV("sndmonitor registerer num_cards %d", num_cards);
sndmonitor.num_cards = num_cards;
return num_cards ? 0 : -1;
@@ -383,7 +413,6 @@
ALOGV("card num %d, new state %s", s->card, rd_buf);
- bool is_cpe = (s->card >= CPE_MAGIC_NUM);
if (strstr(rd_buf, "OFFLINE"))
status = CARD_STATUS_OFFLINE;
else if (strstr(rd_buf, "ONLINE"))
@@ -404,11 +433,18 @@
return -1;
char val[32] = {0};
- // cpe actual card num is (card - MAGIC_NUM). so subtract accordingly
- snprintf(val, sizeof(val), "%d,%s", s->card - (is_cpe ? CPE_MAGIC_NUM : 0),
+ bool is_cpe = ((s->card >= CPE_MAGIC_NUM) && (s->card < SLPI_MAGIC_NUM));
+ bool is_slpi = (s->card == SLPI_MAGIC_NUM);
+ /*
+ * cpe actual card num is (card - CPE_MAGIC_NUM), so subtract accordingly.
+ * SLPI actual fd num is (card - SLPI_MAGIC_NUM), so subtract accordingly.
+ */
+ snprintf(val, sizeof(val), "%d,%s",
+ s->card - (is_cpe ? CPE_MAGIC_NUM : (is_slpi ? SLPI_MAGIC_NUM : 0)),
status == CARD_STATUS_ONLINE ? "ONLINE" : "OFFLINE");
- if (str_parms_add_str(params, is_cpe ? "CPE_STATUS" : "SND_CARD_STATUS",
+ if (str_parms_add_str(params,
+ is_cpe ? "CPE_STATUS" : (is_slpi ? "SLPI_STATUS" : "SND_CARD_STATUS"),
val) < 0)
return -1;
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index c11e747..063a7ba 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -78,7 +78,9 @@
SND_CARD_STATUS_OFFLINE,
SND_CARD_STATUS_ONLINE,
CPE_STATUS_OFFLINE,
- CPE_STATUS_ONLINE
+ CPE_STATUS_ONLINE,
+ SLPI_STATUS_OFFLINE,
+ SLPI_STATUS_ONLINE,
} ssr_event_status_t;
struct sound_trigger_session_info {
@@ -362,9 +364,6 @@
if (!st_dev)
return;
- if (st_dev->sthal_prop_api_version >= STHAL_PROP_API_VERSION_1_0)
- return;
-
if (snd_device >= SND_DEVICE_OUT_BEGIN &&
snd_device < SND_DEVICE_OUT_END) {
device_type = PCM_PLAYBACK;
@@ -484,6 +483,19 @@
event.u.value = val;
st_dev->st_callback(AUDIO_EVENT_NUM_ST_SESSIONS, &event);
}
+
+ ret = str_parms_get_str(params, "SLPI_STATUS", value, sizeof(value));
+ if (ret > 0) {
+ if (strstr(value, "OFFLINE")) {
+ event.u.status = SLPI_STATUS_OFFLINE;
+ st_dev->st_callback(AUDIO_EVENT_SSR, &event);
+ } else if (strstr(value, "ONLINE")) {
+ event.u.status = SLPI_STATUS_ONLINE;
+ st_dev->st_callback(AUDIO_EVENT_SSR, &event);
+ } else {
+ ALOGE("%s: unknown SLPI status", __func__);
+ }
+ }
}
int audio_extn_sound_trigger_init(struct audio_device *adev)
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 8c09a29..dba69a0 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -780,6 +780,11 @@
}
}
+void audio_extn_spkr_prot_deinit(void *adev __unused)
+{
+ ALOGV("%s: Entry", __func__);
+}
+
int audio_extn_get_spkr_prot_snd_device(snd_device_t snd_device)
{
if (!handle.spkr_prot_enable)
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 1751a30..73de0ab 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -345,6 +345,8 @@
int sample_rate;
int app_type;
int acdb_dev_id;
+ int new_snd_device[2] = {0};
+ int i = 0, num_devices = 1;
size_t app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
int pcm_device_id;
@@ -379,18 +381,33 @@
return -1;
}
- acdb_dev_id = derive_acdb_dev_id(adev, usecase);
- if (acdb_dev_id <= 0) {
- ALOGE("%s: Couldn't get the acdb dev id", __func__);
- return -1;
- }
+ if (usecase->type == PCM_PLAYBACK) {
+ if (platform_can_split_snd_device(usecase->out_snd_device,
+ &num_devices, new_snd_device) < 0)
+ new_snd_device[0] = usecase->out_snd_device;
+
+ } else if (usecase->type == PCM_CAPTURE)
+ new_snd_device[0] = usecase->in_snd_device;
pcm_device_id = platform_get_pcm_device_id(usecase->id, usecase->type);
- set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type, acdb_dev_id,
- sample_rate,
- usecase->type,
- usecase->type == PCM_PLAYBACK ? usecase->out_snd_device :
- usecase->in_snd_device);
+
+ for (i = 0; i < num_devices; i++) {
+ acdb_dev_id = platform_get_snd_device_acdb_id(new_snd_device[i]);
+
+ if (acdb_dev_id < 0) {
+ ALOGE("%s: Could not find acdb id for device(%d)",
+ __func__, new_snd_device[i]);
+ return -EINVAL;
+ }
+ ALOGV("%s: sending app type for snd_device(%d) acdb_id(%d) i %d",
+ __func__, new_snd_device[i], acdb_dev_id, i);
+
+ set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type, acdb_dev_id,
+ sample_rate,
+ usecase->type,
+ new_snd_device[i]);
+ }
+
return 0;
}
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 0a12cff..fb15db5 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1954,6 +1954,8 @@
int i, ret = 0;
struct audio_usecase *uc_info;
struct audio_device *adev = out->dev;
+ bool has_voip_usecase =
+ get_usecase_from_list(adev, USECASE_AUDIO_PLAYBACK_VOIP) != NULL;
ALOGV("%s: enter: usecase(%d: %s)", __func__,
out->usecase, use_case_table[out->usecase]);
@@ -1987,15 +1989,7 @@
/* Must be called after removing the usecase from list */
if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
check_and_set_hdmi_channels(adev, DEFAULT_HDMI_OUT_CHANNELS);
- else if (out->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
- struct listnode *node;
- struct audio_usecase *usecase;
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->devices & AUDIO_DEVICE_OUT_SPEAKER)
- select_devices(adev, usecase->id);
- }
- } else if (audio_is_usb_out_device(out->devices & AUDIO_DEVICE_OUT_ALL_USB)) {
+ else if (audio_is_usb_out_device(out->devices & AUDIO_DEVICE_OUT_ALL_USB)) {
ret = check_and_set_usb_service_interval(adev, uc_info, false /*min*/);
if (ret == 0) {
/* default service interval was successfully updated,
@@ -2005,6 +1999,22 @@
ret = 0;
}
+ if (has_voip_usecase ||
+ out->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
+ struct listnode *node;
+ struct audio_usecase *usecase;
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ if (usecase->type == PCM_CAPTURE || usecase == uc_info)
+ continue;
+
+ ALOGD("%s: select_devices at usecase(%d: %s) after removing the usecase(%d: %s)",
+ __func__, usecase->id, use_case_table[usecase->id],
+ out->usecase, use_case_table[out->usecase]);
+ select_devices(adev, usecase->id);
+ }
+ }
+
free(uc_info);
ALOGV("%s: exit: status(%d)", __func__, ret);
return ret;
@@ -2105,8 +2115,13 @@
if (out->offload_callback)
compress_nonblock(out->compr, out->non_blocking);
- if (adev->visualizer_start_output != NULL)
- adev->visualizer_start_output(out->handle, out->pcm_device_id);
+ if (adev->visualizer_start_output != NULL) {
+ int capture_device_id =
+ platform_get_pcm_device_id(USECASE_AUDIO_RECORD_AFE_PROXY,
+ PCM_CAPTURE);
+ adev->visualizer_start_output(out->handle, out->pcm_device_id,
+ adev->snd_card, capture_device_id);
+ }
if (adev->offload_effects_start_output != NULL)
adev->offload_effects_start_output(out->handle, out->pcm_device_id);
} else if (out->usecase == USECASE_AUDIO_PLAYBACK_MMAP) {
@@ -5608,7 +5623,7 @@
} else {
ALOGV("%s: DLOPEN successful for %s", __func__, VISUALIZER_LIBRARY_PATH);
adev->visualizer_start_output =
- (int (*)(audio_io_handle_t, int))dlsym(adev->visualizer_lib,
+ (int (*)(audio_io_handle_t, int, int, int))dlsym(adev->visualizer_lib,
"visualizer_hal_start_output");
adev->visualizer_stop_output =
(int (*)(audio_io_handle_t, int))dlsym(adev->visualizer_lib,
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 921c249..6379844 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -337,7 +337,7 @@
card_status_t card_status;
void *visualizer_lib;
- int (*visualizer_start_output)(audio_io_handle_t, int);
+ int (*visualizer_start_output)(audio_io_handle_t, int, int, int);
int (*visualizer_stop_output)(audio_io_handle_t, int);
/* The pcm_params use_case_table is loaded by adev_verify_devices() upon
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index d92243e..8edd999 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1205,6 +1205,8 @@
struct operator_specific_device *device_item;
struct listnode *node;
+ audio_extn_spkr_prot_deinit(my_data->adev);
+
hw_info_deinit(my_data->hw_info);
for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 429291c..820b47f 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1834,6 +1834,8 @@
struct platform_data *my_data = (struct platform_data *)platform;
close_csd_client(my_data->csd);
+ audio_extn_spkr_prot_deinit(my_data->adev);
+
hw_info_deinit(my_data->hw_info);
for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
diff --git a/visualizer/Android.mk b/visualizer/Android.mk
index 7d7cfe9..13a45c7 100644
--- a/visualizer/Android.mk
+++ b/visualizer/Android.mk
@@ -27,14 +27,6 @@
libdl \
libtinyalsa
-# HACK to set the right record proxy effect card number.
-# It should be retrieved from the primary hal USECASE_AUDIO_RECORD_AFE_PROXY.
-ifneq ($(filter msm8998,$(TARGET_BOARD_PLATFORM)),)
- LOCAL_CFLAGS := -DCAPTURE_DEVICE=7
-else
- LOCAL_CFLAGS := -DCAPTURE_DEVICE=8
-endif
-
LOCAL_CFLAGS += \
-Wall \
-Werror \
diff --git a/visualizer/offload_visualizer.c b/visualizer/offload_visualizer.c
index 860dfce..74beac7 100644
--- a/visualizer/offload_visualizer.c
+++ b/visualizer/offload_visualizer.c
@@ -145,6 +145,12 @@
NULL,
};
+struct pcm_capture_config {
+ int snd_card_num;
+ int capture_device_id;
+};
+
+struct pcm_capture_config capture_config;
pthread_once_t once = PTHREAD_ONCE_INIT;
int init_status;
@@ -172,16 +178,12 @@
/* 0 if the capture thread was created successfully */
int thread_status;
-
#define DSP_OUTPUT_LATENCY_MS 0 /* Fudge factor for latency after capture point in audio DSP */
/* Retry for delay for mixer open */
#define RETRY_NUMBER 10
#define RETRY_US 500000
-#define MIXER_CARD 0
-#define SOUND_CARD 0
-
/* Proxy port supports only MMAP read and those fixed parameters*/
#define AUDIO_CAPTURE_CHANNEL_COUNT 2
#define AUDIO_CAPTURE_SMP_RATE 48000
@@ -338,10 +340,10 @@
pthread_mutex_lock(&lock);
- mixer = mixer_open(MIXER_CARD);
+ mixer = mixer_open(capture_config.snd_card_num);
while (mixer == NULL && retry_num < RETRY_NUMBER) {
usleep(RETRY_US);
- mixer = mixer_open(MIXER_CARD);
+ mixer = mixer_open(capture_config.snd_card_num);
retry_num++;
}
if (mixer == NULL) {
@@ -357,7 +359,8 @@
if (!capture_enabled) {
ret = configure_proxy_capture(mixer, 1);
if (ret == 0) {
- pcm = pcm_open(SOUND_CARD, CAPTURE_DEVICE,
+ pcm = pcm_open(capture_config.snd_card_num,
+ capture_config.capture_device_id,
PCM_IN|PCM_MMAP|PCM_NOIRQ, &pcm_config_capture);
if (pcm && !pcm_is_ready(pcm)) {
ALOGW("%s: %s", __func__, pcm_get_error(pcm));
@@ -427,7 +430,8 @@
*/
__attribute__ ((visibility ("default")))
-int visualizer_hal_start_output(audio_io_handle_t output, int pcm_id) {
+int visualizer_hal_start_output(audio_io_handle_t output, int pcm_id,
+ int card_number, int pcm_capture_id) {
int ret = 0;
struct listnode *node;
@@ -444,6 +448,11 @@
goto exit;
}
+ ALOGV("%s card number %d pcm_capture_id %d",
+ __func__, card_number, pcm_capture_id);
+ capture_config.snd_card_num = card_number;
+ capture_config.capture_device_id = pcm_capture_id;
+
output_context_t *out_ctxt = (output_context_t *)malloc(sizeof(output_context_t));
out_ctxt->handle = output;
list_init(&out_ctxt->effects_list);