1/*
2 * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
3 * Not a Contribution.
4 *
5 * Copyright (C) 2013 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#define LOG_TAG "msm8916_platform"
21/*#define LOG_NDEBUG 0*/
22#define LOG_NDDEBUG 0
23
24#include <stdlib.h>
25#include <dlfcn.h>
26#include <fcntl.h>
27#include <sys/ioctl.h>
28#include <cutils/log.h>
29#include <cutils/properties.h>
30#include <cutils/str_parms.h>
31#include <audio_hw.h>
32#include <platform_api.h>
33#include "platform.h"
34#include "audio_extn.h"
35#include "voice_extn.h"
36#include "sound/msmcal-hwdep.h"
37#include <dirent.h>
38#define SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID (100)
39#define MAX_MIXER_XML_PATH  100
40#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
41#define MIXER_XML_PATH_MTP "/system/etc/mixer_paths_mtp.xml"
42#define MIXER_XML_PATH_SBC "/system/etc/mixer_paths_sbc.xml"
43#define MIXER_XML_PATH_MSM8909_PM8916 "/system/etc/mixer_paths_msm8909_pm8916.xml"
44#define MIXER_XML_PATH_QRD_SKUH "/system/etc/mixer_paths_qrd_skuh.xml"
45#define MIXER_XML_PATH_QRD_SKUI "/system/etc/mixer_paths_qrd_skui.xml"
46#define MIXER_XML_PATH_QRD_SKUHF "/system/etc/mixer_paths_qrd_skuhf.xml"
47#define MIXER_XML_PATH_QRD_SKUT "/system/etc/mixer_paths_qrd_skut.xml"
48#define MIXER_XML_PATH_SKUK "/system/etc/mixer_paths_skuk.xml"
49#define MIXER_XML_PATH_SKUA "/system/etc/mixer_paths_skua.xml"
50#define MIXER_XML_PATH_SKUC "/system/etc/mixer_paths_skuc.xml"
51#define MIXER_XML_PATH_SKUE "/system/etc/mixer_paths_skue.xml"
52#define MIXER_XML_PATH_SKUL "/system/etc/mixer_paths_skul.xml"
53#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
54#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
55#define MIXER_XML_PATH_WCD9306 "/system/etc/mixer_paths_wcd9306.xml"
56#define MIXER_XML_PATH_WCD9330 "/system/etc/mixer_paths_wcd9330.xml"
57#define MIXER_XML_PATH_WCD9326 "/system/etc/mixer_paths_wcd9326_i2s.xml"
58#define PLATFORM_INFO_XML_PATH      "/system/etc/audio_platform_info.xml"
59#define LIB_ACDB_LOADER "libacdbloader.so"
60#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
61#define CVD_VERSION_MIXER_CTL "CVD Version"
62
63#define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024)
64#define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024)
65#define COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING (2 * 1024)
66#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
67/* Used in calculating fragment size for pcm offload */
68#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 2000 /* 2 secs */
69#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 100 /* 100 millisecs */
70
71/* MAX PCM fragment size cannot be increased  further due
72 * to flinger's cblk size of 1mb,and it has to be a multiple of
73 * 24 - lcm of channels supported by DSP
74 */
75#define MAX_PCM_OFFLOAD_FRAGMENT_SIZE (240 * 1024)
76#define MIN_PCM_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
77
78#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
79/*
80 * This file will have a maximum of 38 bytes:
81 *
82 * 4 bytes: number of audio blocks
83 * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
84 * Maximum 10 * 3 bytes: SAD blocks
85 */
86#define MAX_SAD_BLOCKS      10
87#define SAD_BLOCK_SIZE      3
88#define MAX_CVD_VERSION_STRING_SIZE    100
89
90/* EDID format ID for LPCM audio */
91#define EDID_FORMAT_LPCM    1
92
93/* fallback app type if the default app type from acdb loader fails */
94#define DEFAULT_APP_TYPE  0x11130
95
96/* Retry for delay in FW loading*/
97#define RETRY_NUMBER 20
98#define RETRY_US 500000
99#define MAX_SND_CARD 8
100
101#define SAMPLE_RATE_8KHZ  8000
102#define SAMPLE_RATE_16KHZ 16000
103
104#define AUDIO_PARAMETER_KEY_FLUENCE_TYPE  "fluence"
105#define AUDIO_PARAMETER_KEY_SLOWTALK      "st_enable"
106#define AUDIO_PARAMETER_KEY_HD_VOICE      "hd_voice"
107#define AUDIO_PARAMETER_KEY_VOLUME_BOOST  "volume_boost"
108#define MAX_CAL_NAME 20
109#define APP_TYPE_SYSTEM_SOUNDS 0x00011131
110#define APP_TYPE_GENERAL_RECORDING 0x00011132
111
112char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = {
113        [WCD9XXX_ANC_CAL] = "anc_cal",
114        [WCD9XXX_MBHC_CAL] = "mbhc_cal",
115        [WCD9XXX_MAD_CAL] = "mad_cal",
116};
117
118#define AUDIO_PARAMETER_KEY_REC_PLAY_CONC "rec_play_conc_on"
119
120#define  AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED  "is_hw_dec_session_allowed"
121
122char * dsp_only_decoders_mime[] = {
123    "audio/x-ms-wma" /* wma*/ ,
124    "audio/x-ms-wma-lossless" /* wma lossless */ ,
125    "audio/x-ms-wma-pro" /* wma prop */ ,
126    "audio/amr-wb-plus" /* amr wb plus */ ,
127    "audio/alac"  /*alac */ ,
128    "audio/x-ape" /*ape */,
129};
130
131enum {
132	VOICE_FEATURE_SET_DEFAULT,
133	VOICE_FEATURE_SET_VOLUME_BOOST
134};
135
136struct audio_block_header
137{
138    int reserved;
139    int length;
140};
141
142/* Audio calibration related functions */
143typedef void (*acdb_deallocate_t)();
144typedef int  (*acdb_init_t)(char *, char *, int);
145typedef void (*acdb_send_audio_cal_t)(int, int, int, int);
146typedef void (*acdb_send_voice_cal_t)(int, int);
147typedef int (*acdb_reload_vocvoltable_t)(int);
148typedef int  (*acdb_get_default_app_type_t)(void);
149typedef int (*acdb_loader_get_calibration_t)(char *attr, int size, void *data);
150acdb_loader_get_calibration_t acdb_loader_get_calibration;
151
152struct platform_data {
153    struct audio_device *adev;
154    bool fluence_in_spkr_mode;
155    bool fluence_in_voice_call;
156    bool fluence_in_voice_rec;
157    bool fluence_in_audio_rec;
158    int  fluence_type;
159    char fluence_cap[PROPERTY_VALUE_MAX];
160    int  fluence_mode;
161    bool slowtalk;
162    bool hd_voice;
163    bool ec_ref_enabled;
164    bool is_acdb_initialized;
165    bool is_wsa_speaker;
166    /* Audio calibration related functions */
167    void                       *acdb_handle;
168    int                        voice_feature_set;
169    acdb_init_t                acdb_init;
170    acdb_deallocate_t          acdb_deallocate;
171    acdb_send_audio_cal_t      acdb_send_audio_cal;
172    acdb_send_voice_cal_t      acdb_send_voice_cal;
173    acdb_reload_vocvoltable_t  acdb_reload_vocvoltable;
174    acdb_get_default_app_type_t acdb_get_default_app_type;
175#ifdef RECORD_PLAY_CONCURRENCY
176    bool rec_play_conc_set;
177#endif
178    void *hw_info;
179    struct csd_data *csd;
180};
181
182static bool is_external_codec = false;
183static const int pcm_device_table_of_ext_codec[AUDIO_USECASE_MAX][2] = {
184   [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE_OF_EXT_CODEC, QCHAT_CALL_PCM_DEVICE_OF_EXT_CODEC}
185};
186
187/* List of use cases that has different PCM device ID's for internal and external codecs */
188static const int misc_usecase[AUDIO_USECASE_MAX] = { USECASE_QCHAT_CALL };
189
190static const int pcm_device_table[AUDIO_USECASE_MAX][2] = {
191    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
192                                            DEEP_BUFFER_PCM_DEVICE},
193    [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
194                                           LOWLATENCY_PCM_DEVICE},
195    [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
196                                        MULTIMEDIA2_PCM_DEVICE},
197    [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
198                     {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
199    [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
200    [USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
201    [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
202                                          LOWLATENCY_PCM_DEVICE},
203    [USECASE_AUDIO_RECORD_FM_VIRTUAL] = {MULTIMEDIA2_PCM_DEVICE,
204                                  MULTIMEDIA2_PCM_DEVICE},
205    [USECASE_AUDIO_PLAYBACK_FM] = {FM_PLAYBACK_PCM_DEVICE, FM_CAPTURE_PCM_DEVICE},
206#ifdef ASM_LOOPBACK_RX_ENABLED
207    [USECASE_AUDIO_HFP_SCO] = {HFP_ASM_RX_TX_SESSION2, HFP_ASM_RX_TX_SESSION2},
208    [USECASE_AUDIO_HFP_SCO_WB] = {HFP_ASM_RX_TX_SESSION2, HFP_ASM_RX_TX_SESSION2},
209#else
210    [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
211    [USECASE_AUDIO_HFP_SCO_WB] = {HFP_PCM_RX, HFP_SCO_RX},
212#endif
213    [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE, VOICE_CALL_PCM_DEVICE},
214    [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
215    [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
216    [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
217    [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
218    [USECASE_COMPRESS_VOIP_CALL] = {COMPRESS_VOIP_CALL_PCM_DEVICE, COMPRESS_VOIP_CALL_PCM_DEVICE},
219    [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
220                                   AUDIO_RECORD_PCM_DEVICE},
221    [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
222                                     AUDIO_RECORD_PCM_DEVICE},
223    [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
224                                                AUDIO_RECORD_PCM_DEVICE},
225    [USECASE_INCALL_REC_UPLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
226                                            COMPRESS_CAPTURE_DEVICE},
227    [USECASE_INCALL_REC_DOWNLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
228                                              COMPRESS_CAPTURE_DEVICE},
229    [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
230                                                         COMPRESS_CAPTURE_DEVICE},
231    [USECASE_INCALL_MUSIC_UPLINK] = {INCALL_MUSIC_UPLINK_PCM_DEVICE,
232                                     INCALL_MUSIC_UPLINK_PCM_DEVICE},
233    [USECASE_INCALL_MUSIC_UPLINK2] = {INCALL_MUSIC_UPLINK2_PCM_DEVICE,
234                                      INCALL_MUSIC_UPLINK2_PCM_DEVICE},
235    [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
236    [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
237};
238
239/* Array to store sound devices */
240static const char * const device_table[SND_DEVICE_MAX] = {
241    [SND_DEVICE_NONE] = "none",
242    /* Playback sound devices */
243    [SND_DEVICE_OUT_HANDSET] = "handset",
244    [SND_DEVICE_OUT_SPEAKER] = "speaker",
245    [SND_DEVICE_OUT_SPEAKER_WSA] = "wsa-speaker",
246    [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
247    [SND_DEVICE_OUT_HEADPHONES] = "headphones",
248    [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
249    [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
250    [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
251    [SND_DEVICE_OUT_VOICE_SPEAKER_WSA] = "wsa-voice-speaker",
252    [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
253    [SND_DEVICE_OUT_HDMI] = "hdmi",
254    [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
255    [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
256    [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
257    [SND_DEVICE_OUT_BT_A2DP] = "bt-a2dp",
258    [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = "speaker-and-bt-a2dp",
259    [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
260    [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
261    [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
262    [SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy",
263    [SND_DEVICE_OUT_USB_HEADSET] = "usb-headphones",
264    [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
265    [SND_DEVICE_OUT_TRANSMISSION_FM] = "transmission-fm",
266    [SND_DEVICE_OUT_ANC_HEADSET] = "anc-headphones",
267    [SND_DEVICE_OUT_ANC_FB_HEADSET] = "anc-fb-headphones",
268    [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = "voice-anc-headphones",
269    [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = "voice-anc-fb-headphones",
270    [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = "speaker-and-anc-headphones",
271    [SND_DEVICE_OUT_ANC_HANDSET] = "anc-handset",
272    [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
273#ifdef RECORD_PLAY_CONCURRENCY
274    [SND_DEVICE_OUT_VOIP_HANDSET] = "voip-handset",
275    [SND_DEVICE_OUT_VOIP_SPEAKER] = "voip-speaker",
276    [SND_DEVICE_OUT_VOIP_HEADPHONES] = "voip-headphones",
277#endif
278
279    /* Capture sound devices */
280    [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
281    [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
282    [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
283    [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
284    [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
285    [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
286    [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
287    [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
288    [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
289    [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
290    [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
291    [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
292    [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
293    [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
294    [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
295    [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
296    [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
297    [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = "headset-mic",
298    [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
299    [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
300    [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
301    [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
302    [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
303    [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
304    [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
305    [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
306    [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
307    [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
308    [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = "voice-speaker-qmic",
309    [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
310    [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
311    [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
312    [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
313    [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
314    [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
315    [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
316    [SND_DEVICE_IN_USB_HEADSET_MIC] = "usb-headset-mic",
317    [SND_DEVICE_IN_CAPTURE_FM] = "capture-fm",
318    [SND_DEVICE_IN_AANC_HANDSET_MIC] = "aanc-handset-mic",
319    [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
320    [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = "handset-stereo-dmic-ef",
321    [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = "speaker-stereo-dmic-ef",
322    [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
323    [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE] = "voice-speaker-dmic-broadside",
324    [SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE] = "speaker-dmic-broadside",
325    [SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE] = "speaker-dmic-broadside",
326    [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = "speaker-dmic-broadside",
327    [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = "speaker-dmic-broadside",
328    [SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC] = "aanc-fluence-dmic-handset",
329    [SND_DEVICE_IN_HANDSET_QMIC] = "quad-mic",
330    [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = "quad-mic",
331    [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
332    [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
333};
334
335/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
336static int acdb_device_table[SND_DEVICE_MAX] = {
337    [SND_DEVICE_NONE] = -1,
338    [SND_DEVICE_OUT_HANDSET] = 7,
339    [SND_DEVICE_OUT_SPEAKER] = 14,
340    [SND_DEVICE_OUT_SPEAKER_WSA] = 135,
341    [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
342    [SND_DEVICE_OUT_HEADPHONES] = 10,
343    [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
344    [SND_DEVICE_OUT_VOICE_HANDSET] = 7,
345    [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
346    [SND_DEVICE_OUT_VOICE_SPEAKER_WSA] = 135,
347    [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
348    [SND_DEVICE_OUT_HDMI] = 18,
349    [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
350    [SND_DEVICE_OUT_BT_SCO] = 22,
351    [SND_DEVICE_OUT_BT_SCO_WB] = 39,
352    [SND_DEVICE_OUT_BT_A2DP] = 20,
353    [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = 14,
354    [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
355    [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
356    [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
357    [SND_DEVICE_OUT_AFE_PROXY] = 0,
358    [SND_DEVICE_OUT_USB_HEADSET] = 45,
359    [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
360    [SND_DEVICE_OUT_TRANSMISSION_FM] = 0,
361    [SND_DEVICE_OUT_ANC_HEADSET] = 26,
362    [SND_DEVICE_OUT_ANC_FB_HEADSET] = 27,
363    [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = 26,
364    [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = 27,
365    [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = 26,
366    [SND_DEVICE_OUT_ANC_HANDSET] = 103,
367    [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 101,
368#ifdef RECORD_PLAY_CONCURRENCY
369    [SND_DEVICE_OUT_VOIP_HANDSET] = 133,
370    [SND_DEVICE_OUT_VOIP_SPEAKER] = 132,
371    [SND_DEVICE_OUT_VOIP_HEADPHONES] = 134,
372#endif
373
374    [SND_DEVICE_IN_HANDSET_MIC] = 4,
375    [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
376    [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
377    [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
378    [SND_DEVICE_IN_HANDSET_DMIC] = 41,
379    [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
380    [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
381    [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
382    [SND_DEVICE_IN_SPEAKER_MIC] = 11,
383    [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
384    [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
385    [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
386    [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
387    [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
388    [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
389    [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
390    [SND_DEVICE_IN_HEADSET_MIC] = 8,
391    [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = 47,
392    [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
393    [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
394    [SND_DEVICE_IN_HDMI_MIC] = 4,
395    [SND_DEVICE_IN_BT_SCO_MIC] = 21,
396    [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 122,
397    [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
398    [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 123,
399    [SND_DEVICE_IN_CAMCORDER_MIC] = 4,
400    [SND_DEVICE_IN_VOICE_DMIC] = 41,
401    [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
402    [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = 19,
403    [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
404    [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
405    [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
406    [SND_DEVICE_IN_VOICE_REC_MIC] = 4,
407    [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107,
408    [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34,
409    [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 41,
410    [SND_DEVICE_IN_USB_HEADSET_MIC] = 44,
411    [SND_DEVICE_IN_CAPTURE_FM] = 0,
412    [SND_DEVICE_IN_AANC_HANDSET_MIC] = 104,
413    [SND_DEVICE_IN_QUAD_MIC] = 46,
414    [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = 34,
415    [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = 35,
416    [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
417    [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE] = 12,
418    [SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE] = 12,
419    [SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE] = 119,
420    [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = 121,
421    [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = 120,
422    [SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC] = 135,
423    [SND_DEVICE_IN_HANDSET_QMIC] = 125,
424    [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
425    [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
426    [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
427};
428
429struct snd_device_index {
430    char name[100];
431    unsigned int index;
432};
433
434#define TO_NAME_INDEX(X)   #X, X
435
436/* Used to get index from parsed sting */
437struct snd_device_index snd_device_name_index[SND_DEVICE_MAX] = {
438    {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
439    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
440    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_WSA)},
441    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
442    {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
443    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
444    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
445    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
446    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_WSA)},
447    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
448    {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
449    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
450    {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
451    {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
452    {TO_NAME_INDEX(SND_DEVICE_OUT_BT_A2DP)},
453    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP)},
454    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
455    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
456    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
457    {TO_NAME_INDEX(SND_DEVICE_OUT_AFE_PROXY)},
458    {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET)},
459    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)},
460    {TO_NAME_INDEX(SND_DEVICE_OUT_TRANSMISSION_FM)},
461    {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_HEADSET)},
462    {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_FB_HEADSET)},
463    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_ANC_HEADSET)},
464    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET)},
465    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET)},
466    {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_HANDSET)},
467    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
468#ifdef RECORD_PLAY_CONCURRENCY
469    {TO_NAME_INDEX(SND_DEVICE_OUT_VOIP_HANDSET)},
470    {TO_NAME_INDEX(SND_DEVICE_OUT_VOIP_SPEAKER)},
471    {TO_NAME_INDEX(SND_DEVICE_OUT_VOIP_HEADPHONES)},
472#endif
473    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
474    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
475    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
476    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
477    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
478    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
479    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
480    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
481    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
482    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
483    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
484    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
485    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
486    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
487    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
488    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
489    {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
490    {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_FLUENCE)},
491    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
492    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
493    {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
494    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
495    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
496    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
497    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
498    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
499    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
500    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
501    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_QMIC)},
502    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
503    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
504    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
505    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
506    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
507    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
508    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
509    {TO_NAME_INDEX(SND_DEVICE_IN_USB_HEADSET_MIC)},
510    {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_FM)},
511    {TO_NAME_INDEX(SND_DEVICE_IN_AANC_HANDSET_MIC)},
512    {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
513    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_STEREO_DMIC)},
514    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_STEREO_DMIC)},
515    {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
516    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC)},
517    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
518    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
519    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
520    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
521};
522
523#define NO_COLS 2
524static int msm_be_id_array_len;
525static int (*msm_device_to_be_id)[];
526
527/* Below table lists output device to BE_ID mapping*/
528/* Update the table based on the board configuration*/
529
530static int msm_device_to_be_id_internal_codec [][NO_COLS] = {
531       {AUDIO_DEVICE_OUT_EARPIECE                       ,       34},
532       {AUDIO_DEVICE_OUT_SPEAKER                        ,       34},
533       {AUDIO_DEVICE_OUT_WIRED_HEADSET                  ,       34},
534       {AUDIO_DEVICE_OUT_WIRED_HEADPHONE                ,       34},
535       {AUDIO_DEVICE_OUT_BLUETOOTH_SCO                  ,       11},
536       {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET          ,       11},
537       {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT           ,       11},
538       {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP                 ,       -1},
539       {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES      ,       -1},
540       {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER         ,       -1},
541       {AUDIO_DEVICE_OUT_AUX_DIGITAL                    ,       4},
542       {AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET              ,       9},
543       {AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET              ,       9},
544       {AUDIO_DEVICE_OUT_USB_ACCESSORY                  ,       -1},
545       {AUDIO_DEVICE_OUT_USB_DEVICE                     ,       -1},
546       {AUDIO_DEVICE_OUT_REMOTE_SUBMIX                  ,       9},
547       {AUDIO_DEVICE_OUT_PROXY                          ,       9},
548       {AUDIO_DEVICE_OUT_FM                             ,       7},
549       {AUDIO_DEVICE_OUT_FM_TX                          ,       8},
550       {AUDIO_DEVICE_OUT_ALL                            ,      -1},
551       {AUDIO_DEVICE_NONE                               ,      -1},
552       {AUDIO_DEVICE_OUT_DEFAULT                        ,      -1},
553};
554
555static int msm_device_to_be_id_external_codec [][NO_COLS] = {
556       {AUDIO_DEVICE_OUT_EARPIECE                       ,       2},
557       {AUDIO_DEVICE_OUT_SPEAKER                        ,       2},
558       {AUDIO_DEVICE_OUT_WIRED_HEADSET                  ,       2},
559       {AUDIO_DEVICE_OUT_WIRED_HEADPHONE                ,       2},
560       {AUDIO_DEVICE_OUT_BLUETOOTH_SCO                  ,       11},
561       {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET          ,       11},
562       {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT           ,       11},
563       {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP                 ,       -1},
564       {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES      ,       -1},
565       {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER         ,       -1},
566       {AUDIO_DEVICE_OUT_AUX_DIGITAL                    ,       4},
567       {AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET              ,       9},
568       {AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET              ,       9},
569       {AUDIO_DEVICE_OUT_USB_ACCESSORY                  ,       -1},
570       {AUDIO_DEVICE_OUT_USB_DEVICE                     ,       -1},
571       {AUDIO_DEVICE_OUT_REMOTE_SUBMIX                  ,       9},
572       {AUDIO_DEVICE_OUT_PROXY                          ,       9},
573       {AUDIO_DEVICE_OUT_FM                             ,       7},
574       {AUDIO_DEVICE_OUT_FM_TX                          ,       8},
575       {AUDIO_DEVICE_OUT_ALL                            ,      -1},
576       {AUDIO_DEVICE_NONE                               ,      -1},
577       {AUDIO_DEVICE_OUT_DEFAULT                        ,      -1},
578};
579
580
581#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
582#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
583
584static bool is_misc_usecase(audio_usecase_t usecase) {
585     bool ret = false;
586     int i;
587
588     for (i = 0; i < AUDIO_USECASE_MAX; i++) {
589          if(usecase == misc_usecase[i]) {
590             ret = true;
591             break;
592          }
593     }
594     return ret;
595}
596
597static void update_codec_type(const char *snd_card_name) {
598
599     if (!strncmp(snd_card_name, "msm8939-tapan-snd-card",
600                  sizeof("msm8939-tapan-snd-card")) ||
601         !strncmp(snd_card_name, "msm8939-tapan9302-snd-card",
602                  sizeof("msm8939-tapan9302-snd-card"))||
603         !strncmp(snd_card_name, "msm8939-tomtom9330-snd-card",
604                  sizeof("msm8939-tomtom9330-snd-card")) ||
605         !strncmp(snd_card_name, "msm8x09-tasha9326-snd-card",
606                  sizeof("msm8x09-tasha9326-snd-card"))) {
607         ALOGI("%s: snd_card_name: %s",__func__,snd_card_name);
608         is_external_codec = true;
609     }
610}
611
612static void query_platform(const char *snd_card_name,
613                                      char *mixer_xml_path)
614{
615    if (!strncmp(snd_card_name, "msm8x16-snd-card-mtp",
616                 sizeof("msm8x16-snd-card-mtp"))) {
617        strlcpy(mixer_xml_path, MIXER_XML_PATH_MTP,
618                sizeof(MIXER_XML_PATH_MTP));
619
620        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
621        msm_be_id_array_len  =
622            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
623
624    } else if (!strncmp(snd_card_name, "msm8x16-snd-card-sbc",
625                 sizeof("msm8x16-snd-card-sbc"))) {
626        strlcpy(mixer_xml_path, MIXER_XML_PATH_SBC,
627                sizeof(MIXER_XML_PATH_SBC));
628
629        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
630        msm_be_id_array_len  =
631            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
632
633    } else if (!strncmp(snd_card_name, "msm8x16-skuh-snd-card",
634                 sizeof("msm8x16-skuh-snd-card"))) {
635        strlcpy(mixer_xml_path, MIXER_XML_PATH_QRD_SKUH,
636                sizeof(MIXER_XML_PATH_QRD_SKUH));
637
638        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
639        msm_be_id_array_len  =
640            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
641
642    } else if (!strncmp(snd_card_name, "msm8x16-skui-snd-card",
643                 sizeof("msm8x16-skui-snd-card"))) {
644        strlcpy(mixer_xml_path, MIXER_XML_PATH_QRD_SKUI,
645                sizeof(MIXER_XML_PATH_QRD_SKUI));
646
647        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
648        msm_be_id_array_len  =
649            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
650
651    } else if (!strncmp(snd_card_name, "msm8x16-skuhf-snd-card",
652                 sizeof("msm8x16-skuhf-snd-card"))) {
653        strlcpy(mixer_xml_path, MIXER_XML_PATH_QRD_SKUHF,
654                sizeof(MIXER_XML_PATH_QRD_SKUHF));
655
656        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
657        msm_be_id_array_len  =
658            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
659
660    } else if (!strncmp(snd_card_name, "msm8939-snd-card-mtp",
661                 sizeof("msm8939-snd-card-mtp"))) {
662        strlcpy(mixer_xml_path, MIXER_XML_PATH_MTP,
663                sizeof(MIXER_XML_PATH_MTP));
664
665        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
666        msm_be_id_array_len  =
667            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
668
669    } else if (!strncmp(snd_card_name, "msm8939-snd-card-skuk",
670                 sizeof("msm8939-snd-card-skuk"))) {
671        strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUK,
672                sizeof(MIXER_XML_PATH_SKUK));
673        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
674        msm_be_id_array_len  =
675            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
676
677    } else if (!strncmp(snd_card_name, "msm8939-tapan-snd-card",
678                 sizeof("msm8939-tapan-snd-card"))) {
679        strlcpy(mixer_xml_path, MIXER_XML_PATH_WCD9306,
680                sizeof(MIXER_XML_PATH_WCD9306));
681        msm_device_to_be_id = msm_device_to_be_id_external_codec;
682        msm_be_id_array_len  =
683            sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_external_codec[0]);
684
685    } else if (!strncmp(snd_card_name, "msm8939-tapan9302-snd-card",
686                 sizeof("msm8939-tapan9302-snd-card"))) {
687        strlcpy(mixer_xml_path, MIXER_XML_PATH_WCD9306,
688                sizeof(MIXER_XML_PATH_WCD9306));
689
690        msm_device_to_be_id = msm_device_to_be_id_external_codec;
691        msm_be_id_array_len  =
692            sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_external_codec[0]);
693
694    } else if (!strncmp(snd_card_name, "msm8939-tomtom9330-snd-card",
695                 sizeof("msm8939-tomtom9330-snd-card"))) {
696        strlcpy(mixer_xml_path, MIXER_XML_PATH_WCD9330,
697                sizeof(MIXER_XML_PATH_WCD9330));
698        msm_device_to_be_id = msm_device_to_be_id_external_codec;
699        msm_be_id_array_len  =
700            sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_external_codec[0]);
701    } else if (!strncmp(snd_card_name, "msm8x09-tasha9326-snd-card",
702                 sizeof("msm8x09-tasha9326-snd-card"))) {
703        strlcpy(mixer_xml_path, MIXER_XML_PATH_WCD9326,
704               MAX_MIXER_XML_PATH);
705        msm_device_to_be_id = msm_device_to_be_id_external_codec;
706        msm_be_id_array_len  =
707            sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_external_codec[0]);
708    } else if (!strncmp(snd_card_name, "msm8909-skua-snd-card",
709                sizeof("msm8909-skua-snd-card"))) {
710        strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUA,
711                sizeof(MIXER_XML_PATH_SKUA));
712        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
713        msm_be_id_array_len  =
714            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
715
716    } else if (!strncmp(snd_card_name, "msm8909-skuc-snd-card",
717                 sizeof("msm8909-skuc-snd-card"))) {
718        strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUC,
719                sizeof(MIXER_XML_PATH_SKUC));
720        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
721        msm_be_id_array_len  =
722            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
723
724    } else if (!strncmp(snd_card_name, "msm8909-skut-snd-card",
725                 sizeof("msm8909-skut-snd-card"))) {
726        strlcpy(mixer_xml_path, MIXER_XML_PATH_QRD_SKUT,
727                sizeof(MIXER_XML_PATH_QRD_SKUT));
728        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
729        msm_be_id_array_len  =
730            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
731
732    } else if (!strncmp(snd_card_name, "msm8909-pm8916-snd-card",
733                 sizeof("msm8909-pm8916-snd-card"))) {
734        strlcpy(mixer_xml_path, MIXER_XML_PATH_MSM8909_PM8916,
735                sizeof(MIXER_XML_PATH_MSM8909_PM8916));
736        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
737        msm_be_id_array_len  =
738            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
739
740    } else if (!strncmp(snd_card_name, "msm8909-skue-snd-card",
741                 sizeof("msm8909-skue-snd-card"))) {
742        strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUE,
743                sizeof(MIXER_XML_PATH_SKUE));
744        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
745        msm_be_id_array_len  =
746            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
747
748    } else if (!strncmp(snd_card_name, "msm8939-snd-card-skul",
749                 sizeof("msm8939-snd-card-skul"))) {
750        strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUL,
751                sizeof(MIXER_XML_PATH_SKUL));
752        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
753        msm_be_id_array_len  =
754            sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
755    } else {
756        strlcpy(mixer_xml_path, MIXER_XML_PATH,
757                sizeof(MIXER_XML_PATH));
758
759        msm_device_to_be_id = msm_device_to_be_id_internal_codec;
760        msm_be_id_array_len  =
761            sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
762
763    }
764}
765
766void platform_set_echo_reference(void *platform, bool enable)
767{
768    struct platform_data *my_data = (struct platform_data *)platform;
769    struct audio_device *adev = my_data->adev;
770
771    if (my_data->ec_ref_enabled) {
772        my_data->ec_ref_enabled = false;
773        ALOGD("%s: disabling echo-reference", __func__);
774        audio_route_reset_and_update_path(adev->audio_route, "echo-reference");
775    }
776
777    if (enable) {
778        my_data->ec_ref_enabled = true;
779        ALOGD("%s: enabling echo-reference", __func__);
780        audio_route_apply_and_update_path(adev->audio_route, "echo-reference");
781    }
782
783}
784
785static struct csd_data *open_csd_client()
786{
787    struct csd_data *csd = calloc(1, sizeof(struct csd_data));
788    if (!csd) {
789        ALOGE("failed to allocate csd_data mem");
790        return NULL;
791    }
792
793    csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
794    if (csd->csd_client == NULL) {
795        ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
796        goto error;
797    } else {
798        ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
799
800        csd->deinit = (deinit_t)dlsym(csd->csd_client,
801                                             "csd_client_deinit");
802        if (csd->deinit == NULL) {
803            ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
804                  dlerror());
805            goto error;
806        }
807        csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
808                                             "csd_client_disable_device");
809        if (csd->disable_device == NULL) {
810            ALOGE("%s: dlsym error %s for csd_client_disable_device",
811                  __func__, dlerror());
812            goto error;
813        }
814        csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
815                                               "csd_client_enable_device_config");
816        if (csd->enable_device_config == NULL) {
817            ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
818                  __func__, dlerror());
819            goto error;
820        }
821        csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
822                                             "csd_client_enable_device");
823        if (csd->enable_device == NULL) {
824            ALOGE("%s: dlsym error %s for csd_client_enable_device",
825                  __func__, dlerror());
826            goto error;
827        }
828        csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
829                                             "csd_client_start_voice");
830        if (csd->start_voice == NULL) {
831            ALOGE("%s: dlsym error %s for csd_client_start_voice",
832                  __func__, dlerror());
833            goto error;
834        }
835        csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
836                                             "csd_client_stop_voice");
837        if (csd->stop_voice == NULL) {
838            ALOGE("%s: dlsym error %s for csd_client_stop_voice",
839                  __func__, dlerror());
840            goto error;
841        }
842        csd->volume = (volume_t)dlsym(csd->csd_client,
843                                             "csd_client_volume");
844        if (csd->volume == NULL) {
845            ALOGE("%s: dlsym error %s for csd_client_volume",
846                  __func__, dlerror());
847            goto error;
848        }
849        csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
850                                             "csd_client_mic_mute");
851        if (csd->mic_mute == NULL) {
852            ALOGE("%s: dlsym error %s for csd_client_mic_mute",
853                  __func__, dlerror());
854            goto error;
855        }
856        csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
857                                             "csd_client_slow_talk");
858        if (csd->slow_talk == NULL) {
859            ALOGE("%s: dlsym error %s for csd_client_slow_talk",
860                  __func__, dlerror());
861            goto error;
862        }
863        csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
864                                             "csd_client_start_playback");
865        if (csd->start_playback == NULL) {
866            ALOGE("%s: dlsym error %s for csd_client_start_playback",
867                  __func__, dlerror());
868            goto error;
869        }
870        csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
871                                             "csd_client_stop_playback");
872        if (csd->stop_playback == NULL) {
873            ALOGE("%s: dlsym error %s for csd_client_stop_playback",
874                  __func__, dlerror());
875            goto error;
876        }
877        csd->set_lch = (set_lch_t)dlsym(csd->csd_client, "csd_client_set_lch");
878        if (csd->set_lch == NULL) {
879            ALOGE("%s: dlsym error %s for csd_client_set_lch",
880                  __func__, dlerror());
881            /* Ignore the error as this is not mandatory function for
882             * basic voice call to work.
883             */
884        }
885        csd->start_record = (start_record_t)dlsym(csd->csd_client,
886                                             "csd_client_start_record");
887        if (csd->start_record == NULL) {
888            ALOGE("%s: dlsym error %s for csd_client_start_record",
889                  __func__, dlerror());
890            goto error;
891        }
892        csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
893                                             "csd_client_stop_record");
894        if (csd->stop_record == NULL) {
895            ALOGE("%s: dlsym error %s for csd_client_stop_record",
896                  __func__, dlerror());
897            goto error;
898        }
899        csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
900
901        if (csd->init == NULL) {
902            ALOGE("%s: dlsym error %s for csd_client_init",
903                  __func__, dlerror());
904            goto error;
905        } else {
906            csd->init();
907        }
908    }
909    return csd;
910
911error:
912    free(csd);
913    csd = NULL;
914    return csd;
915}
916
917void close_csd_client(struct csd_data *csd)
918{
919    if (csd != NULL) {
920        csd->deinit();
921        dlclose(csd->csd_client);
922        free(csd);
923        csd = NULL;
924    }
925}
926
927void get_cvd_version(char *cvd_version, struct audio_device *adev)
928{
929    struct mixer_ctl *ctl;
930    int count;
931    int ret = 0;
932
933    ctl = mixer_get_ctl_by_name(adev->mixer, CVD_VERSION_MIXER_CTL);
934    if (!ctl) {
935        ALOGE("%s: Could not get ctl for mixer cmd - %s",  __func__, CVD_VERSION_MIXER_CTL);
936        goto done;
937    }
938    mixer_ctl_update(ctl);
939
940    count = mixer_ctl_get_num_values(ctl);
941    if (count > MAX_CVD_VERSION_STRING_SIZE)
942        count = MAX_CVD_VERSION_STRING_SIZE;
943
944    ret = mixer_ctl_get_array(ctl, cvd_version, count);
945    if (ret != 0) {
946        ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
947        goto done;
948    }
949
950done:
951    return;
952}
953
954static int hw_util_open(int card_no)
955{
956    int fd = -1;
957    char dev_name[256];
958
959    snprintf(dev_name, sizeof(dev_name), "/dev/snd/hwC%uD%u",
960                               card_no, WCD9XXX_CODEC_HWDEP_NODE);
961    ALOGD("%s Opening device %s\n", __func__, dev_name);
962    fd = open(dev_name, O_WRONLY);
963    if (fd < 0) {
964        ALOGE("%s: cannot open device '%s'\n", __func__, dev_name);
965        return fd;
966    }
967    ALOGD("%s success", __func__);
968    return fd;
969}
970
971struct param_data {
972    int    use_case;
973    int    acdb_id;
974    int    get_size;
975    int    buff_size;
976    int    data_size;
977    void   *buff;
978};
979
980static int send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration, int fd)
981{
982    int ret = 0, type;
983
984    for (type = WCD9XXX_ANC_CAL; type < WCD9XXX_MAX_CAL; type++) {
985        struct wcdcal_ioctl_buffer codec_buffer;
986        struct param_data calib;
987
988        if (!strcmp(cal_name_info[type], "mad_cal"))
989            calib.acdb_id = SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID;
990        calib.get_size = 1;
991        ret = acdb_loader_get_calibration(cal_name_info[type], sizeof(struct param_data),
992                                                                 &calib);
993        if (ret < 0) {
994            ALOGE("%s get_calibration failed\n", __func__);
995            return ret;
996        }
997        calib.get_size = 0;
998        calib.buff = malloc(calib.buff_size);
999        if(calib.buff == NULL) {
1000            ALOGE("%s mem allocation for %d bytes for %s failed\n"
1001                , __func__, calib.buff_size, cal_name_info[type]);
1002            return -1;
1003        }
1004        ret = acdb_loader_get_calibration(cal_name_info[type],
1005                              sizeof(struct param_data), &calib);
1006        if (ret < 0) {
1007            ALOGE("%s get_calibration failed type=%s calib.size=%d\n"
1008                , __func__, cal_name_info[type], codec_buffer.size);
1009            free(calib.buff);
1010            return ret;
1011        }
1012        codec_buffer.buffer = calib.buff;
1013        codec_buffer.size = calib.data_size;
1014        codec_buffer.cal_type = type;
1015        if (ioctl(fd, SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE, &codec_buffer) < 0)
1016            ALOGE("Failed to call ioctl  for %s err=%d calib.size=%d",
1017                cal_name_info[type], errno, codec_buffer.size);
1018        ALOGD("%s cal sent for %s calib.size=%d"
1019            , __func__, cal_name_info[type], codec_buffer.size);
1020        free(calib.buff);
1021    }
1022    return ret;
1023}
1024
1025static void audio_hwdep_send_cal(struct platform_data *plat_data)
1026{
1027    int fd;
1028
1029    fd = hw_util_open(plat_data->adev->snd_card);
1030    if (fd == -1) {
1031        ALOGE("%s error open\n", __func__);
1032        return;
1033    }
1034
1035    acdb_loader_get_calibration = (acdb_loader_get_calibration_t)
1036          dlsym(plat_data->acdb_handle, "acdb_loader_get_calibration");
1037
1038    if (acdb_loader_get_calibration == NULL) {
1039        ALOGE("%s: ERROR. dlsym Error:%s acdb_loader_get_calibration", __func__,
1040           dlerror());
1041        close(fd);
1042        return;
1043    }
1044    if (send_codec_cal(acdb_loader_get_calibration, fd) < 0)
1045        ALOGE("%s: Could not send anc cal", __FUNCTION__);
1046    close(fd);
1047}
1048
1049int platform_acdb_init(void *platform)
1050{
1051    struct platform_data *my_data = (struct platform_data *)platform;
1052    char *cvd_version = NULL;
1053    int key = 0;
1054    const char *snd_card_name;
1055    int result;
1056    char value[PROPERTY_VALUE_MAX];
1057    cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
1058    if (!cvd_version)
1059        ALOGE("Failed to allocate cvd version");
1060    else
1061        get_cvd_version(cvd_version, my_data->adev);
1062
1063    property_get("audio.ds1.metainfo.key",value,"0");
1064    key = atoi(value);
1065    snd_card_name = mixer_get_name(my_data->adev->mixer);
1066    result = my_data->acdb_init(snd_card_name, cvd_version, key);
1067    if (cvd_version)
1068        free(cvd_version);
1069    if (!result) {
1070        my_data->is_acdb_initialized = true;
1071        ALOGD("ACDB initialized");
1072        audio_hwdep_send_cal(my_data);
1073    } else {
1074        my_data->is_acdb_initialized = false;
1075        ALOGD("ACDB initialization failed");
1076    }
1077    return result;
1078}
1079
1080#define MAX_PATH             (256)
1081#define THERMAL_SYSFS "/sys/class/thermal"
1082#define TZ_TYPE "/sys/class/thermal/thermal_zone%d/type"
1083#define TZ_WSA "/sys/class/thermal/thermal_zone%d/temp"
1084
1085static bool is_wsa_found(int *wsaCount)
1086{
1087    DIR *tdir = NULL;
1088    struct dirent *tdirent = NULL;
1089    int tzn = 0;
1090    char name[MAX_PATH] = {0};
1091    char cwd[MAX_PATH] = {0};
1092    char file[10] = "wsa";
1093    bool found = false;
1094    int wsa_count = 0;
1095
1096    if (!getcwd(cwd, sizeof(cwd)))
1097        return false;
1098
1099    chdir(THERMAL_SYSFS); /* Change dir to read the entries. Doesnt work
1100                             otherwise */
1101    tdir = opendir(THERMAL_SYSFS);
1102    if (!tdir) {
1103        ALOGE("Unable to open %s\n", THERMAL_SYSFS);
1104        return false;
1105    }
1106
1107    while ((tdirent = readdir(tdir))) {
1108        char buf[50];
1109        struct dirent *tzdirent;
1110        DIR *tzdir = NULL;
1111
1112        tzdir = opendir(tdirent->d_name);
1113        if (!tzdir)
1114            continue;
1115        while ((tzdirent = readdir(tzdir))) {
1116            if (strcmp(tzdirent->d_name, "type"))
1117                continue;
1118            snprintf(name, MAX_PATH, TZ_TYPE, tzn);
1119            ALOGD("Opening %s\n", name);
1120            read_line_from_file(name, buf, sizeof(buf));
1121            if (strstr(buf, file)) {
1122                wsa_count++;
1123                /*We support max only two WSA speakers*/
1124                if (wsa_count == 2)
1125                    break;
1126            }
1127            tzn++;
1128        }
1129        closedir(tzdir);
1130    }
1131    if (wsa_count > 0){
1132         ALOGD("Found %d WSA present on the platform", wsa_count);
1133         found = true;
1134         *wsaCount = wsa_count;
1135    }
1136    closedir(tdir);
1137    chdir(cwd); /* Restore current working dir */
1138    return found;
1139}
1140
1141void *platform_init(struct audio_device *adev)
1142{
1143    char platform[PROPERTY_VALUE_MAX];
1144    char baseband[PROPERTY_VALUE_MAX];
1145    char value[PROPERTY_VALUE_MAX];
1146    struct platform_data *my_data = NULL;
1147    int retry_num = 0, snd_card_num = 0, key = 0;
1148    const char *snd_card_name;
1149    char mixer_xml_path[100],ffspEnable[PROPERTY_VALUE_MAX];
1150    char *cvd_version = NULL;
1151    int wsaCount =0;
1152
1153    my_data = calloc(1, sizeof(struct platform_data));
1154    if (!my_data) {
1155        ALOGE("failed to allocate platform data");
1156        return NULL;
1157    }
1158
1159    while (snd_card_num < MAX_SND_CARD) {
1160        adev->mixer = mixer_open(snd_card_num);
1161
1162        while (!adev->mixer && retry_num < RETRY_NUMBER) {
1163            usleep(RETRY_US);
1164            adev->mixer = mixer_open(snd_card_num);
1165            retry_num++;
1166        }
1167
1168        if (!adev->mixer) {
1169            ALOGE("%s: Unable to open the mixer card: %d", __func__,
1170                   snd_card_num);
1171            retry_num = 0;
1172            snd_card_num++;
1173            continue;
1174        }
1175
1176        snd_card_name = mixer_get_name(adev->mixer);
1177        ALOGV("%s: snd_card_name: %s", __func__, snd_card_name);
1178
1179        my_data->hw_info = hw_info_init(snd_card_name);
1180        if (!my_data->hw_info) {
1181            ALOGE("%s: Failed to init hardware info", __func__);
1182        } else {
1183            query_platform(snd_card_name, mixer_xml_path);
1184            ALOGD("%s: mixer path file is %s", __func__,
1185                                    mixer_xml_path);
1186            if (audio_extn_read_xml(adev, snd_card_num, mixer_xml_path,
1187                                    MIXER_XML_PATH_AUXPCM) == -ENOSYS) {
1188                adev->audio_route = audio_route_init(snd_card_num,
1189                                                 mixer_xml_path);
1190            }
1191            if (!adev->audio_route) {
1192                ALOGE("%s: Failed to init audio route controls, aborting.",
1193                       __func__);
1194                free(my_data);
1195                mixer_close(adev->mixer);
1196                return NULL;
1197            }
1198            adev->snd_card = snd_card_num;
1199            update_codec_type(snd_card_name);
1200            ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
1201            break;
1202        }
1203        retry_num = 0;
1204        snd_card_num++;
1205        mixer_close(adev->mixer);
1206    }
1207
1208    if (snd_card_num >= MAX_SND_CARD) {
1209        ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
1210        free(my_data);
1211        return NULL;
1212    }
1213
1214    my_data->adev = adev;
1215    my_data->fluence_in_spkr_mode = false;
1216    my_data->fluence_in_voice_call = false;
1217    my_data->fluence_in_voice_rec = false;
1218    my_data->fluence_in_audio_rec = false;
1219    my_data->fluence_type = FLUENCE_NONE;
1220    my_data->fluence_mode = FLUENCE_ENDFIRE;
1221    my_data->slowtalk = false;
1222    my_data->hd_voice = false;
1223    my_data->is_wsa_speaker = false;
1224
1225    property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
1226    if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
1227        my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
1228    } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
1229        my_data->fluence_type = FLUENCE_DUAL_MIC;
1230    } else {
1231        my_data->fluence_type = FLUENCE_NONE;
1232    }
1233
1234    if (my_data->fluence_type != FLUENCE_NONE) {
1235        property_get("persist.audio.fluence.voicecall",value,"");
1236        if (!strncmp("true", value, sizeof("true"))) {
1237            my_data->fluence_in_voice_call = true;
1238        }
1239
1240        property_get("persist.audio.fluence.voicerec",value,"");
1241        if (!strncmp("true", value, sizeof("true"))) {
1242            my_data->fluence_in_voice_rec = true;
1243        }
1244
1245        property_get("persist.audio.fluence.audiorec",value,"");
1246        if (!strncmp("true", value, sizeof("true"))) {
1247            my_data->fluence_in_audio_rec = true;
1248        }
1249
1250        property_get("persist.audio.fluence.speaker",value,"");
1251        if (!strncmp("true", value, sizeof("true"))) {
1252            my_data->fluence_in_spkr_mode = true;
1253        }
1254
1255        property_get("persist.audio.fluence.mode",value,"");
1256        if (!strncmp("broadside", value, sizeof("broadside"))) {
1257            my_data->fluence_mode = FLUENCE_BROADSIDE;
1258        }
1259    }
1260
1261    if (is_wsa_found(&wsaCount)) {
1262        /*Set ACDB ID of Stereo speaker if two WSAs are present*/
1263        /*Default ACDB ID for wsa speaker is that for mono*/
1264        if (wsaCount == 2) {
1265            platform_set_snd_device_acdb_id(SND_DEVICE_OUT_SPEAKER_WSA, 15);
1266        }
1267        my_data->is_wsa_speaker = true;
1268    }
1269
1270    property_get("persist.audio.FFSP.enable", ffspEnable, "");
1271    if (!strncmp("true", ffspEnable, sizeof("true"))) {
1272        acdb_device_table[SND_DEVICE_OUT_SPEAKER] = 131;
1273        acdb_device_table[SND_DEVICE_OUT_SPEAKER_WSA] = 131;
1274        acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = 131;
1275        acdb_device_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 131;
1276        acdb_device_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 131;
1277    }
1278
1279    my_data->voice_feature_set = VOICE_FEATURE_SET_DEFAULT;
1280    my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
1281    if (my_data->acdb_handle == NULL) {
1282        ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
1283    } else {
1284        ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
1285        my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
1286                                                    "acdb_loader_deallocate_ACDB");
1287        if (!my_data->acdb_deallocate)
1288            ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
1289                  __func__, LIB_ACDB_LOADER);
1290
1291        my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
1292                                                    "acdb_loader_send_audio_cal_v2");
1293        if (!my_data->acdb_send_audio_cal)
1294            ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
1295                  __func__, LIB_ACDB_LOADER);
1296
1297        my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
1298                                                    "acdb_loader_send_voice_cal");
1299        if (!my_data->acdb_send_voice_cal)
1300            ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
1301                  __func__, LIB_ACDB_LOADER);
1302
1303        my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
1304                                                    "acdb_loader_reload_vocvoltable");
1305        if (!my_data->acdb_reload_vocvoltable)
1306            ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
1307                  __func__, LIB_ACDB_LOADER);
1308
1309        my_data->acdb_get_default_app_type = (acdb_get_default_app_type_t)dlsym(
1310                                                    my_data->acdb_handle,
1311                                                    "acdb_loader_get_default_app_type");
1312        if (!my_data->acdb_get_default_app_type)
1313            ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
1314                  __func__, LIB_ACDB_LOADER);
1315
1316        my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
1317                                                    "acdb_loader_init_v2");
1318        if (my_data->acdb_init == NULL) {
1319            ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
1320            goto acdb_init_fail;
1321        }
1322        platform_acdb_init(my_data);
1323    }
1324    audio_extn_pm_vote();
1325
1326acdb_init_fail:
1327    /* Initialize ACDB ID's */
1328    platform_info_init(PLATFORM_INFO_XML_PATH);
1329
1330    /* init usb */
1331    audio_extn_usb_init(adev);
1332
1333    /*init a2dp*/
1334    audio_extn_a2dp_init();
1335
1336    /* update sound cards appropriately */
1337    audio_extn_usb_set_proxy_sound_card(adev->snd_card);
1338
1339    /* Read one time ssr property */
1340    audio_extn_ssr_update_enabled();
1341    audio_extn_spkr_prot_init(adev);
1342
1343    /* init dap hal */
1344    audio_extn_dap_hal_init(adev->snd_card);
1345
1346    audio_extn_dolby_set_license(adev);
1347    audio_hwdep_send_cal(my_data);
1348
1349    return my_data;
1350}
1351
1352void platform_deinit(void *platform)
1353{
1354    struct platform_data *my_data = (struct platform_data *)platform;
1355
1356    hw_info_deinit(my_data->hw_info);
1357    close_csd_client(my_data->csd);
1358
1359    free(platform);
1360    /* deinit usb */
1361    audio_extn_usb_deinit();
1362    audio_extn_dap_hal_deinit();
1363}
1364
1365int platform_is_acdb_initialized(void *platform)
1366{
1367    struct platform_data *my_data = (struct platform_data *)platform;
1368    ALOGD("%s: acdb initialized %d\n", __func__, my_data->is_acdb_initialized);
1369    return my_data->is_acdb_initialized;
1370}
1371
1372const char *platform_get_snd_device_name(snd_device_t snd_device)
1373{
1374    if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
1375        return device_table[snd_device];
1376    else
1377        return "";
1378}
1379
1380int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
1381                                      char *device_name)
1382{
1383    struct platform_data *my_data = (struct platform_data *)platform;
1384
1385    if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
1386        strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
1387        hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
1388    } else {
1389        strlcpy(device_name, "", DEVICE_NAME_MAX_SIZE);
1390        return -EINVAL;
1391    }
1392
1393    return 0;
1394}
1395
1396void platform_add_backend_name(char *mixer_path, snd_device_t snd_device)
1397{
1398    if ((snd_device == SND_DEVICE_IN_BT_SCO_MIC) ||
1399         (snd_device == SND_DEVICE_IN_BT_SCO_MIC_NREC))
1400        strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
1401    else if ((snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB) ||
1402              (snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB_NREC))
1403        strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
1404    else if(snd_device == SND_DEVICE_OUT_BT_SCO)
1405        strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
1406    else if(snd_device == SND_DEVICE_OUT_BT_A2DP)
1407        strlcat(mixer_path, " bt-a2dp", MIXER_PATH_MAX_LENGTH);
1408    else if(snd_device == SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP)
1409        strlcat(mixer_path, " speaker-and-bt-a2dp", MIXER_PATH_MAX_LENGTH);
1410    else if(snd_device == SND_DEVICE_OUT_BT_SCO_WB)
1411        strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
1412    else if (snd_device == SND_DEVICE_OUT_HDMI)
1413        strlcat(mixer_path, " hdmi", MIXER_PATH_MAX_LENGTH);
1414    else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI)
1415        strlcat(mixer_path, " speaker-and-hdmi", MIXER_PATH_MAX_LENGTH);
1416    else if (snd_device == SND_DEVICE_OUT_AFE_PROXY)
1417        strlcat(mixer_path, " afe-proxy", MIXER_PATH_MAX_LENGTH);
1418    else if (snd_device == SND_DEVICE_OUT_USB_HEADSET)
1419        strlcat(mixer_path, " usb-headphones", MIXER_PATH_MAX_LENGTH);
1420    else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)
1421        strlcat(mixer_path, " speaker-and-usb-headphones",
1422                MIXER_PATH_MAX_LENGTH);
1423    else if (snd_device == SND_DEVICE_IN_USB_HEADSET_MIC)
1424        strlcat(mixer_path, " usb-headset-mic", MIXER_PATH_MAX_LENGTH);
1425    else if (snd_device == SND_DEVICE_IN_CAPTURE_FM)
1426        strlcat(mixer_path, " capture-fm", MIXER_PATH_MAX_LENGTH);
1427    else if (snd_device == SND_DEVICE_OUT_TRANSMISSION_FM)
1428        strlcat(mixer_path, " transmission-fm", MIXER_PATH_MAX_LENGTH);
1429}
1430
1431int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
1432{
1433    int device_id = -1;
1434
1435    if (is_external_codec && is_misc_usecase(usecase)) {
1436        if (device_type == PCM_PLAYBACK)
1437            device_id = pcm_device_table_of_ext_codec[usecase][0];
1438        else
1439            device_id = pcm_device_table_of_ext_codec[usecase][1];
1440    } else {
1441        if (device_type == PCM_PLAYBACK)
1442            device_id = pcm_device_table[usecase][0];
1443        else
1444            device_id = pcm_device_table[usecase][1];
1445    }
1446    return device_id;
1447}
1448
1449int platform_get_snd_device_index(char *snd_device_index_name)
1450{
1451    int ret = 0;
1452    int i;
1453
1454    if (snd_device_index_name == NULL) {
1455        ALOGE("%s: snd_device_index_name is NULL", __func__);
1456        ret = -ENODEV;
1457        goto done;
1458    }
1459
1460    for (i=0; i < SND_DEVICE_MAX; i++) {
1461        if(strcmp(snd_device_name_index[i].name, snd_device_index_name) == 0) {
1462            ret = snd_device_name_index[i].index;
1463            goto done;
1464        }
1465    }
1466    ALOGE("%s: Could not find index for snd_device_index_name = %s",
1467            __func__, snd_device_index_name);
1468    ret = -ENODEV;
1469done:
1470    return ret;
1471}
1472
1473int platform_set_fluence_type(void *platform, char *value)
1474{
1475    int ret = 0;
1476    int fluence_type = FLUENCE_NONE;
1477    int fluence_flag = NONE_FLAG;
1478    struct platform_data *my_data = (struct platform_data *)platform;
1479    struct audio_device *adev = my_data->adev;
1480
1481    ALOGV("%s: fluence type:%d", __func__, my_data->fluence_type);
1482
1483    /* only dual mic turn on and off is supported as of now through setparameters */
1484    if (!strncmp(AUDIO_PARAMETER_VALUE_DUALMIC,value, sizeof(AUDIO_PARAMETER_VALUE_DUALMIC))) {
1485        if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro")) ||
1486            !strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
1487            ALOGV("fluence dualmic feature enabled \n");
1488            fluence_type = FLUENCE_DUAL_MIC;
1489            fluence_flag = DMIC_FLAG;
1490        } else {
1491            ALOGE("%s: Failed to set DUALMIC", __func__);
1492            ret = -1;
1493            goto done;
1494        }
1495    } else if (!strncmp(AUDIO_PARAMETER_KEY_NO_FLUENCE, value, sizeof(AUDIO_PARAMETER_KEY_NO_FLUENCE))) {
1496        ALOGV("fluence disabled");
1497        fluence_type = FLUENCE_NONE;
1498    } else {
1499        ALOGE("Invalid fluence value : %s",value);
1500        ret = -1;
1501        goto done;
1502    }
1503
1504    if (fluence_type != my_data->fluence_type) {
1505        ALOGV("%s: Updating fluence_type to :%d", __func__, fluence_type);
1506        my_data->fluence_type = fluence_type;
1507        adev->acdb_settings = (adev->acdb_settings & FLUENCE_MODE_CLEAR) | fluence_flag;
1508    }
1509done:
1510    return ret;
1511}
1512
1513int platform_get_fluence_type(void *platform, char *value, uint32_t len)
1514{
1515    int ret = 0;
1516    struct platform_data *my_data = (struct platform_data *)platform;
1517
1518    if (my_data->fluence_type == FLUENCE_QUAD_MIC) {
1519        strlcpy(value, "quadmic", len);
1520    } else if (my_data->fluence_type == FLUENCE_DUAL_MIC) {
1521        strlcpy(value, "dualmic", len);
1522    } else if (my_data->fluence_type == FLUENCE_NONE) {
1523        strlcpy(value, "none", len);
1524    } else
1525        ret = -1;
1526
1527    return ret;
1528}
1529
1530int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
1531{
1532    int ret = 0;
1533
1534    if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1535        ALOGE("%s: Invalid snd_device = %d",
1536            __func__, snd_device);
1537        ret = -EINVAL;
1538        goto done;
1539    }
1540
1541    acdb_device_table[snd_device] = acdb_id;
1542done:
1543    return ret;
1544}
1545
1546int platform_get_default_app_type(void *platform)
1547{
1548    struct platform_data *my_data = (struct platform_data *)platform;
1549
1550    if (my_data->acdb_get_default_app_type)
1551        return my_data->acdb_get_default_app_type();
1552    else
1553        return DEFAULT_APP_TYPE;
1554}
1555
1556int platform_get_snd_device_acdb_id(snd_device_t snd_device)
1557{
1558    if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1559        ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1560        return -EINVAL;
1561    }
1562    return acdb_device_table[snd_device];
1563}
1564
1565int platform_set_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width)
1566{
1567    ALOGE("%s: Not implemented", __func__);
1568    return -ENOSYS;
1569}
1570
1571int platform_get_snd_device_bit_width(snd_device_t snd_device)
1572{
1573    ALOGE("%s: Not implemented", __func__);
1574    return -ENOSYS;
1575}
1576
1577int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
1578                                    int app_type, int sample_rate)
1579{
1580    struct platform_data *my_data = (struct platform_data *)platform;
1581    int acdb_dev_id, acdb_dev_type;
1582    struct audio_device *adev = my_data->adev;
1583    int snd_device = SND_DEVICE_OUT_SPEAKER;
1584
1585    if (usecase->type == PCM_PLAYBACK) {
1586        snd_device = usecase->out_snd_device;
1587        if(usecase->id != USECASE_AUDIO_PLAYBACK_OFFLOAD)
1588            app_type = APP_TYPE_SYSTEM_SOUNDS;
1589    } else if ((usecase->type == PCM_HFP_CALL) || (usecase->type == PCM_CAPTURE)) {
1590        snd_device = usecase->in_snd_device;
1591        app_type = APP_TYPE_GENERAL_RECORDING;
1592    }
1593
1594    acdb_dev_id = acdb_device_table[snd_device];
1595    if (acdb_dev_id < 0) {
1596        ALOGE("%s: Could not find acdb id for device(%d)",
1597              __func__, snd_device);
1598        return -EINVAL;
1599    }
1600    if (my_data->acdb_send_audio_cal) {
1601        ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
1602              __func__, snd_device, acdb_dev_id);
1603        if (snd_device >= SND_DEVICE_OUT_BEGIN &&
1604                snd_device < SND_DEVICE_OUT_END)
1605            acdb_dev_type = ACDB_DEV_TYPE_OUT;
1606        else
1607            acdb_dev_type = ACDB_DEV_TYPE_IN;
1608        my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type, app_type,
1609                                     sample_rate);
1610    }
1611    return 0;
1612}
1613
1614int platform_switch_voice_call_device_pre(void *platform)
1615{
1616    struct platform_data *my_data = (struct platform_data *)platform;
1617    int ret = 0;
1618
1619    if (my_data->csd != NULL &&
1620        my_data->adev->mode == AUDIO_MODE_IN_CALL) {
1621        /* This must be called before disabling mixer controls on APQ side */
1622        ret = my_data->csd->disable_device();
1623        if (ret < 0) {
1624            ALOGE("%s: csd_client_disable_device, failed, error %d",
1625                  __func__, ret);
1626        }
1627    }
1628    return ret;
1629}
1630int platform_switch_voice_call_enable_device_config(void *platform,
1631                                                    snd_device_t out_snd_device,
1632                                                    snd_device_t in_snd_device)
1633{
1634    struct platform_data *my_data = (struct platform_data *)platform;
1635    int acdb_rx_id, acdb_tx_id;
1636    int ret = 0;
1637
1638    acdb_rx_id = acdb_device_table[out_snd_device];
1639    acdb_tx_id = acdb_device_table[in_snd_device];
1640
1641    if (my_data->csd != NULL) {
1642        if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1643            ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
1644            if (ret < 0) {
1645                ALOGE("%s: csd_enable_device_config, failed, error %d",
1646                      __func__, ret);
1647            }
1648        } else {
1649            ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1650                  acdb_rx_id, acdb_tx_id);
1651        }
1652    }
1653    return ret;
1654}
1655
1656
1657int platform_switch_voice_call_device_post(void *platform,
1658                                           snd_device_t out_snd_device,
1659                                           snd_device_t in_snd_device)
1660{
1661    struct platform_data *my_data = (struct platform_data *)platform;
1662    int acdb_rx_id, acdb_tx_id;
1663
1664    if (my_data->acdb_send_voice_cal == NULL) {
1665        ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
1666    } else {
1667        acdb_rx_id = acdb_device_table[out_snd_device];
1668        acdb_tx_id = acdb_device_table[in_snd_device];
1669
1670        if (acdb_rx_id > 0 && acdb_tx_id > 0)
1671            my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
1672        else
1673            ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1674                  acdb_rx_id, acdb_tx_id);
1675    }
1676
1677    return 0;
1678}
1679
1680int platform_switch_voice_call_usecase_route_post(void *platform,
1681                                                  snd_device_t out_snd_device,
1682                                                  snd_device_t in_snd_device)
1683{
1684    struct platform_data *my_data = (struct platform_data *)platform;
1685    int acdb_rx_id, acdb_tx_id;
1686    int ret = 0;
1687
1688    acdb_rx_id = acdb_device_table[out_snd_device];
1689    acdb_tx_id = acdb_device_table[in_snd_device];
1690
1691    if (my_data->csd != NULL) {
1692        if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1693            ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
1694                                              my_data->adev->acdb_settings);
1695            if (ret < 0) {
1696                ALOGE("%s: csd_enable_device, failed, error %d",
1697                      __func__, ret);
1698            }
1699        } else {
1700            ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1701                  acdb_rx_id, acdb_tx_id);
1702        }
1703    }
1704    return ret;
1705}
1706
1707int platform_start_voice_call(void *platform, uint32_t vsid)
1708{
1709    struct platform_data *my_data = (struct platform_data *)platform;
1710    int ret = 0;
1711
1712    if (my_data->csd != NULL) {
1713        ret = my_data->csd->start_voice(vsid);
1714        if (ret < 0) {
1715            ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
1716        }
1717    }
1718    return ret;
1719}
1720
1721int platform_stop_voice_call(void *platform, uint32_t vsid)
1722{
1723    struct platform_data *my_data = (struct platform_data *)platform;
1724    int ret = 0;
1725
1726    if (my_data->csd != NULL) {
1727        ret = my_data->csd->stop_voice(vsid);
1728        if (ret < 0) {
1729            ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
1730        }
1731    }
1732    return ret;
1733}
1734
1735int platform_get_sample_rate(void *platform __unused, uint32_t *rate __unused)
1736{
1737    return 0;
1738}
1739
1740int platform_set_voice_volume(void *platform, int volume)
1741{
1742    struct platform_data *my_data = (struct platform_data *)platform;
1743    struct audio_device *adev = my_data->adev;
1744    struct mixer_ctl *ctl;
1745    const char *mixer_ctl_name = "Voice Rx Gain";
1746    int vol_index = 0, ret = 0;
1747    uint32_t set_values[ ] = {0,
1748                              ALL_SESSION_VSID,
1749                              DEFAULT_VOLUME_RAMP_DURATION_MS};
1750
1751    // Voice volume levels are mapped to adsp volume levels as follows.
1752    // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1  0 -> 0
1753    // But this values don't changed in kernel. So, below change is need.
1754    vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
1755    set_values[0] = vol_index;
1756
1757    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1758    if (!ctl) {
1759        ALOGE("%s: Could not get ctl for mixer cmd - %s",
1760              __func__, mixer_ctl_name);
1761        return -EINVAL;
1762    }
1763    ALOGV("Setting voice volume index: %d", set_values[0]);
1764    mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1765
1766    if (my_data->csd != NULL) {
1767        ret = my_data->csd->volume(ALL_SESSION_VSID, volume);
1768        if (ret < 0) {
1769            ALOGE("%s: csd_volume error %d", __func__, ret);
1770        }
1771    }
1772    return ret;
1773}
1774
1775int platform_set_mic_mute(void *platform, bool state)
1776{
1777    struct platform_data *my_data = (struct platform_data *)platform;
1778    struct audio_device *adev = my_data->adev;
1779    struct mixer_ctl *ctl;
1780    const char *mixer_ctl_name = "Voice Tx Mute";
1781    int ret = 0;
1782    uint32_t set_values[ ] = {0,
1783                              ALL_SESSION_VSID,
1784                              DEFAULT_VOLUME_RAMP_DURATION_MS};
1785
1786    set_values[0] = state;
1787    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1788    if (!ctl) {
1789        ALOGE("%s: Could not get ctl for mixer cmd - %s",
1790              __func__, mixer_ctl_name);
1791        return -EINVAL;
1792    }
1793    ALOGV("Setting voice mute state: %d", state);
1794    mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1795
1796    if (my_data->csd != NULL) {
1797        ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state);
1798        if (ret < 0) {
1799            ALOGE("%s: csd_mic_mute error %d", __func__, ret);
1800        }
1801    }
1802    return ret;
1803}
1804
1805int platform_set_device_mute(void *platform, bool state, char *dir)
1806{
1807    struct platform_data *my_data = (struct platform_data *)platform;
1808    struct audio_device *adev = my_data->adev;
1809    struct mixer_ctl *ctl;
1810    char *mixer_ctl_name = NULL;
1811    int ret = 0;
1812    uint32_t set_values[ ] = {0,
1813                              ALL_SESSION_VSID,
1814                              0};
1815    if(dir == NULL) {
1816        ALOGE("%s: Invalid direction:%s", __func__, dir);
1817        return -EINVAL;
1818    }
1819
1820    if (!strncmp("rx", dir, sizeof("rx"))) {
1821        mixer_ctl_name = "Voice Rx Device Mute";
1822    } else if (!strncmp("tx", dir, sizeof("tx"))) {
1823        mixer_ctl_name = "Voice Tx Device Mute";
1824    } else {
1825        return -EINVAL;
1826    }
1827
1828    set_values[0] = state;
1829    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1830    if (!ctl) {
1831        ALOGE("%s: Could not get ctl for mixer cmd - %s",
1832              __func__, mixer_ctl_name);
1833        return -EINVAL;
1834    }
1835
1836    ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
1837          __func__,state, mixer_ctl_name);
1838    mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1839
1840    return ret;
1841}
1842
1843snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
1844{
1845    struct platform_data *my_data = (struct platform_data *)platform;
1846    struct audio_device *adev = my_data->adev;
1847    audio_mode_t mode = adev->mode;
1848    snd_device_t snd_device = SND_DEVICE_NONE;
1849#ifdef RECORD_PLAY_CONCURRENCY
1850    bool use_voip_out_devices = false;
1851    bool prop_rec_play_enabled = false;
1852    char recConcPropValue[PROPERTY_VALUE_MAX];
1853
1854    if (property_get("rec.playback.conc.disabled", recConcPropValue, NULL)) {
1855        prop_rec_play_enabled = atoi(recConcPropValue) || !strncmp("true", recConcPropValue, 4);
1856    }
1857    use_voip_out_devices =  prop_rec_play_enabled &&
1858                        (my_data->rec_play_conc_set || adev->mode == AUDIO_MODE_IN_COMMUNICATION);
1859    ALOGV("platform_get_output_snd_device use_voip_out_devices : %d",use_voip_out_devices);
1860#endif
1861
1862    audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1863                                AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1864    int channel_count = popcount(channel_mask);
1865
1866    ALOGV("%s: enter: output devices(%#x)", __func__, devices);
1867    if (devices == AUDIO_DEVICE_NONE ||
1868        devices & AUDIO_DEVICE_BIT_IN) {
1869        ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
1870        goto exit;
1871    }
1872
1873    if (popcount(devices) == 2) {
1874        if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1875                        AUDIO_DEVICE_OUT_SPEAKER)) {
1876            snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1877        } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1878                               AUDIO_DEVICE_OUT_SPEAKER)) {
1879            if (audio_extn_get_anc_enabled())
1880                snd_device = SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET;
1881            else
1882                snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1883        } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
1884                               AUDIO_DEVICE_OUT_SPEAKER)) {
1885            snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
1886        } else if (devices == (AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
1887                               AUDIO_DEVICE_OUT_SPEAKER)) {
1888            snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
1889        } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER) &&
1890                   (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
1891            snd_device = SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP;
1892        } else {
1893            ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
1894            goto exit;
1895        }
1896        if (snd_device != SND_DEVICE_NONE) {
1897            goto exit;
1898        }
1899    }
1900
1901    if (popcount(devices) != 1) {
1902        ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
1903        goto exit;
1904    }
1905
1906    if ((mode == AUDIO_MODE_IN_CALL) ||
1907        voice_extn_compress_voip_is_active(adev)) {
1908        if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1909            devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1910            if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
1911                !voice_extn_compress_voip_is_active(adev)) {
1912                switch (adev->voice.tty_mode) {
1913                case TTY_MODE_FULL:
1914                    snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
1915                    break;
1916                case TTY_MODE_VCO:
1917                    snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
1918                    break;
1919                case TTY_MODE_HCO:
1920                    snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
1921                    break;
1922                default:
1923                    ALOGE("%s: Invalid TTY mode (%#x)",
1924                          __func__, adev->voice.tty_mode);
1925                }
1926            } else if (audio_extn_get_anc_enabled()) {
1927                if (audio_extn_should_use_fb_anc())
1928                    snd_device = SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET;
1929                else
1930                    snd_device = SND_DEVICE_OUT_VOICE_ANC_HEADSET;
1931            } else {
1932                snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
1933            }
1934        } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
1935            if (adev->bt_wb_speech_enabled)
1936                snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1937            else
1938                snd_device = SND_DEVICE_OUT_BT_SCO;
1939        } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
1940                if (my_data->is_wsa_speaker)
1941                    snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_WSA;
1942                else
1943                    snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
1944        } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
1945                   devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
1946            snd_device = SND_DEVICE_OUT_USB_HEADSET;
1947        } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
1948            snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
1949        } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
1950            if (audio_extn_should_use_handset_anc(channel_count))
1951                snd_device = SND_DEVICE_OUT_ANC_HANDSET;
1952            else
1953                snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
1954        }
1955        if (snd_device != SND_DEVICE_NONE) {
1956            goto exit;
1957        }
1958    }
1959
1960    if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1961        devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1962        if (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET
1963            && audio_extn_get_anc_enabled()) {
1964#ifdef RECORD_PLAY_CONCURRENCY
1965            if (use_voip_out_devices) {
1966                // ANC should be disabled for voip concurrency
1967                snd_device = SND_DEVICE_OUT_VOIP_HEADPHONES;
1968            } else
1969#endif
1970            {
1971                if (audio_extn_should_use_fb_anc())
1972                    snd_device = SND_DEVICE_OUT_ANC_FB_HEADSET;
1973                else
1974                    snd_device = SND_DEVICE_OUT_ANC_HEADSET;
1975            }
1976        } else {
1977#ifdef RECORD_PLAY_CONCURRENCY
1978            if (use_voip_out_devices)
1979                snd_device = SND_DEVICE_OUT_VOIP_HEADPHONES;
1980            else
1981#endif
1982                snd_device = SND_DEVICE_OUT_HEADPHONES;
1983        }
1984    } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
1985#ifdef RECORD_PLAY_CONCURRENCY
1986        if (use_voip_out_devices) {
1987            snd_device = SND_DEVICE_OUT_VOIP_SPEAKER;
1988        } else
1989#endif
1990        {
1991            if (adev->speaker_lr_swap)
1992                snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
1993            else
1994            {
1995                if (my_data->is_wsa_speaker)
1996                    snd_device = SND_DEVICE_OUT_SPEAKER_WSA;
1997                else
1998                    snd_device = SND_DEVICE_OUT_SPEAKER;
1999            }
2000        }
2001    } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2002        if (adev->bt_wb_speech_enabled)
2003            snd_device = SND_DEVICE_OUT_BT_SCO_WB;
2004        else
2005            snd_device = SND_DEVICE_OUT_BT_SCO;
2006    } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
2007        snd_device = SND_DEVICE_OUT_HDMI ;
2008    } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
2009        snd_device = SND_DEVICE_OUT_BT_A2DP;
2010    } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
2011               devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
2012        ALOGD("%s: setting USB hadset channel capability(2) for Proxy", __func__);
2013        audio_extn_set_afe_proxy_channel_mixer(adev, 2);
2014        snd_device = SND_DEVICE_OUT_USB_HEADSET;
2015    } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
2016        snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
2017    } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
2018#ifdef RECORD_PLAY_CONCURRENCY
2019        if (use_voip_out_devices)
2020            snd_device = SND_DEVICE_OUT_VOIP_HANDSET;
2021        else
2022#endif
2023            snd_device = SND_DEVICE_OUT_HANDSET;
2024    } else if (devices & AUDIO_DEVICE_OUT_PROXY) {
2025        channel_count = audio_extn_get_afe_proxy_channel_count();
2026        ALOGD("%s: setting sink capability(%d) for Proxy", __func__, channel_count);
2027        audio_extn_set_afe_proxy_channel_mixer(adev, channel_count);
2028        snd_device = SND_DEVICE_OUT_AFE_PROXY;
2029    } else {
2030        ALOGE("%s: Unknown device(s) %#x", __func__, devices);
2031    }
2032exit:
2033    ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
2034    return snd_device;
2035}
2036
2037snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
2038{
2039    struct platform_data *my_data = (struct platform_data *)platform;
2040    struct audio_device *adev = my_data->adev;
2041    audio_source_t  source = (adev->active_input == NULL) ?
2042                                AUDIO_SOURCE_DEFAULT : adev->active_input->source;
2043
2044    audio_mode_t    mode   = adev->mode;
2045    audio_devices_t in_device = ((adev->active_input == NULL) ?
2046                                    AUDIO_DEVICE_NONE : adev->active_input->device)
2047                                & ~AUDIO_DEVICE_BIT_IN;
2048    audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
2049                                AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
2050    snd_device_t snd_device = SND_DEVICE_NONE;
2051    int channel_count = popcount(channel_mask);
2052
2053    ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
2054          __func__, out_device, in_device);
2055    if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
2056        voice_extn_compress_voip_is_active(adev) || audio_extn_hfp_is_active(adev))) {
2057        if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
2058            !voice_extn_compress_voip_is_active(adev)) {
2059            if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
2060                out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
2061                switch (adev->voice.tty_mode) {
2062                case TTY_MODE_FULL:
2063                    snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
2064                    break;
2065                case TTY_MODE_VCO:
2066                    snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
2067                    break;
2068                case TTY_MODE_HCO:
2069                    snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
2070                    break;
2071                default:
2072                    ALOGE("%s: Invalid TTY mode (%#x)",
2073                          __func__, adev->voice.tty_mode);
2074                }
2075                goto exit;
2076            }
2077        }
2078        if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
2079            out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
2080            if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
2081                audio_extn_should_use_handset_anc(channel_count) &&
2082                my_data->fluence_type != FLUENCE_NONE) {
2083                snd_device = SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC;
2084                adev->acdb_settings |= DMIC_FLAG;
2085                ALOGD("Selecting AANC, Fluence combo device");
2086            } else if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
2087                audio_extn_should_use_handset_anc(channel_count)) {
2088                snd_device = SND_DEVICE_IN_AANC_HANDSET_MIC;
2089            } else if (my_data->fluence_type == FLUENCE_NONE ||
2090                my_data->fluence_in_voice_call == false) {
2091                snd_device = SND_DEVICE_IN_HANDSET_MIC;
2092                if (audio_extn_hfp_is_active(adev))
2093                    platform_set_echo_reference(adev->platform, true);
2094            } else {
2095                snd_device = SND_DEVICE_IN_VOICE_DMIC;
2096                adev->acdb_settings |= DMIC_FLAG;
2097            }
2098        } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
2099            snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
2100               if (audio_extn_hfp_is_active(adev))
2101                   platform_set_echo_reference(adev->platform, true);
2102        } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
2103            if (adev->bt_wb_speech_enabled) {
2104                if (adev->bluetooth_nrec)
2105                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2106                else
2107                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
2108            } else {
2109                if (adev->bluetooth_nrec)
2110                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2111                else
2112                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
2113            }
2114        } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
2115            if (my_data->fluence_type != FLUENCE_NONE &&
2116                my_data->fluence_in_voice_call &&
2117                my_data->fluence_in_spkr_mode) {
2118                if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
2119                    adev->acdb_settings |= QMIC_FLAG;
2120                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_QMIC;
2121                } else {
2122                    adev->acdb_settings |= DMIC_FLAG;
2123                    if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2124                       snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE;
2125                    else
2126                       snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
2127                }
2128            } else {
2129                snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
2130                if (audio_extn_hfp_is_active(adev))
2131                    platform_set_echo_reference(adev->platform, true);
2132            }
2133        }
2134    } else if (source == AUDIO_SOURCE_CAMCORDER) {
2135        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
2136            in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2137            if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
2138                channel_count == 2)
2139                snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
2140            else
2141                snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
2142        }
2143    } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
2144        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2145           if (channel_count == 2) {
2146                snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
2147                adev->acdb_settings |= DMIC_FLAG;
2148            } else if (adev->active_input->enable_ns)
2149                snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
2150            else if (my_data->fluence_type != FLUENCE_NONE &&
2151                     my_data->fluence_in_voice_rec) {
2152                snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
2153                adev->acdb_settings |= DMIC_FLAG;
2154            } else {
2155                snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
2156            }
2157        }
2158    } else if ((source == AUDIO_SOURCE_VOICE_COMMUNICATION) ||
2159              (mode == AUDIO_MODE_IN_COMMUNICATION)) {
2160        if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
2161            in_device = AUDIO_DEVICE_IN_BACK_MIC;
2162        if (adev->active_input) {
2163            if (adev->active_input->enable_aec &&
2164                    adev->active_input->enable_ns) {
2165                if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2166                    if (my_data->fluence_in_spkr_mode) {
2167                        if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
2168                            snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
2169                        } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2170                            if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2171                                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
2172                            else
2173                                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
2174                        }
2175                        adev->acdb_settings |= DMIC_FLAG;
2176                    } else
2177                        snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
2178                } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2179                    if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2180                        snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
2181                        adev->acdb_settings |= DMIC_FLAG;
2182                    } else
2183                        snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
2184                } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2185                    snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
2186                }
2187                platform_set_echo_reference(adev->platform, true);
2188            } else if (adev->active_input->enable_aec) {
2189                if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2190                    if (my_data->fluence_in_spkr_mode) {
2191                        if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
2192                            snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
2193                        } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2194                            if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2195                                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
2196                            else
2197                                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
2198                        }
2199                        adev->acdb_settings |= DMIC_FLAG;
2200                    } else
2201                        snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
2202                } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2203                    if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2204                        snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
2205                        adev->acdb_settings |= DMIC_FLAG;
2206                    } else
2207                        snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
2208                } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2209                    snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
2210                }
2211                platform_set_echo_reference(adev->platform, true);
2212            } else if (adev->active_input->enable_ns) {
2213                if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2214                    if (my_data->fluence_in_spkr_mode) {
2215                        if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
2216                            snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
2217                        } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2218                            if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2219                                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
2220                            else
2221                                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
2222                        }
2223                        adev->acdb_settings |= DMIC_FLAG;
2224                    } else
2225                        snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
2226                } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2227                    if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2228                        snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
2229                        adev->acdb_settings |= DMIC_FLAG;
2230                    } else
2231                        snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
2232                } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2233                    snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
2234                }
2235                platform_set_echo_reference(adev->platform,false);
2236            } else
2237                platform_set_echo_reference(adev->platform, false);
2238        }
2239    } else if (source == AUDIO_SOURCE_MIC) {
2240        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
2241                channel_count == 1 ) {
2242            ALOGD("Record path active");
2243            if(my_data->fluence_in_audio_rec) {
2244                if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
2245                    ALOGD(" snd_device = SND_DEVICE_IN_HANDSET_QMIC");
2246                    snd_device = SND_DEVICE_IN_HANDSET_QMIC;
2247                    platform_set_echo_reference(adev->platform, true);
2248                } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2249                    snd_device = SND_DEVICE_IN_HANDSET_DMIC;
2250                    platform_set_echo_reference(adev->platform, true);
2251                }
2252            }
2253        }
2254    } else if (source == AUDIO_SOURCE_FM_TUNER) {
2255        snd_device = SND_DEVICE_IN_CAPTURE_FM;
2256    } else if (source == AUDIO_SOURCE_DEFAULT) {
2257        goto exit;
2258    }
2259
2260
2261    if (snd_device != SND_DEVICE_NONE) {
2262        goto exit;
2263    }
2264
2265    if (in_device != AUDIO_DEVICE_NONE &&
2266            !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
2267            !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
2268        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2269            if (audio_extn_ssr_get_enabled() && channel_count == 6)
2270                snd_device = SND_DEVICE_IN_QUAD_MIC;
2271            else if (channel_count == 2)
2272                snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
2273            else
2274                snd_device = SND_DEVICE_IN_HANDSET_MIC;
2275        } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2276            snd_device = SND_DEVICE_IN_SPEAKER_MIC;
2277        } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2278            snd_device = SND_DEVICE_IN_HEADSET_MIC;
2279        } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
2280            if (adev->bt_wb_speech_enabled) {
2281                if (adev->bluetooth_nrec)
2282                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2283                else
2284                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
2285            } else {
2286                if (adev->bluetooth_nrec)
2287                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2288                else
2289                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
2290            }
2291        } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
2292            snd_device = SND_DEVICE_IN_HDMI_MIC;
2293        } else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
2294                   in_device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) {
2295            snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
2296        } else if (in_device & AUDIO_DEVICE_IN_FM_TUNER) {
2297            snd_device = SND_DEVICE_IN_CAPTURE_FM;
2298        } else {
2299            ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
2300            ALOGW("%s: Using default handset-mic", __func__);
2301            snd_device = SND_DEVICE_IN_HANDSET_MIC;
2302        }
2303    } else {
2304        if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
2305            snd_device = SND_DEVICE_IN_HANDSET_MIC;
2306        } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
2307            snd_device = SND_DEVICE_IN_HEADSET_MIC;
2308        } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
2309            if (channel_count > 1)
2310                snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
2311            else
2312                snd_device = SND_DEVICE_IN_SPEAKER_MIC;
2313        } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
2314            snd_device = SND_DEVICE_IN_HANDSET_MIC;
2315        } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
2316            if (adev->bt_wb_speech_enabled) {
2317                if (adev->bluetooth_nrec)
2318                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2319                else
2320                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
2321            } else {
2322                if (adev->bluetooth_nrec)
2323                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2324                else
2325                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
2326            }
2327        } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
2328            snd_device = SND_DEVICE_IN_HDMI_MIC;
2329        } else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
2330                   out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
2331            snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
2332        } else {
2333            ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
2334            ALOGW("%s: Using default handset-mic", __func__);
2335            snd_device = SND_DEVICE_IN_HANDSET_MIC;
2336        }
2337    }
2338exit:
2339    ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
2340    return snd_device;
2341}
2342
2343int platform_set_hdmi_channels(void *platform,  int channel_count)
2344{
2345    struct platform_data *my_data = (struct platform_data *)platform;
2346    struct audio_device *adev = my_data->adev;
2347    struct mixer_ctl *ctl;
2348    const char *channel_cnt_str = NULL;
2349    const char *mixer_ctl_name = "HDMI_RX Channels";
2350    switch (channel_count) {
2351    case 8:
2352        channel_cnt_str = "Eight"; break;
2353    case 7:
2354        channel_cnt_str = "Seven"; break;
2355    case 6:
2356        channel_cnt_str = "Six"; break;
2357    case 5:
2358        channel_cnt_str = "Five"; break;
2359    case 4:
2360        channel_cnt_str = "Four"; break;
2361    case 3:
2362        channel_cnt_str = "Three"; break;
2363    default:
2364        channel_cnt_str = "Two"; break;
2365    }
2366    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2367    if (!ctl) {
2368        ALOGE("%s: Could not get ctl for mixer cmd - %s",
2369              __func__, mixer_ctl_name);
2370        return -EINVAL;
2371    }
2372    ALOGV("HDMI channel count: %s", channel_cnt_str);
2373    mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
2374    return 0;
2375}
2376
2377int platform_edid_get_max_channels(void *platform)
2378{
2379    struct platform_data *my_data = (struct platform_data *)platform;
2380    struct audio_device *adev = my_data->adev;
2381    char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
2382    char *sad = block;
2383    int num_audio_blocks;
2384    int channel_count;
2385    int max_channels = 0;
2386    int i, ret, count;
2387
2388    struct mixer_ctl *ctl;
2389
2390    ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
2391    if (!ctl) {
2392        ALOGE("%s: Could not get ctl for mixer cmd - %s",
2393              __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
2394        return 0;
2395    }
2396
2397    mixer_ctl_update(ctl);
2398
2399    count = mixer_ctl_get_num_values(ctl);
2400
2401    /* Read SAD blocks, clamping the maximum size for safety */
2402    if (count > (int)sizeof(block))
2403        count = (int)sizeof(block);
2404
2405    ret = mixer_ctl_get_array(ctl, block, count);
2406    if (ret != 0) {
2407        ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
2408        return 0;
2409    }
2410
2411    /* Calculate the number of SAD blocks */
2412    num_audio_blocks = count / SAD_BLOCK_SIZE;
2413
2414    for (i = 0; i < num_audio_blocks; i++) {
2415        /* Only consider LPCM blocks */
2416        if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
2417            sad += 3;
2418            continue;
2419        }
2420
2421        channel_count = (sad[0] & 0x7) + 1;
2422        if (channel_count > max_channels)
2423            max_channels = channel_count;
2424
2425        /* Advance to next block */
2426        sad += 3;
2427    }
2428
2429    return max_channels;
2430}
2431
2432static int platform_set_slowtalk(struct platform_data *my_data, bool state)
2433{
2434    int ret = 0;
2435    struct audio_device *adev = my_data->adev;
2436    struct mixer_ctl *ctl;
2437    const char *mixer_ctl_name = "Slowtalk Enable";
2438    uint32_t set_values[ ] = {0,
2439                              ALL_SESSION_VSID};
2440
2441    set_values[0] = state;
2442    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2443    if (!ctl) {
2444        ALOGE("%s: Could not get ctl for mixer cmd - %s",
2445              __func__, mixer_ctl_name);
2446        ret = -EINVAL;
2447    } else {
2448        ALOGV("Setting slowtalk state: %d", state);
2449        ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
2450        my_data->slowtalk = state;
2451    }
2452
2453    if (my_data->csd != NULL) {
2454        ret = my_data->csd->slow_talk(ALL_SESSION_VSID, state);
2455        if (ret < 0) {
2456            ALOGE("%s: csd_client_disable_device, failed, error %d",
2457                  __func__, ret);
2458        }
2459    }
2460    return ret;
2461}
2462
2463static int set_hd_voice(struct platform_data *my_data, bool state)
2464{
2465    struct audio_device *adev = my_data->adev;
2466    struct mixer_ctl *ctl;
2467    const char *mixer_ctl_name = "HD Voice Enable";
2468    int ret = 0;
2469    uint32_t set_values[ ] = {0,
2470                              ALL_SESSION_VSID};
2471
2472    set_values[0] = state;
2473    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2474    if (!ctl) {
2475        ALOGE("%s: Could not get ctl for mixer cmd - %s",
2476              __func__, mixer_ctl_name);
2477        ret = -EINVAL;
2478    } else {
2479        ALOGV("Setting HD Voice state: %d", state);
2480        ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
2481        my_data->hd_voice = state;
2482    }
2483
2484    return ret;
2485}
2486
2487int platform_set_parameters(void *platform, struct str_parms *parms)
2488{
2489    struct platform_data *my_data = (struct platform_data *)platform;
2490    char *str;
2491    char value[256] = {0};
2492    int val;
2493    int ret = 0, err;
2494    char *kv_pairs = NULL;
2495
2496    kv_pairs = str_parms_to_str(parms);
2497    ALOGV("%s: enter: - %s", __func__, kv_pairs);
2498    free(kv_pairs);
2499
2500    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, sizeof(value));
2501    if (err >= 0) {
2502        bool state = false;
2503        if (!strncmp("true", value, sizeof("true"))) {
2504            state = true;
2505        }
2506
2507        str_parms_del(parms, AUDIO_PARAMETER_KEY_SLOWTALK);
2508        ret = platform_set_slowtalk(my_data, state);
2509        if (ret)
2510            ALOGE("%s: Failed to set slow talk err: %d", __func__, ret);
2511    }
2512
2513    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HD_VOICE, value, sizeof(value));
2514    if (err >= 0) {
2515        bool state = false;
2516        if (!strncmp("true", value, sizeof("true"))) {
2517            state = true;
2518        }
2519
2520        str_parms_del(parms, AUDIO_PARAMETER_KEY_HD_VOICE);
2521        if (my_data->hd_voice != state) {
2522            ret = set_hd_voice(my_data, state);
2523            if (ret)
2524                ALOGE("%s: Failed to set HD voice err: %d", __func__, ret);
2525        } else {
2526            ALOGV("%s: HD Voice already set to %d", __func__, state);
2527        }
2528    }
2529
2530    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
2531                            value, sizeof(value));
2532    if (err >= 0) {
2533        str_parms_del(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST);
2534
2535        if (my_data->acdb_reload_vocvoltable == NULL) {
2536            ALOGE("%s: acdb_reload_vocvoltable is NULL", __func__);
2537        } else if (!strcmp(value, "on")) {
2538            if (!my_data->acdb_reload_vocvoltable(VOICE_FEATURE_SET_VOLUME_BOOST)) {
2539                my_data->voice_feature_set = 1;
2540            }
2541        } else {
2542            if (!my_data->acdb_reload_vocvoltable(VOICE_FEATURE_SET_DEFAULT)) {
2543                my_data->voice_feature_set = 0;
2544            }
2545        }
2546    }
2547
2548#ifdef RECORD_PLAY_CONCURRENCY
2549    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_REC_PLAY_CONC, value, sizeof(value));
2550    if (err >= 0) {
2551        if (!strncmp("true", value, sizeof("true"))) {
2552            ALOGD("setting record playback concurrency to true");
2553            my_data->rec_play_conc_set = true;
2554        } else {
2555            ALOGD("setting record playback concurrency to false");
2556            my_data->rec_play_conc_set = false;
2557        }
2558    }
2559#endif
2560    ALOGV("%s: exit with code(%d)", __func__, ret);
2561    return ret;
2562}
2563
2564int platform_set_incall_recording_session_id(void *platform,
2565                                             uint32_t session_id, int rec_mode)
2566{
2567    int ret = 0;
2568    struct platform_data *my_data = (struct platform_data *)platform;
2569    struct audio_device *adev = my_data->adev;
2570    struct mixer_ctl *ctl;
2571    const char *mixer_ctl_name = "Voc VSID";
2572    int num_ctl_values;
2573    int i;
2574
2575    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2576    if (!ctl) {
2577        ALOGE("%s: Could not get ctl for mixer cmd - %s",
2578              __func__, mixer_ctl_name);
2579        ret = -EINVAL;
2580    } else {
2581        num_ctl_values = mixer_ctl_get_num_values(ctl);
2582        for (i = 0; i < num_ctl_values; i++) {
2583            if (mixer_ctl_set_value(ctl, i, session_id)) {
2584                ALOGV("Error: invalid session_id: %x", session_id);
2585                ret = -EINVAL;
2586                break;
2587            }
2588        }
2589    }
2590
2591    if (my_data->csd != NULL) {
2592        ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
2593        if (ret < 0) {
2594            ALOGE("%s: csd_client_start_record failed, error %d",
2595                  __func__, ret);
2596        }
2597    }
2598
2599    return ret;
2600}
2601
2602int platform_stop_incall_recording_usecase(void *platform)
2603{
2604    int ret = 0;
2605    struct platform_data *my_data = (struct platform_data *)platform;
2606
2607    if (my_data->csd != NULL) {
2608        ret = my_data->csd->stop_record(ALL_SESSION_VSID);
2609        if (ret < 0) {
2610            ALOGE("%s: csd_client_stop_record failed, error %d",
2611                  __func__, ret);
2612        }
2613    }
2614
2615    return ret;
2616}
2617
2618int platform_start_incall_music_usecase(void *platform)
2619{
2620    int ret = 0;
2621    struct platform_data *my_data = (struct platform_data *)platform;
2622
2623    if (my_data->csd != NULL) {
2624        ret = my_data->csd->start_playback(ALL_SESSION_VSID);
2625        if (ret < 0) {
2626            ALOGE("%s: csd_client_start_playback failed, error %d",
2627                  __func__, ret);
2628        }
2629    }
2630
2631    return ret;
2632}
2633
2634int platform_stop_incall_music_usecase(void *platform)
2635{
2636    int ret = 0;
2637    struct platform_data *my_data = (struct platform_data *)platform;
2638
2639    if (my_data->csd != NULL) {
2640        ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
2641        if (ret < 0) {
2642            ALOGE("%s: csd_client_stop_playback failed, error %d",
2643                  __func__, ret);
2644        }
2645    }
2646
2647    return ret;
2648}
2649
2650int platform_update_lch(void *platform, struct voice_session *session,
2651                        enum voice_lch_mode lch_mode)
2652{
2653    int ret = 0;
2654    struct platform_data *my_data = (struct platform_data *)platform;
2655
2656    if ((my_data->csd != NULL) && (my_data->csd->set_lch != NULL))
2657        ret = my_data->csd->set_lch(session->vsid, lch_mode);
2658    else
2659        ret = pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode);
2660
2661    return ret;
2662}
2663
2664void platform_get_parameters(void *platform,
2665                            struct str_parms *query,
2666                            struct str_parms *reply)
2667{
2668    struct platform_data *my_data = (struct platform_data *)platform;
2669    char *str = NULL;
2670    char value[256] = {0};
2671    int ret;
2672    char *kv_pairs = NULL;
2673    char propValue[PROPERTY_VALUE_MAX]={0};
2674    bool prop_playback_enabled = false;
2675
2676    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SLOWTALK,
2677                            value, sizeof(value));
2678    if (ret >= 0) {
2679        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SLOWTALK,
2680                          my_data->slowtalk?"true":"false");
2681    }
2682
2683    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_HD_VOICE,
2684                            value, sizeof(value));
2685    if (ret >= 0) {
2686        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_HD_VOICE,
2687                          my_data->hd_voice?"true":"false");
2688    }
2689
2690    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
2691                            value, sizeof(value));
2692    if (ret >= 0) {
2693        if (my_data->voice_feature_set == VOICE_FEATURE_SET_VOLUME_BOOST) {
2694            strlcpy(value, "on", sizeof(value));
2695        } else {
2696            strlcpy(value, "off", sizeof(value));
2697        }
2698
2699        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_VOLUME_BOOST, value);
2700    }
2701
2702    ret = str_parms_get_str(query, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED,
2703                                    value, sizeof(value));
2704    if (ret >= 0) {
2705        int isallowed = 1; /*true*/
2706
2707        if (property_get("voice.playback.conc.disabled", propValue, NULL)) {
2708            prop_playback_enabled = atoi(propValue) ||
2709                !strncmp("true", propValue, 4);
2710        }
2711
2712        if (prop_playback_enabled && (voice_is_in_call(my_data->adev) ||
2713             (SND_CARD_STATE_OFFLINE == get_snd_card_state(my_data->adev)))) {
2714            char *decoder_mime_type = value;
2715
2716            //check if unsupported mime type or not
2717            if(decoder_mime_type) {
2718                int i = 0;
2719                for (i = 0; i < sizeof(dsp_only_decoders_mime)/sizeof(dsp_only_decoders_mime[0]); i++) {
2720                    if (!strncmp(decoder_mime_type, dsp_only_decoders_mime[i],
2721                    strlen(dsp_only_decoders_mime[i]))) {
2722                       ALOGD("Rejecting request for DSP only session from HAL during voice call/SSR state");
2723                       isallowed = 0;
2724                       break;
2725                    }
2726                }
2727            }
2728        }
2729        str_parms_add_int(reply, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED, isallowed);
2730    }
2731
2732
2733    /* Handle audio calibration keys */
2734    kv_pairs = str_parms_to_str(reply);
2735    ALOGV("%s: exit: returns - %s", __func__, kv_pairs);
2736    free(kv_pairs);
2737}
2738
2739/* Delay in Us */
2740int64_t platform_render_latency(audio_usecase_t usecase)
2741{
2742    switch (usecase) {
2743        case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
2744            return DEEP_BUFFER_PLATFORM_DELAY;
2745        case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
2746            return LOW_LATENCY_PLATFORM_DELAY;
2747        default:
2748            return 0;
2749    }
2750}
2751
2752int platform_update_usecase_from_source(int source, int usecase)
2753{
2754    ALOGV("%s: input source :%d", __func__, source);
2755    if(source == AUDIO_SOURCE_FM_TUNER)
2756        usecase = USECASE_AUDIO_RECORD_FM_VIRTUAL;
2757    return usecase;
2758}
2759
2760bool platform_listen_device_needs_event(snd_device_t snd_device)
2761{
2762    bool needs_event = false;
2763
2764    if ((snd_device >= SND_DEVICE_IN_BEGIN) &&
2765        (snd_device < SND_DEVICE_IN_END) &&
2766        (snd_device != SND_DEVICE_IN_CAPTURE_FM) &&
2767        (snd_device != SND_DEVICE_IN_CAPTURE_VI_FEEDBACK))
2768        needs_event = true;
2769
2770    return needs_event;
2771}
2772
2773bool platform_listen_usecase_needs_event(audio_usecase_t uc_id)
2774{
2775    bool needs_event = false;
2776
2777    switch(uc_id){
2778    /* concurrent playback usecases needs event */
2779    case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
2780    case USECASE_AUDIO_PLAYBACK_MULTI_CH:
2781    case USECASE_AUDIO_PLAYBACK_OFFLOAD:
2782        needs_event = true;
2783        break;
2784    /* concurrent playback in low latency allowed */
2785    case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
2786        break;
2787    /* concurrent playback FM needs event */
2788    case USECASE_AUDIO_PLAYBACK_FM:
2789        needs_event = true;
2790        break;
2791
2792    /* concurrent capture usecases, no event, capture handled by device
2793    *  USECASE_AUDIO_RECORD:
2794    *  USECASE_AUDIO_RECORD_COMPRESS:
2795    *  USECASE_AUDIO_RECORD_LOW_LATENCY:
2796
2797    *  USECASE_VOICE_CALL:
2798    *  USECASE_VOICE2_CALL:
2799    *  USECASE_VOLTE_CALL:
2800    *  USECASE_QCHAT_CALL:
2801    *  USECASE_VOWLAN_CALL:
2802    *  USECASE_COMPRESS_VOIP_CALL:
2803    *  USECASE_AUDIO_RECORD_FM_VIRTUAL:
2804    *  USECASE_INCALL_REC_UPLINK:
2805    *  USECASE_INCALL_REC_DOWNLINK:
2806    *  USECASE_INCALL_REC_UPLINK_AND_DOWNLINK:
2807    *  USECASE_INCALL_REC_UPLINK_COMPRESS:
2808    *  USECASE_INCALL_REC_DOWNLINK_COMPRESS:
2809    *  USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS:
2810    *  USECASE_INCALL_MUSIC_UPLINK:
2811    *  USECASE_INCALL_MUSIC_UPLINK2:
2812    *  USECASE_AUDIO_SPKR_CALIB_RX:
2813    *  USECASE_AUDIO_SPKR_CALIB_TX:
2814    */
2815    default:
2816        ALOGV("%s:usecase_id[%d} no need to raise event.", __func__, uc_id);
2817    }
2818    return needs_event;
2819}
2820
2821bool platform_sound_trigger_device_needs_event(snd_device_t snd_device)
2822{
2823    bool needs_event = false;
2824
2825    if ((snd_device >= SND_DEVICE_IN_BEGIN) &&
2826        (snd_device < SND_DEVICE_IN_END) &&
2827        (snd_device != SND_DEVICE_IN_CAPTURE_FM) &&
2828        (snd_device != SND_DEVICE_IN_CAPTURE_VI_FEEDBACK))
2829        needs_event = true;
2830
2831    return needs_event;
2832}
2833
2834bool platform_sound_trigger_usecase_needs_event(audio_usecase_t uc_id)
2835{
2836    bool needs_event = false;
2837
2838    switch(uc_id){
2839    /* concurrent playback usecases needs event */
2840    case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
2841    case USECASE_AUDIO_PLAYBACK_MULTI_CH:
2842    case USECASE_AUDIO_PLAYBACK_OFFLOAD:
2843        needs_event = true;
2844        break;
2845    /* concurrent playback in low latency allowed */
2846    case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
2847        break;
2848    /* concurrent playback FM needs event */
2849    case USECASE_AUDIO_PLAYBACK_FM:
2850        needs_event = true;
2851        break;
2852
2853    /* concurrent capture usecases, no event, capture handled by device
2854    *  USECASE_AUDIO_RECORD:
2855    *  USECASE_AUDIO_RECORD_COMPRESS:
2856    *  USECASE_AUDIO_RECORD_LOW_LATENCY:
2857
2858    *  USECASE_VOICE_CALL:
2859    *  USECASE_VOICE2_CALL:
2860    *  USECASE_VOLTE_CALL:
2861    *  USECASE_QCHAT_CALL:
2862    *  USECASE_VOWLAN_CALL:
2863    *  USECASE_COMPRESS_VOIP_CALL:
2864    *  USECASE_AUDIO_RECORD_FM_VIRTUAL:
2865    *  USECASE_INCALL_REC_UPLINK:
2866    *  USECASE_INCALL_REC_DOWNLINK:
2867    *  USECASE_INCALL_REC_UPLINK_AND_DOWNLINK:
2868    *  USECASE_INCALL_REC_UPLINK_COMPRESS:
2869    *  USECASE_INCALL_REC_DOWNLINK_COMPRESS:
2870    *  USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS:
2871    *  USECASE_INCALL_MUSIC_UPLINK:
2872    *  USECASE_INCALL_MUSIC_UPLINK2:
2873    *  USECASE_AUDIO_SPKR_CALIB_RX:
2874    *  USECASE_AUDIO_SPKR_CALIB_TX:
2875    */
2876    default:
2877        ALOGV("%s:usecase_id[%d] no need to raise event.", __func__, uc_id);
2878    }
2879    return needs_event;
2880}
2881
2882/* Read  offload buffer size from a property.
2883 * If value is not power of 2  round it to
2884 * power of 2.
2885 */
2886uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info)
2887{
2888    char value[PROPERTY_VALUE_MAX] = {0};
2889    uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2890    if((property_get("audio.offload.buffer.size.kb", value, "")) &&
2891            atoi(value)) {
2892        fragment_size =  atoi(value) * 1024;
2893    }
2894
2895    if (info != NULL && info->has_video && info->is_streaming) {
2896        fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;
2897        ALOGV("%s: offload fragment size reduced for AV streaming to %d",
2898               __func__, fragment_size);
2899    }
2900
2901    fragment_size = ALIGN( fragment_size, 1024);
2902
2903    if(fragment_size < MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
2904        fragment_size = MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2905    else if(fragment_size > MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
2906        fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2907    ALOGV("%s: fragment_size %d", __func__, fragment_size);
2908    return fragment_size;
2909}
2910
2911uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
2912{
2913    uint32_t fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
2914    uint32_t bits_per_sample = 16;
2915
2916    if (info->format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) {
2917        bits_per_sample = 32;
2918    }
2919
2920    if (!info->has_video) {
2921        fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
2922
2923    } else if (info->has_video && info->is_streaming) {
2924        fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING
2925                                     * info->sample_rate
2926                                     * bits_per_sample
2927                                     * popcount(info->channel_mask))/1000;
2928
2929    } else if (info->has_video) {
2930        fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV
2931                                     * info->sample_rate
2932                                     * bits_per_sample
2933                                     * popcount(info->channel_mask))/1000;
2934    }
2935
2936    fragment_size = ALIGN( fragment_size, 1024);
2937
2938    if(fragment_size < MIN_PCM_OFFLOAD_FRAGMENT_SIZE)
2939        fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
2940    else if(fragment_size > MAX_PCM_OFFLOAD_FRAGMENT_SIZE)
2941        fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
2942
2943    ALOGV("%s: fragment_size %d", __func__, fragment_size);
2944    return fragment_size;
2945}
2946
2947void platform_get_device_to_be_id_map(int **device_to_be_id, int *length)
2948{
2949     *device_to_be_id = msm_device_to_be_id;
2950     *length = msm_be_id_array_len;
2951}
2952
2953bool platform_check_24_bit_support() {
2954    return false;
2955}
2956
2957bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev __unused,
2958                                              struct audio_usecase *usecase __unused)
2959{
2960    return false;
2961}
2962
2963int platform_get_usecase_index(const char * usecase __unused)
2964{
2965    return -ENOSYS;
2966}
2967
2968int platform_set_usecase_pcm_id(audio_usecase_t usecase __unused, int32_t type __unused,
2969                                int32_t pcm_id __unused)
2970{
2971    return -ENOSYS;
2972}
2973
2974int platform_set_snd_device_backend(snd_device_t snd_device __unused,
2975                                    const char * backend __unused)
2976{
2977    return -ENOSYS;
2978}
2979
2980int platform_get_subsys_image_name(char *buf)
2981{
2982    strlcpy(buf, PLATFORM_IMAGE_NAME, sizeof(PLATFORM_IMAGE_NAME));
2983    return 0;
2984}
2985
2986/*
2987 * This is a lookup table to map android audio input device to audio h/w interface (backend).
2988 * The table can be extended for other input devices by adding appropriate entries.
2989 * The audio interface for a particular input device need to be added in
2990 * audio_platform_info.xml file.
2991 */
2992struct audio_device_to_audio_interface audio_device_to_interface_table[] = {
2993    {AUDIO_DEVICE_IN_BUILTIN_MIC, ENUM_TO_STRING(AUDIO_DEVICE_IN_BUILTIN_MIC), ""},
2994    {AUDIO_DEVICE_IN_BACK_MIC, ENUM_TO_STRING(AUDIO_DEVICE_IN_BACK_MIC), ""},
2995};
2996
2997int audio_device_to_interface_table_len  =
2998    sizeof(audio_device_to_interface_table) / sizeof(audio_device_to_interface_table[0]);
2999
3000int platform_set_audio_device_interface(const char * device_name,
3001                                        const char *intf_name,
3002                                        const char *codec_type)
3003{
3004    int ret = 0;
3005    int i;
3006
3007    if (device_name == NULL || intf_name == NULL || codec_type == NULL) {
3008        ALOGE("%s: Invalid input", __func__);
3009
3010        ret = -EINVAL;
3011        goto done;
3012    }
3013
3014    ALOGD("%s: Enter, device name:%s, intf name:%s, codec_type:%s", __func__,
3015                            device_name, intf_name, codec_type);
3016
3017    size_t device_name_len = strlen(device_name);
3018    for (i = 0; i < audio_device_to_interface_table_len; i++) {
3019        char* name = audio_device_to_interface_table[i].device_name;
3020        size_t name_len = strlen(name);
3021        if ((name_len == device_name_len) &&
3022            (strncmp(device_name, name, name_len) == 0)) {
3023            if (is_external_codec &&
3024               (strncmp(codec_type, "external", strlen(codec_type)) == 0)) {
3025                ALOGD("%s: Matched device name:%s, overwrite intf name with %s",
3026                  __func__, device_name, intf_name);
3027
3028                strlcpy(audio_device_to_interface_table[i].interface_name, intf_name,
3029                    sizeof(audio_device_to_interface_table[i].interface_name));
3030            } else if (!is_external_codec &&
3031                       (strncmp(codec_type, "internal", strlen(codec_type)) == 0)) {
3032                ALOGD("%s: Matched device name:%s, overwrite intf name with %s",
3033                  __func__, device_name, intf_name);
3034
3035                strlcpy(audio_device_to_interface_table[i].interface_name, intf_name,
3036                    sizeof(audio_device_to_interface_table[i].interface_name));
3037            } else
3038                ALOGE("Invalid codec_type specified. Ignoring this interface entry.");
3039            goto done;
3040        }
3041    }
3042    ALOGE("%s: Could not find matching device name %s",
3043            __func__, device_name);
3044
3045    ret = -EINVAL;
3046
3047done:
3048    return ret;
3049}
3050