hal: send capture stream events to sound trigger hal
Instead of sending device enable/disable events, send use case
enable/disable events with use case type and device info to
sound trigger hal.
Sound trigger hal can decide to support the concurrent capture
based on the audio use case.
Also avoid compilation dependency on sound trigger hal proprietary
interface header file by maintaining interface APIs locally.
CRs-Fixed: 2173226
Change-Id: I7837523a31da3298fd817bb8355993f9861daca3
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index 7ad8e9f..aa541f0 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -39,7 +39,105 @@
#include "audio_extn.h"
#include "platform.h"
#include "platform_api.h"
-#include "sound_trigger_prop_intf.h"
+
+/*-------------------- Begin: AHAL-STHAL Interface ---------------------------*/
+/*
+ * Maintain the proprietary interface between AHAL and STHAL locally to avoid
+ * the compilation dependency of interface header file from STHAL.
+ */
+
+#define MAKE_HAL_VERSION(maj, min) ((((maj) & 0xff) << 8) | ((min) & 0xff))
+#define MAJOR_VERSION(ver) (((ver) & 0xff00) >> 8)
+#define MINOR_VERSION(ver) ((ver) & 0x00ff)
+
+/* Proprietary interface version used for compatibility with STHAL */
+#define STHAL_PROP_API_VERSION_1_0 MAKE_HAL_VERSION(1, 0)
+#define STHAL_PROP_API_CURRENT_VERSION STHAL_PROP_API_VERSION_1_0
+
+#define ST_EVENT_CONFIG_MAX_STR_VALUE 32
+#define ST_DEVICE_HANDSET_MIC 1
+
+typedef enum {
+ ST_EVENT_SESSION_REGISTER,
+ ST_EVENT_SESSION_DEREGISTER,
+ ST_EVENT_START_KEEP_ALIVE,
+ ST_EVENT_STOP_KEEP_ALIVE,
+} sound_trigger_event_type_t;
+
+typedef enum {
+ AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE,
+ AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE,
+ AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE,
+ AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE,
+ AUDIO_EVENT_STOP_LAB,
+ AUDIO_EVENT_SSR,
+ AUDIO_EVENT_NUM_ST_SESSIONS,
+ AUDIO_EVENT_READ_SAMPLES,
+ AUDIO_EVENT_DEVICE_CONNECT,
+ AUDIO_EVENT_DEVICE_DISCONNECT,
+ AUDIO_EVENT_SVA_EXEC_MODE,
+ AUDIO_EVENT_SVA_EXEC_MODE_STATUS,
+ AUDIO_EVENT_CAPTURE_STREAM_INACTIVE,
+ AUDIO_EVENT_CAPTURE_STREAM_ACTIVE,
+} audio_event_type_t;
+
+typedef enum {
+ USECASE_TYPE_PCM_PLAYBACK,
+ USECASE_TYPE_PCM_CAPTURE,
+ USECASE_TYPE_VOICE_CALL,
+ USECASE_TYPE_VOIP_CALL,
+} audio_stream_usecase_type_t;
+
+typedef enum {
+ SND_CARD_STATUS_OFFLINE,
+ SND_CARD_STATUS_ONLINE,
+ CPE_STATUS_OFFLINE,
+ CPE_STATUS_ONLINE
+} ssr_event_status_t;
+
+struct sound_trigger_session_info {
+ void* p_ses; /* opaque pointer to st_session obj */
+ int capture_handle;
+ struct pcm *pcm;
+ struct pcm_config config;
+};
+
+struct audio_read_samples_info {
+ struct sound_trigger_session_info *ses_info;
+ void *buf;
+ size_t num_bytes;
+};
+
+struct audio_hal_usecase {
+ audio_stream_usecase_type_t type;
+};
+
+struct sound_trigger_event_info {
+ struct sound_trigger_session_info st_ses;
+};
+typedef struct sound_trigger_event_info sound_trigger_event_info_t;
+
+struct sound_trigger_device_info {
+ int device;
+};
+
+struct audio_event_info {
+ union {
+ ssr_event_status_t status;
+ int value;
+ struct sound_trigger_session_info ses_info;
+ struct audio_read_samples_info aud_info;
+ char str_value[ST_EVENT_CONFIG_MAX_STR_VALUE];
+ struct audio_hal_usecase usecase;
+ } u;
+ struct sound_trigger_device_info device_info;
+};
+typedef struct audio_event_info audio_event_info_t;
+/* STHAL callback which is called by AHAL */
+typedef int (*sound_trigger_hw_call_back_t)(audio_event_type_t,
+ struct audio_event_info*);
+
+/*---------------- End: AHAL-STHAL Interface ----------------------------------*/
#ifdef DYNAMIC_LOG_ENABLED
#include <log_xml_parser.h>
@@ -51,6 +149,28 @@
#define STR(x) #x
#define MAX_LIBRARY_PATH 100
+#define DLSYM(handle, ptr, symbol, err) \
+do {\
+ const char* error; \
+ *(void**)&ptr = dlsym(handle, #symbol); \
+ if ((error = dlerror())) {\
+ ALOGE("%s: ERROR. %s", __func__, error);\
+ err = -ENODEV;\
+ }\
+} while(0)
+
+#ifdef __LP64__
+#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib64/hw/sound_trigger.primary.%s.so"
+#else
+#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib/hw/sound_trigger.primary.%s.so"
+#endif
+
+/*
+ * Current proprietary API version used by AHAL. Queried by STHAL
+ * for compatibility check with AHAL
+ */
+const unsigned int sthal_prop_api_version = STHAL_PROP_API_CURRENT_VERSION;
+
struct sound_trigger_info {
struct sound_trigger_session_info st_ses;
bool lab_stopped;
@@ -63,6 +183,7 @@
sound_trigger_hw_call_back_t st_callback;
struct listnode st_ses_list;
pthread_mutex_t lock;
+ unsigned int sthal_prop_api_version;
};
static struct sound_trigger_audio_device *st_dev;
@@ -97,6 +218,37 @@
return NULL;
}
+static int populate_usecase(struct audio_hal_usecase *usecase,
+ struct audio_usecase *uc_info)
+{
+ int status = 0;
+
+ switch(uc_info->type) {
+ case PCM_PLAYBACK:
+ if (uc_info->id == USECASE_AUDIO_PLAYBACK_VOIP)
+ usecase->type = USECASE_TYPE_VOIP_CALL;
+ else
+ usecase->type = USECASE_TYPE_PCM_PLAYBACK;
+ break;
+
+ case PCM_CAPTURE:
+ if (uc_info->id == USECASE_AUDIO_RECORD_VOIP)
+ usecase->type = USECASE_TYPE_VOIP_CALL;
+ else
+ usecase->type = USECASE_TYPE_PCM_CAPTURE;
+ break;
+
+ case VOICE_CALL:
+ usecase->type = USECASE_TYPE_VOICE_CALL;
+ break;
+
+ default:
+ ALOGE("%s: unsupported usecase type %d", __func__, uc_info->type);
+ status = -EINVAL;
+ }
+ return status;
+}
+
static void stdev_snd_mon_cb(void * stream __unused, struct str_parms * parms)
{
if (!parms)
@@ -259,6 +411,22 @@
pthread_mutex_unlock(&st_dev->lock);
}
+bool is_same_as_st_device(snd_device_t snd_device)
+{
+ if (snd_device == SND_DEVICE_IN_HANDSET_MIC_AEC ||
+ snd_device == SND_DEVICE_IN_HANDSET_MIC ||
+ snd_device == SND_DEVICE_IN_HANDSET_MIC_AEC_NS ||
+ snd_device == SND_DEVICE_IN_SPEAKER_MIC ||
+ snd_device == SND_DEVICE_IN_VOICE_SPEAKER_MIC ||
+ snd_device == SND_DEVICE_IN_SPEAKER_MIC_AEC ||
+ snd_device == SND_DEVICE_IN_SPEAKER_MIC_AEC_NS ||
+ snd_device == SND_DEVICE_IN_SPEAKER_MIC_NS) {
+ ALOGD("audio HAL using same device %d as ST", snd_device);
+ return true;
+ }
+ return false;
+}
+
void audio_extn_sound_trigger_update_device_status(snd_device_t snd_device,
st_event_type_t event)
{
@@ -268,6 +436,9 @@
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;
@@ -302,36 +473,58 @@
st_event_type_t event)
{
bool raise_event = false;
- audio_usecase_t uc_id;
- int usecase_type = -1;
+ struct audio_event_info ev_info;
+ audio_event_type_t ev;
+ /*Initialize to invalid device*/
+ ev_info.device_info.device = -1;
- if (!st_dev) {
+ if (!st_dev)
+ return;
+
+ if (st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0)
return;
- }
if (uc_info == NULL) {
ALOGE("%s: usecase is NULL!!!", __func__);
return;
}
- uc_id = uc_info->id;
- usecase_type = uc_info->type;
- raise_event = platform_sound_trigger_usecase_needs_event(uc_id);
- ALOGD("%s: uc_id %d of type %d for Event %d, with Raise=%d",
- __func__, uc_id, usecase_type, event, raise_event);
- if (raise_event && (usecase_type == PCM_PLAYBACK)) {
- switch(event) {
- case ST_EVENT_STREAM_FREE:
- st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE, NULL);
- break;
- case ST_EVENT_STREAM_BUSY:
- st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE, NULL);
- break;
- default:
- ALOGW("%s:invalid event %d, for usecase %d",
- __func__, event, uc_id);
+ if ((uc_info->in_snd_device >= SND_DEVICE_IN_BEGIN &&
+ uc_info->in_snd_device < SND_DEVICE_IN_END)) {
+ if (is_same_as_st_device(uc_info->in_snd_device))
+ ev_info.device_info.device = ST_DEVICE_HANDSET_MIC;
+ } else {
+ ALOGE("%s: invalid input device 0x%x, for event %d",
+ __func__, uc_info->in_snd_device, event);
+ }
+ raise_event = platform_sound_trigger_usecase_needs_event(uc_info->id);
+ ALOGD("%s: uc_info->id %d of type %d for Event %d, with Raise=%d",
+ __func__, uc_info->id, uc_info->type, event, raise_event);
+ if (raise_event) {
+ if (uc_info->type == PCM_PLAYBACK) {
+ switch(event) {
+ case ST_EVENT_STREAM_FREE:
+ st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE, NULL);
+ break;
+ case ST_EVENT_STREAM_BUSY:
+ st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE, NULL);
+ break;
+ default:
+ ALOGW("%s:invalid event %d, for usecase %d",
+ __func__, event, uc_info->id);
+ }
+ } else if (uc_info->type == PCM_CAPTURE) {
+ if (event == ST_EVENT_STREAM_BUSY)
+ ev = AUDIO_EVENT_CAPTURE_STREAM_ACTIVE;
+ else
+ ev = AUDIO_EVENT_CAPTURE_STREAM_INACTIVE;
+ if (!populate_usecase(&ev_info.u.usecase, uc_info)) {
+ ALOGD("%s: send event %d: usecase id %d, type %d",
+ __func__, ev, uc_info->id, uc_info->type);
+ st_dev->st_callback(ev, &ev_info);
+ }
}
- }/*Events for capture usecase, if required can be placed here in else*/
+ }
}
void audio_extn_sound_trigger_set_parameters(struct audio_device *adev __unused,
@@ -419,6 +612,7 @@
{
int status = 0;
char sound_trigger_lib[100];
+ void *sthal_prop_api_version;
ALOGI("%s: Enter", __func__);
@@ -433,20 +627,34 @@
st_dev->lib_handle = dlopen(sound_trigger_lib, RTLD_NOW);
if (st_dev->lib_handle == NULL) {
- ALOGE("%s: DLOPEN failed for %s. error = %s", __func__, sound_trigger_lib,
- dlerror());
- status = -EINVAL;
+ ALOGE("%s: error %s", __func__, dlerror());
+ status = -ENODEV;
goto cleanup;
}
ALOGI("%s: DLOPEN successful for %s", __func__, sound_trigger_lib);
- st_dev->st_callback = (sound_trigger_hw_call_back_t)
- dlsym(st_dev->lib_handle, "sound_trigger_hw_call_back");
+ dlerror();
+ DLSYM(st_dev->lib_handle, st_dev->st_callback, sound_trigger_hw_call_back,
+ status);
+ if (status)
+ goto cleanup;
- if (st_dev->st_callback == NULL) {
- ALOGE("%s: ERROR. dlsym Error:%s sound_trigger_hw_call_back", __func__,
- dlerror());
- goto cleanup;
+ DLSYM(st_dev->lib_handle, sthal_prop_api_version,
+ sthal_prop_api_version, status);
+ if (status) {
+ st_dev->sthal_prop_api_version = 0;
+ status = 0; /* passthru for backward compability */
+ } else {
+ st_dev->sthal_prop_api_version = *(int*)sthal_prop_api_version;
+ if (MAJOR_VERSION(st_dev->sthal_prop_api_version) !=
+ MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
+ ALOGE("%s: Incompatible API versions ahal:0x%x != sthal:0x%x",
+ __func__, STHAL_PROP_API_CURRENT_VERSION,
+ st_dev->sthal_prop_api_version);
+ goto cleanup;
+ }
+ ALOGD("%s: sthal is using proprietary API version 0x%04x", __func__,
+ st_dev->sthal_prop_api_version);
}
st_dev->adev = adev;
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
old mode 100755
new mode 100644
index 930c5d4..2db83b7
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -5444,31 +5444,34 @@
needs_event = true;
break;
- /* concurrent capture usecases, no event, capture handled by device
- * USECASE_AUDIO_RECORD:
- * USECASE_AUDIO_RECORD_COMPRESS:
- * USECASE_AUDIO_RECORD_LOW_LATENCY:
-
- * USECASE_VOICE_CALL:
- * USECASE_VOICE2_CALL:
- * USECASE_VOLTE_CALL:
- * USECASE_QCHAT_CALL:
- * USECASE_VOWLAN_CALL:
- * USECASE_VOICEMMODE1_CALL:
- * USECASE_VOICEMMODE2_CALL:
- * USECASE_COMPRESS_VOIP_CALL:
- * USECASE_AUDIO_RECORD_FM_VIRTUAL:
- * USECASE_INCALL_REC_UPLINK:
- * USECASE_INCALL_REC_DOWNLINK:
- * USECASE_INCALL_REC_UPLINK_AND_DOWNLINK:
- * USECASE_INCALL_REC_UPLINK_COMPRESS:
- * USECASE_INCALL_REC_DOWNLINK_COMPRESS:
- * USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS:
- * USECASE_INCALL_MUSIC_UPLINK:
- * USECASE_INCALL_MUSIC_UPLINK2:
- * USECASE_AUDIO_SPKR_CALIB_RX:
- * USECASE_AUDIO_SPKR_CALIB_TX:
- */
+ /* concurrent capture usecases which needs event */
+ case USECASE_AUDIO_RECORD:
+ case USECASE_AUDIO_RECORD_LOW_LATENCY:
+ case USECASE_AUDIO_RECORD_COMPRESS:
+ case USECASE_AUDIO_RECORD_MMAP:
+ case USECASE_AUDIO_RECORD_HIFI:
+ case USECASE_VOICE_CALL:
+ case USECASE_VOICE2_CALL:
+ case USECASE_VOLTE_CALL:
+ case USECASE_QCHAT_CALL:
+ case USECASE_VOWLAN_CALL:
+ case USECASE_VOICEMMODE1_CALL:
+ case USECASE_VOICEMMODE2_CALL:
+ case USECASE_COMPRESS_VOIP_CALL:
+ case USECASE_AUDIO_RECORD_FM_VIRTUAL:
+ case USECASE_INCALL_REC_UPLINK:
+ case USECASE_INCALL_REC_DOWNLINK:
+ case USECASE_INCALL_REC_UPLINK_AND_DOWNLINK:
+ case USECASE_INCALL_REC_UPLINK_COMPRESS:
+ case USECASE_INCALL_REC_DOWNLINK_COMPRESS:
+ case USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS:
+ case USECASE_INCALL_MUSIC_UPLINK:
+ case USECASE_INCALL_MUSIC_UPLINK2:
+ case USECASE_AUDIO_SPKR_CALIB_RX:
+ case USECASE_AUDIO_SPKR_CALIB_TX:
+ case USECASE_AUDIO_RECORD_VOIP:
+ needs_event = true;
+ break;
default:
ALOGV("%s:usecase_id[%d] no need to raise event.", __func__, uc_id);
}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
old mode 100755
new mode 100644
index da2ccb6..0e10b94
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -5414,31 +5414,34 @@
needs_event = true;
break;
- /* concurrent capture usecases, no event, capture handled by device
- * USECASE_AUDIO_RECORD:
- * USECASE_AUDIO_RECORD_COMPRESS:
- * USECASE_AUDIO_RECORD_LOW_LATENCY:
-
- * USECASE_VOICE_CALL:
- * USECASE_VOICE2_CALL:
- * USECASE_VOLTE_CALL:
- * USECASE_QCHAT_CALL:
- * USECASE_VOWLAN_CALL:
- * USECASE_VOICEMMODE1_CALL:
- * USECASE_VOICEMMODE2_CALL:
- * USECASE_COMPRESS_VOIP_CALL:
- * USECASE_AUDIO_RECORD_FM_VIRTUAL:
- * USECASE_INCALL_REC_UPLINK:
- * USECASE_INCALL_REC_DOWNLINK:
- * USECASE_INCALL_REC_UPLINK_AND_DOWNLINK:
- * USECASE_INCALL_REC_UPLINK_COMPRESS:
- * USECASE_INCALL_REC_DOWNLINK_COMPRESS:
- * USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS:
- * USECASE_INCALL_MUSIC_UPLINK:
- * USECASE_INCALL_MUSIC_UPLINK2:
- * USECASE_AUDIO_SPKR_CALIB_RX:
- * USECASE_AUDIO_SPKR_CALIB_TX:
- */
+ /* concurrent capture usecases which needs event */
+ case USECASE_AUDIO_RECORD:
+ case USECASE_AUDIO_RECORD_LOW_LATENCY:
+ case USECASE_AUDIO_RECORD_COMPRESS:
+ case USECASE_AUDIO_RECORD_MMAP:
+ case USECASE_AUDIO_RECORD_HIFI:
+ case USECASE_VOICE_CALL:
+ case USECASE_VOICE2_CALL:
+ case USECASE_VOLTE_CALL:
+ case USECASE_QCHAT_CALL:
+ case USECASE_VOWLAN_CALL:
+ case USECASE_VOICEMMODE1_CALL:
+ case USECASE_VOICEMMODE2_CALL:
+ case USECASE_COMPRESS_VOIP_CALL:
+ case USECASE_AUDIO_RECORD_FM_VIRTUAL:
+ case USECASE_INCALL_REC_UPLINK:
+ case USECASE_INCALL_REC_DOWNLINK:
+ case USECASE_INCALL_REC_UPLINK_AND_DOWNLINK:
+ case USECASE_INCALL_REC_UPLINK_COMPRESS:
+ case USECASE_INCALL_REC_DOWNLINK_COMPRESS:
+ case USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS:
+ case USECASE_INCALL_MUSIC_UPLINK:
+ case USECASE_INCALL_MUSIC_UPLINK2:
+ case USECASE_AUDIO_SPKR_CALIB_RX:
+ case USECASE_AUDIO_SPKR_CALIB_TX:
+ case USECASE_AUDIO_RECORD_VOIP:
+ needs_event = true;
+ break;
default:
ALOGV("%s:usecase_id[%d] no need to raise event.", __func__, uc_id);
}