blob: d22812391f14415ddd4ebfffec23d39f7c56b971 [file] [log] [blame]
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301/*
Preetam Singh Ranawat109bb3c2018-01-30 12:12:02 +05302* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
Naresh Tanniru9d027a62015-03-13 01:32:10 +05303*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are
6* met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above
10* copyright notice, this list of conditions and the following
11* disclaimer in the documentation and/or other materials provided
12* with the distribution.
13* * Neither the name of The Linux Foundation nor the names of its
14* contributors may be used to endorse or promote products derived
15* from this software without specific prior written permission.
16*
17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29#define LOG_TAG "split_a2dp"
30/*#define LOG_NDEBUG 0*/
31#define LOG_NDDEBUG 0
32#include <errno.h>
33#include <cutils/log.h>
34#include <dlfcn.h>
35#include "audio_hw.h"
36#include "platform.h"
37#include "platform_api.h"
Manish Dewangan6a252632017-12-04 17:27:44 +053038#include "audio_extn.h"
Naresh Tanniru9d027a62015-03-13 01:32:10 +053039#include <stdlib.h>
40#include <cutils/str_parms.h>
41#include <hardware/audio.h>
42#include <hardware/hardware.h>
43#include <cutils/properties.h>
44
Revathi Uddaraju1eac8b02017-05-18 17:13:33 +053045#ifdef DYNAMIC_LOG_ENABLED
46#include <log_xml_parser.h>
47#define LOG_MASK HAL_MOD_FILE_A2DP
48#include <log_utils.h>
49#endif
50
Naresh Tanniru9d027a62015-03-13 01:32:10 +053051#ifdef SPLIT_A2DP_ENABLED
52#define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted"
53#define BT_IPC_LIB_NAME "libbthost_if.so"
54#define ENC_MEDIA_FMT_NONE 0
55#define ENC_MEDIA_FMT_AAC 0x00010DA6
56#define ENC_MEDIA_FMT_APTX 0x000131ff
57#define ENC_MEDIA_FMT_APTX_HD 0x00013200
58#define ENC_MEDIA_FMT_SBC 0x00010BF2
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053059#define ENC_MEDIA_FMT_CELT 0x00013221
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +053060#define ENC_MEDIA_FMT_LDAC 0x00013224
Naresh Tanniru9d027a62015-03-13 01:32:10 +053061#define MEDIA_FMT_AAC_AOT_LC 2
62#define MEDIA_FMT_AAC_AOT_SBR 5
63#define MEDIA_FMT_AAC_AOT_PS 29
Naresh Tanniru9d027a62015-03-13 01:32:10 +053064#define PCM_CHANNEL_L 1
65#define PCM_CHANNEL_R 2
66#define PCM_CHANNEL_C 3
67#define MEDIA_FMT_SBC_CHANNEL_MODE_MONO 1
68#define MEDIA_FMT_SBC_CHANNEL_MODE_STEREO 2
69#define MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO 8
70#define MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO 9
71#define MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS 0
72#define MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR 1
73#define MIXER_ENC_CONFIG_BLOCK "SLIM_7_RX Encoder Config"
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -080074#define MIXER_DEC_CONFIG_BLOCK "SLIM_7_TX Decoder Config"
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +053075#define MIXER_ENC_BIT_FORMAT "AFE Input Bit Format"
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +053076#define MIXER_SCRAMBLER_MODE "AFE Scrambler Mode"
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -080077#define MIXER_SAMPLE_RATE_RX "BT SampleRate RX"
78#define MIXER_SAMPLE_RATE_TX "BT SampleRate TX"
Samyak Jainf69e9ef2018-06-12 12:26:37 +053079#define MIXER_SAMPLE_RATE_DEFAULT "BT SampleRate"
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +053080#define MIXER_AFE_IN_CHANNELS "AFE Input Channels"
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -080081#define MIXER_ABR_TX_FEEDBACK_PATH "A2DP_SLIM7_UL_HL Switch"
82#define MIXER_SET_FEEDBACK_CHANNEL "BT set feedback channel"
Naresh Tanniru9d027a62015-03-13 01:32:10 +053083#define MIXER_ENC_FMT_SBC "SBC"
84#define MIXER_ENC_FMT_AAC "AAC"
85#define MIXER_ENC_FMT_APTX "APTX"
86#define MIXER_ENC_FMT_APTXHD "APTXHD"
87#define MIXER_ENC_FMT_NONE "NONE"
yidongh0515e042017-07-06 15:00:34 +080088#define ENCODER_LATENCY_SBC 10
89#define ENCODER_LATENCY_APTX 40
90#define ENCODER_LATENCY_APTX_HD 20
91#define ENCODER_LATENCY_AAC 70
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +053092//To Do: Fine Tune Encoder CELT/LDAC latency.
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053093#define ENCODER_LATENCY_CELT 40
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +053094#define ENCODER_LATENCY_LDAC 40
yidongh0515e042017-07-06 15:00:34 +080095#define DEFAULT_SINK_LATENCY_SBC 140
96#define DEFAULT_SINK_LATENCY_APTX 160
97#define DEFAULT_SINK_LATENCY_APTX_HD 180
98#define DEFAULT_SINK_LATENCY_AAC 180
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +053099//To Do: Fine Tune Default CELT/LDAC Latency.
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530100#define DEFAULT_SINK_LATENCY_CELT 180
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530101#define DEFAULT_SINK_LATENCY_LDAC 180
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530102
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800103// Slimbus Tx sample rate for ABR feedback channel
104#define ABR_TX_SAMPLE_RATE "KHZ_8"
105
106// Purpose ID for Inter Module Communication (IMC) in AFE
107#define IMC_PURPOSE_ID_BT_INFO 0x000132E2
108
109// Maximum quality levels for ABR
110#define MAX_ABR_QUALITY_LEVELS 5
111
112// Instance identifier for A2DP
113#define MAX_INSTANCE_ID (UINT32_MAX / 2)
114
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530115/*
116 * Below enum values are extended from audio_base.h to
117 * to keep encoder codec type local to bthost_ipc
118 * and audio_hal as these are intended only for handshake
119 * between IPC lib and Audio HAL.
120 */
121typedef enum {
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530122 ENC_CODEC_TYPE_INVALID = AUDIO_FORMAT_INVALID, // 0xFFFFFFFFUL
123 ENC_CODEC_TYPE_AAC = AUDIO_FORMAT_AAC, // 0x04000000UL
124 ENC_CODEC_TYPE_SBC = AUDIO_FORMAT_SBC, // 0x1F000000UL
125 ENC_CODEC_TYPE_APTX = AUDIO_FORMAT_APTX, // 0x20000000UL
126 ENC_CODEC_TYPE_APTX_HD = AUDIO_FORMAT_APTX_HD, // 0x21000000UL
Manish Dewangan6a252632017-12-04 17:27:44 +0530127#ifndef LINUX_ENABLED
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700128 ENC_CODEC_TYPE_APTX_DUAL_MONO = 570425344u, // 0x22000000UL
Manish Dewangan6a252632017-12-04 17:27:44 +0530129#endif
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530130 ENC_CODEC_TYPE_LDAC = AUDIO_FORMAT_LDAC, // 0x23000000UL
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530131 ENC_CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
132}enc_codec_t;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530133
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530134typedef int (*audio_stream_open_t)(void);
135typedef int (*audio_stream_close_t)(void);
136typedef int (*audio_start_stream_t)(void);
137typedef int (*audio_stop_stream_t)(void);
138typedef int (*audio_suspend_stream_t)(void);
139typedef void (*audio_handoff_triggered_t)(void);
140typedef void (*clear_a2dpsuspend_flag_t)(void);
141typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530142 enc_codec_t *codec_type);
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530143typedef int (*audio_check_a2dp_ready_t)(void);
yidongh0515e042017-07-06 15:00:34 +0800144typedef uint16_t (*audio_get_a2dp_sink_latency_t)(void);
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530145typedef int (*audio_is_scrambling_enabled_t)(void);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530146
147enum A2DP_STATE {
148 A2DP_STATE_CONNECTED,
149 A2DP_STATE_STARTED,
150 A2DP_STATE_STOPPED,
151 A2DP_STATE_DISCONNECTED,
152};
153
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800154typedef enum {
155 IMC_TRANSMIT,
156 IMC_RECEIVE,
157} imc_direction_t;
158
159typedef enum {
160 IMC_DISABLE,
161 IMC_ENABLE,
162} imc_status_t;
163
164/* PCM config for ABR Feedback hostless front end */
165static struct pcm_config pcm_config_abr = {
166 .channels = 1,
167 .rate = 8000,
168 .period_size = 240,
169 .period_count = 2,
170 .format = PCM_FORMAT_S16_LE,
171 .start_threshold = 0,
172 .stop_threshold = INT_MAX,
173 .avail_min = 0,
174};
175
176/* Adaptive bitrate config for A2DP codecs */
177struct a2dp_abr_config {
178 /* Flag to denote whether Adaptive bitrate is enabled for codec */
179 bool is_abr_enabled;
180 /* Flag to denote whether front end has been opened for ABR */
181 bool abr_started;
182 /* ABR Tx path pcm handle */
183 struct pcm *abr_tx_handle;
184 /* ABR Inter Module Communication (IMC) instance ID */
185 uint32_t imc_instance;
186};
187
188static uint32_t instance_id = MAX_INSTANCE_ID;
189
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530190/* structure used to update a2dp state machine
191 * to communicate IPC library
192 * to store DSP encoder configuration information
193 */
194struct a2dp_data {
195 struct audio_device *adev;
196 void *bt_lib_handle;
197 audio_stream_open_t audio_stream_open;
198 audio_stream_close_t audio_stream_close;
199 audio_start_stream_t audio_start_stream;
200 audio_stop_stream_t audio_stop_stream;
201 audio_suspend_stream_t audio_suspend_stream;
202 audio_handoff_triggered_t audio_handoff_triggered;
203 clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag;
204 audio_get_codec_config_t audio_get_codec_config;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530205 audio_check_a2dp_ready_t audio_check_a2dp_ready;
yidongh0515e042017-07-06 15:00:34 +0800206 audio_get_a2dp_sink_latency_t audio_get_a2dp_sink_latency;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530207 audio_is_scrambling_enabled_t audio_is_scrambling_enabled;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530208 enum A2DP_STATE bt_state;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530209 enc_codec_t bt_encoder_format;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530210 uint32_t enc_sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530211 uint32_t enc_channels;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530212 bool a2dp_started;
213 bool a2dp_suspended;
214 int a2dp_total_active_session_request;
215 bool is_a2dp_offload_supported;
216 bool is_handoff_in_progress;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700217 bool is_aptx_dual_mono_supported;
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800218 /* Adaptive bitrate config for A2DP codecs */
219 struct a2dp_abr_config abr_config;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530220};
221
222struct a2dp_data a2dp;
223
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800224/* Adaptive bitrate (ABR) is supported by certain Bluetooth codecs.
225 * Structures sent to configure DSP for ABR are defined below.
226 * This data helps DSP configure feedback path (BTSoC to LPASS)
227 * for link quality levels and mapping quality levels to codec
228 * specific bitrate.
229 */
230
231/* Key value pair for link quality level to bitrate mapping. */
232struct bit_rate_level_map_t {
233 uint32_t link_quality_level;
234 uint32_t bitrate;
235};
236
237/* Link quality level to bitrate mapping info sent to DSP. */
238struct quality_level_to_bitrate_info {
239 /* Number of quality levels being mapped.
240 * This will be equal to the size of mapping table.
241 */
242 uint32_t num_levels;
243 /* Quality level to bitrate mapping table */
244 struct bit_rate_level_map_t bit_rate_level_map[MAX_ABR_QUALITY_LEVELS];
245};
246
247/* Structure to set up Inter Module Communication (IMC) between
248 * AFE Decoder and Encoder.
249 */
250struct imc_dec_enc_info {
251 /* Decoder to encoder communication direction.
252 * Transmit = 0 / Receive = 1
253 */
254 uint32_t direction;
255 /* Enable / disable IMC between decoder and encoder */
256 uint32_t enable;
257 /* Purpose of IMC being set up between decoder and encoder.
258 * IMC_PURPOSE_ID_BT_INFO defined for link quality feedback
259 * is the default value to be sent as purpose.
260 */
261 uint32_t purpose;
262 /* Unique communication instance ID.
263 * purpose and comm_instance together form the actual key
264 * used in IMC registration, which must be the same for
265 * encoder and decoder for which IMC is being set up.
266 */
267 uint32_t comm_instance;
268};
269
270/* Structure used for ABR config of AFE encoder and decoder. */
271struct abr_enc_cfg_t {
272 /* Link quality level to bitrate mapping info sent to DSP. */
273 struct quality_level_to_bitrate_info mapping_info;
274 /* Information to set up IMC between decoder and encoder */
275 struct imc_dec_enc_info imc_info;
276} __attribute__ ((packed));
277
278/* Structure to send configuration for decoder introduced
279 * on AFE Tx path for ABR link quality feedback to BT encoder.
280 */
281struct abr_dec_cfg_t {
282 /* Decoder media format */
283 uint32_t dec_format;
284 /* Information to set up IMC between decoder and encoder */
285 struct imc_dec_enc_info imc_info;
286} __attribute__ ((packed));
287
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530288/* START of DSP configurable structures
289 * These values should match with DSP interface defintion
290 */
291
292/* AAC encoder configuration structure. */
293typedef struct aac_enc_cfg_t aac_enc_cfg_t;
294
295/* supported enc_mode are AAC_LC, AAC_SBR, AAC_PS
296 * supported aac_fmt_flag are ADTS/RAW
297 * supported channel_cfg are Native mode, Mono , Stereo
298 */
299struct aac_enc_cfg_t {
300 uint32_t enc_format;
301 uint32_t bit_rate;
302 uint32_t enc_mode;
303 uint16_t aac_fmt_flag;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530304 uint16_t channel_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530305 uint32_t sample_rate;
Manish Dewangan6a252632017-12-04 17:27:44 +0530306} __attribute__ ((packed));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530307
308/* SBC encoder configuration structure. */
309typedef struct sbc_enc_cfg_t sbc_enc_cfg_t;
310
311/* supported num_subbands are 4/8
312 * supported blk_len are 4, 8, 12, 16
313 * supported channel_mode are MONO, STEREO, DUAL_MONO, JOINT_STEREO
314 * supported alloc_method are LOUNDNESS/SNR
315 * supported bit_rate for mono channel is max 320kbps
316 * supported bit rate for stereo channel is max 512 kbps
317 */
318struct sbc_enc_cfg_t{
319 uint32_t enc_format;
320 uint32_t num_subbands;
321 uint32_t blk_len;
322 uint32_t channel_mode;
323 uint32_t alloc_method;
324 uint32_t bit_rate;
325 uint32_t sample_rate;
Manish Dewangan6a252632017-12-04 17:27:44 +0530326} __attribute__ ((packed));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530327
328
329/* supported num_channels are Mono/Stereo
330 * supported channel_mapping for mono is CHANNEL_C
331 * supported channel mapping for stereo is CHANNEL_L and CHANNEL_R
332 * custom size and reserved are not used(for future enhancement)
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700333 */
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530334struct custom_enc_cfg_t
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530335{
336 uint32_t enc_format;
337 uint32_t sample_rate;
338 uint16_t num_channels;
339 uint16_t reserved;
340 uint8_t channel_mapping[8];
341 uint32_t custom_size;
Manish Dewangan6a252632017-12-04 17:27:44 +0530342} __attribute__ ((packed));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530343
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530344struct celt_specific_enc_cfg_t
345{
346 uint32_t bit_rate;
347 uint16_t frame_size;
348 uint16_t complexity;
349 uint16_t prediction_mode;
350 uint16_t vbr_flag;
Manish Dewangan6a252632017-12-04 17:27:44 +0530351} __attribute__ ((packed));
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530352
353struct celt_enc_cfg_t
354{
355 struct custom_enc_cfg_t custom_cfg;
356 struct celt_specific_enc_cfg_t celt_cfg;
Manish Dewangan6a252632017-12-04 17:27:44 +0530357} __attribute__ ((packed));
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700358
359/* sync_mode introduced with APTX V2 libraries
360 * sync mode: 0x0 = stereo sync mode
361 * 0x01 = dual mono sync mode
362 * 0x02 = dual mono with no sync on either L or R codewords
363 */
364struct aptx_v2_enc_cfg_ext_t
365{
366 uint32_t sync_mode;
Manish Dewangan6a252632017-12-04 17:27:44 +0530367} __attribute__ ((packed));
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700368
369/* APTX struct for combining custom enc and V2 fields */
370struct aptx_enc_cfg_t
371{
372 struct custom_enc_cfg_t custom_cfg;
373 struct aptx_v2_enc_cfg_ext_t aptx_v2_cfg;
Manish Dewangan6a252632017-12-04 17:27:44 +0530374} __attribute__ ((packed));
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700375
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530376struct ldac_specific_enc_cfg_t
377{
378 uint32_t bit_rate;
379 uint16_t channel_mode;
380 uint16_t mtu;
Manish Dewangan6a252632017-12-04 17:27:44 +0530381} __attribute__ ((packed));
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530382
383struct ldac_enc_cfg_t
384{
385 struct custom_enc_cfg_t custom_cfg;
386 struct ldac_specific_enc_cfg_t ldac_cfg;
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800387 struct abr_enc_cfg_t abr_cfg;
Manish Dewangan6a252632017-12-04 17:27:44 +0530388} __attribute__ ((packed));
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530389
Sachin Mohan Gadag1657c052017-09-13 16:00:27 +0530390/* In LE BT source code uses system/audio.h for below
391 * structure definition. To avoid multiple definition
392 * compilation error for audiohal in LE , masking structure
393 * definition under "LINUX_ENABLED" which is defined only
394 * in LE
395 */
396#ifndef LINUX_ENABLED
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530397/* TODO: Define the following structures only for O using PLATFORM_VERSION */
398/* Information about BT SBC encoder configuration
399 * This data is used between audio HAL module and
400 * BT IPC library to configure DSP encoder
401 */
402typedef struct {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530403 uint32_t subband; /* 4, 8 */
404 uint32_t blk_len; /* 4, 8, 12, 16 */
405 uint16_t sampling_rate; /*44.1khz,48khz*/
406 uint8_t channels; /*0(Mono),1(Dual_mono),2(Stereo),3(JS)*/
407 uint8_t alloc; /*0(Loudness),1(SNR)*/
408 uint8_t min_bitpool; /* 2 */
409 uint8_t max_bitpool; /*53(44.1khz),51 (48khz) */
410 uint32_t bitrate; /* 320kbps to 512kbps */
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530411} audio_sbc_encoder_config;
412
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530413/* Information about BT APTX encoder configuration
414 * This data is used between audio HAL module and
415 * BT IPC library to configure DSP encoder
416 */
417typedef struct {
418 uint16_t sampling_rate;
419 uint8_t channels;
420 uint32_t bitrate;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700421} audio_aptx_default_config;
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530422
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700423typedef struct {
424 uint16_t sampling_rate;
425 uint8_t channels;
426 uint32_t bitrate;
427 uint32_t sync_mode;
428} audio_aptx_dual_mono_config;
429
430typedef union {
431 audio_aptx_default_config *default_cfg;
432 audio_aptx_dual_mono_config *dual_mono_cfg;
433} audio_aptx_encoder_config;
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530434
435/* Information about BT AAC encoder configuration
436 * This data is used between audio HAL module and
437 * BT IPC library to configure DSP encoder
438 */
439typedef struct {
440 uint32_t enc_mode; /* LC, SBR, PS */
441 uint16_t format_flag; /* RAW, ADTS */
442 uint16_t channels; /* 1-Mono, 2-Stereo */
443 uint32_t sampling_rate;
444 uint32_t bitrate;
445} audio_aac_encoder_config;
Sachin Mohan Gadag1657c052017-09-13 16:00:27 +0530446#endif
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530447
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530448/* Information about BT CELT encoder configuration
449 * This data is used between audio HAL module and
450 * BT IPC library to configure DSP encoder
451 */
452typedef struct {
453 uint32_t sampling_rate; /* 32000 - 48000, 48000 */
454 uint16_t channels; /* 1-Mono, 2-Stereo, 2*/
455 uint16_t frame_size; /* 64-128-256-512, 512 */
456 uint16_t complexity; /* 0-10, 1 */
457 uint16_t prediction_mode; /* 0-1-2, 0 */
458 uint16_t vbr_flag; /* 0-1, 0*/
459 uint32_t bitrate; /*32000 - 1536000, 139500*/
460} audio_celt_encoder_config;
461
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530462/* Information about BT LDAC encoder configuration
463 * This data is used between audio HAL module and
464 * BT IPC library to configure DSP encoder
465 */
466typedef struct {
467 uint32_t sampling_rate; /*44100,48000,88200,96000*/
468 uint32_t bit_rate; /*303000,606000,909000(in bits per second)*/
469 uint16_t channel_mode; /* 0, 4, 2, 1*/
470 uint16_t mtu; /*679*/
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800471 bool is_abr_enabled;
472 struct quality_level_to_bitrate_info level_to_bitrate_map;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530473} audio_ldac_encoder_config;
474
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530475/*********** END of DSP configurable structures ********************/
476
477/* API to identify DSP encoder captabilities */
478static void a2dp_offload_codec_cap_parser(char *value)
479{
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530480 char *tok = NULL,*saveptr;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530481
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530482 tok = strtok_r(value, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530483 while (tok != NULL) {
484 if (strcmp(tok, "sbc") == 0) {
485 ALOGD("%s: SBC offload supported\n",__func__);
486 a2dp.is_a2dp_offload_supported = true;
487 break;
488 } else if (strcmp(tok, "aptx") == 0) {
489 ALOGD("%s: aptx offload supported\n",__func__);
490 a2dp.is_a2dp_offload_supported = true;
491 break;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700492 } else if (strcmp(tok, "aptxtws") == 0) {
493 ALOGD("%s: aptx dual mono offload supported\n",__func__);
494 a2dp.is_a2dp_offload_supported = true;
495 break;
Naresh Tannirued694c82017-02-07 17:01:28 +0530496 } else if (strcmp(tok, "aptxhd") == 0) {
497 ALOGD("%s: aptx HD offload supported\n",__func__);
498 a2dp.is_a2dp_offload_supported = true;
499 break;
500 } else if (strcmp(tok, "aac") == 0) {
501 ALOGD("%s: aac offload supported\n",__func__);
502 a2dp.is_a2dp_offload_supported = true;
503 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530504 } else if (strcmp(tok, "celt") == 0) {
505 ALOGD("%s: celt offload supported\n",__func__);
506 a2dp.is_a2dp_offload_supported = true;
507 break;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530508 } else if (strcmp(tok, "ldac") == 0) {
509 ALOGD("%s: ldac offload supported\n",__func__);
510 a2dp.is_a2dp_offload_supported = true;
511 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530512 }
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530513 tok = strtok_r(NULL, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530514 };
515}
516
517static void update_offload_codec_capabilities()
518{
519 char value[PROPERTY_VALUE_MAX] = {'\0'};
520
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700521 property_get("persist.vendor.bt.a2dp_offload_cap", value, "false");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530522 ALOGD("get_offload_codec_capabilities = %s",value);
523 a2dp.is_a2dp_offload_supported =
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700524 property_get_bool("persist.vendor.bt.a2dp_offload_cap", false);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530525 if (strcmp(value, "false") != 0)
526 a2dp_offload_codec_cap_parser(value);
527 ALOGD("%s: codec cap = %s",__func__,value);
528}
529
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800530static int stop_abr()
531{
532 struct mixer_ctl *ctl_abr_tx_path = NULL;
533 struct mixer_ctl *ctl_set_bt_feedback_channel = NULL;
534
535 /* This function can be used if !abr_started for clean up */
536 ALOGV("%s: enter", __func__);
537
538 // Close hostless front end
539 if (a2dp.abr_config.abr_tx_handle != NULL) {
540 pcm_close(a2dp.abr_config.abr_tx_handle);
541 a2dp.abr_config.abr_tx_handle = NULL;
542 }
543 a2dp.abr_config.abr_started = false;
544 a2dp.abr_config.imc_instance = 0;
545
546 // Reset BT driver mixer control for ABR usecase
547 ctl_set_bt_feedback_channel = mixer_get_ctl_by_name(a2dp.adev->mixer,
548 MIXER_SET_FEEDBACK_CHANNEL);
549 if (!ctl_set_bt_feedback_channel) {
550 ALOGE("%s: ERROR Set usecase mixer control not identifed", __func__);
551 return -ENOSYS;
552 }
553 if (mixer_ctl_set_value(ctl_set_bt_feedback_channel, 0, 0) != 0) {
554 ALOGE("%s: Failed to set BT usecase", __func__);
555 return -ENOSYS;
556 }
557
558 // Reset ABR Tx feedback path
559 ALOGV("%s: Disable ABR Tx feedback path", __func__);
560 ctl_abr_tx_path = mixer_get_ctl_by_name(a2dp.adev->mixer,
561 MIXER_ABR_TX_FEEDBACK_PATH);
562 if (!ctl_abr_tx_path) {
563 ALOGE("%s: ERROR ABR Tx feedback path mixer control not identifed", __func__);
564 return -ENOSYS;
565 }
566 if (mixer_ctl_set_value(ctl_abr_tx_path, 0, 0) != 0) {
567 ALOGE("%s: Failed to set ABR Tx feedback path", __func__);
568 return -ENOSYS;
569 }
570
571 return 0;
572}
573
574static int start_abr()
575{
576 struct mixer_ctl *ctl_abr_tx_path = NULL;
577 struct mixer_ctl *ctl_set_bt_feedback_channel = NULL;
578 int abr_device_id;
579 int ret = 0;
580
581 if (!a2dp.abr_config.is_abr_enabled) {
582 ALOGE("%s: Cannot start if ABR is not enabled", __func__);
583 return -ENOSYS;
584 }
585
586 if (a2dp.abr_config.abr_started) {
587 ALOGI("%s: ABR has already started", __func__);
588 return ret;
589 }
590
591 // Enable Slimbus 7 Tx feedback path
592 ALOGV("%s: Enable ABR Tx feedback path", __func__);
593 ctl_abr_tx_path = mixer_get_ctl_by_name(a2dp.adev->mixer,
594 MIXER_ABR_TX_FEEDBACK_PATH);
595 if (!ctl_abr_tx_path) {
596 ALOGE("%s: ERROR ABR Tx feedback path mixer control not identifed", __func__);
597 return -ENOSYS;
598 }
599 if (mixer_ctl_set_value(ctl_abr_tx_path, 0, 1) != 0) {
600 ALOGE("%s: Failed to set ABR Tx feedback path", __func__);
601 return -ENOSYS;
602 }
603
604 // Notify ABR usecase information to BT driver to distinguish
605 // between SCO and feedback usecase
606 ctl_set_bt_feedback_channel = mixer_get_ctl_by_name(a2dp.adev->mixer,
607 MIXER_SET_FEEDBACK_CHANNEL);
608 if (!ctl_set_bt_feedback_channel) {
609 ALOGE("%s: ERROR Set usecase mixer control not identifed", __func__);
610 return -ENOSYS;
611 }
612 if (mixer_ctl_set_value(ctl_set_bt_feedback_channel, 0, 1) != 0) {
613 ALOGE("%s: Failed to set BT usecase", __func__);
614 return -ENOSYS;
615 }
616
617 // Open hostless front end and prepare ABR Tx path
618 abr_device_id = platform_get_pcm_device_id(USECASE_AUDIO_A2DP_ABR_FEEDBACK,
619 PCM_CAPTURE);
620 if (!a2dp.abr_config.abr_tx_handle) {
621 a2dp.abr_config.abr_tx_handle = pcm_open(a2dp.adev->snd_card,
622 abr_device_id, PCM_IN,
623 &pcm_config_abr);
624 if (a2dp.abr_config.abr_tx_handle == NULL ||
625 !pcm_is_ready(a2dp.abr_config.abr_tx_handle))
626 goto fail;
627 }
628 ret = pcm_start(a2dp.abr_config.abr_tx_handle);
629 if (ret < 0)
630 goto fail;
631 a2dp.abr_config.abr_started = true;
632
633 return ret;
634
635fail:
636 ALOGE("%s: %s", __func__, pcm_get_error(a2dp.abr_config.abr_tx_handle));
637 stop_abr();
638 return -ENOSYS;
639}
640
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530641/* API to open BT IPC library to start IPC communication */
642static void open_a2dp_output()
643{
644 int ret = 0;
645
646 ALOGD(" Open A2DP output start ");
647 if (a2dp.bt_lib_handle == NULL){
648 ALOGD(" Requesting for BT lib handle");
649 a2dp.bt_lib_handle = dlopen(BT_IPC_LIB_NAME, RTLD_NOW);
650
651 if (a2dp.bt_lib_handle == NULL) {
652 ALOGE("%s: DLOPEN failed for %s", __func__, BT_IPC_LIB_NAME);
653 ret = -ENOSYS;
654 goto init_fail;
655 } else {
656 a2dp.audio_stream_open = (audio_stream_open_t)
657 dlsym(a2dp.bt_lib_handle, "audio_stream_open");
658 a2dp.audio_start_stream = (audio_start_stream_t)
659 dlsym(a2dp.bt_lib_handle, "audio_start_stream");
660 a2dp.audio_get_codec_config = (audio_get_codec_config_t)
661 dlsym(a2dp.bt_lib_handle, "audio_get_codec_config");
662 a2dp.audio_suspend_stream = (audio_suspend_stream_t)
663 dlsym(a2dp.bt_lib_handle, "audio_suspend_stream");
664 a2dp.audio_handoff_triggered = (audio_handoff_triggered_t)
665 dlsym(a2dp.bt_lib_handle, "audio_handoff_triggered");
666 a2dp.clear_a2dpsuspend_flag = (clear_a2dpsuspend_flag_t)
667 dlsym(a2dp.bt_lib_handle, "clear_a2dpsuspend_flag");
668 a2dp.audio_stop_stream = (audio_stop_stream_t)
669 dlsym(a2dp.bt_lib_handle, "audio_stop_stream");
670 a2dp.audio_stream_close = (audio_stream_close_t)
671 dlsym(a2dp.bt_lib_handle, "audio_stream_close");
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530672 a2dp.audio_check_a2dp_ready = (audio_check_a2dp_ready_t)
673 dlsym(a2dp.bt_lib_handle,"audio_check_a2dp_ready");
yidongh0515e042017-07-06 15:00:34 +0800674 a2dp.audio_get_a2dp_sink_latency = (audio_get_a2dp_sink_latency_t)
675 dlsym(a2dp.bt_lib_handle,"audio_get_a2dp_sink_latency");
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530676 a2dp.audio_is_scrambling_enabled = (audio_is_scrambling_enabled_t)
677 dlsym(a2dp.bt_lib_handle,"audio_is_scrambling_enabled");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530678 }
679 }
680
681 if (a2dp.bt_lib_handle && a2dp.audio_stream_open) {
682 if (a2dp.bt_state == A2DP_STATE_DISCONNECTED) {
683 ALOGD("calling BT stream open");
684 ret = a2dp.audio_stream_open();
685 if(ret != 0) {
686 ALOGE("Failed to open output stream for a2dp: status %d", ret);
687 goto init_fail;
688 }
689 a2dp.bt_state = A2DP_STATE_CONNECTED;
690 } else {
691 ALOGD("Called a2dp open with improper state, Ignoring request state %d", a2dp.bt_state);
692 }
693 } else {
694 ALOGE("a2dp handle is not identified, Ignoring open request");
695 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
696 goto init_fail;
697 }
698
699init_fail:
700 if(ret != 0 && (a2dp.bt_lib_handle != NULL)) {
701 dlclose(a2dp.bt_lib_handle);
702 a2dp.bt_lib_handle = NULL;
703 }
704}
705
706static int close_a2dp_output()
707{
708 ALOGV("%s\n",__func__);
709 if (!(a2dp.bt_lib_handle && a2dp.audio_stream_close)) {
710 ALOGE("a2dp handle is not identified, Ignoring close request");
711 return -ENOSYS;
712 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530713 if (a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530714 ALOGD("calling BT stream close");
715 if(a2dp.audio_stream_close() == false)
716 ALOGE("failed close a2dp control path from BT library");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530717 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530718 a2dp.a2dp_started = false;
719 a2dp.a2dp_total_active_session_request = 0;
720 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530721 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530722 a2dp.enc_sampling_rate = 48000;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530723 a2dp.enc_channels = 2;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530724 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800725 if (a2dp.abr_config.is_abr_enabled && a2dp.abr_config.abr_started)
726 stop_abr();
727 a2dp.abr_config.is_abr_enabled = false;
728 a2dp.abr_config.abr_started = false;
729 a2dp.abr_config.imc_instance = 0;
730 a2dp.abr_config.abr_tx_handle = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530731
732 return 0;
733}
734
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530735static void a2dp_check_and_set_scrambler()
736{
737 bool scrambler_mode = false;
738 struct mixer_ctl *ctrl_scrambler_mode = NULL;
739 if (a2dp.audio_is_scrambling_enabled && (a2dp.bt_state != A2DP_STATE_DISCONNECTED))
740 scrambler_mode = a2dp.audio_is_scrambling_enabled();
741
742 if (scrambler_mode) {
743 //enable scrambler in dsp
744 ctrl_scrambler_mode = mixer_get_ctl_by_name(a2dp.adev->mixer,
745 MIXER_SCRAMBLER_MODE);
746 if (!ctrl_scrambler_mode) {
747 ALOGE(" ERROR scrambler mode mixer control not identifed");
748 return;
749 } else {
750 if (mixer_ctl_set_value(ctrl_scrambler_mode, 0, true) != 0) {
751 ALOGE("%s: Could not set scrambler mode", __func__);
752 return;
753 }
754 }
755 }
756}
757
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800758static int a2dp_set_backend_cfg()
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530759{
760 char *rate_str = NULL, *in_channels = NULL;
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800761 uint32_t sampling_rate_rx = a2dp.enc_sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530762 struct mixer_ctl *ctl_sample_rate = NULL, *ctrl_in_channels = NULL;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530763
764 //For LDAC encoder open slimbus port at 96Khz for 48Khz input
765 //and 88.2Khz for 44.1Khz input.
766 if ((a2dp.bt_encoder_format == ENC_CODEC_TYPE_LDAC) &&
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800767 (sampling_rate_rx == 48000 || sampling_rate_rx == 44100 )) {
768 sampling_rate_rx *= 2;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +0530769 }
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800770
771 // Set Rx backend sample rate
772 switch (sampling_rate_rx) {
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530773 case 44100:
774 rate_str = "KHZ_44P1";
775 break;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530776 case 88200:
777 rate_str = "KHZ_88P2";
778 break;
779 case 96000:
780 rate_str = "KHZ_96";
781 break;
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800782 case 48000:
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530783 default:
784 rate_str = "KHZ_48";
785 break;
786 }
787
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800788 ALOGD("%s: set backend rx sample rate = %s", __func__, rate_str);
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530789 ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800790 MIXER_SAMPLE_RATE_RX);
Samyak Jainf69e9ef2018-06-12 12:26:37 +0530791 if (ctl_sample_rate) {
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800792
Samyak Jainf69e9ef2018-06-12 12:26:37 +0530793 if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
794 ALOGE("%s: Failed to set backend sample rate = %s", __func__, rate_str);
795 return -ENOSYS;
796 }
797
798 /* Set Tx backend sample rate */
799 if (a2dp.abr_config.is_abr_enabled)
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800800 rate_str = ABR_TX_SAMPLE_RATE;
801
Samyak Jainf69e9ef2018-06-12 12:26:37 +0530802 ALOGD("%s: set backend tx sample rate = %s", __func__, rate_str);
803 ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
804 MIXER_SAMPLE_RATE_TX);
805 if (!ctl_sample_rate) {
806 ALOGE("%s: ERROR backend sample rate mixer control not identifed", __func__);
807 return -ENOSYS;
808 }
809
810 if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
811 ALOGE("%s: Failed to set backend sample rate = %s", __func__, rate_str);
812 return -ENOSYS;
813 }
814 } else {
815 /* Fallback to legacy approch if MIXER_SAMPLE_RATE_RX and
816 MIXER_SAMPLE_RATE_TX is not supported */
817 ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
818 MIXER_SAMPLE_RATE_DEFAULT);
819 if (!ctl_sample_rate) {
820 ALOGE("%s: ERROR backend sample rate mixer control not identifed", __func__);
821 return -ENOSYS;
822 }
823
824 if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
825 ALOGE("%s: Failed to set backend sample rate = %s", __func__, rate_str);
826 return -ENOSYS;
827 }
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530828 }
829
830 //Configure AFE input channels
831 switch (a2dp.enc_channels) {
832 case 1:
833 in_channels = "One";
834 break;
835 case 2:
836 default:
837 in_channels = "Two";
838 break;
839 }
840
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800841 ALOGD("%s: set AFE input channels = %d", __func__, a2dp.enc_channels);
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530842 ctrl_in_channels = mixer_get_ctl_by_name(a2dp.adev->mixer,
843 MIXER_AFE_IN_CHANNELS);
844 if (!ctrl_in_channels) {
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800845 ALOGE("%s: ERROR AFE input channels mixer control not identifed", __func__);
846 return -ENOSYS;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530847 }
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800848 if (mixer_ctl_set_enum_by_string(ctrl_in_channels, in_channels) != 0) {
849 ALOGE("%s: Failed to set AFE in channels = %d", __func__, a2dp.enc_channels);
850 return -ENOSYS;
851 }
852
853 return 0;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530854}
855
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800856static int a2dp_reset_backend_cfg()
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530857{
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800858 const char *rate_str = "KHZ_8", *in_channels = "Zero";
859 struct mixer_ctl *ctl_sample_rate_rx = NULL, *ctl_sample_rate_tx = NULL;
860 struct mixer_ctl *ctrl_in_channels = NULL;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530861
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800862 // Reset backend sampling rate
863 ALOGD("%s: reset backend sample rate = %s", __func__, rate_str);
864 ctl_sample_rate_rx = mixer_get_ctl_by_name(a2dp.adev->mixer,
865 MIXER_SAMPLE_RATE_RX);
Samyak Jainf69e9ef2018-06-12 12:26:37 +0530866 if (ctl_sample_rate_rx) {
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530867
Samyak Jainf69e9ef2018-06-12 12:26:37 +0530868 if (mixer_ctl_set_enum_by_string(ctl_sample_rate_rx, rate_str) != 0) {
869 ALOGE("%s: Failed to reset Rx backend sample rate = %s", __func__, rate_str);
870 return -ENOSYS;
871 }
872
873 ctl_sample_rate_tx = mixer_get_ctl_by_name(a2dp.adev->mixer,
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800874 MIXER_SAMPLE_RATE_TX);
Samyak Jainf69e9ef2018-06-12 12:26:37 +0530875 if (!ctl_sample_rate_tx) {
876 ALOGE("%s: ERROR Tx backend sample rate mixer control not identifed", __func__);
877 return -ENOSYS;
878 }
879
880 if (mixer_ctl_set_enum_by_string(ctl_sample_rate_tx, rate_str) != 0) {
881 ALOGE("%s: Failed to reset Tx backend sample rate = %s", __func__, rate_str);
882 return -ENOSYS;
883 }
884 } else {
885
886 ctl_sample_rate_rx = mixer_get_ctl_by_name(a2dp.adev->mixer,
887 MIXER_SAMPLE_RATE_DEFAULT);
888 if (!ctl_sample_rate_rx) {
889 ALOGE("%s: ERROR backend sample rate mixer control not identifed", __func__);
890 return -ENOSYS;
891 }
892
893 if (mixer_ctl_set_enum_by_string(ctl_sample_rate_rx, rate_str) != 0) {
894 ALOGE("%s: Failed to reset backend sample rate = %s", __func__, rate_str);
895 return -ENOSYS;
896 }
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800897 }
898
899 // Reset AFE input channels
900 ALOGD("%s: reset AFE input channels = %s", __func__, in_channels);
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530901 ctrl_in_channels = mixer_get_ctl_by_name(a2dp.adev->mixer,
902 MIXER_AFE_IN_CHANNELS);
903 if (!ctrl_in_channels) {
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800904 ALOGE("%s: ERROR AFE input channels mixer control not identifed", __func__);
905 return -ENOSYS;
906 }
907 if (mixer_ctl_set_enum_by_string(ctrl_in_channels, in_channels) != 0) {
908 ALOGE("%s: Failed to reset AFE in channels = %d", __func__, a2dp.enc_channels);
909 return -ENOSYS;
910 }
911
912 return 0;
913}
914
915/* API to configure AFE decoder in DSP */
916static bool configure_a2dp_decoder_format(int dec_format)
917{
918 struct mixer_ctl *ctl_dec_data = NULL;
919 struct abr_dec_cfg_t dec_cfg;
920 int ret = 0;
921
922 if (a2dp.abr_config.is_abr_enabled) {
923 ctl_dec_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_DEC_CONFIG_BLOCK);
924 if (!ctl_dec_data) {
925 ALOGE("%s: ERROR A2DP codec config data mixer control not identifed", __func__);
926 return false;
927 }
928 memset(&dec_cfg, 0x0, sizeof(dec_cfg));
929 dec_cfg.dec_format = dec_format;
930 dec_cfg.imc_info.direction = IMC_TRANSMIT;
931 dec_cfg.imc_info.enable = IMC_ENABLE;
932 dec_cfg.imc_info.purpose = IMC_PURPOSE_ID_BT_INFO;
933 dec_cfg.imc_info.comm_instance = a2dp.abr_config.imc_instance;
934
935 ret = mixer_ctl_set_array(ctl_dec_data, &dec_cfg,
936 sizeof(dec_cfg));
937 if (ret != 0) {
938 ALOGE("%s: Failed to set decoder config", __func__);
939 return false;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530940 }
941 }
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -0800942
943 return true;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530944}
945
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530946/* API to configure SBC DSP encoder */
947bool configure_sbc_enc_format(audio_sbc_encoder_config *sbc_bt_cfg)
948{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530949 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530950 struct sbc_enc_cfg_t sbc_dsp_cfg;
951 bool is_configured = false;
952 int ret = 0;
953
954 if(sbc_bt_cfg == NULL)
955 return false;
956
957 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
958 if (!ctl_enc_data) {
959 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
960 is_configured = false;
961 goto fail;
962 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530963 memset(&sbc_dsp_cfg, 0x0, sizeof(struct sbc_enc_cfg_t));
964 sbc_dsp_cfg.enc_format = ENC_MEDIA_FMT_SBC;
965 sbc_dsp_cfg.num_subbands = sbc_bt_cfg->subband;
966 sbc_dsp_cfg.blk_len = sbc_bt_cfg->blk_len;
967 switch(sbc_bt_cfg->channels) {
968 case 0:
969 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_MONO;
970 break;
971 case 1:
972 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO;
973 break;
974 case 3:
975 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO;
976 break;
977 case 2:
978 default:
979 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_STEREO;
980 break;
981 }
982 if (sbc_bt_cfg->alloc)
983 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS;
984 else
985 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR;
986 sbc_dsp_cfg.bit_rate = sbc_bt_cfg->bitrate;
987 sbc_dsp_cfg.sample_rate = sbc_bt_cfg->sampling_rate;
988 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&sbc_dsp_cfg,
989 sizeof(struct sbc_enc_cfg_t));
990 if (ret != 0) {
991 ALOGE("%s: failed to set SBC encoder config", __func__);
992 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530993 goto fail;
994 }
995 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
996 MIXER_ENC_BIT_FORMAT);
997 if (!ctrl_bit_format) {
998 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
999 is_configured = false;
1000 goto fail;
1001 }
1002 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
1003 if (ret != 0) {
1004 ALOGE("%s: Failed to set bit format to encoder", __func__);
1005 is_configured = false;
1006 goto fail;
1007 }
1008 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301009 a2dp.bt_encoder_format = ENC_CODEC_TYPE_SBC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301010 a2dp.enc_sampling_rate = sbc_bt_cfg->sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301011
1012 if (sbc_dsp_cfg.channel_mode == MEDIA_FMT_SBC_CHANNEL_MODE_MONO)
1013 a2dp.enc_channels = 1;
1014 else
1015 a2dp.enc_channels = 2;
1016
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301017 ALOGV("Successfully updated SBC enc format with samplingrate: %d channelmode:%d",
1018 sbc_dsp_cfg.sample_rate, sbc_dsp_cfg.channel_mode);
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301019fail:
1020 return is_configured;
1021}
1022
Manish Dewangan6a252632017-12-04 17:27:44 +05301023#ifndef LINUX_ENABLED
1024static int update_aptx_dsp_config_v2(struct aptx_enc_cfg_t *aptx_dsp_cfg,
1025 audio_aptx_encoder_config *aptx_bt_cfg)
1026{
1027 int ret = 0;
1028
1029 if(aptx_dsp_cfg == NULL || aptx_bt_cfg == NULL) {
1030 ALOGE("Invalid param, aptx_dsp_cfg %p aptx_bt_cfg %p",
1031 aptx_dsp_cfg, aptx_bt_cfg);
1032 return -EINVAL;
1033 }
1034
1035 memset(aptx_dsp_cfg, 0x0, sizeof(struct aptx_enc_cfg_t));
1036 aptx_dsp_cfg->custom_cfg.enc_format = ENC_MEDIA_FMT_APTX;
1037
1038 if (!a2dp.is_aptx_dual_mono_supported) {
1039 aptx_dsp_cfg->custom_cfg.sample_rate = aptx_bt_cfg->default_cfg->sampling_rate;
1040 aptx_dsp_cfg->custom_cfg.num_channels = aptx_bt_cfg->default_cfg->channels;
1041 } else {
1042 aptx_dsp_cfg->custom_cfg.sample_rate = aptx_bt_cfg->dual_mono_cfg->sampling_rate;
1043 aptx_dsp_cfg->custom_cfg.num_channels = aptx_bt_cfg->dual_mono_cfg->channels;
1044 aptx_dsp_cfg->aptx_v2_cfg.sync_mode = aptx_bt_cfg->dual_mono_cfg->sync_mode;
1045 }
1046
1047 switch(aptx_dsp_cfg->custom_cfg.num_channels) {
1048 case 1:
1049 aptx_dsp_cfg->custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
1050 break;
1051 case 2:
1052 default:
1053 aptx_dsp_cfg->custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
1054 aptx_dsp_cfg->custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
1055 break;
1056 }
1057 a2dp.enc_channels = aptx_dsp_cfg->custom_cfg.num_channels;
1058 if (!a2dp.is_aptx_dual_mono_supported) {
1059 a2dp.enc_sampling_rate = aptx_bt_cfg->default_cfg->sampling_rate;
1060 ALOGV("Successfully updated APTX enc format with samplingrate: %d \
1061 channels:%d", aptx_dsp_cfg->custom_cfg.sample_rate,
1062 aptx_dsp_cfg->custom_cfg.num_channels);
1063 } else {
1064 a2dp.enc_sampling_rate = aptx_bt_cfg->dual_mono_cfg->sampling_rate;
1065 ALOGV("Successfully updated APTX dual mono enc format with \
1066 samplingrate: %d channels:%d syncmode %d",
1067 aptx_dsp_cfg->custom_cfg.sample_rate,
1068 aptx_dsp_cfg->custom_cfg.num_channels,
1069 aptx_dsp_cfg->aptx_v2_cfg.sync_mode);
1070 }
1071 return ret;
1072}
1073#else
1074static int update_aptx_dsp_config_v1(struct custom_enc_cfg_t *aptx_dsp_cfg,
1075 audio_aptx_encoder_config *aptx_bt_cfg)
1076{
1077 int ret = 0;
1078
1079 if(aptx_dsp_cfg == NULL || aptx_bt_cfg == NULL) {
1080 ALOGE("Invalid param, aptx_dsp_cfg %p aptx_bt_cfg %p",
1081 aptx_dsp_cfg, aptx_bt_cfg);
1082 return -EINVAL;
1083 }
1084
1085 memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_t));
1086 aptx_dsp_cfg->enc_format = ENC_MEDIA_FMT_APTX;
1087 aptx_dsp_cfg->sample_rate = aptx_bt_cfg->sampling_rate;
1088 aptx_dsp_cfg->num_channels = aptx_bt_cfg->channels;
1089 switch(aptx_dsp_cfg->num_channels) {
1090 case 1:
1091 aptx_dsp_cfg->channel_mapping[0] = PCM_CHANNEL_C;
1092 break;
1093 case 2:
1094 default:
1095 aptx_dsp_cfg->channel_mapping[0] = PCM_CHANNEL_L;
1096 aptx_dsp_cfg->channel_mapping[1] = PCM_CHANNEL_R;
1097 break;
1098 }
1099
1100 ALOGV("Updated APTX enc format with samplingrate: %d channels:%d",
1101 aptx_dsp_cfg->sample_rate, aptx_dsp_cfg->num_channels);
1102
1103 return ret;
1104}
1105#endif
1106
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301107/* API to configure APTX DSP encoder */
1108bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
1109{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301110 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Manish Dewangan6a252632017-12-04 17:27:44 +05301111 int mixer_size;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301112 bool is_configured = false;
1113 int ret = 0;
Manish Dewangan6a252632017-12-04 17:27:44 +05301114 int sample_rate_backup;
Preetam Singh Ranawat109bb3c2018-01-30 12:12:02 +05301115
1116 if(aptx_bt_cfg == NULL)
1117 return false;
1118
Manish Dewangan6a252632017-12-04 17:27:44 +05301119#ifndef LINUX_ENABLED
1120 struct aptx_enc_cfg_t aptx_dsp_cfg;
1121 mixer_size = sizeof(struct aptx_enc_cfg_t);
1122 sample_rate_backup = aptx_bt_cfg->default_cfg->sampling_rate;
1123#else
1124 struct custom_enc_cfg_t aptx_dsp_cfg;
1125 mixer_size = sizeof(struct custom_enc_cfg_t);
1126 sample_rate_backup = aptx_bt_cfg->sampling_rate;
1127#endif
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301128
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301129 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
1130 if (!ctl_enc_data) {
1131 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
1132 is_configured = false;
1133 goto fail;
1134 }
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001135
Manish Dewangan6a252632017-12-04 17:27:44 +05301136#ifndef LINUX_ENABLED
1137 ret = update_aptx_dsp_config_v2(&aptx_dsp_cfg, aptx_bt_cfg);
1138#else
1139 ret = update_aptx_dsp_config_v1(&aptx_dsp_cfg, aptx_bt_cfg);
1140#endif
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001141
Manish Dewangan6a252632017-12-04 17:27:44 +05301142 if (ret) {
1143 is_configured = false;
1144 goto fail;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301145 }
1146 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Manish Dewangan6a252632017-12-04 17:27:44 +05301147 mixer_size);
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301148 if (ret != 0) {
1149 ALOGE("%s: Failed to set APTX encoder config", __func__);
1150 is_configured = false;
1151 goto fail;
1152 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301153 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
1154 MIXER_ENC_BIT_FORMAT);
1155 if (!ctrl_bit_format) {
1156 ALOGE("ERROR bit format CONFIG data mixer control not identifed");
1157 is_configured = false;
1158 goto fail;
1159 } else {
1160 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
1161 if (ret != 0) {
1162 ALOGE("%s: Failed to set bit format to encoder", __func__);
1163 is_configured = false;
1164 goto fail;
1165 }
1166 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301167 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301168 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301169fail:
Manish Dewangan6a252632017-12-04 17:27:44 +05301170 /*restore sample rate */
1171 if(!is_configured)
1172 a2dp.enc_sampling_rate = sample_rate_backup;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301173 return is_configured;
1174}
1175
1176/* API to configure APTX HD DSP encoder
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301177 */
Manish Dewangan6a252632017-12-04 17:27:44 +05301178#ifndef LINUX_ENABLED
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001179bool configure_aptx_hd_enc_format(audio_aptx_default_config *aptx_bt_cfg)
Manish Dewangan6a252632017-12-04 17:27:44 +05301180#else
1181bool configure_aptx_hd_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
1182#endif
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301183{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301184 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301185 struct custom_enc_cfg_t aptx_dsp_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301186 bool is_configured = false;
1187 int ret = 0;
1188
1189 if(aptx_bt_cfg == NULL)
1190 return false;
1191
1192 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
1193 if (!ctl_enc_data) {
1194 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
1195 is_configured = false;
1196 goto fail;
1197 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301198
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301199 memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301200 aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX_HD;
1201 aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
1202 aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
1203 switch(aptx_dsp_cfg.num_channels) {
1204 case 1:
1205 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
1206 break;
1207 case 2:
1208 default:
1209 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
1210 aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
1211 break;
1212 }
1213 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301214 sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301215 if (ret != 0) {
1216 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
1217 is_configured = false;
1218 goto fail;
1219 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301220 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
1221 if (!ctrl_bit_format) {
1222 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
1223 is_configured = false;
1224 goto fail;
1225 }
1226 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S24_LE");
1227 if (ret != 0) {
1228 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
1229 is_configured = false;
1230 goto fail;
1231 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301232 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301233 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX_HD;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301234 a2dp.enc_sampling_rate = aptx_bt_cfg->sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301235 a2dp.enc_channels = aptx_bt_cfg->channels;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301236 ALOGV("Successfully updated APTX HD encformat with samplingrate: %d channels:%d",
1237 aptx_dsp_cfg.sample_rate, aptx_dsp_cfg.num_channels);
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301238fail:
1239 return is_configured;
1240}
1241
1242/* API to configure AAC DSP encoder */
1243bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
1244{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301245 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301246 struct aac_enc_cfg_t aac_dsp_cfg;
1247 bool is_configured = false;
1248 int ret = 0;
1249
1250 if(aac_bt_cfg == NULL)
1251 return false;
1252
1253 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
1254 if (!ctl_enc_data) {
1255 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
1256 is_configured = false;
1257 goto fail;
1258 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301259 memset(&aac_dsp_cfg, 0x0, sizeof(struct aac_enc_cfg_t));
1260 aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC;
1261 aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +05301262 aac_dsp_cfg.sample_rate = aac_bt_cfg->sampling_rate;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301263 switch(aac_bt_cfg->enc_mode) {
1264 case 0:
1265 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
1266 break;
1267 case 2:
1268 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
1269 break;
1270 case 1:
1271 default:
1272 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
1273 break;
1274 }
Naresh Tannirua42d0bd2016-09-21 15:30:46 +05301275 aac_dsp_cfg.aac_fmt_flag = aac_bt_cfg->format_flag;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301276 aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels;
1277 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg,
1278 sizeof(struct aac_enc_cfg_t));
1279 if (ret != 0) {
1280 ALOGE("%s: failed to set SBC encoder config", __func__);
1281 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301282 goto fail;
1283 }
1284 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
1285 MIXER_ENC_BIT_FORMAT);
1286 if (!ctrl_bit_format) {
1287 is_configured = false;
1288 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
1289 goto fail;
1290 }
1291 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
1292 if (ret != 0) {
1293 ALOGE("%s: Failed to set bit format to encoder", __func__);
1294 is_configured = false;
1295 goto fail;
1296 }
1297 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301298 a2dp.bt_encoder_format = ENC_CODEC_TYPE_AAC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301299 a2dp.enc_sampling_rate = aac_bt_cfg->sampling_rate;
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -08001300 a2dp.enc_channels = aac_bt_cfg->channels;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301301 ALOGV("Successfully updated AAC enc format with samplingrate: %d channels:%d",
1302 aac_dsp_cfg.sample_rate, aac_dsp_cfg.channel_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301303fail:
1304 return is_configured;
1305}
1306
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301307bool configure_celt_enc_format(audio_celt_encoder_config *celt_bt_cfg)
1308{
1309 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
1310 struct celt_enc_cfg_t celt_dsp_cfg;
1311 bool is_configured = false;
1312 int ret = 0;
1313 if(celt_bt_cfg == NULL)
1314 return false;
1315
1316 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
1317 if (!ctl_enc_data) {
1318 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
1319 is_configured = false;
1320 goto fail;
1321 }
1322 memset(&celt_dsp_cfg, 0x0, sizeof(struct celt_enc_cfg_t));
1323
1324 celt_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_CELT;
1325 celt_dsp_cfg.custom_cfg.sample_rate = celt_bt_cfg->sampling_rate;
1326 celt_dsp_cfg.custom_cfg.num_channels = celt_bt_cfg->channels;
1327 switch(celt_dsp_cfg.custom_cfg.num_channels) {
1328 case 1:
1329 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
1330 break;
1331 case 2:
1332 default:
1333 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
1334 celt_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
1335 break;
1336 }
1337
1338 celt_dsp_cfg.custom_cfg.custom_size = sizeof(struct celt_enc_cfg_t);
1339
1340 celt_dsp_cfg.celt_cfg.frame_size = celt_bt_cfg->frame_size;
1341 celt_dsp_cfg.celt_cfg.complexity = celt_bt_cfg->complexity;
1342 celt_dsp_cfg.celt_cfg.prediction_mode = celt_bt_cfg->prediction_mode;
1343 celt_dsp_cfg.celt_cfg.vbr_flag = celt_bt_cfg->vbr_flag;
1344 celt_dsp_cfg.celt_cfg.bit_rate = celt_bt_cfg->bitrate;
1345
1346 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&celt_dsp_cfg,
1347 sizeof(struct celt_enc_cfg_t));
1348 if (ret != 0) {
1349 ALOGE("%s: Failed to set CELT encoder config", __func__);
1350 is_configured = false;
1351 goto fail;
1352 }
1353 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
1354 if (!ctrl_bit_format) {
1355 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
1356 is_configured = false;
1357 goto fail;
1358 }
1359 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
1360 if (ret != 0) {
1361 ALOGE("%s: Failed to set bit format to encoder", __func__);
1362 is_configured = false;
1363 goto fail;
1364 }
1365 is_configured = true;
1366 a2dp.bt_encoder_format = ENC_CODEC_TYPE_CELT;
1367 a2dp.enc_sampling_rate = celt_bt_cfg->sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301368 a2dp.enc_channels = celt_bt_cfg->channels;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301369 ALOGV("Successfully updated CELT encformat with samplingrate: %d channels:%d",
1370 celt_dsp_cfg.custom_cfg.sample_rate, celt_dsp_cfg.custom_cfg.num_channels);
1371fail:
1372 return is_configured;
1373}
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301374
1375bool configure_ldac_enc_format(audio_ldac_encoder_config *ldac_bt_cfg)
1376{
1377 struct mixer_ctl *ldac_enc_data = NULL, *ctrl_bit_format = NULL;
1378 struct ldac_enc_cfg_t ldac_dsp_cfg;
1379 bool is_configured = false;
1380 int ret = 0;
1381 if(ldac_bt_cfg == NULL)
1382 return false;
1383
1384 ldac_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
1385 if (!ldac_enc_data) {
1386 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
1387 is_configured = false;
1388 goto fail;
1389 }
1390 memset(&ldac_dsp_cfg, 0x0, sizeof(struct ldac_enc_cfg_t));
1391
1392 ldac_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_LDAC;
1393 ldac_dsp_cfg.custom_cfg.sample_rate = ldac_bt_cfg->sampling_rate;
1394 ldac_dsp_cfg.ldac_cfg.channel_mode = ldac_bt_cfg->channel_mode;
1395 switch(ldac_dsp_cfg.ldac_cfg.channel_mode) {
1396 case 4:
1397 ldac_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
1398 ldac_dsp_cfg.custom_cfg.num_channels = 1;
1399 break;
1400 case 2:
1401 case 1:
1402 default:
1403 ldac_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
1404 ldac_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
1405 ldac_dsp_cfg.custom_cfg.num_channels = 2;
1406 break;
1407 }
1408
1409 ldac_dsp_cfg.custom_cfg.custom_size = sizeof(struct ldac_enc_cfg_t);
1410 ldac_dsp_cfg.ldac_cfg.mtu = ldac_bt_cfg->mtu;
1411 ldac_dsp_cfg.ldac_cfg.bit_rate = ldac_bt_cfg->bit_rate;
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -08001412 if (ldac_bt_cfg->is_abr_enabled) {
1413 ldac_dsp_cfg.abr_cfg.mapping_info = ldac_bt_cfg->level_to_bitrate_map;
1414 ldac_dsp_cfg.abr_cfg.imc_info.direction = IMC_RECEIVE;
1415 ldac_dsp_cfg.abr_cfg.imc_info.enable = IMC_ENABLE;
1416 ldac_dsp_cfg.abr_cfg.imc_info.purpose = IMC_PURPOSE_ID_BT_INFO;
1417 ldac_dsp_cfg.abr_cfg.imc_info.comm_instance = a2dp.abr_config.imc_instance;
1418 }
1419
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301420 ret = mixer_ctl_set_array(ldac_enc_data, (void *)&ldac_dsp_cfg,
1421 sizeof(struct ldac_enc_cfg_t));
1422 if (ret != 0) {
1423 ALOGE("%s: Failed to set LDAC encoder config", __func__);
1424 is_configured = false;
1425 goto fail;
1426 }
1427 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
1428 if (!ctrl_bit_format) {
1429 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
1430 is_configured = false;
1431 goto fail;
1432 }
1433 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
1434 if (ret != 0) {
1435 ALOGE("%s: Failed to set bit format to encoder", __func__);
1436 is_configured = false;
1437 goto fail;
1438 }
1439 is_configured = true;
1440 a2dp.bt_encoder_format = ENC_CODEC_TYPE_LDAC;
1441 a2dp.enc_sampling_rate = ldac_bt_cfg->sampling_rate;
1442 a2dp.enc_channels = ldac_dsp_cfg.custom_cfg.num_channels;
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -08001443 a2dp.abr_config.is_abr_enabled = ldac_bt_cfg->is_abr_enabled;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301444 ALOGV("Successfully updated LDAC encformat with samplingrate: %d channels:%d",
1445 ldac_dsp_cfg.custom_cfg.sample_rate, ldac_dsp_cfg.custom_cfg.num_channels);
1446fail:
1447 return is_configured;
1448}
1449
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301450bool configure_a2dp_encoder_format()
1451{
1452 void *codec_info = NULL;
1453 uint8_t multi_cast = 0, num_dev = 1;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301454 enc_codec_t codec_type = ENC_CODEC_TYPE_INVALID;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301455 bool is_configured = false;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001456 audio_aptx_encoder_config aptx_encoder_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301457
1458 if (!a2dp.audio_get_codec_config) {
1459 ALOGE(" a2dp handle is not identified, ignoring a2dp encoder config");
1460 return false;
1461 }
1462 ALOGD("configure_a2dp_encoder_format start");
1463 codec_info = a2dp.audio_get_codec_config(&multi_cast, &num_dev,
1464 &codec_type);
1465
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -08001466 // ABR disabled by default for all codecs
1467 a2dp.abr_config.is_abr_enabled = false;
1468
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301469 switch(codec_type) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301470 case ENC_CODEC_TYPE_SBC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301471 ALOGD(" Received SBC encoder supported BT device");
1472 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001473 configure_sbc_enc_format((audio_sbc_encoder_config *)codec_info);
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301474 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301475 case ENC_CODEC_TYPE_APTX:
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301476 ALOGD(" Received APTX encoder supported BT device");
Manish Dewangan6a252632017-12-04 17:27:44 +05301477#ifndef LINUX_ENABLED
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001478 a2dp.is_aptx_dual_mono_supported = false;
1479 aptx_encoder_cfg.default_cfg = (audio_aptx_default_config *)codec_info;
Manish Dewangan6a252632017-12-04 17:27:44 +05301480#endif
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301481 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001482 configure_aptx_enc_format(&aptx_encoder_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301483 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301484 case ENC_CODEC_TYPE_APTX_HD:
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301485 ALOGD(" Received APTX HD encoder supported BT device");
Manish Dewangan6a252632017-12-04 17:27:44 +05301486#ifndef LINUX_ENABLED
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301487 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001488 configure_aptx_hd_enc_format((audio_aptx_default_config *)codec_info);
Manish Dewangan6a252632017-12-04 17:27:44 +05301489#else
1490 is_configured =
1491 configure_aptx_hd_enc_format((audio_aptx_encoder_config *)codec_info);
1492#endif
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001493 break;
Manish Dewangan6a252632017-12-04 17:27:44 +05301494#ifndef LINUX_ENABLED
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001495 case ENC_CODEC_TYPE_APTX_DUAL_MONO:
1496 ALOGD(" Received APTX dual mono encoder supported BT device");
1497 a2dp.is_aptx_dual_mono_supported = true;
1498 aptx_encoder_cfg.dual_mono_cfg = (audio_aptx_dual_mono_config *)codec_info;
1499 is_configured =
1500 configure_aptx_enc_format(&aptx_encoder_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301501 break;
Manish Dewangan6a252632017-12-04 17:27:44 +05301502#endif
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301503 case ENC_CODEC_TYPE_AAC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301504 ALOGD(" Received AAC encoder supported BT device");
1505 is_configured =
1506 configure_aac_enc_format((audio_aac_encoder_config *)codec_info);
1507 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301508 case ENC_CODEC_TYPE_CELT:
1509 ALOGD(" Received CELT encoder supported BT device");
1510 is_configured =
1511 configure_celt_enc_format((audio_celt_encoder_config *)codec_info);
1512 break;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301513 case ENC_CODEC_TYPE_LDAC:
1514 ALOGD(" Received LDAC encoder supported BT device");
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -08001515 if (!instance_id || instance_id > MAX_INSTANCE_ID)
1516 instance_id = MAX_INSTANCE_ID;
1517 a2dp.abr_config.imc_instance = instance_id--;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301518 is_configured =
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -08001519 (configure_ldac_enc_format((audio_ldac_encoder_config *)codec_info) &&
1520 configure_a2dp_decoder_format(ENC_CODEC_TYPE_LDAC));
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301521 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301522 default:
1523 ALOGD(" Received Unsupported encoder formar");
1524 is_configured = false;
1525 break;
1526 }
1527 return is_configured;
1528}
1529
1530int audio_extn_a2dp_start_playback()
1531{
1532 int ret = 0;
1533
1534 ALOGD("audio_extn_a2dp_start_playback start");
1535
1536 if(!(a2dp.bt_lib_handle && a2dp.audio_start_stream
1537 && a2dp.audio_get_codec_config)) {
1538 ALOGE("a2dp handle is not identified, Ignoring start request");
1539 return -ENOSYS;
1540 }
1541
1542 if(a2dp.a2dp_suspended == true) {
1543 //session will be restarted after suspend completion
1544 ALOGD("a2dp start requested during suspend state");
Naresh Tannirucd2353e2016-08-19 00:37:25 +05301545 return -ENOSYS;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301546 }
1547
1548 if (!a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
1549 ALOGD("calling BT module stream start");
1550 /* This call indicates BT IPC lib to start playback */
1551 ret = a2dp.audio_start_stream();
1552 ALOGE("BT controller start return = %d",ret);
1553 if (ret != 0 ) {
1554 ALOGE("BT controller start failed");
1555 a2dp.a2dp_started = false;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301556 } else {
1557 if(configure_a2dp_encoder_format() == true) {
1558 a2dp.a2dp_started = true;
1559 ret = 0;
1560 ALOGD("Start playback successful to BT library");
1561 } else {
1562 ALOGD(" unable to configure DSP encoder");
1563 a2dp.a2dp_started = false;
1564 ret = -ETIMEDOUT;
1565 }
1566 }
1567 }
1568
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301569 if (a2dp.a2dp_started) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301570 a2dp.a2dp_total_active_session_request++;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301571 a2dp_check_and_set_scrambler();
1572 a2dp_set_backend_cfg();
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -08001573 if (a2dp.abr_config.is_abr_enabled)
1574 start_abr();
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301575 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301576
1577 ALOGD("start A2DP playback total active sessions :%d",
1578 a2dp.a2dp_total_active_session_request);
1579 return ret;
1580}
1581
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301582static void reset_a2dp_enc_config_params()
1583{
1584 int ret =0;
1585
1586 struct mixer_ctl *ctl_enc_config, *ctrl_bit_format;
1587 struct sbc_enc_cfg_t dummy_reset_config;
1588
1589 memset(&dummy_reset_config, 0x0, sizeof(struct sbc_enc_cfg_t));
1590 ctl_enc_config = mixer_get_ctl_by_name(a2dp.adev->mixer,
1591 MIXER_ENC_CONFIG_BLOCK);
1592 if (!ctl_enc_config) {
1593 ALOGE(" ERROR a2dp encoder format mixer control not identifed");
1594 } else {
1595 ret = mixer_ctl_set_array(ctl_enc_config, (void *)&dummy_reset_config,
1596 sizeof(struct sbc_enc_cfg_t));
1597 a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
1598 }
1599 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
1600 MIXER_ENC_BIT_FORMAT);
1601 if (!ctrl_bit_format) {
1602 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
1603 } else {
1604 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
1605 if (ret != 0) {
1606 ALOGE("%s: Failed to set bit format to encoder", __func__);
1607 }
1608 }
1609}
1610
Aniket Kumar Latae1220c32018-05-29 14:55:47 -07001611static int reset_a2dp_dec_config_params()
1612{
1613 struct mixer_ctl *ctl_dec_data = NULL;
1614 struct abr_dec_cfg_t dummy_reset_cfg;
1615 int ret = 0;
1616
1617 if (a2dp.abr_config.is_abr_enabled) {
1618 ctl_dec_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_DEC_CONFIG_BLOCK);
1619 if (!ctl_dec_data) {
1620 ALOGE("%s: ERROR A2DP decoder config mixer control not identifed", __func__);
1621 return -EINVAL;
1622 }
1623 memset(&dummy_reset_cfg, 0x0, sizeof(dummy_reset_cfg));
1624 ret = mixer_ctl_set_array(ctl_dec_data, (void *)&dummy_reset_cfg,
1625 sizeof(dummy_reset_cfg));
1626 if (ret != 0) {
1627 ALOGE("%s: Failed to set dummy decoder config", __func__);
1628 return ret;
1629 }
1630 }
1631
1632 return ret;
1633}
1634
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301635int audio_extn_a2dp_stop_playback()
1636{
1637 int ret =0;
1638
1639 ALOGV("audio_extn_a2dp_stop_playback start");
1640 if(!(a2dp.bt_lib_handle && a2dp.audio_stop_stream)) {
1641 ALOGE("a2dp handle is not identified, Ignoring start request");
1642 return -ENOSYS;
1643 }
1644
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301645 if (a2dp.a2dp_total_active_session_request > 0)
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301646 a2dp.a2dp_total_active_session_request--;
1647
1648 if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301649 ALOGV("calling BT module stream stop");
1650 ret = a2dp.audio_stop_stream();
1651 if (ret < 0)
1652 ALOGE("stop stream to BT IPC lib failed");
1653 else
1654 ALOGV("stop steam to BT IPC lib successful");
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301655 reset_a2dp_enc_config_params();
Aniket Kumar Latae1220c32018-05-29 14:55:47 -07001656 reset_a2dp_dec_config_params();
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301657 a2dp_reset_backend_cfg();
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -08001658 if (a2dp.abr_config.is_abr_enabled && a2dp.abr_config.abr_started)
1659 stop_abr();
1660 a2dp.abr_config.is_abr_enabled = false;
1661 a2dp.a2dp_started = false;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301662 }
1663 if(!a2dp.a2dp_total_active_session_request)
1664 a2dp.a2dp_started = false;
1665 ALOGD("Stop A2DP playback total active sessions :%d",
1666 a2dp.a2dp_total_active_session_request);
1667 return 0;
1668}
1669
1670void audio_extn_a2dp_set_parameters(struct str_parms *parms)
1671{
1672 int ret, val;
1673 char value[32]={0};
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301674 struct audio_usecase *uc_info;
1675 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301676
1677 if(a2dp.is_a2dp_offload_supported == false) {
1678 ALOGV("no supported encoders identified,ignoring a2dp setparam");
1679 return;
1680 }
1681
1682 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
1683 sizeof(value));
Zhou Song681350a2017-10-19 16:28:42 +08001684 if (ret >= 0) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301685 val = atoi(value);
Zhou Song681350a2017-10-19 16:28:42 +08001686 if (audio_is_a2dp_out_device(val)) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301687 ALOGV("Received device connect request for A2DP");
1688 open_a2dp_output();
1689 }
1690 goto param_handled;
1691 }
1692
1693 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
1694 sizeof(value));
1695
Zhou Song681350a2017-10-19 16:28:42 +08001696 if (ret >= 0) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301697 val = atoi(value);
Zhou Song681350a2017-10-19 16:28:42 +08001698 if (audio_is_a2dp_out_device(val)) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301699 ALOGV("Received device dis- connect request");
1700 close_a2dp_output();
kunleiz4a1fad62018-02-08 18:00:16 +08001701 reset_a2dp_enc_config_params();
Aniket Kumar Latae1220c32018-05-29 14:55:47 -07001702 reset_a2dp_dec_config_params();
kunleiz4a1fad62018-02-08 18:00:16 +08001703 a2dp_reset_backend_cfg();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301704 }
1705 goto param_handled;
1706 }
1707
1708 ret = str_parms_get_str(parms, "A2dpSuspended", value, sizeof(value));
1709 if (ret >= 0) {
1710 if (a2dp.bt_lib_handle && (a2dp.bt_state != A2DP_STATE_DISCONNECTED) ) {
1711 if ((!strncmp(value,"true",sizeof(value)))) {
1712 ALOGD("Setting a2dp to suspend state");
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301713 a2dp.a2dp_suspended = true;
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301714 list_for_each(node, &a2dp.adev->usecase_list) {
1715 uc_info = node_to_item(node, struct audio_usecase, list);
Zhou Songc66eb7e2017-08-08 18:29:07 +08001716 if (uc_info->type == PCM_PLAYBACK &&
1717 (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301718 pthread_mutex_unlock(&a2dp.adev->lock);
1719 check_a2dp_restore(a2dp.adev, uc_info->stream.out, false);
1720 pthread_mutex_lock(&a2dp.adev->lock);
1721 }
1722 }
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301723 reset_a2dp_enc_config_params();
Aniket Kumar Latae1220c32018-05-29 14:55:47 -07001724 reset_a2dp_dec_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301725 if(a2dp.audio_suspend_stream)
1726 a2dp.audio_suspend_stream();
1727 } else if (a2dp.a2dp_suspended == true) {
1728 ALOGD("Resetting a2dp suspend state");
Zhou Song10617ed2017-05-26 13:28:48 +08001729 struct audio_usecase *uc_info;
1730 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301731 if(a2dp.clear_a2dpsuspend_flag)
1732 a2dp.clear_a2dpsuspend_flag();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301733 a2dp.a2dp_suspended = false;
Naresh Tanniru649871a2016-11-04 18:08:32 +05301734 /*
1735 * It is possible that before suspend,a2dp sessions can be active
1736 * for example during music + voice activation concurrency
1737 * a2dp suspend will be called & BT will change to sco mode
1738 * though music is paused as a part of voice activation
1739 * compress session close happens only after pause timeout(10secs)
1740 * so if resume request comes before pause timeout as a2dp session
1741 * is already active IPC start will not be called from APM/audio_hw
1742 * Fix is to call a2dp start for IPC library post suspend
1743 * based on number of active session count
1744 */
1745 if (a2dp.a2dp_total_active_session_request > 0) {
1746 ALOGD(" Calling IPC lib start post suspend state");
1747 if(a2dp.audio_start_stream) {
1748 ret = a2dp.audio_start_stream();
1749 if (ret != 0) {
1750 ALOGE("BT controller start failed");
1751 a2dp.a2dp_started = false;
1752 }
1753 }
1754 }
Zhou Song10617ed2017-05-26 13:28:48 +08001755 list_for_each(node, &a2dp.adev->usecase_list) {
1756 uc_info = node_to_item(node, struct audio_usecase, list);
Zhou Songc66eb7e2017-08-08 18:29:07 +08001757 if (uc_info->type == PCM_PLAYBACK &&
1758 (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301759 pthread_mutex_unlock(&a2dp.adev->lock);
1760 check_a2dp_restore(a2dp.adev, uc_info->stream.out, true);
1761 pthread_mutex_lock(&a2dp.adev->lock);
1762 }
Zhou Song10617ed2017-05-26 13:28:48 +08001763 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301764 }
1765 }
1766 goto param_handled;
1767 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301768param_handled:
1769 ALOGV("end of a2dp setparam");
1770}
1771
Naresh Tannirucd2353e2016-08-19 00:37:25 +05301772void audio_extn_a2dp_set_handoff_mode(bool is_on)
1773{
1774 a2dp.is_handoff_in_progress = is_on;
1775}
1776
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301777bool audio_extn_a2dp_is_force_device_switch()
1778{
1779 //During encoder reconfiguration mode, force a2dp device switch
Ashish Jainc597d102016-12-12 10:31:34 +05301780 // Or if a2dp device is selected but earlier start failed ( as a2dp
1781 // was suspended, force retry.
1782 return a2dp.is_handoff_in_progress || !a2dp.a2dp_started;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301783}
1784
Preetam Singh Ranawatb7475ba2017-02-24 18:17:06 +05301785void audio_extn_a2dp_get_sample_rate(int *sample_rate)
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301786{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301787 *sample_rate = a2dp.enc_sampling_rate;
1788}
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301789
1790bool audio_extn_a2dp_is_ready()
1791{
1792 bool ret = false;
1793
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301794 if (a2dp.a2dp_suspended)
1795 return ret;
1796
Aniket Kumar Lata901bcb82017-03-10 15:42:46 -08001797 if ((a2dp.bt_state != A2DP_STATE_DISCONNECTED) &&
1798 (a2dp.is_a2dp_offload_supported) &&
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301799 (a2dp.audio_check_a2dp_ready))
1800 ret = a2dp.audio_check_a2dp_ready();
1801 return ret;
1802}
1803
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301804bool audio_extn_a2dp_is_suspended()
1805{
1806 return a2dp.a2dp_suspended;
1807}
1808
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301809void audio_extn_a2dp_init (void *adev)
1810{
1811 a2dp.adev = (struct audio_device*)adev;
1812 a2dp.bt_lib_handle = NULL;
1813 a2dp.a2dp_started = false;
1814 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
1815 a2dp.a2dp_total_active_session_request = 0;
1816 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301817 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301818 a2dp.enc_sampling_rate = 48000;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301819 a2dp.is_a2dp_offload_supported = false;
1820 a2dp.is_handoff_in_progress = false;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001821 a2dp.is_aptx_dual_mono_supported = false;
Aniket Kumar Lata7fd86e12018-02-20 19:26:10 -08001822 a2dp.abr_config.is_abr_enabled = false;
1823 a2dp.abr_config.abr_started = false;
1824 a2dp.abr_config.imc_instance = 0;
1825 a2dp.abr_config.abr_tx_handle = NULL;
kunleiz5a127262017-09-08 14:47:48 +08001826 reset_a2dp_enc_config_params();
Aniket Kumar Latae1220c32018-05-29 14:55:47 -07001827 reset_a2dp_dec_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301828 update_offload_codec_capabilities();
1829}
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001830
1831uint32_t audio_extn_a2dp_get_encoder_latency()
1832{
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001833 uint32_t latency = 0;
1834 int avsync_runtime_prop = 0;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301835 int sbc_offset = 0, aptx_offset = 0, aptxhd_offset = 0,
1836 aac_offset = 0, celt_offset = 0, ldac_offset = 0;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001837 char value[PROPERTY_VALUE_MAX];
1838
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001839 memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -07001840 avsync_runtime_prop = property_get("vendor.audio.a2dp.codec.latency", value, NULL);
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001841 if (avsync_runtime_prop > 0) {
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301842 if (sscanf(value, "%d/%d/%d/%d/%d%d",
1843 &sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset, &celt_offset, &ldac_offset) != 6) {
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001844 ALOGI("Failed to parse avsync offset params from '%s'.", value);
1845 avsync_runtime_prop = 0;
1846 }
1847 }
1848
yidongh0515e042017-07-06 15:00:34 +08001849 uint32_t slatency = 0;
1850 if (a2dp.audio_get_a2dp_sink_latency && a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
1851 slatency = a2dp.audio_get_a2dp_sink_latency();
1852 }
1853
Aniket Kumar Latafaaffde2017-03-22 19:18:15 -07001854 switch(a2dp.bt_encoder_format) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301855 case ENC_CODEC_TYPE_SBC:
yidongh0515e042017-07-06 15:00:34 +08001856 latency = (avsync_runtime_prop > 0) ? sbc_offset : ENCODER_LATENCY_SBC;
1857 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_SBC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001858 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301859 case ENC_CODEC_TYPE_APTX:
yidongh0515e042017-07-06 15:00:34 +08001860 latency = (avsync_runtime_prop > 0) ? aptx_offset : ENCODER_LATENCY_APTX;
1861 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001862 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301863 case ENC_CODEC_TYPE_APTX_HD:
yidongh0515e042017-07-06 15:00:34 +08001864 latency = (avsync_runtime_prop > 0) ? aptxhd_offset : ENCODER_LATENCY_APTX_HD;
1865 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX_HD : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001866 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301867 case ENC_CODEC_TYPE_AAC:
yidongh0515e042017-07-06 15:00:34 +08001868 latency = (avsync_runtime_prop > 0) ? aac_offset : ENCODER_LATENCY_AAC;
1869 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_AAC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001870 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301871 case ENC_CODEC_TYPE_CELT:
1872 latency = (avsync_runtime_prop > 0) ? celt_offset : ENCODER_LATENCY_CELT;
1873 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_CELT : slatency;
1874 break;
Preetam Singh Ranawatd058a3d2017-10-25 17:31:37 +05301875 case ENC_CODEC_TYPE_LDAC:
1876 latency = (avsync_runtime_prop > 0) ? ldac_offset : ENCODER_LATENCY_LDAC;
1877 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_LDAC : slatency;
1878 break;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001879 default:
1880 latency = 200;
1881 break;
1882 }
1883 return latency;
1884}
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301885#endif // SPLIT_A2DP_ENABLED