summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaynes Mathew George <hgeorge@codeaurora.org>2015-08-27 04:04:20 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-08-27 04:04:20 +0000
commitcc64df8ed2804c204bfb3c6202498755835336d6 (patch)
treed86f908ab0bf8d0e203f0a84c4ba300f1207b12d
parent6f3f9984555d9628df2cb38526d1f030b445585c (diff)
parent88e6fb26adb91de5c914713a820a2fe21048d1b5 (diff)
downloadhardware_qcom_audio-cc64df8ed2804c204bfb3c6202498755835336d6.tar.gz
hardware_qcom_audio-cc64df8ed2804c204bfb3c6202498755835336d6.tar.bz2
hardware_qcom_audio-cc64df8ed2804c204bfb3c6202498755835336d6.zip
am 88e6fb26: hal: integrate ADM module
* commit '88e6fb26adb91de5c914713a820a2fe21048d1b5': hal: integrate ADM module
-rw-r--r--hal/audio_hw.c61
-rw-r--r--hal/audio_hw.h20
2 files changed, 81 insertions, 0 deletions
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 486ce8f1..70ce0dc3 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -838,7 +838,10 @@ int start_input_stream(struct stream_in *in)
break;
}
+ ALOGV("%s: pcm_prepare start", __func__);
+ pcm_prepare(in->pcm);
ALOGV("%s: exit", __func__);
+
return ret;
error_open:
@@ -1174,6 +1177,10 @@ int start_output_stream(struct stream_out *out)
}
break;
}
+ ALOGV("%s: pcm_prepare start", __func__);
+ if (pcm_is_ready(out->pcm))
+ pcm_prepare(out->pcm);
+
} else {
out->pcm = NULL;
out->compr = compress_open(adev->snd_card, out->pcm_device_id,
@@ -1315,6 +1322,9 @@ static int out_standby(struct audio_stream *stream)
pthread_mutex_lock(&out->lock);
if (!out->standby) {
+ if (adev->adm_deregister_stream)
+ adev->adm_deregister_stream(adev->adm_data, out->handle);
+
pthread_mutex_lock(&adev->lock);
out->standby = true;
if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
@@ -1589,6 +1599,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
out->standby = true;
goto exit;
}
+ if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD && adev->adm_register_output_stream)
+ adev->adm_register_output_stream(adev->adm_data, out->handle, out->flags);
}
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
@@ -1615,14 +1627,22 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
if (out->pcm) {
if (out->muted)
memset((void *)buffer, 0, bytes);
+
ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
+ if (adev->adm_request_focus)
+ adev->adm_request_focus(adev->adm_data, out->handle);
+
if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) {
ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes);
}
else
ret = pcm_write(out->pcm, (void *)buffer, bytes);
+
if (ret == 0)
out->written += bytes / (out->config.channels * sizeof(short));
+
+ if (adev->adm_abandon_focus)
+ adev->adm_abandon_focus(adev->adm_data, out->handle);
}
}
@@ -1849,6 +1869,9 @@ static int in_standby(struct audio_stream *stream)
}
if (!in->standby) {
+ if (adev->adm_deregister_stream)
+ adev->adm_deregister_stream(adev->adm_data, in->capture_handle);
+
pthread_mutex_lock(&adev->lock);
in->standby = true;
if (in->pcm) {
@@ -1950,8 +1973,13 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
goto exit;
}
in->standby = 0;
+ if (adev->adm_register_input_stream)
+ adev->adm_register_input_stream(adev->adm_data, in->capture_handle, in->flags);
}
+ if (adev->adm_request_focus)
+ adev->adm_request_focus(adev->adm_data, in->capture_handle);
+
if (in->pcm) {
if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) {
ret = pcm_mmap_read(in->pcm, buffer, bytes);
@@ -1959,6 +1987,9 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
ret = pcm_read(in->pcm, buffer, bytes);
}
+ if (adev->adm_abandon_focus)
+ adev->adm_abandon_focus(adev->adm_data, in->capture_handle);
+
/*
* Instead of writing zeroes here, we could trust the hardware
* to always provide zeroes when muted.
@@ -2518,6 +2549,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
in->standby = 1;
in->channel_mask = config->channel_mask;
in->capture_handle = handle;
+ in->flags = flags;
/* Update config params with the requested sample rate and channels */
if (in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
@@ -2743,10 +2775,13 @@ static int adev_close(hw_device_t *device)
for (i = 0; i < ARRAY_SIZE(adev->use_case_table); ++i) {
pcm_params_free(adev->use_case_table[i]);
}
+ if (adev->adm_deinit)
+ adev->adm_deinit(adev->adm_data);
free(device);
}
pthread_mutex_unlock(&adev_init_lock);
+
return 0;
}
@@ -2873,6 +2908,29 @@ static int adev_open(const hw_module_t *module, const char *name,
}
}
+ if (access(ADM_LIBRARY_PATH, R_OK) == 0) {
+ adev->adm_lib = dlopen(ADM_LIBRARY_PATH, RTLD_NOW);
+ if (adev->adm_lib == NULL) {
+ ALOGE("%s: DLOPEN failed for %s", __func__, ADM_LIBRARY_PATH);
+ } else {
+ ALOGV("%s: DLOPEN successful for %s", __func__, ADM_LIBRARY_PATH);
+ adev->adm_init = (adm_init_t)
+ dlsym(adev->adm_lib, "adm_init");
+ adev->adm_deinit = (adm_deinit_t)
+ dlsym(adev->adm_lib, "adm_deinit");
+ adev->adm_register_input_stream = (adm_register_input_stream_t)
+ dlsym(adev->adm_lib, "adm_register_input_stream");
+ adev->adm_register_output_stream = (adm_register_output_stream_t)
+ dlsym(adev->adm_lib, "adm_register_output_stream");
+ adev->adm_deregister_stream = (adm_deregister_stream_t)
+ dlsym(adev->adm_lib, "adm_deregister_stream");
+ adev->adm_request_focus = (adm_request_focus_t)
+ dlsym(adev->adm_lib, "adm_request_focus");
+ adev->adm_abandon_focus = (adm_abandon_focus_t)
+ dlsym(adev->adm_lib, "adm_abandon_focus");
+ }
+ }
+
adev->bt_wb_speech_enabled = false;
adev->enable_voicerx = false;
@@ -2902,6 +2960,9 @@ static int adev_open(const hw_module_t *module, const char *name,
audio_device_ref_count++;
pthread_mutex_unlock(&adev_init_lock);
+ if (adev->adm_init)
+ adev->adm_data = adev->adm_init();
+
ALOGV("%s: exit", __func__);
return 0;
}
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 760e2f04..39e5263d 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -29,6 +29,7 @@
#define VISUALIZER_LIBRARY_PATH "/system/lib/soundfx/libqcomvisualizer.so"
#define OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH "/system/lib/soundfx/libqcompostprocbundle.so"
+#define ADM_LIBRARY_PATH "/system/vendor/lib/libadm.so"
/* Flags used to initialize acdb_settings variable that goes to ACDB library */
#define DMIC_FLAG 0x00000002
@@ -174,6 +175,7 @@ struct stream_in {
bool enable_ns;
audio_io_handle_t capture_handle;
+ audio_input_flags_t flags;
bool is_st_session;
bool is_st_session_active;
@@ -202,6 +204,14 @@ struct audio_usecase {
union stream_ptr stream;
};
+typedef void* (*adm_init_t)();
+typedef void (*adm_deinit_t)(void *);
+typedef void (*adm_register_output_stream_t)(void *, audio_io_handle_t, audio_output_flags_t);
+typedef void (*adm_register_input_stream_t)(void *, audio_io_handle_t, audio_input_flags_t);
+typedef void (*adm_deregister_stream_t)(void *, audio_io_handle_t);
+typedef void (*adm_request_focus_t)(void *, audio_io_handle_t);
+typedef void (*adm_abandon_focus_t)(void *, audio_io_handle_t);
+
struct audio_device {
struct audio_hw_device device;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
@@ -241,6 +251,16 @@ struct audio_device {
void *offload_effects_lib;
int (*offload_effects_start_output)(audio_io_handle_t, int);
int (*offload_effects_stop_output)(audio_io_handle_t, int);
+
+ void *adm_data;
+ void *adm_lib;
+ adm_init_t adm_init;
+ adm_deinit_t adm_deinit;
+ adm_register_input_stream_t adm_register_input_stream;
+ adm_register_output_stream_t adm_register_output_stream;
+ adm_deregister_stream_t adm_deregister_stream;
+ adm_request_focus_t adm_request_focus;
+ adm_abandon_focus_t adm_abandon_focus;
};
int select_devices(struct audio_device *adev,