Merge "audio: add wsa combo device for jacala sku3" into audio-userspace.lnx.2.1-dev
diff --git a/configs/msmcobalt/audio_platform_info.xml b/configs/msmcobalt/audio_platform_info.xml
index 512e8ee..696a5d0 100644
--- a/configs/msmcobalt/audio_platform_info.xml
+++ b/configs/msmcobalt/audio_platform_info.xml
@@ -55,6 +55,8 @@
<usecase name="USECASE_AUDIO_SPKR_CALIB_TX" type="in" id="35"/>
<usecase name="USECASE_AUDIO_PLAYBACK_AFE_PROXY" type="out" id="6"/>
<usecase name="USECASE_AUDIO_RECORD_AFE_PROXY" type="in" id="7"/>
+ <usecase name="USECASE_AUDIO_RECORD_LOW_LATENCY" type="in" id="17" />
+ <usecase name="USECASE_AUDIO_PLAYBACK_ULL" type="out" id="17" />
</pcm_ids>
<config_params>
<param key="spkr_1_tz_name" value="wsatz.13"/>
diff --git a/configs/msmcobalt/audio_policy.conf b/configs/msmcobalt/audio_policy.conf
index dd827fe..a3b0c55 100644
--- a/configs/msmcobalt/audio_policy.conf
+++ b/configs/msmcobalt/audio_policy.conf
@@ -26,21 +26,21 @@
sampling_rates 44100|48000
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
- devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE
+ devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
flags AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_PRIMARY
}
raw {
sampling_rates 48000
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
- devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE
+ devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
flags AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_RAW
}
deep_buffer {
sampling_rates 44100|48000
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
- devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE
+ devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
flags AUDIO_OUTPUT_FLAG_DEEP_BUFFER
}
compress_passthrough {
@@ -61,14 +61,14 @@
sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000|64000|88200|96000|176400|192000
channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_2POINT1|AUDIO_CHANNEL_OUT_QUAD|AUDIO_CHANNEL_OUT_PENTA|AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_6POINT1|AUDIO_CHANNEL_OUT_7POINT1
formats AUDIO_FORMAT_PCM_16_BIT|AUDIO_FORMAT_PCM_24_BIT_PACKED|AUDIO_FORMAT_PCM_8_24_BIT
- devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE
+ devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_DIRECT_PCM
}
compress_offload {
sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000|64000|88200|96000|176400|192000
channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_2POINT1|AUDIO_CHANNEL_OUT_QUAD|AUDIO_CHANNEL_OUT_PENTA|AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_6POINT1|AUDIO_CHANNEL_OUT_7POINT1
formats AUDIO_FORMAT_MP3|AUDIO_FORMAT_FLAC|AUDIO_FORMAT_ALAC|AUDIO_FORMAT_APE|AUDIO_FORMAT_AAC_LC|AUDIO_FORMAT_AAC_HE_V1|AUDIO_FORMAT_AAC_HE_V2|AUDIO_FORMAT_WMA|AUDIO_FORMAT_WMA_PRO|AUDIO_FORMAT_VORBIS|AUDIO_FORMAT_AAC_ADTS_LC|AUDIO_FORMAT_AAC_ADTS_HE_V1|AUDIO_FORMAT_AAC_ADTS_HE_V2
- devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE
+ devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING
}
incall_music {
@@ -108,14 +108,6 @@
}
}
a2dp {
- outputs {
- a2dp {
- sampling_rates 44100
- channel_masks AUDIO_CHANNEL_OUT_STEREO
- formats AUDIO_FORMAT_PCM_16_BIT
- devices AUDIO_DEVICE_OUT_ALL_A2DP
- }
- }
inputs {
a2dp {
sampling_rates 44100|48000
diff --git a/configs/msmcobalt/audio_policy_configuration.xml b/configs/msmcobalt/audio_policy_configuration.xml
index 235c157..4336aa2 100644
--- a/configs/msmcobalt/audio_policy_configuration.xml
+++ b/configs/msmcobalt/audio_policy_configuration.xml
@@ -228,6 +228,18 @@
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
+ <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
@@ -288,12 +300,37 @@
sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic"/>
<route type="mix" sink="voice_rx"
sources="Telephony Rx"/>
+ <route type="mix" sink="BT A2DP Out"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
+ <route type="mix" sink="BT A2DP Headphones"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
+ <route type="mix" sink="BT A2DP Speaker"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
</routes>
</module>
- <!-- A2dp Audio HAL -->
- <xi:include href="a2dp_audio_policy_configuration.xml"/>
+ <!-- A2DP Audio HAL -->
+ <module name="a2dp" halVersion="2.0">
+ <mixPorts>
+ <mixPort name="a2dp input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ </mixPort>
+ </mixPorts>
+
+ <devicePorts>
+ <devicePort tagName="BT A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ </devicePort>
+ </devicePorts>
+
+ <routes>
+ <route type="mix" sink="a2dp input"
+ sources="BT A2DP In"/>
+ </routes>
+ </module>
<!-- Usb Audio HAL -->
<xi:include href="usb_audio_policy_configuration.xml"/>
diff --git a/configs/msmcobalt/graphite_ipc_platform_info.xml b/configs/msmcobalt/graphite_ipc_platform_info.xml
new file mode 100644
index 0000000..f6775be
--- /dev/null
+++ b/configs/msmcobalt/graphite_ipc_platform_info.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--- Copyright (c) 2016, 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. -->
+<graphite_ipc_platform_info>
+ <no_of_glink_channels value="4">
+ </no_of_glink_channels>
+ <!-- channel 1 configuration -->
+ <glink_channel name="g_glink_ctrl" latency_in_us="5000"
+ no_of_intents="1" intents_size="1024">
+ </glink_channel>
+ <!-- channel 2 configuration -->
+ <glink_channel name="g_glink_persistent_data_ild" latency_in_us="30000"
+ no_of_intents="0">
+ </glink_channel>
+ <!-- channel 3 configuration -->
+ <glink_channel name="g_glink_persistent_data_nild" latency_in_us="30000"
+ no_of_intents="0">
+ </glink_channel>
+ <!-- channel 4 configuration -->
+ <glink_channel name="g_glink_audio_data" latency_in_us="10000"
+ no_of_intents="2" intents_size="4096, 4096">
+ </glink_channel>
+</graphite_ipc_platform_info>
diff --git a/configs/msmcobalt/mixer_paths_dtp.xml b/configs/msmcobalt/mixer_paths_dtp.xml
index 9bcf15b..a6c61e4 100644
--- a/configs/msmcobalt/mixer_paths_dtp.xml
+++ b/configs/msmcobalt/mixer_paths_dtp.xml
@@ -138,6 +138,8 @@
<ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia5" value="0" />
<ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia7" value="0" />
+ <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia8" value="0" />
+ <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia8" value="0" />
<ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia10" value="0" />
<ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia10" value="0" />
<ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia11" value="0" />
@@ -617,7 +619,7 @@
</path>
<path name="audio-ull-playback">
- <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback speaker-protected">
@@ -634,11 +636,11 @@
</path>
<path name="audio-ull-playback hdmi">
- <ctl name="HDMI Mixer MultiMedia3" value="1" />
+ <ctl name="HDMI Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback bt-sco">
- <ctl name="AUX_PCM_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="AUX_PCM_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback bt-sco-wb">
@@ -652,7 +654,7 @@
</path>
<path name="audio-ull-playback afe-proxy">
- <ctl name="AFE_PCM_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="multi-channel-playback hdmi">
<ctl name="HDMI Mixer MultiMedia2" value="1" />
@@ -1103,11 +1105,11 @@
</path>
<path name="low-latency-record">
- <ctl name="MultiMedia5 Mixer SLIM_0_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="1" />
</path>
<path name="low-latency-record bt-sco">
- <ctl name="MultiMedia5 Mixer AUX_PCM_UL_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer AUX_PCM_UL_TX" value="1" />
</path>
<path name="low-latency-record bt-sco-wb">
@@ -1116,11 +1118,11 @@
</path>
<path name="low-latency-record usb-headset-mic">
- <ctl name="MultiMedia5 Mixer AFE_PCM_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer AFE_PCM_TX" value="1" />
</path>
<path name="low-latency-record capture-fm">
- <ctl name="MultiMedia5 Mixer TERT_MI2S_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer TERT_MI2S_TX" value="1" />
</path>
<path name="fm-virtual-record capture-fm">
diff --git a/configs/msmcobalt/mixer_paths_tasha.xml b/configs/msmcobalt/mixer_paths_tasha.xml
index 860d014..3c6f642 100644
--- a/configs/msmcobalt/mixer_paths_tasha.xml
+++ b/configs/msmcobalt/mixer_paths_tasha.xml
@@ -548,6 +548,11 @@
<ctl name="LSM8 MUX" value="None" />
<ctl name="SLIMBUS_5_TX LSM Function" value="None" />
<!-- listen end-->
+ <!-- split a2dp -->
+ <ctl name="BT SampleRate" value="KHZ_8" />
+ <ctl name="AFE Input Channels" value="Zero" />
+ <ctl name="SLIM7_RX ADM Channels" value="Zero" />
+ <!-- split a2dp end-->
<!-- ADSP testfwk -->
<ctl name="SLIMBUS_DL_HL Switch" value="0" />
@@ -614,7 +619,7 @@
</path>
<path name="deep-buffer-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="deep-buffer-playback bt-sco" />
</path>
@@ -657,7 +662,7 @@
</path>
<path name="low-latency-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="low-latency-playback bt-sco" />
</path>
@@ -689,7 +694,7 @@
</path>
<path name="audio-ull-playback">
- <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback speaker-protected">
@@ -697,7 +702,7 @@
</path>
<path name="audio-ull-playback headphones">
- <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback speaker-and-headphones">
@@ -706,15 +711,15 @@
</path>
<path name="audio-ull-playback hdmi">
- <ctl name="HDMI Mixer MultiMedia3" value="1" />
+ <ctl name="HDMI Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback bt-sco">
- <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="audio-ull-playback bt-sco" />
</path>
@@ -724,11 +729,11 @@
</path>
<path name="audio-ull-playback afe-proxy">
- <ctl name="AFE_PCM_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback usb-headphones">
- <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="multi-channel-playback hdmi">
@@ -760,7 +765,7 @@
</path>
<path name="compress-offload-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback bt-sco" />
</path>
@@ -808,7 +813,7 @@
</path>
<path name="compress-offload-playback2 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback2 bt-sco" />
</path>
@@ -856,7 +861,7 @@
</path>
<path name="compress-offload-playback3 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback3 bt-sco" />
</path>
@@ -904,7 +909,7 @@
</path>
<path name="compress-offload-playback4 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback4 bt-sco" />
</path>
@@ -952,7 +957,7 @@
</path>
<path name="compress-offload-playback5 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback5 bt-sco" />
</path>
@@ -1000,7 +1005,7 @@
</path>
<path name="compress-offload-playback6 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback6 bt-sco" />
</path>
@@ -1048,7 +1053,7 @@
</path>
<path name="compress-offload-playback7 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback7 bt-sco" />
</path>
@@ -1096,7 +1101,7 @@
</path>
<path name="compress-offload-playback8 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback8 bt-sco" />
</path>
@@ -1144,7 +1149,7 @@
</path>
<path name="compress-offload-playback9 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback9 bt-sco" />
</path>
@@ -1192,7 +1197,7 @@
</path>
<path name="audio-record bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="audio-record bt-sco" />
</path>
@@ -1209,7 +1214,7 @@
</path>
<path name="audio-record-compress bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="audio-record-compress bt-sco" />
</path>
@@ -1218,24 +1223,24 @@
</path>
<path name="low-latency-record">
- <ctl name="MultiMedia5 Mixer SLIM_0_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="1" />
</path>
<path name="low-latency-record bt-sco">
- <ctl name="MultiMedia5 Mixer SLIM_7_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer SLIM_7_TX" value="1" />
</path>
<path name="low-latency-record bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="low-latency-record bt-sco" />
</path>
<path name="low-latency-record usb-headset-mic">
- <ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="1" />
</path>
<path name="low-latency-record capture-fm">
- <ctl name="MultiMedia5 Mixer SLIM_8_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer SLIM_8_TX" value="1" />
</path>
<path name="fm-virtual-record capture-fm">
@@ -1393,12 +1398,12 @@
</path>
<path name="hfp-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="hfp-sco" />
</path>
<path name="hfp-sco-wb headphones">
- <ctl name="AUX PCM SampleRate" value="16000" />
+ <ctl name="AUX PCM SampleRate" value="KHZ_16" />
<path name="hfp-sco headphones" />
</path>
@@ -1419,7 +1424,7 @@
</path>
<path name="compress-voip-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-voip-call bt-sco" />
</path>
@@ -1459,7 +1464,7 @@
</path>
<path name="vowlan-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="vowlan-call bt-sco" />
</path>
@@ -1499,7 +1504,7 @@
</path>
<path name="voicemmode1-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="voicemmode1-call bt-sco" />
</path>
@@ -1539,7 +1544,7 @@
</path>
<path name="voicemmode2-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="voicemmode2-call bt-sco" />
</path>
@@ -2376,4 +2381,122 @@
<ctl name="SLIMBUS_DL_HL Switch" value="1" />
</path>
+ <path name="bt-a2dp">
+ <ctl name="BT SampleRate" value="KHZ_48" />
+ <ctl name="AFE Input Channels" value="Two" />
+ <ctl name="SLIM7_RX ADM Channels" value="Two" />
+ </path>
+
+ <path name="speaker-and-bt-a2dp">
+ <path name="speaker" />
+ <path name="bt-a2dp" />
+ </path>
+
+ <path name="deep-buffer-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia1" value="1" />
+ </path>
+
+ <path name="low-latency-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia5" value="1" />
+ </path>
+
+ <path name="compress-offload-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia4" value="1" />
+ </path>
+
+ <path name="compress-offload-playback2 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia7" value="1" />
+ </path>
+
+ <path name="compress-offload-playback3 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia10" value="1" />
+ </path>
+
+ <path name="compress-offload-playback4 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia11" value="1" />
+ </path>
+
+ <path name="compress-offload-playback5 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia12" value="1" />
+ </path>
+
+ <path name="compress-offload-playback6 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia13" value="1" />
+ </path>
+
+ <path name="compress-offload-playback7 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia14" value="1" />
+ </path>
+
+ <path name="compress-offload-playback8 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia15" value="1" />
+ </path>
+
+ <path name="compress-offload-playback9 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia16" value="1" />
+ </path>
+
+ <path name="audio-ull-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia3" value="1" />
+ </path>
+
+ <path name="deep-buffer-playback speaker-and-bt-a2dp">
+ <path name="deep-buffer-playback bt-a2dp" />
+ <path name="deep-buffer-playback" />
+ </path>
+
+ <path name="compress-offload-playback speaker-and-bt-a2dp">
+ <path name="compress-offload-playback bt-a2dp" />
+ <path name="compress-offload-playback" />
+ </path>
+
+ <path name="low-latency-playback speaker-and-bt-a2dp">
+ <path name="low-latency-playback bt-a2dp" />
+ <path name="low-latency-playback" />
+ </path>
+
+ <path name="compress-offload-playback2 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback2 bt-a2dp" />
+ <path name="compress-offload-playback2" />
+ </path>
+
+ <path name="compress-offload-playback3 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback3 bt-a2dp" />
+ <path name="compress-offload-playback3" />
+ </path>
+
+ <path name="compress-offload-playback4 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback4 bt-a2dp" />
+ <path name="compress-offload-playback4" />
+ </path>
+
+ <path name="compress-offload-playback5 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback5 bt-a2dp" />
+ <path name="compress-offload-playback5" />
+ </path>
+
+ <path name="compress-offload-playback6 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback6 bt-a2dp" />
+ <path name="compress-offload-playback6" />
+ </path>
+
+ <path name="compress-offload-playback7 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback7 bt-a2dp" />
+ <path name="compress-offload-playback7" />
+ </path>
+
+ <path name="compress-offload-playback8 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback8 bt-a2dp" />
+ <path name="compress-offload-playback8" />
+ </path>
+
+ <path name="compress-offload-playback9 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback9 bt-a2dp" />
+ <path name="compress-offload-playback9" />
+ </path>
+
+ <path name="audio-ull-playback speaker-and-bt-a2dp">
+ <path name="audio-ull-playback bt-a2dp" />
+ <path name="audio-ull-playback" />
+ </path>
</mixer>
diff --git a/configs/msmcobalt/mixer_paths_tavil.xml b/configs/msmcobalt/mixer_paths_tavil.xml
index 1c92421..3a188f9 100644
--- a/configs/msmcobalt/mixer_paths_tavil.xml
+++ b/configs/msmcobalt/mixer_paths_tavil.xml
@@ -50,6 +50,7 @@
<ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia5" value="0" />
<ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia7" value="0" />
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia8" value="0" />
<ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia10" value="0" />
<ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia11" value="0" />
<ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia12" value="0" />
@@ -67,6 +68,9 @@
<ctl name="MultiMedia1 Mixer SLIM_0_TX" value="0" />
<ctl name="MultiMedia1 Mixer SLIM_4_TX" value="0" />
<ctl name="MultiMedia1 Mixer SLIM_7_TX" value="0" />
+ <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="0" />
+ <ctl name="MultiMedia8 Mixer SLIM_4_TX" value="0" />
+ <ctl name="MultiMedia8 Mixer SLIM_7_TX" value="0" />
<ctl name="HDMI Mixer MultiMedia1" value="0" />
<ctl name="HDMI Mixer MultiMedia2" value="0" />
<ctl name="HDMI Mixer MultiMedia3" value="0" />
@@ -95,6 +99,9 @@
<ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia7" value="0" />
<ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia7" value="0" />
+ <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia8" value="0" />
+ <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia8" value="0" />
+ <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia8" value="0" />
<ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia10" value="0" />
<ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia10" value="0" />
<ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia10" value="0" />
@@ -122,6 +129,7 @@
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia4" value="0" />
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia5" value="0" />
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia7" value="0" />
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia8" value="0" />
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia10" value="0" />
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia11" value="0" />
<ctl name="USB_AUDIO_RX Audio Mixer MultiMedia12" value="0" />
@@ -262,6 +270,12 @@
<ctl name="MultiMedia8 Mixer AFE_PCM_TX" value="0" />
<!-- audio record compress end-->
+ <!-- split a2dp -->
+ <ctl name="BT SampleRate" value="KHZ_8" />
+ <ctl name="AFE Input Channels" value="Zero" />
+ <ctl name="SLIM7_RX ADM Channels" value="0" />
+ <!-- split a2dp end-->
+
<!-- ADSP testfwk -->
<ctl name="SLIMBUS_DL_HL Switch" value="0" />
<ctl name="SLIMBUS6_DL_HL Switch" value="0" />
@@ -286,6 +300,12 @@
<ctl name="SpkrRight VISENSE Switch" value="0" />
<ctl name="SpkrLeft SWR DAC_Port Switch" value="0" />
<ctl name="SpkrRight SWR DAC_Port Switch" value="0" />
+ <ctl name="SLIM0_RX_VI_FB_LCH_MUX" value="ZERO" />
+ <ctl name="SLIM0_RX_VI_FB_RCH_MUX" value="ZERO" />
+ <ctl name="VI_FEED_TX Channels" value="Two" />
+ <ctl name="AIF4_VI Mixer SPKR_VI_1" value="0" />
+ <ctl name="AIF4_VI Mixer SPKR_VI_2" value="0" />
+ <ctl name="SLIM_4_TX Format" value="UNPACKED" />
<ctl name="AIF1_CAP Mixer SLIM TX0" value="0" />
<ctl name="AIF1_CAP Mixer SLIM TX2" value="0" />
@@ -357,7 +377,7 @@
</path>
<path name="deep-buffer-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="deep-buffer-playback bt-sco" />
</path>
@@ -400,7 +420,7 @@
</path>
<path name="low-latency-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="low-latency-playback bt-sco" />
</path>
@@ -432,7 +452,7 @@
</path>
<path name="audio-ull-playback">
- <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback speaker-protected">
@@ -440,7 +460,7 @@
</path>
<path name="audio-ull-playback headphones">
- <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback speaker-and-headphones">
@@ -449,15 +469,15 @@
</path>
<path name="audio-ull-playback hdmi">
- <ctl name="HDMI Mixer MultiMedia3" value="1" />
+ <ctl name="HDMI Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback bt-sco">
- <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="audio-ull-playback bt-sco" />
</path>
@@ -467,11 +487,11 @@
</path>
<path name="audio-ull-playback afe-proxy">
- <ctl name="AFE_PCM_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="AFE_PCM_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="audio-ull-playback usb-headphones">
- <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia3" value="1" />
+ <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia8" value="1" />
</path>
<path name="multi-channel-playback hdmi">
@@ -503,7 +523,7 @@
</path>
<path name="compress-offload-playback bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback bt-sco" />
</path>
@@ -551,7 +571,7 @@
</path>
<path name="compress-offload-playback2 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback2 bt-sco" />
</path>
@@ -599,7 +619,7 @@
</path>
<path name="compress-offload-playback3 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback3 bt-sco" />
</path>
@@ -647,7 +667,7 @@
</path>
<path name="compress-offload-playback4 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback4 bt-sco" />
</path>
@@ -695,7 +715,7 @@
</path>
<path name="compress-offload-playback5 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback5 bt-sco" />
</path>
@@ -743,7 +763,7 @@
</path>
<path name="compress-offload-playback6 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback6 bt-sco" />
</path>
@@ -791,7 +811,7 @@
</path>
<path name="compress-offload-playback7 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback7 bt-sco" />
</path>
@@ -839,7 +859,7 @@
</path>
<path name="compress-offload-playback8 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback8 bt-sco" />
</path>
@@ -887,7 +907,7 @@
</path>
<path name="compress-offload-playback9 bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-offload-playback9 bt-sco" />
</path>
@@ -935,7 +955,7 @@
</path>
<path name="audio-record bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="audio-record bt-sco" />
</path>
@@ -952,7 +972,7 @@
</path>
<path name="audio-record-compress bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="audio-record-compress bt-sco" />
</path>
@@ -961,24 +981,24 @@
</path>
<path name="low-latency-record">
- <ctl name="MultiMedia5 Mixer SLIM_0_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="1" />
</path>
<path name="low-latency-record bt-sco">
- <ctl name="MultiMedia5 Mixer SLIM_7_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer SLIM_7_TX" value="1" />
</path>
<path name="low-latency-record bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="low-latency-record bt-sco" />
</path>
<path name="low-latency-record usb-headset-mic">
- <ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="1" />
</path>
<path name="low-latency-record capture-fm">
- <ctl name="MultiMedia5 Mixer SLIM_8_TX" value="1" />
+ <ctl name="MultiMedia8 Mixer SLIM_8_TX" value="1" />
</path>
<path name="fm-virtual-record capture-fm">
@@ -1150,7 +1170,7 @@
</path>
<path name="compress-voip-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="compress-voip-call bt-sco" />
</path>
@@ -1190,7 +1210,7 @@
</path>
<path name="voicemmode1-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="voicemmode1-call bt-sco" />
</path>
@@ -1230,7 +1250,7 @@
</path>
<path name="voicemmode2-call bt-sco-wb">
- <ctl name="BT_SCO SampleRate" value="16000" />
+ <ctl name="BT SampleRate" value="KHZ_16" />
<path name="voicemmode2-call bt-sco" />
</path>
@@ -1364,11 +1384,21 @@
</path>
<path name="speaker-protected">
+ <ctl name="AIF4_VI Mixer SPKR_VI_1" value="1" />
+ <ctl name="AIF4_VI Mixer SPKR_VI_2" value="1" />
+ <ctl name="SLIM_4_TX Format" value="PACKED_16B" />
<path name="speaker" />
+ <ctl name="VI_FEED_TX Channels" value="Two" />
+ <ctl name="SLIM0_RX_VI_FB_LCH_MUX" value="SLIM4_TX" />
+ <ctl name="SLIM0_RX_VI_FB_RCH_MUX" value="SLIM4_TX" />
</path>
<path name="voice-speaker-protected">
+ <ctl name="AIF4_VI Mixer SPKR_VI_1" value="1" />
+ <ctl name="SLIM_4_TX Format" value="PACKED_16B" />
<path name="speaker-mono" />
+ <ctl name="VI_FEED_TX Channels" value="One" />
+ <ctl name="SLIM0_RX_VI_FB_LCH_MUX" value="SLIM4_TX" />
</path>
<path name="vi-feedback">
@@ -1715,4 +1745,122 @@
<ctl name="SLIMBUS_DL_HL Switch" value="1" />
</path>
+ <path name="bt-a2dp">
+ <ctl name="BT SampleRate" value="KHZ_48" />
+ <ctl name="AFE Input Channels" value="Two" />
+ <ctl name="SLIM7_RX ADM Channels" value="2" />
+ </path>
+
+ <path name="speaker-and-bt-a2dp">
+ <path name="speaker" />
+ <path name="bt-a2dp" />
+ </path>
+
+ <path name="deep-buffer-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia1" value="1" />
+ </path>
+
+ <path name="low-latency-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia5" value="1" />
+ </path>
+
+ <path name="compress-offload-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia4" value="1" />
+ </path>
+
+ <path name="compress-offload-playback2 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia7" value="1" />
+ </path>
+
+ <path name="compress-offload-playback3 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia10" value="1" />
+ </path>
+
+ <path name="compress-offload-playback4 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia11" value="1" />
+ </path>
+
+ <path name="compress-offload-playback5 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia12" value="1" />
+ </path>
+
+ <path name="compress-offload-playback6 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia13" value="1" />
+ </path>
+
+ <path name="compress-offload-playback7 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia14" value="1" />
+ </path>
+
+ <path name="compress-offload-playback8 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia15" value="1" />
+ </path>
+
+ <path name="compress-offload-playback9 bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia16" value="1" />
+ </path>
+
+ <path name="audio-ull-playback bt-a2dp">
+ <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia3" value="1" />
+ </path>
+
+ <path name="deep-buffer-playback speaker-and-bt-a2dp">
+ <path name="deep-buffer-playback bt-a2dp" />
+ <path name="deep-buffer-playback" />
+ </path>
+
+ <path name="compress-offload-playback speaker-and-bt-a2dp">
+ <path name="compress-offload-playback bt-a2dp" />
+ <path name="compress-offload-playback" />
+ </path>
+
+ <path name="low-latency-playback speaker-and-bt-a2dp">
+ <path name="low-latency-playback bt-a2dp" />
+ <path name="low-latency-playback" />
+ </path>
+
+ <path name="compress-offload-playback2 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback2 bt-a2dp" />
+ <path name="compress-offload-playback2" />
+ </path>
+
+ <path name="compress-offload-playback3 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback3 bt-a2dp" />
+ <path name="compress-offload-playback3" />
+ </path>
+
+ <path name="compress-offload-playback4 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback4 bt-a2dp" />
+ <path name="compress-offload-playback4" />
+ </path>
+
+ <path name="compress-offload-playback5 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback5 bt-a2dp" />
+ <path name="compress-offload-playback5" />
+ </path>
+
+ <path name="compress-offload-playback6 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback6 bt-a2dp" />
+ <path name="compress-offload-playback6" />
+ </path>
+
+ <path name="compress-offload-playback7 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback7 bt-a2dp" />
+ <path name="compress-offload-playback7" />
+ </path>
+
+ <path name="compress-offload-playback8 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback8 bt-a2dp" />
+ <path name="compress-offload-playback8" />
+ </path>
+
+ <path name="compress-offload-playback9 speaker-and-bt-a2dp">
+ <path name="compress-offload-playback9 bt-a2dp" />
+ <path name="compress-offload-playback9" />
+ </path>
+
+ <path name="audio-ull-playback speaker-and-bt-a2dp">
+ <path name="audio-ull-playback bt-a2dp" />
+ <path name="audio-ull-playback" />
+ </path>
</mixer>
diff --git a/configs/msmcobalt/msmcobalt.mk b/configs/msmcobalt/msmcobalt.mk
index ff73287..aaf9db5 100644
--- a/configs/msmcobalt/msmcobalt.mk
+++ b/configs/msmcobalt/msmcobalt.mk
@@ -52,6 +52,7 @@
AUDIO_FEATURE_ENABLED_SOURCE_TRACKING := true
AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
+AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
##AUDIO_FEATURE_FLAGS
#Audio Specific device overlays
@@ -79,6 +80,7 @@
hardware/qcom/audio/configs/msmcobalt/sound_trigger_mixer_paths.xml:system/etc/sound_trigger_mixer_paths.xml \
hardware/qcom/audio/configs/msmcobalt/sound_trigger_mixer_paths_wcd9330.xml:system/etc/sound_trigger_mixer_paths_wcd9330.xml \
hardware/qcom/audio/configs/msmcobalt/sound_trigger_platform_info.xml:system/etc/sound_trigger_platform_info.xml \
+ hardware/qcom/audio/configs/msmcobalt/graphite_ipc_platform_info.xml:system/etc/graphite_ipc_platform_info.xml \
hardware/qcom/audio/configs/msmcobalt/audio_platform_info.xml:system/etc/audio_platform_info.xml
#XML Audio configuration files
@@ -189,3 +191,7 @@
#flac sw decoder 24 bit decode capability
PRODUCT_PROPERTY_OVERRIDES += \
flac.sw.decoder.24bit.support=true
+
+#split a2dp DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bt.a2dp_offload_cap=sbc-aptx
diff --git a/hal/Android.mk b/hal/Android.mk
index 83787e3..adee78b 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -243,6 +243,11 @@
LOCAL_SRC_FILES += audio_extn/source_track.c
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SPLIT_A2DP)),true)
+ LOCAL_CFLAGS += -DSPLIT_A2DP_ENABLED
+ LOCAL_SRC_FILES += audio_extn/a2dp.c
+endif
+
LOCAL_SHARED_LIBRARIES := \
liblog \
libcutils \
@@ -251,6 +256,7 @@
libaudioroute \
libdl \
libaudioutils \
+ libhardware \
libexpat
LOCAL_C_INCLUDES += \
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
new file mode 100644
index 0000000..414fc79
--- /dev/null
+++ b/hal/audio_extn/a2dp.c
@@ -0,0 +1,733 @@
+/*
+* Copyright (c) 2015-16, 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 <dlfcn.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>
+#include <cutils/properties.h>
+
+#ifdef SPLIT_A2DP_ENABLED
+#define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted"
+#define BT_IPC_LIB_NAME "libbthost_if.so"
+#define ENC_MEDIA_FMT_NONE 0
+#define ENC_MEDIA_FMT_AAC 0x00010DA6
+#define ENC_MEDIA_FMT_APTX 0x000131ff
+#define ENC_MEDIA_FMT_APTX_HD 0x00013200
+#define ENC_MEDIA_FMT_SBC 0x00010BF2
+#define MEDIA_FMT_AAC_AOT_LC 2
+#define MEDIA_FMT_AAC_AOT_SBR 5
+#define MEDIA_FMT_AAC_AOT_PS 29
+#define MEDIA_FMT_AAC_FORMAT_FLAG_ADTS 0
+#define MEDIA_FMT_AAC_FORMAT_FLAG_RAW 3
+#define PCM_CHANNEL_L 1
+#define PCM_CHANNEL_R 2
+#define PCM_CHANNEL_C 3
+#define MEDIA_FMT_SBC_CHANNEL_MODE_MONO 1
+#define MEDIA_FMT_SBC_CHANNEL_MODE_STEREO 2
+#define MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO 8
+#define MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO 9
+#define MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS 0
+#define MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR 1
+#define MIXER_ENC_CONFIG_BLOCK "SLIM_7_RX Encoder Config"
+#define MIXER_ENC_FMT_SBC "SBC"
+#define MIXER_ENC_FMT_AAC "AAC"
+#define MIXER_ENC_FMT_APTX "APTX"
+#define MIXER_ENC_FMT_APTXHD "APTXHD"
+#define MIXER_ENC_FMT_NONE "NONE"
+
+
+typedef int (*audio_stream_open_t)(void);
+typedef int (*audio_stream_close_t)(void);
+typedef int (*audio_start_stream_t)(void);
+typedef int (*audio_stop_stream_t)(void);
+typedef int (*audio_suspend_stream_t)(void);
+typedef void (*audio_handoff_triggered_t)(void);
+typedef void (*clear_a2dpsuspend_flag_t)(void);
+typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev,
+ audio_format_t *codec_type);
+
+enum A2DP_STATE {
+ A2DP_STATE_CONNECTED,
+ A2DP_STATE_STARTED,
+ A2DP_STATE_STOPPED,
+ A2DP_STATE_DISCONNECTED,
+};
+
+/* structure used to update a2dp state machine
+ * to communicate IPC library
+ * to store DSP encoder configuration information
+ */
+struct a2dp_data {
+ struct audio_device *adev;
+ void *bt_lib_handle;
+ audio_stream_open_t audio_stream_open;
+ audio_stream_close_t audio_stream_close;
+ audio_start_stream_t audio_start_stream;
+ audio_stop_stream_t audio_stop_stream;
+ audio_suspend_stream_t audio_suspend_stream;
+ audio_handoff_triggered_t audio_handoff_triggered;
+ clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag;
+ audio_get_codec_config_t audio_get_codec_config;
+ enum A2DP_STATE bt_state;
+ audio_format_t bt_encoder_format;
+ void *enc_config_data;
+ bool a2dp_started;
+ bool a2dp_suspended;
+ int a2dp_total_active_session_request;
+ bool is_a2dp_offload_supported;
+ bool is_handoff_in_progress;
+};
+
+struct a2dp_data a2dp;
+
+/* START of DSP configurable structures
+ * These values should match with DSP interface defintion
+ */
+
+/* AAC encoder configuration structure. */
+typedef struct aac_enc_cfg_t aac_enc_cfg_t;
+
+/* supported enc_mode are AAC_LC, AAC_SBR, AAC_PS
+ * supported aac_fmt_flag are ADTS/RAW
+ * supported channel_cfg are Native mode, Mono , Stereo
+ */
+struct aac_enc_cfg_t {
+ uint32_t enc_format;
+ uint32_t bit_rate;
+ uint32_t enc_mode;
+ uint16_t aac_fmt_flag;
+ uint32_t channel_cfg;
+ uint32_t sample_rate;
+} ;
+
+/* SBC encoder configuration structure. */
+typedef struct sbc_enc_cfg_t sbc_enc_cfg_t;
+
+/* supported num_subbands are 4/8
+ * supported blk_len are 4, 8, 12, 16
+ * supported channel_mode are MONO, STEREO, DUAL_MONO, JOINT_STEREO
+ * supported alloc_method are LOUNDNESS/SNR
+ * supported bit_rate for mono channel is max 320kbps
+ * supported bit rate for stereo channel is max 512 kbps
+ */
+struct sbc_enc_cfg_t{
+ uint32_t enc_format;
+ uint32_t num_subbands;
+ uint32_t blk_len;
+ uint32_t channel_mode;
+ uint32_t alloc_method;
+ uint32_t bit_rate;
+ uint32_t sample_rate;
+};
+
+
+/* supported num_channels are Mono/Stereo
+ * supported channel_mapping for mono is CHANNEL_C
+ * supported channel mapping for stereo is CHANNEL_L and CHANNEL_R
+ * custom size and reserved are not used(for future enhancement)
+ */
+struct custom_enc_cfg_aptx_t
+{
+ uint32_t enc_format;
+ uint32_t sample_rate;
+ uint16_t num_channels;
+ uint16_t reserved;
+ uint8_t channel_mapping[8];
+ uint32_t custom_size;
+};
+
+/*********** END of DSP configurable structures ********************/
+
+/* API to identify DSP encoder captabilities */
+static void a2dp_offload_codec_cap_parser(char *value)
+{
+ char *tok = NULL;
+
+ tok = strtok(value, "-");
+ while (tok != NULL) {
+ if (strcmp(tok, "sbc") == 0) {
+ ALOGD("%s: SBC offload supported\n",__func__);
+ a2dp.is_a2dp_offload_supported = true;
+ break;
+ } else if (strcmp(tok, "aptx") == 0) {
+ ALOGD("%s: aptx offload supported\n",__func__);
+ a2dp.is_a2dp_offload_supported = true;
+ break;
+ }
+ tok = strtok(NULL,"-");
+ };
+}
+
+static void update_offload_codec_capabilities()
+{
+ char value[PROPERTY_VALUE_MAX] = {'\0'};
+
+ property_get("persist.bt.a2dp_offload_cap", value, "false");
+ ALOGD("get_offload_codec_capabilities = %s",value);
+ a2dp.is_a2dp_offload_supported =
+ property_get_bool("persist.bt.a2dp_offload_cap", false);
+ if (strcmp(value, "false") != 0)
+ a2dp_offload_codec_cap_parser(value);
+ ALOGD("%s: codec cap = %s",__func__,value);
+}
+
+/* API to open BT IPC library to start IPC communication */
+static void open_a2dp_output()
+{
+ int ret = 0;
+
+ ALOGD(" Open A2DP output start ");
+ if (a2dp.bt_lib_handle == NULL){
+ ALOGD(" Requesting for BT lib handle");
+ a2dp.bt_lib_handle = dlopen(BT_IPC_LIB_NAME, RTLD_NOW);
+
+ if (a2dp.bt_lib_handle == NULL) {
+ ALOGE("%s: DLOPEN failed for %s", __func__, BT_IPC_LIB_NAME);
+ ret = -ENOSYS;
+ goto init_fail;
+ } else {
+ a2dp.audio_stream_open = (audio_stream_open_t)
+ dlsym(a2dp.bt_lib_handle, "audio_stream_open");
+ a2dp.audio_start_stream = (audio_start_stream_t)
+ dlsym(a2dp.bt_lib_handle, "audio_start_stream");
+ a2dp.audio_get_codec_config = (audio_get_codec_config_t)
+ dlsym(a2dp.bt_lib_handle, "audio_get_codec_config");
+ a2dp.audio_suspend_stream = (audio_suspend_stream_t)
+ dlsym(a2dp.bt_lib_handle, "audio_suspend_stream");
+ a2dp.audio_handoff_triggered = (audio_handoff_triggered_t)
+ dlsym(a2dp.bt_lib_handle, "audio_handoff_triggered");
+ a2dp.clear_a2dpsuspend_flag = (clear_a2dpsuspend_flag_t)
+ dlsym(a2dp.bt_lib_handle, "clear_a2dpsuspend_flag");
+ a2dp.audio_stop_stream = (audio_stop_stream_t)
+ dlsym(a2dp.bt_lib_handle, "audio_stop_stream");
+ a2dp.audio_stream_close = (audio_stream_close_t)
+ dlsym(a2dp.bt_lib_handle, "audio_stream_close");
+ }
+ }
+
+ if (a2dp.bt_lib_handle && a2dp.audio_stream_open) {
+ if (a2dp.bt_state == A2DP_STATE_DISCONNECTED) {
+ ALOGD("calling BT stream open");
+ ret = a2dp.audio_stream_open();
+ if(ret != 0) {
+ ALOGE("Failed to open output stream for a2dp: status %d", ret);
+ goto init_fail;
+ }
+ a2dp.bt_state = A2DP_STATE_CONNECTED;
+ } else {
+ ALOGD("Called a2dp open with improper state, Ignoring request state %d", a2dp.bt_state);
+ }
+ } else {
+ ALOGE("a2dp handle is not identified, Ignoring open request");
+ a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+ goto init_fail;
+ }
+
+init_fail:
+ if(ret != 0 && (a2dp.bt_lib_handle != NULL)) {
+ dlclose(a2dp.bt_lib_handle);
+ a2dp.bt_lib_handle = NULL;
+ }
+}
+
+static int close_a2dp_output()
+{
+ ALOGV("%s\n",__func__);
+ if (!(a2dp.bt_lib_handle && a2dp.audio_stream_close)) {
+ ALOGE("a2dp handle is not identified, Ignoring close request");
+ return -ENOSYS;
+ }
+ if ((a2dp.bt_state == A2DP_STATE_CONNECTED) &&
+ (a2dp.bt_state == A2DP_STATE_STARTED) &&
+ (a2dp.bt_state == A2DP_STATE_STOPPED)) {
+ ALOGD("calling BT stream close");
+ if(a2dp.audio_stream_close() == false)
+ ALOGE("failed close a2dp control path from BT library");
+ a2dp.a2dp_started = false;
+ a2dp.a2dp_total_active_session_request = 0;
+ a2dp.a2dp_suspended = false;
+ a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
+ a2dp.enc_config_data = NULL;
+ a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+ } else {
+ ALOGD("close a2dp called in improper state");
+ a2dp.a2dp_started = false;
+ a2dp.a2dp_total_active_session_request = 0;
+ a2dp.a2dp_suspended = false;
+ a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
+ a2dp.enc_config_data = NULL;
+ a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+ }
+
+ return 0;
+}
+
+/* API to configure SBC DSP encoder */
+bool configure_sbc_enc_format(audio_sbc_encoder_config *sbc_bt_cfg)
+{
+ struct mixer_ctl *ctl_enc_data;
+ struct sbc_enc_cfg_t sbc_dsp_cfg;
+ bool is_configured = false;
+ int ret = 0;
+
+ if(sbc_bt_cfg == NULL)
+ return false;
+
+ 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");
+ is_configured = false;
+ goto fail;
+ }
+ a2dp.bt_encoder_format = AUDIO_FORMAT_SBC;
+ memset(&sbc_dsp_cfg, 0x0, sizeof(struct sbc_enc_cfg_t));
+ sbc_dsp_cfg.enc_format = ENC_MEDIA_FMT_SBC;
+ sbc_dsp_cfg.num_subbands = sbc_bt_cfg->subband;
+ sbc_dsp_cfg.blk_len = sbc_bt_cfg->blk_len;
+ switch(sbc_bt_cfg->channels) {
+ case 0:
+ sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_MONO;
+ break;
+ case 1:
+ sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO;
+ break;
+ case 3:
+ sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO;
+ break;
+ case 2:
+ default:
+ sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_STEREO;
+ break;
+ }
+ if (sbc_bt_cfg->alloc)
+ sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS;
+ else
+ sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR;
+ sbc_dsp_cfg.bit_rate = sbc_bt_cfg->bitrate;
+ sbc_dsp_cfg.sample_rate = sbc_bt_cfg->sampling_rate;
+ ret = mixer_ctl_set_array(ctl_enc_data, (void *)&sbc_dsp_cfg,
+ sizeof(struct sbc_enc_cfg_t));
+ if (ret != 0) {
+ ALOGE("%s: failed to set SBC encoder config", __func__);
+ is_configured = false;
+ } else
+ is_configured = true;
+fail:
+ return is_configured;
+}
+
+/* API to configure APTX DSP encoder */
+bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
+{
+ struct mixer_ctl *ctl_enc_data;
+ struct custom_enc_cfg_aptx_t aptx_dsp_cfg;
+ bool is_configured = false;
+ int ret = 0;
+
+ if(aptx_bt_cfg == NULL)
+ return false;
+
+ 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");
+ is_configured = false;
+ goto fail;
+ }
+ a2dp.bt_encoder_format = AUDIO_FORMAT_APTX;
+ memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_aptx_t));
+ aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX;
+ aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
+ aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
+ switch(aptx_dsp_cfg.num_channels) {
+ case 1:
+ aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
+ break;
+ case 2:
+ default:
+ aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
+ aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
+ break;
+ }
+ ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
+ sizeof(struct custom_enc_cfg_aptx_t));
+ if (ret != 0) {
+ ALOGE("%s: Failed to set APTX encoder config", __func__);
+ is_configured = false;
+ goto fail;
+ }
+ is_configured = true;
+fail:
+ return is_configured;
+}
+
+/* API to configure APTX HD DSP encoder
+ * TODO: ADD 24 bit configuration support
+ */
+bool configure_aptx_hd_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
+{
+ struct mixer_ctl *ctl_enc_data;
+ struct custom_enc_cfg_aptx_t aptx_dsp_cfg;
+ bool is_configured = false;
+ int ret = 0;
+
+ if(aptx_bt_cfg == NULL)
+ return false;
+
+ 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");
+ is_configured = false;
+ goto fail;
+ }
+ a2dp.bt_encoder_format = AUDIO_FORMAT_APTX_HD;
+ memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_aptx_t));
+ aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX_HD;
+ aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
+ aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
+ switch(aptx_dsp_cfg.num_channels) {
+ case 1:
+ aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
+ break;
+ case 2:
+ default:
+ aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
+ aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
+ break;
+ }
+ ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
+ sizeof(struct custom_enc_cfg_aptx_t));
+ if (ret != 0) {
+ ALOGE("%s: Failed to set APTX HD encoder config", __func__);
+ is_configured = false;
+ goto fail;
+ }
+ is_configured = true;
+fail:
+ return is_configured;
+}
+
+/* API to configure AAC DSP encoder */
+bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
+{
+ struct mixer_ctl *ctl_enc_data;
+ struct aac_enc_cfg_t aac_dsp_cfg;
+ bool is_configured = false;
+ int ret = 0;
+
+ if(aac_bt_cfg == NULL)
+ return false;
+
+ 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");
+ is_configured = false;
+ goto fail;
+ }
+ a2dp.bt_encoder_format = AUDIO_FORMAT_AAC;
+ memset(&aac_dsp_cfg, 0x0, sizeof(struct aac_enc_cfg_t));
+ aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC;
+ aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate;
+ switch(aac_bt_cfg->enc_mode) {
+ case 0:
+ aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
+ break;
+ case 2:
+ aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
+ break;
+ case 1:
+ default:
+ aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
+ break;
+ }
+ if (aac_bt_cfg->format_flag)
+ aac_dsp_cfg.aac_fmt_flag = MEDIA_FMT_AAC_FORMAT_FLAG_RAW;
+ else
+ aac_dsp_cfg.aac_fmt_flag = MEDIA_FMT_AAC_FORMAT_FLAG_ADTS;
+ aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels;
+ ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg,
+ sizeof(struct aac_enc_cfg_t));
+ if (ret != 0) {
+ ALOGE("%s: failed to set SBC encoder config", __func__);
+ is_configured = false;
+ } else
+ is_configured = true;
+fail:
+ return is_configured;
+}
+
+bool configure_a2dp_encoder_format()
+{
+ void *codec_info = NULL;
+ uint8_t multi_cast = 0, num_dev = 1;
+ audio_format_t codec_type = AUDIO_FORMAT_INVALID;
+ bool is_configured = false;
+
+ if (!a2dp.audio_get_codec_config) {
+ ALOGE(" a2dp handle is not identified, ignoring a2dp encoder config");
+ return false;
+ }
+ ALOGD("configure_a2dp_encoder_format start");
+ codec_info = a2dp.audio_get_codec_config(&multi_cast, &num_dev,
+ &codec_type);
+
+ switch(codec_type) {
+ case AUDIO_FORMAT_SBC:
+ ALOGD(" Received SBC encoder supported BT device");
+ is_configured =
+ configure_sbc_enc_format((audio_sbc_encoder_config *)codec_info);
+ break;
+ case AUDIO_FORMAT_APTX:
+ ALOGD(" Received APTX encoder supported BT device");
+ is_configured =
+ configure_aptx_enc_format((audio_aptx_encoder_config *)codec_info);
+ break;
+ case AUDIO_FORMAT_APTX_HD:
+ ALOGD(" Received APTX HD encoder supported BT device");
+ is_configured =
+ configure_aptx_hd_enc_format((audio_aptx_encoder_config *)codec_info);
+ break;
+ case AUDIO_FORMAT_AAC:
+ ALOGD(" Received AAC encoder supported BT device");
+ is_configured =
+ configure_aac_enc_format((audio_aac_encoder_config *)codec_info);
+ break;
+ default:
+ ALOGD(" Received Unsupported encoder formar");
+ is_configured = false;
+ break;
+ }
+ return is_configured;
+}
+
+int audio_extn_a2dp_start_playback()
+{
+ int ret = 0;
+
+ ALOGD("audio_extn_a2dp_start_playback start");
+
+ if(!(a2dp.bt_lib_handle && a2dp.audio_start_stream
+ && a2dp.audio_get_codec_config)) {
+ ALOGE("a2dp handle is not identified, Ignoring start request");
+ return -ENOSYS;
+ }
+
+ if(a2dp.a2dp_suspended == true) {
+ //session will be restarted after suspend completion
+ ALOGD("a2dp start requested during suspend state");
+ a2dp.a2dp_total_active_session_request++;
+ return 0;
+ }
+
+ if (!a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
+ ALOGD("calling BT module stream start");
+ /* This call indicates BT IPC lib to start playback */
+ ret = a2dp.audio_start_stream();
+ ALOGE("BT controller start return = %d",ret);
+ if (ret != 0 ) {
+ ALOGE("BT controller start failed");
+ a2dp.a2dp_started = false;
+ ret = -ETIMEDOUT;
+ } else {
+ if(configure_a2dp_encoder_format() == true) {
+ a2dp.a2dp_started = true;
+ ret = 0;
+ ALOGD("Start playback successful to BT library");
+ } else {
+ ALOGD(" unable to configure DSP encoder");
+ a2dp.a2dp_started = false;
+ ret = -ETIMEDOUT;
+ }
+ }
+ }
+
+ if (a2dp.a2dp_started)
+ a2dp.a2dp_total_active_session_request++;
+
+ ALOGD("start A2DP playback total active sessions :%d",
+ a2dp.a2dp_total_active_session_request);
+ return ret;
+}
+
+int audio_extn_a2dp_stop_playback()
+{
+ int ret =0;
+
+ ALOGV("audio_extn_a2dp_stop_playback start");
+ if(!(a2dp.bt_lib_handle && a2dp.audio_stop_stream)) {
+ ALOGE("a2dp handle is not identified, Ignoring start request");
+ return -ENOSYS;
+ }
+
+ if(a2dp.a2dp_suspended == true) {
+ ALOGD("STOP playback is called during suspend state");
+
+ // sessions are already closed during suspend, just update active sessions counts
+ if(a2dp.a2dp_total_active_session_request > 0)
+ a2dp.a2dp_total_active_session_request--;
+ return 0;
+ }
+ if (a2dp.a2dp_started && (a2dp.a2dp_total_active_session_request > 0))
+ a2dp.a2dp_total_active_session_request--;
+
+ if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
+ struct mixer_ctl *ctl_enc_config;
+ struct sbc_enc_cfg_t dummy_reset_config;
+
+ ALOGV("calling BT module stream stop");
+ ret = a2dp.audio_stop_stream();
+ if (ret < 0)
+ ALOGE("stop stream to BT IPC lib failed");
+ else
+ ALOGV("stop steam to BT IPC lib successful");
+ a2dp.is_handoff_in_progress = false;
+
+ memset(&dummy_reset_config, 0x0, sizeof(struct sbc_enc_cfg_t));
+ ctl_enc_config = mixer_get_ctl_by_name(a2dp.adev->mixer,
+ MIXER_ENC_CONFIG_BLOCK);
+ if (!ctl_enc_config) {
+ ALOGE(" ERROR a2dp encoder format mixer control not identifed");
+ } else {
+ ret = mixer_ctl_set_array(ctl_enc_config, (void *)&dummy_reset_config,
+ sizeof(struct sbc_enc_cfg_t));
+ a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
+ }
+ }
+ if(!a2dp.a2dp_total_active_session_request)
+ a2dp.a2dp_started = false;
+ ALOGD("Stop A2DP playback total active sessions :%d",
+ a2dp.a2dp_total_active_session_request);
+ return 0;
+}
+
+void audio_extn_a2dp_set_parameters(struct str_parms *parms)
+{
+ int ret, val;
+ char value[32]={0};
+
+ if(a2dp.is_a2dp_offload_supported == false) {
+ ALOGV("no supported encoders identified,ignoring a2dp setparam");
+ return;
+ }
+
+ 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();
+ }
+ goto param_handled;
+ }
+
+ 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();
+ }
+ goto param_handled;
+ }
+
+ ret = str_parms_get_str(parms, "A2dpSuspended", value, sizeof(value));
+ if (ret >= 0) {
+ if (a2dp.bt_lib_handle && (a2dp.bt_state != A2DP_STATE_DISCONNECTED) ) {
+ if ((!strncmp(value,"true",sizeof(value)))) {
+ ALOGD("Setting a2dp to suspend state");
+ int active_sessions = a2dp.a2dp_total_active_session_request, count = 0;
+ //Force close all active sessions on suspend (if any)
+ for(count = 0; count< active_sessions; count ++)
+ audio_extn_a2dp_stop_playback();
+ a2dp.a2dp_total_active_session_request = active_sessions;
+ a2dp.a2dp_suspended = true;
+
+ if(a2dp.audio_suspend_stream)
+ a2dp.audio_suspend_stream();
+ } else if (a2dp.a2dp_suspended == true) {
+ ALOGD("Resetting a2dp suspend state");
+ if(a2dp.clear_a2dpsuspend_flag)
+ a2dp.clear_a2dpsuspend_flag();
+
+ a2dp.a2dp_suspended = false;
+ //Force restart all active sessions post suspend (if any)
+ if(a2dp.a2dp_total_active_session_request > 0){
+ int active_sessions = a2dp.a2dp_total_active_session_request;
+ a2dp.a2dp_total_active_session_request = 0;
+ audio_extn_a2dp_start_playback();
+ a2dp.a2dp_total_active_session_request = active_sessions;
+ }
+ }
+ }
+ goto param_handled;
+ }
+ ret = str_parms_get_str(parms,"reconfigA2dp", value, sizeof(value));
+ if (ret >= 0) {
+ if (a2dp.bt_lib_handle && (a2dp.bt_state != A2DP_STATE_DISCONNECTED)) {
+ if (!strncmp(value,"true",sizeof(value)))
+ a2dp.is_handoff_in_progress = true;
+ }
+ goto param_handled;
+ }
+param_handled:
+ ALOGV("end of a2dp setparam");
+}
+
+bool audio_extn_a2dp_is_force_device_switch()
+{
+ //During encoder reconfiguration mode, force a2dp device switch
+ return a2dp.is_handoff_in_progress;
+}
+
+void audio_extn_a2dp_init (void *adev)
+{
+ a2dp.adev = (struct audio_device*)adev;
+ a2dp.bt_lib_handle = NULL;
+ a2dp.a2dp_started = false;
+ a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+ a2dp.a2dp_total_active_session_request = 0;
+ a2dp.a2dp_suspended = false;
+ a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
+ a2dp.enc_config_data = NULL;
+ a2dp.is_a2dp_offload_supported = false;
+ a2dp.is_handoff_in_progress = false;
+ update_offload_codec_capabilities();
+}
+#endif // SPLIT_A2DP_ENABLED
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 49e649c..569b4b2 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -755,6 +755,7 @@
audio_extn_ssr_set_parameters(adev, parms);
audio_extn_hfp_set_parameters(adev, parms);
audio_extn_dts_eagle_set_parameters(adev, parms);
+ audio_extn_a2dp_set_parameters(parms);
audio_extn_ddp_set_parameters(adev, parms);
audio_extn_ds2_set_parameters(adev, parms);
audio_extn_customstereo_set_parameters(adev, parms);
@@ -762,6 +763,7 @@
audio_extn_pm_set_parameters(parms);
audio_extn_source_track_set_parameters(adev, parms);
audio_extn_fbsp_set_parameters(parms);
+ audio_extn_keep_alive_set_parameters(adev, parms);
check_and_set_hdmi_connection_status(parms);
if (adev->offload_effects_set_parameters != NULL)
adev->offload_effects_set_parameters(parms);
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index fe3fe95..d186a5f 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -171,6 +171,20 @@
char *value, int len);
#endif
+#ifndef SPLIT_A2DP_ENABLED
+#define audio_extn_a2dp_init(adev) (0)
+#define audio_extn_a2dp_start_playback() (0)
+#define audio_extn_a2dp_stop_playback() (0)
+#define audio_extn_a2dp_set_parameters(parms) (0)
+#define audio_extn_a2dp_is_force_device_switch() (0)
+#else
+void audio_extn_a2dp_init(void *adev);
+int audio_extn_a2dp_start_playback();
+void audio_extn_a2dp_stop_playback();
+void audio_extn_a2dp_set_parameters(struct str_parms *parms);
+bool audio_extn_a2dp_is_force_device_switch();
+#endif
+
#ifndef SSR_ENABLED
#define audio_extn_ssr_check_and_set_usecase(in) (0)
#define audio_extn_ssr_init(in, num_out_chan) (0)
diff --git a/hal/audio_extn/keep_alive.c b/hal/audio_extn/keep_alive.c
index 1a4f135..60e7eef 100644
--- a/hal/audio_extn/keep_alive.c
+++ b/hal/audio_extn/keep_alive.c
@@ -38,7 +38,7 @@
#define SILENCE_MIXER_PATH "silence-playback hdmi"
#define SILENCE_DEV_ID 32 /* index into machine driver */
-#define SILENCE_INTERVAL_US 2000000
+#define SILENCE_INTERVAL 2 /*In secs*/
typedef enum {
STATE_DEINIT = -1,
@@ -52,7 +52,9 @@
typedef struct {
pthread_mutex_t lock;
+ pthread_mutex_t sleep_lock;
pthread_cond_t cond;
+ pthread_cond_t wake_up_cond;
pthread_t thread;
state_t state;
struct listnode cmd_list;
@@ -88,6 +90,8 @@
ka.pcm = NULL;
pthread_mutex_init(&ka.lock, (const pthread_mutexattr_t *) NULL);
pthread_cond_init(&ka.cond, (const pthread_condattr_t *) NULL);
+ pthread_cond_init(&ka.wake_up_cond, (const pthread_condattr_t *) NULL);
+ pthread_mutex_init(&ka.sleep_lock, (const pthread_mutexattr_t *) NULL);
list_init(&ka.cmd_list);
if (pthread_create(&ka.thread, (const pthread_attr_t *) NULL,
keep_alive_loop, NULL) < 0) {
@@ -143,6 +147,27 @@
return 0;
}
+
+static int set_mixer_control(struct mixer *mixer,
+ const char * mixer_ctl_name,
+ const char *mixer_val)
+{
+ struct mixer_ctl *ctl;
+ if ((mixer == NULL) || (mixer_ctl_name == NULL) || (mixer_val == NULL)) {
+ ALOGE("%s: Invalid input", __func__);
+ return -EINVAL;
+ }
+ ALOGD("setting mixer ctl %s with value %s", mixer_ctl_name, mixer_val);
+ ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ return mixer_ctl_set_enum_by_string(ctl, mixer_val);
+}
+
/* must be called with adev lock held */
void audio_extn_keep_alive_start()
{
@@ -151,18 +176,20 @@
int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc;
struct mixer_ctl *ctl;
int acdb_dev_id, snd_device;
+ struct listnode *node;
+ struct audio_usecase *usecase;
int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
pthread_mutex_lock(&ka.lock);
if (ka.state == STATE_DEINIT) {
ALOGE(" %s : Invalid state ",__func__);
- return;
+ goto exit;
}
if (audio_extn_passthru_is_active()) {
ALOGE(" %s : Pass through is already active", __func__);
- return;
+ goto exit;
}
if (ka.state == STATE_ACTIVE) {
@@ -170,6 +197,14 @@
goto exit;
}
+ /* Dont start keep_alive if any other PCM session is routed to HDMI*/
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ if (usecase->type == PCM_PLAYBACK &&
+ usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
+ goto exit;
+ }
+
ka.done = false;
/*configure app type */
@@ -202,9 +237,15 @@
platform_get_default_app_type(adev->platform),
acdb_dev_id, sample_rate);
mixer_ctl_set_array(ctl, app_type_cfg, len);
+ /*Configure HDMI Backend with default values, this as well
+ *helps reconfigure HDMI backend after passthrough
+ */
+ set_mixer_control(adev->mixer, "HDMI RX Format", "LPCM");
+ set_mixer_control(adev->mixer, "HDMI_RX SampleRate", "KHZ_48");
+ set_mixer_control(adev->mixer, "HDMI_RX Channels", "Two");
/*send calibration*/
- struct audio_usecase *usecase = calloc(1, sizeof(struct audio_usecase));
+ usecase = calloc(1, sizeof(struct audio_usecase));
usecase->type = PCM_PLAYBACK;
usecase->out_snd_device = SND_DEVICE_OUT_HDMI;
@@ -232,13 +273,13 @@
pthread_mutex_lock(&ka.lock);
- if (ka.state == STATE_DEINIT)
- return;
-
- if (ka.state == STATE_IDLE)
+ if ((ka.state == STATE_DEINIT) || (ka.state == STATE_IDLE))
goto exit;
+ pthread_mutex_lock(&ka.sleep_lock);
ka.done = true;
+ pthread_cond_signal(&ka.wake_up_cond);
+ pthread_mutex_unlock(&ka.sleep_lock);
while (ka.state != STATE_IDLE) {
pthread_cond_wait(&ka.cond, &ka.lock);
}
@@ -290,6 +331,7 @@
struct listnode *item;
uint8_t * silence = NULL;
int32_t bytes = 0;
+ struct timespec ts;
while (true) {
pthread_mutex_lock(&ka.lock);
@@ -328,9 +370,17 @@
* Just something to keep the connection alive is sufficient.
* Hence a short burst of silence periodically.
*/
- usleep(SILENCE_INTERVAL_US);
- }
+ pthread_mutex_lock(&ka.sleep_lock);
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += SILENCE_INTERVAL;
+ ts.tv_nsec = 0;
+ if (!ka.done)
+ pthread_cond_timedwait(&ka.wake_up_cond,
+ &ka.sleep_lock, &ts);
+
+ pthread_mutex_unlock(&ka.sleep_lock);
+ }
pthread_mutex_lock(&ka.lock);
ka.state = STATE_IDLE;
pthread_cond_signal(&ka.cond);
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
index e6ac4dd..eaa8c0a 100644
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -82,8 +82,14 @@
*/
bool audio_extn_passthru_should_drop_data(struct stream_out * out)
{
-
- if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ /*Drop data only
+ *stream is routed to HDMI and
+ *stream has PCM format or
+ *if a compress offload (DSP decode) session
+ */
+ if ((out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
+ (((out->format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) ||
+ ((out->compr_config.codec != NULL) && (out->compr_config.codec->compr_passthr == LEGACY_PCM)))) {
if (android_atomic_acquire_load(&compress_passthru_active) > 0) {
ALOGI("drop data as pass thru is active");
return true;
@@ -112,9 +118,6 @@
ALOGV("inc pass thru count to notify other streams");
android_atomic_inc(&compress_passthru_active);
- ALOGV("keep_alive_stop");
- audio_extn_keep_alive_stop();
-
while (true) {
/* find max period time among active playback use cases */
list_for_each(node, &adev->usecase_list) {
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index 7e37efc..6142e86 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -98,9 +98,9 @@
status = -ENOMEM;
break;
}
- memcpy(&st_ses_info->st_ses, &config->st_ses, sizeof (config->st_ses));
- ALOGV("%s: add capture_handle %d pcm %p", __func__,
- st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.pcm);
+ memcpy(&st_ses_info->st_ses, &config->st_ses, sizeof (struct sound_trigger_session_info));
+ ALOGV("%s: add capture_handle %d st session opaque ptr %p", __func__,
+ st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
list_add_tail(&st_dev->st_ses_list, &st_ses_info->list);
break;
@@ -112,12 +112,12 @@
}
st_ses_info = get_sound_trigger_info(config->st_ses.capture_handle);
if (!st_ses_info) {
- ALOGE("%s: pcm %p not in the list!", __func__, config->st_ses.pcm);
+ ALOGE("%s: st session opaque ptr %p not in the list!", __func__, config->st_ses.p_ses);
status = -EINVAL;
break;
}
- ALOGV("%s: remove capture_handle %d pcm %p", __func__,
- st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.pcm);
+ ALOGV("%s: remove capture_handle %d st session opaque ptr %p", __func__,
+ st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
list_remove(&st_ses_info->list);
free(st_ses_info);
break;
@@ -181,7 +181,7 @@
pthread_mutex_unlock(&st_dev->lock);
if (st_ses_info) {
event.u.ses_info = st_ses_info->st_ses;
- ALOGV("%s: AUDIO_EVENT_STOP_LAB pcm %p", __func__, st_ses_info->st_ses.pcm);
+ ALOGV("%s: AUDIO_EVENT_STOP_LAB st sess %p", __func__, st_ses_info->st_ses.p_ses);
st_dev->st_callback(AUDIO_EVENT_STOP_LAB, &event);
in->is_st_session_active = false;
}
@@ -201,7 +201,6 @@
list_for_each(node, &st_dev->st_ses_list) {
st_ses_info = node_to_item(node, struct sound_trigger_info , list);
if (st_ses_info->st_ses.capture_handle == in->capture_handle) {
- in->pcm = st_ses_info->st_ses.pcm;
in->config = st_ses_info->st_ses.config;
in->channel_mask = audio_channel_in_mask_from_count(in->config.channels);
in->is_st_session = true;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 272d64b..69d5cce 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -716,6 +716,13 @@
audio_extn_spkr_prot_calib_cancel(adev);
+ if (((SND_DEVICE_OUT_BT_A2DP == snd_device) ||
+ (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device))
+ && (audio_extn_a2dp_start_playback() < 0)) {
+ ALOGE(" fail to configure A2dp control path ");
+ return -EINVAL;
+ }
+
if (platform_can_enable_spkr_prot_on_device(snd_device) &&
audio_extn_spkr_prot_is_enabled()) {
if (platform_get_spkr_prot_acdb_id(snd_device) < 0) {
@@ -791,6 +798,11 @@
if (adev->snd_dev_ref_cnt[snd_device] == 0) {
ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
+
+ if ((SND_DEVICE_OUT_BT_A2DP == snd_device) ||
+ (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device))
+ audio_extn_a2dp_stop_playback();
+
if (platform_can_enable_spkr_prot_on_device(snd_device) &&
audio_extn_spkr_prot_is_enabled()) {
audio_extn_spkr_prot_stop_processing(snd_device);
@@ -832,7 +844,7 @@
struct audio_usecase *usecase;
bool switch_device[AUDIO_USECASE_MAX];
int i, num_uc_to_switch = 0;
-
+ bool force_restart_session = false;
/*
* This function is to make sure that all the usecases that are active on
* the hardware codec backend are always routed to any one device that is
@@ -852,7 +864,15 @@
*/
bool force_routing = platform_check_and_set_codec_backend_cfg(adev, uc_info,
snd_device);
-
+ /* For a2dp device reconfigure all active sessions
+ * with new AFE encoder format based on a2dp state
+ */
+ if ((SND_DEVICE_OUT_BT_A2DP == snd_device ||
+ SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device) &&
+ audio_extn_a2dp_is_force_device_switch()) {
+ force_routing = true;
+ force_restart_session = true;
+ }
ALOGD("%s:becf: force routing %d", __func__, force_routing);
/* Disable all the usecases on the shared backend other than the
@@ -871,8 +891,10 @@
platform_check_backends_match(snd_device, usecase->out_snd_device));
if (usecase->type != PCM_CAPTURE &&
usecase != uc_info &&
- (usecase->out_snd_device != snd_device || force_routing) &&
- usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND &&
+ (usecase->out_snd_device != snd_device || force_routing) &&
+ ((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
+ (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
+ (force_restart_session)) &&
platform_check_backends_match(snd_device, usecase->out_snd_device)) {
ALOGD("%s:becf: check_usecases (%s) is active on (%s) - disabling ..",
__func__, use_case_table[usecase->id],
@@ -1163,6 +1185,14 @@
}
}
+ // Force all a2dp output devices to reconfigure for proper AFE encode format
+ if((usecase->stream.out) &&
+ (usecase->stream.out->devices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) &&
+ audio_extn_a2dp_is_force_device_switch()) {
+ ALOGD("Force a2dp device switch to update new encoder config");
+ ret = true;
+ }
+
return ret;
}
@@ -1207,6 +1237,8 @@
get_usecase_id_from_usecase_type(adev, VOICE_CALL));
if ((vc_usecase) && (((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
(usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND)) ||
+ ((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
+ (usecase->devices & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND)) ||
(usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL))) {
in_snd_device = vc_usecase->in_snd_device;
out_snd_device = vc_usecase->out_snd_device;
@@ -1214,7 +1246,8 @@
} else if (voice_extn_compress_voip_is_active(adev)) {
voip_usecase = get_usecase_from_list(adev, USECASE_COMPRESS_VOIP_CALL);
if ((voip_usecase) && ((voip_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
- (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
+ ((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
+ ((usecase->devices & ~AUDIO_DEVICE_BIT_IN) & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND)) &&
(voip_usecase->stream.out != adev->primary_output))) {
in_snd_device = voip_usecase->in_snd_device;
out_snd_device = voip_usecase->out_snd_device;
@@ -1770,193 +1803,6 @@
return 0;
}
-static bool allow_hdmi_channel_config(struct audio_device *adev,
- bool enable_passthru)
-{
- struct listnode *node;
- struct audio_usecase *usecase;
- bool ret = true;
-
- if (enable_passthru && !audio_extn_passthru_is_enabled()) {
- ret = false;
- goto exit;
- }
-
- if (audio_extn_passthru_is_active()) {
- ALOGI("%s: Compress audio passthrough is active,"
- "no HDMI config change allowed", __func__);
- ret = false;
- goto exit;
- }
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- /*
- * If voice call is already existing, do not proceed further to avoid
- * disabling/enabling both RX and TX devices, CSD calls, etc.
- * Once the voice call done, the HDMI channels can be configured to
- * max channels of remaining use cases.
- */
- if (usecase->id == USECASE_VOICE_CALL) {
- ALOGV("%s: voice call is active, no change in HDMI channels",
- __func__);
- ret = false;
- break;
- } else if (usecase->id == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
- if (!enable_passthru) {
- ALOGV("%s: multi channel playback is active, "
- "no change in HDMI channels", __func__);
- ret = false;
- break;
- }
- } else if (is_offload_usecase(usecase->id) &&
- audio_channel_count_from_out_mask(usecase->stream.out->channel_mask) > 2) {
- if (!enable_passthru) {
- ALOGD("%s:multi-channel(%x) compress offload playback is active"
- ", no change in HDMI channels", __func__,
- usecase->stream.out->channel_mask);
- ret = false;
- break;
- }
- }
- }
- }
- ALOGV("allow hdmi config %d", ret);
-exit:
- return ret;
-}
-
-static int check_and_set_hdmi_config(struct audio_device *adev,
- uint32_t channels,
- uint32_t sample_rate,
- audio_format_t format,
- bool enable_passthru)
-{
- struct listnode *node;
- struct audio_usecase *usecase;
- int32_t factor = 1;
- bool config = false;
-
- ALOGV("%s channels %d sample_rate %d format:%x enable_passthru:%d",
- __func__, channels, sample_rate, format, enable_passthru);
-
- if (channels != adev->cur_hdmi_channels) {
- ALOGV("channel does not match current hdmi channels");
- config = true;
- }
-
- if (sample_rate != adev->cur_hdmi_sample_rate) {
- ALOGV("sample rate does not match current hdmi sample rate");
- config = true;
- }
-
- if (format != adev->cur_hdmi_format) {
- ALOGV("format does not match current hdmi format");
- config = true;
- }
-
- /* TBD - add check for bit width */
- if (!config) {
- ALOGV("No need to config hdmi");
- return 0;
- }
-
- if (enable_passthru &&
- (format == AUDIO_FORMAT_E_AC3)) {
- ALOGV("factor 4 for E_AC3 passthru");
- factor = 4;
- }
-
- platform_set_hdmi_config(adev->platform, channels, factor * sample_rate,
- enable_passthru);
- adev->cur_hdmi_channels = channels;
- adev->cur_hdmi_format = format;
- adev->cur_hdmi_sample_rate = sample_rate;
-
- /*
- * Deroute all the playback streams routed to HDMI so that
- * the back end is deactivated. Note that backend will not
- * be deactivated if any one stream is connected to it.
- */
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_PLAYBACK &&
- usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- disable_audio_route(adev, usecase);
- }
- }
-
- bool was_active = audio_extn_keep_alive_is_active();
- if (was_active)
- audio_extn_keep_alive_stop();
-
- /*
- * Enable all the streams disabled above. Now the HDMI backend
- * will be activated with new channel configuration
- */
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_PLAYBACK &&
- usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- enable_audio_route(adev, usecase);
- }
- }
-
- if (was_active)
- audio_extn_keep_alive_start();
-
- return 0;
-}
-
-/* called with out lock taken */
-static int check_and_set_hdmi_backend(struct stream_out *out)
-{
- struct audio_device *adev = out->dev;
- int ret;
- bool enable_passthru = false;
-
- if (!(out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL))
- return -1;
-
- ALOGV("%s usecase %s out->format:%x out->bit_width:%d", __func__, use_case_table[out->usecase],out->format,out->bit_width);
-
- if (is_offload_usecase(out->usecase) &&
- audio_extn_passthru_is_passthrough_stream(out)) {
- enable_passthru = true;
- ALOGV("%s : enable_passthru is set to true", __func__);
- }
-
- /* Check if change in HDMI channel config is allowed */
- if (!allow_hdmi_channel_config(adev, enable_passthru)) {
- return -EPERM;
- }
-
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
- uint32_t channels;
- ALOGV("Offload usecase, enable passthru %d", enable_passthru);
-
- if (enable_passthru) {
- audio_extn_passthru_on_start(out);
- audio_extn_passthru_update_stream_configuration(adev, out);
- }
-
- /* For pass through case, the backend should be configured as stereo */
- channels = enable_passthru ? DEFAULT_HDMI_OUT_CHANNELS :
- out->compr_config.codec->ch_in;
-
- ret = check_and_set_hdmi_config(adev, channels,
- out->sample_rate, out->format,
- enable_passthru);
- } else
- ret = check_and_set_hdmi_config(adev, out->config.channels,
- out->config.rate,
- out->format,
- false);
- return ret;
-}
-
-
static int stop_output_stream(struct stream_out *out)
{
int ret = 0;
@@ -1997,17 +1843,14 @@
ALOGV("Disable passthrough , reset mixer to pcm");
/* NO_PASSTHROUGH */
out->compr_config.codec->compr_passthr = 0;
-
audio_extn_passthru_on_stop(out);
audio_extn_dolby_set_dap_bypass(adev, DAP_STATE_ON);
}
/* Must be called after removing the usecase from list */
if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
- check_and_set_hdmi_config(adev, DEFAULT_HDMI_OUT_CHANNELS,
- DEFAULT_HDMI_OUT_SAMPLE_RATE,
- DEFAULT_HDMI_OUT_FORMAT,
- false);
+ audio_extn_keep_alive_start();
+
ALOGV("%s: exit: status(%d)", __func__, ret);
return ret;
}
@@ -2049,12 +1892,6 @@
goto error_config;
}
- /* This must be called before adding this usecase to the list */
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- /* This call can fail if compress pass thru is already active */
- check_and_set_hdmi_backend(out);
- }
-
uc_info->id = out->usecase;
uc_info->type = PCM_PLAYBACK;
uc_info->stream.out = out;
@@ -2066,6 +1903,16 @@
audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
adev->perf_lock_opts,
adev->perf_lock_opts_size);
+
+ if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ audio_extn_keep_alive_stop();
+ if (audio_extn_passthru_is_enabled() &&
+ audio_extn_passthru_is_passthrough_stream(out)) {
+ audio_extn_passthru_on_start(out);
+ audio_extn_passthru_update_stream_configuration(adev, out);
+ }
+ }
+
select_devices(adev, out->usecase);
ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
@@ -2451,6 +2298,17 @@
(platform_get_edid_info(adev->platform) != 0) /* HDMI disconnected */) {
val = AUDIO_DEVICE_OUT_SPEAKER;
}
+ /*
+ * When A2DP is disconnected the
+ * music playback is paused and the policy manager sends routing=0
+ * But the audioflingercontinues to write data until standby time
+ * (3sec). As BT is turned off, the write gets blocked.
+ * Avoid this by routing audio to speaker until standby.
+ */
+ if ((out->devices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) &&
+ (val == AUDIO_DEVICE_NONE)) {
+ val = AUDIO_DEVICE_OUT_SPEAKER;
+ }
/*
* select_devices() call below switches all the usecases on the same
@@ -2748,9 +2606,10 @@
}
if (audio_extn_passthru_should_drop_data(out)) {
- ALOGD(" %s : Drop data as compress passthrough session is going on", __func__);
- usleep((uint64_t)bytes * 1000000 / audio_stream_out_frame_size(stream) /
- out_get_sample_rate(&out->stream.common));
+ ALOGV(" %s : Drop data as compress passthrough session is going on", __func__);
+ if (audio_bytes_per_sample(out->format) != 0)
+ out->written += bytes / (out->config.channels * audio_bytes_per_sample(out->format));
+ ret = -EIO;
goto exit;
}
@@ -3125,7 +2984,6 @@
if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
pthread_mutex_lock(&out->dev->lock);
ALOGV("offload resume, check and set hdmi backend again");
- check_and_set_hdmi_backend(out);
pthread_mutex_unlock(&out->dev->lock);
}
status = compress_resume(out->compr);
@@ -3721,7 +3579,7 @@
out->compr_config.codec->bit_rate =
config->offload_info.bit_rate;
out->compr_config.codec->ch_in =
- audio_channel_count_from_out_mask(config->channel_mask);
+ audio_channel_count_from_out_mask(out->channel_mask);
out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
out->bit_width = AUDIO_OUTPUT_BIT_WIDTH;
/*TODO: Do we need to change it for passthrough */
@@ -4173,6 +4031,22 @@
}
audio_extn_set_parameters(adev, parms);
+ // reconfigure should be done only after updating a2dpstate in audio extn
+ ret = str_parms_get_str(parms,"reconfigA2dp", value, sizeof(value));
+ if (ret >= 0) {
+ struct audio_usecase *usecase;
+ struct listnode *node;
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ if ((usecase->type == PCM_PLAYBACK) &&
+ (usecase->devices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP)){
+ ALOGD("reconfigure a2dp... forcing device switch");
+ //force device switch to re configure encoder
+ select_devices(adev, usecase->id);
+ break;
+ }
+ }
+ }
done:
str_parms_destroy(parms);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 9a87c0f..bf5b62b 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -192,8 +192,10 @@
typedef struct codec_backend_cfg {
uint32_t sample_rate;
uint32_t bit_width;
+ uint32_t channels;
char *bitwidth_mixer_ctl;
char *samplerate_mixer_ctl;
+ char *channels_mixer_ctl;
} codec_backend_cfg_t;
static native_audio_prop na_props = {0, 0, 0};
@@ -346,6 +348,8 @@
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
[SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
[SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
+ [SND_DEVICE_OUT_BT_A2DP] = "bt-a2dp",
+ [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = "speaker-and-bt-a2dp",
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
@@ -465,6 +469,8 @@
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
[SND_DEVICE_OUT_BT_SCO] = 22,
[SND_DEVICE_OUT_BT_SCO_WB] = 39,
+ [SND_DEVICE_OUT_BT_A2DP] = 20,
+ [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = 14,
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
@@ -586,6 +592,8 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_BT_A2DP)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
@@ -1206,6 +1214,8 @@
backend_tag_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
backend_tag_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("vbat-voice-speaker");
+ backend_tag_table[SND_DEVICE_OUT_BT_A2DP] = strdup("bt-a2dp");
+ backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
@@ -1848,6 +1858,9 @@
/* init usb */
audio_extn_usb_init(adev);
+ /*init a2dp*/
+ audio_extn_a2dp_init(adev);
+
/* Read one time ssr property */
audio_extn_ssr_update_enabled();
audio_extn_spkr_prot_init(adev);
@@ -1916,6 +1929,8 @@
strdup("HDMI_RX Bit Format");
my_data->current_backend_cfg[HDMI_RX_BACKEND].samplerate_mixer_ctl =
strdup("HDMI_RX SampleRate");
+ my_data->current_backend_cfg[HDMI_RX_BACKEND].channels_mixer_ctl =
+ strdup("HDMI_RX Channels");
ret = audio_extn_utils_get_codec_version(snd_card_name,
my_data->adev->snd_card,
@@ -2421,6 +2436,17 @@
return ret;
}
+int check_44100_support_device(audio_devices_t out_device)
+{
+ int ret = true;
+
+ if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+ out_device & AUDIO_DEVICE_OUT_LINE)
+ ret = false;
+
+ return ret;
+}
static int platform_get_backend_index(snd_device_t snd_device)
{
@@ -2876,6 +2902,9 @@
} else if (devices == (AUDIO_DEVICE_OUT_USB_DEVICE |
AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
+ } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER) &&
+ (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP;
} else {
ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
goto exit;
@@ -2926,6 +2955,8 @@
snd_device = SND_DEVICE_OUT_BT_SCO_WB;
else
snd_device = SND_DEVICE_OUT_BT_SCO;
+ } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ snd_device = SND_DEVICE_OUT_BT_A2DP;
} else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
if (my_data->is_vbat_speaker)
snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_VBAT;
@@ -3009,6 +3040,8 @@
snd_device = SND_DEVICE_OUT_BT_SCO;
} else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
snd_device = SND_DEVICE_OUT_HDMI ;
+ } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ snd_device = SND_DEVICE_OUT_BT_A2DP;
} else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
ALOGD("%s: setting USB hadset channel capability(2) for Proxy", __func__);
@@ -3788,8 +3821,8 @@
!strncmp("true", propValue, 4);
}
- if (prop_playback_enabled && (voice_is_in_call(my_data->adev) ||
- (SND_CARD_STATE_OFFLINE == get_snd_card_state(my_data->adev)))) {
+ if ((prop_playback_enabled && (voice_is_in_call(my_data->adev))) ||
+ (SND_CARD_STATE_OFFLINE == get_snd_card_state(my_data->adev))) {
char *decoder_mime_type = value;
//check if unsupported mime type or not
@@ -4017,16 +4050,21 @@
* configures afe with bit width and Sample Rate
*/
static int platform_set_codec_backend_cfg(struct audio_device* adev,
- snd_device_t snd_device, unsigned int bit_width,
- unsigned int sample_rate, audio_format_t format)
+ snd_device_t snd_device, struct audio_backend_cfg backend_cfg)
{
int ret = 0;
int backend_idx = DEFAULT_CODEC_BACKEND;
struct platform_data *my_data = (struct platform_data *)adev->platform;
+ unsigned int bit_width = backend_cfg.bit_width;
+ unsigned int sample_rate = backend_cfg.sample_rate;
+ unsigned int channels = backend_cfg.channels;
+ audio_format_t format = backend_cfg.format;
+ bool passthrough_enabled = backend_cfg.passthrough_enabled;
backend_idx = platform_get_backend_index(snd_device);
- ALOGI("%s:becf: afe: bitwidth %d, samplerate %d, backend_idx %d device (%s)",
- __func__, bit_width, sample_rate, backend_idx,
+
+ ALOGI("%s:becf: afe: bitwidth %d, samplerate %d channels %d, backend_idx %d device (%s)",
+ __func__, bit_width, sample_rate, channels,backend_idx,
platform_get_snd_device_name(snd_device));
if (bit_width !=
@@ -4118,19 +4156,146 @@
mixer_ctl_set_enum_by_string(ctl, rate_str);
my_data->current_backend_cfg[backend_idx].sample_rate = sample_rate;
}
+ if ((backend_idx == HDMI_RX_BACKEND) &&
+ (channels != my_data->current_backend_cfg[backend_idx].channels)) {
+ struct mixer_ctl *ctl;
+ char *channel_cnt_str = NULL;
+
+ switch (channels) {
+ case 8:
+ channel_cnt_str = "Eight"; break;
+ case 7:
+ channel_cnt_str = "Seven"; break;
+ case 6:
+ channel_cnt_str = "Six"; break;
+ case 5:
+ channel_cnt_str = "Five"; break;
+ case 4:
+ channel_cnt_str = "Four"; break;
+ case 3:
+ channel_cnt_str = "Three"; break;
+ default:
+ channel_cnt_str = "Two"; break;
+ }
+
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[backend_idx].channels_mixer_ctl);
+ if (!ctl) {
+ ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
+ __func__,
+ my_data->current_backend_cfg[backend_idx].channels_mixer_ctl);
+ return -EINVAL;
+ }
+ mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
+ my_data->current_backend_cfg[backend_idx].channels = channels;
+ platform_set_edid_channels_configuration(adev->platform, channels);
+ ALOGD("%s:becf: afe: %s set to %s", __func__,
+ my_data->current_backend_cfg[backend_idx].channels_mixer_ctl, channel_cnt_str);
+ }
+
+ if (backend_idx == HDMI_RX_BACKEND) {
+ const char *hdmi_format_ctrl = "HDMI RX Format";
+ struct mixer_ctl *ctl;
+ ctl = mixer_get_ctl_by_name(adev->mixer,hdmi_format_ctrl);
+
+ if (!ctl) {
+ ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
+ __func__, hdmi_format_ctrl);
+ return -EINVAL;
+ }
+
+ if (passthrough_enabled) {
+ ALOGD("%s:HDMI compress format", __func__);
+ mixer_ctl_set_enum_by_string(ctl, "Compr");
+ } else {
+ ALOGD("%s: HDMI PCM format", __func__);
+ mixer_ctl_set_enum_by_string(ctl, "LPCM");
+ }
+ }
return ret;
}
/*
+ *Validate the selected bit_width, sample_rate and channels using the edid
+ *of the connected sink device.
+ */
+static void platform_check_hdmi_backend_cfg(struct audio_device* adev,
+ struct audio_usecase* usecase,
+ struct audio_backend_cfg *hdmi_backend_cfg)
+{
+ unsigned int bit_width;
+ unsigned int sample_rate;
+ unsigned int channels, max_supported_channels = 0;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+ edid_audio_info *edid_info = (edid_audio_info *)my_data->edid_info;
+ bool passthrough_enabled = false;
+
+ bit_width = hdmi_backend_cfg->bit_width;
+ sample_rate = hdmi_backend_cfg->sample_rate;
+ channels = hdmi_backend_cfg->channels;
+
+
+ ALOGI("%s:becf: HDMI: bitwidth %d, samplerate %d, channels %d"
+ ", usecase = %d", __func__, bit_width,
+ sample_rate, channels, usecase->id);
+
+ if (audio_extn_passthru_is_enabled() && audio_extn_passthru_is_active()
+ && (usecase->stream.out->compr_config.codec->compr_passthr != 0)) {
+ passthrough_enabled = true;
+ ALOGI("passthrough is enabled for this stream");
+ }
+
+ // For voice calls use default configuration i.e. 16b/48K, only applicable to
+ // default backend
+ if (!passthrough_enabled) {
+
+ max_supported_channels = platform_edid_get_max_channels(my_data);
+
+ //Check EDID info for supported samplerate
+ if (!edid_is_supported_sr(edid_info,sample_rate)) {
+ //reset to current sample rate
+ sample_rate = my_data->current_backend_cfg[HDMI_RX_BACKEND].sample_rate;
+ }
+
+ //Check EDID info for supported bit width
+ if (!edid_is_supported_bps(edid_info,bit_width)) {
+ //reset to current sample rate
+ bit_width = my_data->current_backend_cfg[HDMI_RX_BACKEND].bit_width;
+ }
+
+ if (channels > max_supported_channels)
+ channels = max_supported_channels;
+
+ } else {
+ /*During pass through set default bit width and channels*/
+ channels = DEFAULT_HDMI_OUT_CHANNELS;
+ if ((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
+ (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))
+ sample_rate = sample_rate * 4 ;
+
+ bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+ /* We force route so that the BE format can be set to Compr */
+ }
+
+ ALOGI("%s:becf: afe: HDMI backend: passthrough %d updated bit width: %d and sample rate: %d"
+ "channels %d", __func__, passthrough_enabled , bit_width,
+ sample_rate, channels);
+
+ hdmi_backend_cfg->bit_width = bit_width;
+ hdmi_backend_cfg->sample_rate = sample_rate;
+ hdmi_backend_cfg->channels = channels;
+ hdmi_backend_cfg->passthrough_enabled = passthrough_enabled;
+}
+
+/*
* goes through all the current usecases and picks the highest
* bitwidth & samplerate
*/
static bool platform_check_codec_backend_cfg(struct audio_device* adev,
struct audio_usecase* usecase,
snd_device_t snd_device,
- unsigned int* new_bit_width,
- unsigned int* new_sample_rate)
+ struct audio_backend_cfg *backend_cfg)
{
bool backend_change = false;
struct listnode *node;
@@ -4138,18 +4303,21 @@
char value[PROPERTY_VALUE_MAX] = {0};
unsigned int bit_width;
unsigned int sample_rate;
+ unsigned int channels;
+ bool passthrough_enabled = false;
int backend_idx = DEFAULT_CODEC_BACKEND;
struct platform_data *my_data = (struct platform_data *)adev->platform;
int na_mode = platform_get_native_support();
- edid_audio_info *edid_info = (edid_audio_info *)my_data->edid_info;
+ bool channels_updated = false;
backend_idx = platform_get_backend_index(snd_device);
- bit_width = *new_bit_width;
- sample_rate = *new_sample_rate;
+ bit_width = backend_cfg->bit_width;
+ sample_rate = backend_cfg->sample_rate;
+ channels = backend_cfg->channels;
- ALOGI("%s:becf: afe: Codec selected backend: %d current bit width: %d and sample rate: %d",
- __func__, backend_idx, bit_width, sample_rate);
+ ALOGI("%s:becf: afe: Codec selected backend: %d current bit width: %d sample rate: %d channels: %d",
+ __func__, backend_idx, bit_width, sample_rate, channels);
// For voice calls use default configuration i.e. 16b/48K, only applicable to
// default backend
@@ -4175,12 +4343,13 @@
struct audio_usecase *uc;
uc = node_to_item(node, struct audio_usecase, list);
struct stream_out *out = (struct stream_out*) uc->stream.out;
+ unsigned int out_channels = audio_channel_count_from_out_mask(out->channel_mask);
if (uc->type == PCM_PLAYBACK && out && usecase != uc) {
ALOGD("%s:napb: (%d) - (%s)id (%d) sr %d bw "
- "(%d) device %s", __func__, i++, use_case_table[uc->id],
+ "(%d) ch (%d) device %s", __func__, i++, use_case_table[uc->id],
uc->id, out->sample_rate,
- out->bit_width,
+ out->bit_width, out_channels,
platform_get_snd_device_name(uc->out_snd_device));
if (platform_check_backends_match(snd_device, uc->out_snd_device)) {
@@ -4190,6 +4359,8 @@
sample_rate = out->sample_rate;
if (out->sample_rate < OUTPUT_SAMPLING_RATE_44100)
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ if (channels < out_channels)
+ channels = out_channels;
}
}
}
@@ -4218,14 +4389,12 @@
}
/*
- * hifi playback not supported on spkr devices, limit the Sample Rate
+ * hifi playback not supported on non-44.1-support devices, limit the Sample Rate
* to 48 khz.
*/
- if (SND_DEVICE_OUT_SPEAKER == snd_device ||
- SND_DEVICE_OUT_SPEAKER_WSA == snd_device ||
- SND_DEVICE_OUT_SPEAKER_VBAT == snd_device) {
+ if (check_44100_support_device(usecase->devices)) {
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- ALOGD("%s:becf: afe: playback on speaker device Configure afe to "
+ ALOGD("%s:becf: afe: playback on non-44.1-support device Configure afe to "
"default Sample Rate(48k)", __func__);
}
@@ -4249,16 +4418,21 @@
}
if (backend_idx == HDMI_RX_BACKEND) {
- //Check EDID info for supported samplerate
- if (!edid_is_supported_sr(edid_info,sample_rate)) {
- //reset to current sample rate
- sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
- }
- //Check EDID info for supported bit widhth
- if (!edid_is_supported_bps(edid_info,bit_width)) {
- //reset to current sample rate
- bit_width = my_data->current_backend_cfg[backend_idx].bit_width;
- }
+ struct audio_backend_cfg hdmi_backend_cfg;
+ hdmi_backend_cfg.bit_width = bit_width;
+ hdmi_backend_cfg.sample_rate = sample_rate;
+ hdmi_backend_cfg.channels = channels;
+ hdmi_backend_cfg.passthrough_enabled = false;
+
+ platform_check_hdmi_backend_cfg(adev, usecase, &hdmi_backend_cfg);
+
+ bit_width = hdmi_backend_cfg.bit_width;
+ sample_rate = hdmi_backend_cfg.sample_rate;
+ channels = hdmi_backend_cfg.channels;
+ passthrough_enabled = hdmi_backend_cfg.passthrough_enabled;
+
+ if (channels != my_data->current_backend_cfg[backend_idx].channels)
+ channels_updated = true;
}
//check if mulitchannel clip needs to be down sampled to 48k
@@ -4289,13 +4463,16 @@
// Force routing if the expected bitwdith or samplerate
// is not same as current backend comfiguration
if ((bit_width != my_data->current_backend_cfg[backend_idx].bit_width) ||
- (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate)) {
- *new_bit_width = bit_width;
- *new_sample_rate = sample_rate;
+ (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate) ||
+ passthrough_enabled || channels_updated) {
+ backend_cfg->bit_width = bit_width;
+ backend_cfg->sample_rate = sample_rate;
+ backend_cfg->channels = channels;
+ backend_cfg->passthrough_enabled = passthrough_enabled;
backend_change = true;
- ALOGI("%s:becf: afe: Codec backend needs to be updated. new bit width: %d new sample rate: %d",
- __func__,
- *new_bit_width, *new_sample_rate);
+ ALOGI("%s:becf: afe: Codec backend needs to be updated. new bit width: %d"
+ " new sample rate: %d new channels %d",__func__,
+ backend_cfg->bit_width, backend_cfg->sample_rate, backend_cfg->channels);
}
return backend_change;
@@ -4304,23 +4481,24 @@
bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev,
struct audio_usecase *usecase, snd_device_t snd_device)
{
- unsigned int new_bit_width;
- unsigned int new_sample_rate;
int backend_idx = DEFAULT_CODEC_BACKEND;
int new_snd_devices[SND_DEVICE_OUT_END];
int i, num_devices = 1;
+ struct audio_backend_cfg backend_cfg;
bool ret = false;
- audio_format_t format;
backend_idx = platform_get_backend_index(snd_device);
- new_bit_width = usecase->stream.out->bit_width;
- new_sample_rate = usecase->stream.out->sample_rate;
- format = usecase->stream.out->format;
+ backend_cfg.bit_width = usecase->stream.out->bit_width;
+ backend_cfg.sample_rate = usecase->stream.out->sample_rate;
+ backend_cfg.format = usecase->stream.out->format;
+ backend_cfg.channels = audio_channel_count_from_out_mask(usecase->stream.out->channel_mask);
+ /*this is populated by check_codec_backend_cfg hence set default value to false*/
+ backend_cfg.passthrough_enabled = false;
- ALOGI("%s:becf: afe: bitwidth %d, samplerate %d"
- ", backend_idx %d usecase = %d device (%s)", __func__, new_bit_width,
- new_sample_rate, backend_idx, usecase->id,
+ ALOGI("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
+ ", backend_idx %d usecase = %d device (%s)", __func__, backend_cfg.bit_width,
+ backend_cfg.sample_rate, backend_cfg.channels, backend_idx, usecase->id,
platform_get_snd_device_name(snd_device));
if (!platform_can_split_snd_device(adev->platform, snd_device,
@@ -4331,9 +4509,9 @@
ALOGI("%s: becf: new_snd_devices[%d] is %s", __func__, i,
platform_get_snd_device_name(new_snd_devices[i]));
if (platform_check_codec_backend_cfg(adev, usecase, new_snd_devices[i],
- &new_bit_width, &new_sample_rate)) {
+ &backend_cfg)) {
platform_set_codec_backend_cfg(adev, new_snd_devices[i],
- new_bit_width, new_sample_rate, format);
+ backend_cfg);
ret = true;
}
}
@@ -5003,6 +5181,7 @@
//reset HDMI_RX_BACKEND to default values
my_data->current_backend_cfg[HDMI_RX_BACKEND].sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
my_data->current_backend_cfg[HDMI_RX_BACKEND].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+ my_data->current_backend_cfg[HDMI_RX_BACKEND].channels = DEFAULT_HDMI_OUT_CHANNELS;
}
int platform_set_mixer_control(struct stream_out *out, const char * mixer_ctl_name,
@@ -5021,91 +5200,6 @@
return mixer_ctl_set_enum_by_string(ctl, mixer_val);
}
-static int set_mixer_control(struct mixer *mixer,
- const char * mixer_ctl_name,
- const char *mixer_val)
-{
- struct mixer_ctl *ctl;
- ALOGD("setting mixer ctl %s with value %s", mixer_ctl_name, mixer_val);
- ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- return -EINVAL;
- }
-
- return mixer_ctl_set_enum_by_string(ctl, mixer_val);
-}
-
-int platform_set_hdmi_config(void *platform, uint32_t channel_count,
- uint32_t sample_rate, bool enable_passthrough)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- struct audio_device *adev = my_data->adev;
- const char *hdmi_format_ctrl = "HDMI RX Format";
- const char *hdmi_rate_ctrl = "HDMI_RX SampleRate";
- const char *hdmi_chans_ctrl = "HDMI_RX Channels";
- const char *channel_cnt_str = NULL;
-
- ALOGI("%s ch[%d] sr[%d], pthru[%d]", __func__,
- channel_count, sample_rate, enable_passthrough);
-
- switch (channel_count) {
- case 8:
- channel_cnt_str = "Eight"; break;
- case 7:
- channel_cnt_str = "Seven"; break;
- case 6:
- channel_cnt_str = "Six"; break;
- case 5:
- channel_cnt_str = "Five"; break;
- case 4:
- channel_cnt_str = "Four"; break;
- case 3:
- channel_cnt_str = "Three"; break;
- default:
- channel_cnt_str = "Two"; break;
- }
- ALOGV("%s: HDMI channel count: %s", __func__, channel_cnt_str);
- set_mixer_control(adev->mixer, hdmi_chans_ctrl, channel_cnt_str);
-
- if (enable_passthrough) {
- ALOGD("%s:HDMI compress format", __func__);
- set_mixer_control(adev->mixer, hdmi_format_ctrl, "Compr");
- } else {
- ALOGD("%s: HDMI PCM format", __func__);
- set_mixer_control(adev->mixer, hdmi_format_ctrl, "LPCM");
- }
-
- switch (sample_rate) {
- case 32000:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_32");
- break;
- case 44100:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_44P1");
- break;
- case 96000:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_96");
- break;
- case 128000:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_128");
- break;
- case 176400:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_176_4");
- break;
- case 192000:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_192");
- break;
- default:
- case 48000:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_48");
- break;
- }
-
- return 0;
-}
-
-
int platform_set_device_params(struct stream_out *out, int param, int value)
{
struct audio_device *adev = out->dev;
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 756c749..dcd351a 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -98,6 +98,8 @@
SND_DEVICE_OUT_SPEAKER_AND_HDMI,
SND_DEVICE_OUT_BT_SCO,
SND_DEVICE_OUT_BT_SCO_WB,
+ SND_DEVICE_OUT_BT_A2DP,
+ SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
@@ -370,4 +372,13 @@
char device_name[100];
char interface_name[100];
};
+
+struct audio_backend_cfg {
+ unsigned int sample_rate;
+ unsigned int channels;
+ unsigned int bit_width;
+ bool passthrough_enabled;
+ audio_format_t format;
+};
+
#endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/msm8960/platform.h b/hal/msm8960/platform.h
index aab5436..e42af8c 100644
--- a/hal/msm8960/platform.h
+++ b/hal/msm8960/platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016 The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -64,6 +64,8 @@
SND_DEVICE_OUT_HDMI,
SND_DEVICE_OUT_SPEAKER_AND_HDMI,
SND_DEVICE_OUT_BT_SCO,
+ SND_DEVICE_OUT_BT_A2DP,
+ SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
SND_DEVICE_OUT_BT_SCO_WB,
SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 44bcbc8..f0f507d 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -188,8 +188,10 @@
typedef struct codec_backend_cfg {
uint32_t sample_rate;
uint32_t bit_width;
+ uint32_t channels;
char *bitwidth_mixer_ctl;
char *samplerate_mixer_ctl;
+ char *channels_mixer_ctl;
} codec_backend_cfg_t;
static native_audio_prop na_props = {0, 0, 0};
@@ -347,6 +349,8 @@
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
[SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
[SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
+ [SND_DEVICE_OUT_BT_A2DP] = "bt-a2dp",
+ [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = "speaker-and-bt-a2dp",
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
@@ -461,6 +465,8 @@
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
[SND_DEVICE_OUT_BT_SCO] = 22,
[SND_DEVICE_OUT_BT_SCO_WB] = 39,
+ [SND_DEVICE_OUT_BT_A2DP] = 20,
+ [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = 14,
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
@@ -577,6 +583,8 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_BT_A2DP)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
@@ -1055,7 +1063,8 @@
sizeof("apq8084-taiko-i2s-cdp-snd-card"))) {
plat_data->is_i2s_ext_modem = true;
}
- ALOGV("%s, is_i2s_ext_modem:%d",__func__, plat_data->is_i2s_ext_modem);
+ ALOGV("%s, is_i2s_ext_modem:%d soundcard name is %s",__func__,
+ plat_data->is_i2s_ext_modem, snd_card_name);
return plat_data->is_i2s_ext_modem;
}
@@ -1095,6 +1104,8 @@
backend_tag_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
backend_tag_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("voice-speaker-vbat");
+ backend_tag_table[SND_DEVICE_OUT_BT_A2DP] = strdup("bt-a2dp");
+ backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
hw_interface_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("SLIMBUS_5_RX");
hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI_RX");
@@ -1676,6 +1687,9 @@
/* init usb */
audio_extn_usb_init(adev);
+ /*init a2dp*/
+ audio_extn_a2dp_init(adev);
+
/* init dap hal */
audio_extn_dap_hal_init(adev->snd_card);
@@ -1739,6 +1753,8 @@
strdup("HDMI_RX Bit Format");
my_data->current_backend_cfg[HDMI_RX_BACKEND].samplerate_mixer_ctl =
strdup("HDMI_RX SampleRate");
+ my_data->current_backend_cfg[HDMI_RX_BACKEND].channels_mixer_ctl =
+ strdup("HDMI_RX Channels");
my_data->current_backend_cfg[USB_AUDIO_RX_BACKEND].bitwidth_mixer_ctl =
strdup("USB_AUDIO_RX Format");
@@ -2209,6 +2225,19 @@
return ret;
}
+
+int check_44100_support_device(audio_devices_t out_device)
+{
+ int ret = true;
+
+ if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+ out_device & AUDIO_DEVICE_OUT_LINE)
+ ret = false;
+
+ return ret;
+}
+
static int platform_get_backend_index(snd_device_t snd_device)
{
int32_t port = DEFAULT_CODEC_BACKEND;
@@ -2646,6 +2675,9 @@
} else if (devices == (AUDIO_DEVICE_OUT_USB_DEVICE |
AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
+ } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER) &&
+ (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP;
} else {
ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
goto exit;
@@ -2701,6 +2733,8 @@
snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_VBAT;
else
snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
+ } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ snd_device = SND_DEVICE_OUT_BT_A2DP;
} else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
snd_device = SND_DEVICE_OUT_USB_HEADSET;
@@ -2750,6 +2784,8 @@
snd_device = SND_DEVICE_OUT_BT_SCO_WB;
else
snd_device = SND_DEVICE_OUT_BT_SCO;
+ } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+ snd_device = SND_DEVICE_OUT_BT_A2DP;
} else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
snd_device = SND_DEVICE_OUT_HDMI ;
} else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
@@ -3854,8 +3890,8 @@
!strncmp("true", propValue, 4);
}
- if (prop_playback_enabled && (voice_is_in_call(my_data->adev) ||
- (SND_CARD_STATE_OFFLINE == get_snd_card_state(my_data->adev)))) {
+ if ((prop_playback_enabled && (voice_is_in_call(my_data->adev))) ||
+ (SND_CARD_STATE_OFFLINE == get_snd_card_state(my_data->adev))) {
char *decoder_mime_type = value;
//check if unsupported mime type or not
@@ -3990,17 +4026,20 @@
* configures afe with bit width and Sample Rate
*/
static int platform_set_codec_backend_cfg(struct audio_device* adev,
- snd_device_t snd_device, unsigned int bit_width,
- unsigned int sample_rate, audio_format_t format)
+ snd_device_t snd_device, struct audio_backend_cfg backend_cfg)
{
int ret = 0;
int backend_idx = DEFAULT_CODEC_BACKEND;
struct platform_data *my_data = (struct platform_data *)adev->platform;
-
backend_idx = platform_get_backend_index(snd_device);
+ unsigned int bit_width = backend_cfg.bit_width;
+ unsigned int sample_rate = backend_cfg.sample_rate;
+ unsigned int channels = backend_cfg.channels;
+ audio_format_t format = backend_cfg.format;
+ bool passthrough_enabled = backend_cfg.passthrough_enabled;
- ALOGI("%s:becf: afe: bitwidth %d, samplerate %d"
- ", backend_idx %d device (%s)", __func__, bit_width, sample_rate, backend_idx,
+ ALOGI("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
+ ", backend_idx %d device (%s)", __func__, bit_width, sample_rate, channels, backend_idx,
platform_get_snd_device_name(snd_device));
if (bit_width !=
@@ -4084,37 +4123,167 @@
mixer_ctl_set_enum_by_string(ctl, rate_str);
my_data->current_backend_cfg[backend_idx].sample_rate = sample_rate;
}
+ if ((backend_idx == HDMI_RX_BACKEND) &&
+ (channels != my_data->current_backend_cfg[backend_idx].channels)) {
+ struct mixer_ctl *ctl;
+ char *channel_cnt_str = NULL;
+
+ switch (channels) {
+ case 8:
+ channel_cnt_str = "Eight"; break;
+ case 7:
+ channel_cnt_str = "Seven"; break;
+ case 6:
+ channel_cnt_str = "Six"; break;
+ case 5:
+ channel_cnt_str = "Five"; break;
+ case 4:
+ channel_cnt_str = "Four"; break;
+ case 3:
+ channel_cnt_str = "Three"; break;
+ default:
+ channel_cnt_str = "Two"; break;
+ }
+
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[backend_idx].channels_mixer_ctl);
+ if (!ctl) {
+ ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
+ __func__,
+ my_data->current_backend_cfg[backend_idx].channels_mixer_ctl);
+ return -EINVAL;
+ }
+ mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
+ my_data->current_backend_cfg[backend_idx].channels = channels;
+ platform_set_edid_channels_configuration(adev->platform, channels);
+ ALOGD("%s:becf: afe: %s set to %s", __func__,
+ my_data->current_backend_cfg[backend_idx].channels_mixer_ctl, channel_cnt_str);
+ }
+
+ if (backend_idx == HDMI_RX_BACKEND) {
+ const char *hdmi_format_ctrl = "HDMI RX Format";
+ struct mixer_ctl *ctl;
+ ctl = mixer_get_ctl_by_name(adev->mixer,hdmi_format_ctrl);
+
+ if (!ctl) {
+ ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
+ __func__, hdmi_format_ctrl);
+ return -EINVAL;
+ }
+
+ if (passthrough_enabled) {
+ ALOGD("%s:HDMI compress format", __func__);
+ mixer_ctl_set_enum_by_string(ctl, "Compr");
+ } else {
+ ALOGD("%s: HDMI PCM format", __func__);
+ mixer_ctl_set_enum_by_string(ctl, "LPCM");
+ }
+ }
return ret;
}
/*
+ *Validate the selected bit_width, sample_rate and channels using the edid
+ *of the connected sink device.
+ */
+static void platform_check_hdmi_backend_cfg(struct audio_device* adev,
+ struct audio_usecase* usecase,
+ struct audio_backend_cfg *hdmi_backend_cfg)
+{
+ unsigned int bit_width;
+ unsigned int sample_rate;
+ unsigned int channels, max_supported_channels = 0;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+ edid_audio_info *edid_info = (edid_audio_info *)my_data->edid_info;
+ bool passthrough_enabled = false;
+
+ bit_width = hdmi_backend_cfg->bit_width;
+ sample_rate = hdmi_backend_cfg->sample_rate;
+ channels = hdmi_backend_cfg->channels;
+
+
+ ALOGI("%s:becf: HDMI: bitwidth %d, samplerate %d, channels %d"
+ ", usecase = %d", __func__, bit_width,
+ sample_rate, channels, usecase->id);
+
+ if (audio_extn_passthru_is_enabled() && audio_extn_passthru_is_active()
+ && (usecase->stream.out->compr_config.codec->compr_passthr != 0)) {
+ passthrough_enabled = true;
+ ALOGI("passthrough is enabled for this stream");
+ }
+
+ // For voice calls use default configuration i.e. 16b/48K, only applicable to
+ // default backend
+ if (!passthrough_enabled) {
+
+ max_supported_channels = platform_edid_get_max_channels(my_data);
+
+ //Check EDID info for supported samplerate
+ if (!edid_is_supported_sr(edid_info,sample_rate)) {
+ //reset to current sample rate
+ sample_rate = my_data->current_backend_cfg[HDMI_RX_BACKEND].sample_rate;
+ }
+
+ //Check EDID info for supported bit width
+ if (!edid_is_supported_bps(edid_info,bit_width)) {
+ //reset to current sample rate
+ bit_width = my_data->current_backend_cfg[HDMI_RX_BACKEND].bit_width;
+ }
+
+ if (channels > max_supported_channels)
+ channels = max_supported_channels;
+
+ } else {
+ /*During pass through set default bit width and channels*/
+ channels = DEFAULT_HDMI_OUT_CHANNELS;
+ if ((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
+ (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))
+ sample_rate = sample_rate * 4 ;
+
+ bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+ /* We force route so that the BE format can be set to Compr */
+ }
+
+ ALOGI("%s:becf: afe: HDMI backend: passthrough %d updated bit width: %d and sample rate: %d"
+ "channels %d", __func__, passthrough_enabled , bit_width,
+ sample_rate, channels);
+
+ hdmi_backend_cfg->bit_width = bit_width;
+ hdmi_backend_cfg->sample_rate = sample_rate;
+ hdmi_backend_cfg->channels = channels;
+ hdmi_backend_cfg->passthrough_enabled = passthrough_enabled;
+}
+
+/*
* goes through all the current usecases and picks the highest
* bitwidth & samplerate
*/
static bool platform_check_codec_backend_cfg(struct audio_device* adev,
struct audio_usecase* usecase,
snd_device_t snd_device,
- unsigned int* new_bit_width,
- unsigned int* new_sample_rate)
+ struct audio_backend_cfg *backend_cfg)
{
bool backend_change = false;
struct listnode *node;
unsigned int bit_width;
unsigned int sample_rate;
+ unsigned int channels;
+ bool passthrough_enabled = false;
int backend_idx = DEFAULT_CODEC_BACKEND;
struct platform_data *my_data = (struct platform_data *)adev->platform;
int na_mode = platform_get_native_support();
- edid_audio_info *edid_info = (edid_audio_info *)my_data->edid_info;
+ bool channels_updated = false;
backend_idx = platform_get_backend_index(snd_device);
- bit_width = *new_bit_width;
- sample_rate = *new_sample_rate;
+ bit_width = backend_cfg->bit_width;
+ sample_rate = backend_cfg->sample_rate;
+ channels = backend_cfg->channels;
- ALOGI("%s:becf: afe: bitwidth %d, samplerate %d"
+ ALOGI("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
", backend_idx %d usecase = %d device (%s)", __func__, bit_width,
- sample_rate, backend_idx, usecase->id,
+ sample_rate, channels, backend_idx, usecase->id,
platform_get_snd_device_name(snd_device));
// For voice calls use default configuration i.e. 16b/48K, only applicable to
@@ -4141,12 +4310,13 @@
struct audio_usecase *uc;
uc = node_to_item(node, struct audio_usecase, list);
struct stream_out *out = (struct stream_out*) uc->stream.out;
+ unsigned int out_channels = audio_channel_count_from_out_mask(out->channel_mask);
if (uc->type == PCM_PLAYBACK && out && usecase != uc) {
ALOGD("%s:napb: (%d) - (%s)id (%d) sr %d bw "
- "(%d) device %s", __func__, i++, use_case_table[uc->id],
+ "(%d) ch (%d) device %s", __func__, i++, use_case_table[uc->id],
uc->id, out->sample_rate,
- out->bit_width,
+ out->bit_width, out_channels,
platform_get_snd_device_name(uc->out_snd_device));
if (platform_check_backends_match(snd_device, uc->out_snd_device)) {
@@ -4156,6 +4326,8 @@
sample_rate = out->sample_rate;
if (out->sample_rate < OUTPUT_SAMPLING_RATE_44100)
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ if (channels < out_channels)
+ channels = out_channels;
}
}
}
@@ -4184,14 +4356,12 @@
}
/*
- * hifi playback not supported on spkr devices, limit the Sample Rate
+ * hifi playback not supported on non-44.1-support devices, limit the Sample Rate
* to 48 khz.
*/
- if (SND_DEVICE_OUT_SPEAKER == snd_device ||
- SND_DEVICE_OUT_SPEAKER_WSA == snd_device ||
- SND_DEVICE_OUT_SPEAKER_VBAT == snd_device) {
+ if (check_44100_support_device(usecase->devices)) {
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- ALOGD("%s:becf: afe: playback on speaker device Configure afe to "
+ ALOGD("%s:becf: afe: playback on non-44.1-support device Configure afe to "
"default Sample Rate(48k)", __func__);
}
@@ -4213,29 +4383,39 @@
}
if (backend_idx == HDMI_RX_BACKEND) {
- //Check EDID info for supported samplerate
- if (!edid_is_supported_sr(edid_info,sample_rate)) {
- //reset to current sample rate
- sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
- }
- //Check EDID info for supported bit widhth
- if (!edid_is_supported_bps(edid_info,bit_width)) {
- //reset to current sample rate
- bit_width = my_data->current_backend_cfg[backend_idx].bit_width;
- }
+ struct audio_backend_cfg hdmi_backend_cfg;
+ hdmi_backend_cfg.bit_width = bit_width;
+ hdmi_backend_cfg.sample_rate = sample_rate;
+ hdmi_backend_cfg.channels = channels;
+ hdmi_backend_cfg.passthrough_enabled = false;
+
+ platform_check_hdmi_backend_cfg(adev, usecase, &hdmi_backend_cfg);
+
+ bit_width = hdmi_backend_cfg.bit_width;
+ sample_rate = hdmi_backend_cfg.sample_rate;
+ channels = hdmi_backend_cfg.channels;
+ passthrough_enabled = hdmi_backend_cfg.passthrough_enabled;
+
+ if (channels != my_data->current_backend_cfg[backend_idx].channels)
+ channels_updated = true;
}
+
ALOGI("%s:becf: afe: Codec selected backend: %d updated bit width: %d and sample rate: %d",
__func__, backend_idx , bit_width, sample_rate);
// Force routing if the expected bitwdith or samplerate
// is not same as current backend comfiguration
if ((bit_width != my_data->current_backend_cfg[backend_idx].bit_width) ||
- (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate)) {
- *new_bit_width = bit_width;
- *new_sample_rate = sample_rate;
+ (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate) ||
+ passthrough_enabled || channels_updated) {
+ backend_cfg->bit_width = bit_width;
+ backend_cfg->sample_rate = sample_rate;
+ backend_cfg->channels = channels;
+ backend_cfg->passthrough_enabled = passthrough_enabled;
backend_change = true;
- ALOGI("%s:becf: afe: Codec backend needs to be updated. new bit width: %d new sample rate: %d",
- __func__, *new_bit_width, *new_sample_rate);
+ ALOGI("%s:becf: afe: Codec backend needs to be updated. new bit width: %d"
+ "new sample rate: %d new channels: %d",
+ __func__, backend_cfg->bit_width, backend_cfg->sample_rate, backend_cfg->channels);
}
return backend_change;
@@ -4244,40 +4424,39 @@
bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev,
struct audio_usecase *usecase, snd_device_t snd_device)
{
- unsigned int new_bit_width;
- unsigned int new_sample_rate;
int backend_idx = DEFAULT_CODEC_BACKEND;
int new_snd_devices[SND_DEVICE_OUT_END];
int i, num_devices = 1;
bool ret = false;
struct platform_data *my_data = (struct platform_data *)adev->platform;
- audio_format_t format;
+ struct audio_backend_cfg backend_cfg;
backend_idx = platform_get_backend_index(snd_device);
- new_bit_width = usecase->stream.out->bit_width;
- new_sample_rate = usecase->stream.out->sample_rate;
- format = usecase->stream.out->format;
+ backend_cfg.bit_width = usecase->stream.out->bit_width;
+ backend_cfg.sample_rate = usecase->stream.out->sample_rate;
+ backend_cfg.format = usecase->stream.out->format;
+ backend_cfg.channels = audio_channel_count_from_out_mask(usecase->stream.out->channel_mask);
+ /*this is populated by check_codec_backend_cfg hence set default value to false*/
+ backend_cfg.passthrough_enabled = false;
- ALOGI("%s:becf: afe: bitwidth %d, samplerate %d"
- ", backend_idx %d usecase = %d device (%s)", __func__, new_bit_width,
- new_sample_rate, backend_idx, usecase->id,
+ ALOGI("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
+ ", backend_idx %d usecase = %d device (%s)", __func__, backend_cfg.bit_width,
+ backend_cfg.sample_rate, backend_cfg.channels, backend_idx, usecase->id,
platform_get_snd_device_name(snd_device));
-
if (!platform_can_split_snd_device(my_data, snd_device, &num_devices, new_snd_devices))
new_snd_devices[0] = snd_device;
for (i = 0; i < num_devices; i++) {
ALOGI("%s: new_snd_devices[%d] is %d", __func__, i, new_snd_devices[i]);
- if (platform_check_codec_backend_cfg(adev, usecase, new_snd_devices[i],
- &new_bit_width, &new_sample_rate)) {
- platform_set_codec_backend_cfg(adev, new_snd_devices[i],
- new_bit_width, new_sample_rate, format);
- ret = true;
+ if ((platform_check_codec_backend_cfg(adev, usecase, new_snd_devices[i],
+ &backend_cfg))) {
+ platform_set_codec_backend_cfg(adev, new_snd_devices[i],
+ backend_cfg);
+ ret = true;
}
}
-
return ret;
}
@@ -4942,6 +5121,7 @@
//reset HDMI_RX_BACKEND to default values
my_data->current_backend_cfg[HDMI_RX_BACKEND].sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ my_data->current_backend_cfg[HDMI_RX_BACKEND].channels = DEFAULT_HDMI_OUT_CHANNELS;
my_data->current_backend_cfg[HDMI_RX_BACKEND].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
}
@@ -4961,90 +5141,6 @@
return mixer_ctl_set_enum_by_string(ctl, mixer_val);
}
-static int set_mixer_control(struct mixer *mixer,
- const char * mixer_ctl_name,
- const char *mixer_val)
-{
- struct mixer_ctl *ctl;
- ALOGD("setting mixer ctl %s with value %s", mixer_ctl_name, mixer_val);
- ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- return -EINVAL;
- }
-
- return mixer_ctl_set_enum_by_string(ctl, mixer_val);
-}
-
-int platform_set_hdmi_config(void *platform, uint32_t channel_count,
- uint32_t sample_rate, bool enable_passthrough)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- struct audio_device *adev = my_data->adev;
- const char *hdmi_format_ctrl = "HDMI RX Format";
- const char *hdmi_rate_ctrl = "HDMI_RX SampleRate";
- const char *hdmi_chans_ctrl = "HDMI_RX Channels";
- const char *channel_cnt_str = NULL;
-
- ALOGI("%s ch[%d] sr[%d], pthru[%d]", __func__,
- channel_count, sample_rate, enable_passthrough);
-
- switch (channel_count) {
- case 8:
- channel_cnt_str = "Eight"; break;
- case 7:
- channel_cnt_str = "Seven"; break;
- case 6:
- channel_cnt_str = "Six"; break;
- case 5:
- channel_cnt_str = "Five"; break;
- case 4:
- channel_cnt_str = "Four"; break;
- case 3:
- channel_cnt_str = "Three"; break;
- default:
- channel_cnt_str = "Two"; break;
- }
- ALOGV("%s: HDMI channel count: %s", __func__, channel_cnt_str);
- set_mixer_control(adev->mixer, hdmi_chans_ctrl, channel_cnt_str);
-
- if (enable_passthrough) {
- ALOGD("%s:HDMI compress format", __func__);
- set_mixer_control(adev->mixer, hdmi_format_ctrl, "Compr");
- } else {
- ALOGD("%s: HDMI PCM format", __func__);
- set_mixer_control(adev->mixer, hdmi_format_ctrl, "LPCM");
- }
-
- switch (sample_rate) {
- case 32000:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_32");
- break;
- case 44100:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_44P1");
- break;
- case 96000:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_96");
- break;
- case 128000:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_128");
- break;
- case 176400:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_176_4");
- break;
- case 192000:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_192");
- break;
- default:
- case 48000:
- set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_48");
- break;
- }
-
- return 0;
-}
-
int platform_set_device_params(struct stream_out *out, int param, int value)
{
struct audio_device *adev = out->dev;
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 24274c6..48bfb2b 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -94,6 +94,8 @@
SND_DEVICE_OUT_SPEAKER_AND_HDMI,
SND_DEVICE_OUT_BT_SCO,
SND_DEVICE_OUT_BT_SCO_WB,
+ SND_DEVICE_OUT_BT_A2DP,
+ SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
@@ -461,4 +463,13 @@
char device_name[100];
char interface_name[100];
};
+
+struct audio_backend_cfg {
+ unsigned int sample_rate;
+ unsigned int channels;
+ unsigned int bit_width;
+ bool passthrough_enabled;
+ audio_format_t format;
+};
+
#endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index 7293485..3222e0b 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -244,6 +244,7 @@
{
int ret = 0;
struct audio_usecase *uc_info;
+ struct listnode *node;
ALOGD("%s: enter, out_stream_count=%d, in_stream_count=%d",
__func__, voip_data.out_stream_count, voip_data.in_stream_count);
@@ -277,6 +278,12 @@
list_remove(&uc_info->list);
free(uc_info);
+
+ // restore device for other active usecases
+ list_for_each(node, &adev->usecase_list) {
+ uc_info = node_to_item(node, struct audio_usecase, list);
+ select_devices(adev, uc_info->id);
+ }
} else
ALOGV("%s: NO-OP because out_stream_count=%d, in_stream_count=%d",
__func__, voip_data.out_stream_count, voip_data.in_stream_count);