diff options
author | Uday Kishore Pasupuleti <upasupul@codeaurora.org> | 2016-01-06 19:12:41 -0800 |
---|---|---|
committer | Prashant Malani <pmalani@google.com> | 2016-01-08 17:00:16 -0800 |
commit | 582e0a5e965897ea54ecfa5fe206797dab577a45 (patch) | |
tree | 3d99bdf637b54008f1e906975d75f7de7bfb6fb6 /msm8909/hal/audio_extn/a2dp.c | |
parent | befe610a877c3b150a6dd90cf358df4945b8f9a6 (diff) | |
download | hardware_qcom_audio-582e0a5e965897ea54ecfa5fe206797dab577a45.tar.gz hardware_qcom_audio-582e0a5e965897ea54ecfa5fe206797dab577a45.tar.bz2 hardware_qcom_audio-582e0a5e965897ea54ecfa5fe206797dab577a45.zip |
audio: msm8909w caf release LW.BR.1.0-00410-8x09w.0
MSM8909w Audio HAL code copied from CAF release
LW.BR.1.0-00410-8x09w.0
dbcce50 hal: Port wcd9326 changes to 8909
410c530 hal: update error handling for pcm_prepare failures
ff79309 hal: fix compilation issues with audio FM extention
762d7eb policy_hal: add support for fm device loopback
7c418f9 audio_policy: modify few methods to appropriately override base
8b12163 audio: Add support to enable split A2DP
a0559fa Revert "Revert "policy_hal: Function prototype correction for custom policy"."
Fixed makefiles to be compatible with PDK without kernel source
Change-Id: I9c6f2139adee62426b877516deeb41d4ed8052b2
Diffstat (limited to 'msm8909/hal/audio_extn/a2dp.c')
-rw-r--r-- | msm8909/hal/audio_extn/a2dp.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/msm8909/hal/audio_extn/a2dp.c b/msm8909/hal/audio_extn/a2dp.c new file mode 100644 index 00000000..6b22b692 --- /dev/null +++ b/msm8909/hal/audio_extn/a2dp.c @@ -0,0 +1,201 @@ +/* +* Copyright (c) 2015, The Linux Foundation. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided +* with the distribution. +* * Neither the name of The Linux Foundation nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#define LOG_TAG "split_a2dp" +/*#define LOG_NDEBUG 0*/ +#define LOG_NDDEBUG 0 +#include <errno.h> +#include <cutils/log.h> + +#include "audio_hw.h" +#include "platform.h" +#include "platform_api.h" +#include <stdlib.h> +#include <cutils/str_parms.h> +#include <hardware/audio.h> +#include <hardware/hardware.h> + +#ifdef SPLIT_A2DP_ENABLED + +struct a2dp_data{ + struct audio_stream_out *a2dp_stream; + struct audio_hw_device *a2dp_device; + bool a2dp_started; + bool a2dp_suspended; +}; + +struct a2dp_data a2dp; + +#define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted" + +static int open_a2dp_output() +{ + hw_module_t *mod; + int format = AUDIO_FORMAT_PCM_16_BIT; + int rc=0; + uint32_t channels = AUDIO_CHANNEL_OUT_STEREO; + uint32_t sampleRate = DEFAULT_OUTPUT_SAMPLING_RATE; + struct audio_config config; + + ALOGV("open_a2dp_output"); + + config.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; + config.channel_mask = AUDIO_CHANNEL_OUT_STEREO; + config.format = AUDIO_FORMAT_PCM_16_BIT; + + if (a2dp.a2dp_device == NULL){ + rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, (const char*)"a2dp", + (const hw_module_t**)&mod); + if (rc != 0) { + ALOGE("Could not get a2dp hardware module"); + return rc; + } + ALOGV("Opening A2DP device HAL for the first time"); + rc = audio_hw_device_open(mod, &a2dp.a2dp_device); + if (rc != 0) { + ALOGE("couldn't open a2dp audio hw device"); + return rc; + } + } + + rc = a2dp.a2dp_device->open_output_stream(a2dp.a2dp_device, 0,AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, + (audio_output_flags_t)AUDIO_OUTPUT_FLAG_NONE, &config, &a2dp.a2dp_stream, NULL); + + if( rc != 0 ) { + ALOGE("Failed to open output stream for a2dp: status %d", rc); + } + + a2dp.a2dp_suspended = false; + return rc; +} + +static int close_a2dp_output() +{ + + ALOGV("close_a2dp_output"); + if(!a2dp.a2dp_device && !a2dp.a2dp_stream){ + ALOGE("No Active A2dp output found"); + return 0; + } + + a2dp.a2dp_device->close_output_stream(a2dp.a2dp_device, a2dp.a2dp_stream); + a2dp.a2dp_stream = NULL; + a2dp.a2dp_started = false; + a2dp.a2dp_suspended = true; + + return 0; +} + +void audio_extn_a2dp_set_parameters(struct str_parms *parms) +{ + int ret, val; + char value[32]={0}; + + ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value, + sizeof(value)); + if( ret >= 0) { + val = atoi(value); + if (val & AUDIO_DEVICE_OUT_ALL_A2DP) { + ALOGV("Received device connect request for A2DP"); + open_a2dp_output(); + } + } + + ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value, + sizeof(value)); + + if( ret >= 0) { + val = atoi(value); + if (val & AUDIO_DEVICE_OUT_ALL_A2DP) { + ALOGV("Received device dis- connect request"); + close_a2dp_output(); + } + } + + ret = str_parms_get_str(parms, "A2dpSuspended", value, sizeof(value)); + if (ret >= 0) { + if (a2dp.a2dp_device && a2dp.a2dp_stream) { + a2dp.a2dp_device->set_parameters(a2dp.a2dp_device, str_parms_to_str(parms)); + if (!strncmp(value,"true",sizeof(value))) { + a2dp.a2dp_suspended = true; + } else { + a2dp.a2dp_suspended = false; + } + } + } +} + +void audio_extn_a2dp_start_playback() +{ + int ret = 0; + char buf[20]={0}; + + if (!a2dp.a2dp_started && a2dp.a2dp_device && a2dp.a2dp_stream) { + + snprintf(buf,sizeof(buf),"%s=true",AUDIO_PARAMETER_A2DP_STARTED); + /* This call indicates BT HAL to start playback */ + ret = a2dp.a2dp_device->set_parameters(a2dp.a2dp_device, buf); + if (ret < 0 ) { + ALOGE("BT controller start failed, retry on the next write"); + a2dp.a2dp_started = false; + } else { + a2dp.a2dp_started = true; + ALOGV("Start playback successful to BT HAL"); + } + } +} + +void audio_extn_a2dp_stop_playback() +{ + int ret =0; + char buf[20]={0}; + + if ( a2dp.a2dp_started && a2dp.a2dp_device && a2dp.a2dp_stream) { + + snprintf(buf,sizeof(buf),"%s=false",AUDIO_PARAMETER_A2DP_STARTED); + + ret = a2dp.a2dp_device->set_parameters(a2dp.a2dp_device, buf); + + if (ret < 0) + ALOGE("out_standby to BT HAL failed"); + else + ALOGV("out_standby to BT HAL successful"); + + } + a2dp.a2dp_started = false; + a2dp.a2dp_suspended = true; +} + +void audio_extn_a2dp_init () +{ + a2dp.a2dp_started = false; + a2dp.a2dp_suspended = true; + a2dp.a2dp_stream = NULL; + a2dp.a2dp_device = NULL; +} +#endif // SPLIT_A2DP_ENABLED |