1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "msm8916_platform"
18 /*#define LOG_NDEBUG 0*/
19 #define LOG_NDDEBUG 0
20 
21 #include <stdlib.h>
22 #include <dlfcn.h>
23 #include <fcntl.h>
24 #include <sys/ioctl.h>
25 #include <log/log.h>
26 #include <cutils/properties.h>
27 #include <cutils/str_parms.h>
28 #include <audio_hw.h>
29 #include <platform_api.h>
30 #include "platform.h"
31 #include "audio_extn.h"
32 #include "acdb.h"
33 #include "voice_extn.h"
34 #include "sound/msmcal-hwdep.h"
35 #include "audio_extn/tfa_98xx.h"
36 #include <dirent.h>
37 #define MAX_MIXER_XML_PATH  100
38 #define MIXER_XML_PATH "mixer_paths.xml"
39 #define MIXER_XML_PATH_MTP "mixer_paths_mtp.xml"
40 #define MIXER_XML_PATH_MSM8909_PM8916 "mixer_paths_msm8909_pm8916.xml"
41 #define MIXER_XML_PATH_BG "mixer_paths_bg.xml"
42 #define MIXER_XML_PATH_L9300 "mixer_paths_l9300.xml"
43 
44 #define LIB_ACDB_LOADER "libacdbloader.so"
45 #define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
46 #define CVD_VERSION_MIXER_CTL "CVD Version"
47 
48 /*
49  * This file will have a maximum of 38 bytes:
50  *
51  * 4 bytes: number of audio blocks
52  * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
53  * Maximum 10 * 3 bytes: SAD blocks
54  */
55 #define MAX_SAD_BLOCKS      10
56 #define SAD_BLOCK_SIZE      3
57 #define MAX_CVD_VERSION_STRING_SIZE    100
58 
59 /* EDID format ID for LPCM audio */
60 #define EDID_FORMAT_LPCM    1
61 
62 /* fallback app type if the default app type from acdb loader fails */
63 #define DEFAULT_APP_TYPE_RX_PATH  0x11130
64 #define DEFAULT_APP_TYPE_TX_PATH  0x11132
65 #define DEFAULT_RX_BACKEND "SLIMBUS_0_RX"
66 
67 /* Retry for delay in FW loading*/
68 #define RETRY_NUMBER 20
69 #define RETRY_US 500000
70 #define MAX_SND_CARD 8
71 
72 #define SAMPLE_RATE_8KHZ  8000
73 #define SAMPLE_RATE_16KHZ 16000
74 
75 #define MAX_SET_CAL_BYTE_SIZE 65536
76 
77 #define MAX_CAL_NAME 20
78 
79 #define QMIC_FLAG 0x00000004
80 
81 #define TOSTRING_(x) #x
82 #define TOSTRING(x) TOSTRING_(x)
83 
84 #define GET_IN_DEVICE_INDEX(SND_DEVICE) ((SND_DEVICE) - (SND_DEVICE_IN_BEGIN))
85 
86 char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = {
87         [WCD9XXX_MBHC_CAL] = "mbhc_cal",
88 };
89 
90 struct audio_block_header
91 {
92     int reserved;
93     int length;
94 };
95 
96 typedef struct acdb_audio_cal_cfg {
97     uint32_t             persist;
98     uint32_t             snd_dev_id;
99     audio_devices_t      dev_id;
100     int32_t              acdb_dev_id;
101     uint32_t             app_type;
102     uint32_t             topo_id;
103     uint32_t             sampling_rate;
104     uint32_t             cal_type;
105     uint32_t             module_id;
106     uint32_t             param_id;
107 } acdb_audio_cal_cfg_t;
108 
109 enum {
110     CAL_MODE_SEND           = 0x1,
111     CAL_MODE_PERSIST        = 0x2,
112     CAL_MODE_RTAC           = 0x4
113 };
114 
115 enum {
116     BUFF_IDX_0 = 0,
117     BUFF_IDX_1 = 1,
118 };
119 
120 #define PLATFORM_CONFIG_KEY_OPERATOR_INFO "operator_info"
121 
122 struct operator_info {
123     struct listnode list;
124     char *name;
125     char *mccmnc;
126 };
127 
128 struct operator_specific_device {
129     struct listnode list;
130     char *operator;
131     char *mixer_path;
132     int acdb_id;
133 };
134 
135 static struct listnode operator_info_list;
136 static struct listnode *operator_specific_device_table[SND_DEVICE_MAX];
137 
138 /* Audio calibration related functions */
139 typedef void (*acdb_send_audio_cal_v3_t)(int, int, int , int, int);
140 typedef int (*acdb_loader_get_calibration_t)(char *attr, int size, void *data);
141 acdb_loader_get_calibration_t acdb_loader_get_calibration;
142 static int platform_get_meta_info_key_from_list(void *platform, char *mod_name);
143 
144 struct platform_data {
145     struct audio_device *adev;
146     bool fluence_in_spkr_mode;
147     bool fluence_in_voice_call;
148     bool fluence_in_voice_rec;
149     int  fluence_type;
150     char fluence_cap[PROPERTY_VALUE_MAX];
151     int  fluence_mode;
152     bool ec_ref_enabled;
153     bool gsm_mode_enabled;
154     /* Audio calibration related functions */
155     void                       *acdb_handle;
156     acdb_init_v3_t             acdb_init_v3;
157     acdb_init_v2_cvd_t         acdb_init;
158     acdb_deallocate_t          acdb_deallocate;
159     acdb_send_audio_cal_t      acdb_send_audio_cal;
160     acdb_send_audio_cal_v3_t   acdb_send_audio_cal_v3;
161     acdb_get_audio_cal_t       acdb_get_audio_cal;
162     acdb_send_voice_cal_t      acdb_send_voice_cal;
163     acdb_reload_vocvoltable_t  acdb_reload_vocvoltable;
164     void *hw_info;
165     char ec_ref_mixer_path[64];
166     bool speaker_lr_swap;
167 
168     int max_vol_index;
169     struct listnode acdb_meta_key_list;
170 };
171 
172 int pcm_device_table[AUDIO_USECASE_MAX][2] = {
173     [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
174                                             DEEP_BUFFER_PCM_DEVICE},
175     [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
176                                            LOWLATENCY_PCM_DEVICE},
177     [USECASE_AUDIO_PLAYBACK_HIFI] = {MULTIMEDIA2_PCM_DEVICE,
178                                         MULTIMEDIA2_PCM_DEVICE},
179     [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
180                      {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
181     [USECASE_AUDIO_PLAYBACK_ULL] = {MULTIMEDIA3_PCM_DEVICE, MULTIMEDIA3_PCM_DEVICE},
182     [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
183     [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
184                                           LOWLATENCY_PCM_DEVICE},
185     [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
186     [USECASE_AUDIO_HFP_SCO_WB] = {HFP_PCM_RX, HFP_SCO_RX},
187     [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE, VOICE_CALL_PCM_DEVICE},
188     [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
189     [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
190     [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
191     [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
192     [USECASE_VOICEMMODE1_CALL] = {-1, -1}, /* pcm ids updated from platform info file */
193     [USECASE_VOICEMMODE2_CALL] = {-1, -1}, /* pcm ids updated from platform info file */
194     [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
195                                    AUDIO_RECORD_PCM_DEVICE},
196     [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
197                                      AUDIO_RECORD_PCM_DEVICE},
198     [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
199                                                 AUDIO_RECORD_PCM_DEVICE},
200     [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
201     [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
202     [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
203                                           AFE_PROXY_RECORD_PCM_DEVICE},
204     [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
205                                         AFE_PROXY_RECORD_PCM_DEVICE},
206 };
207 
208 /* Array to store sound devices */
209 static const char * const device_table[SND_DEVICE_MAX] = {
210     [SND_DEVICE_NONE] = "none",
211     /* Playback sound devices */
212     [SND_DEVICE_OUT_HANDSET] = "handset",
213     [SND_DEVICE_OUT_SPEAKER] = "speaker",
214     [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
215     [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
216     [SND_DEVICE_OUT_HEADPHONES] = "headphones",
217     [SND_DEVICE_OUT_LINE] = "line",
218     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
219     [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
220     [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
221     [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
222     [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
223     [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = "voice-speaker-hfp",
224     [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
225     [SND_DEVICE_OUT_VOICE_HEADSET] = "voice-headphones",
226     [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
227     [SND_DEVICE_OUT_HDMI] = "hdmi",
228     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
229     [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
230     [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
231     [SND_DEVICE_OUT_BT_A2DP] = "bt-a2dp",
232     [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = "speaker-and-bt-a2dp",
233     [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] = "speaker-safe-and-bt-a2dp",
234     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
235     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
236     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
237     [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
238     [SND_DEVICE_OUT_VOICE_MUSIC_TX] = "voice-music-tx",
239     [SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy",
240     [SND_DEVICE_OUT_USB_HEADSET] = "usb-headphones",
241     [SND_DEVICE_OUT_USB_HEADPHONES] = "usb-headphones",
242     [SND_DEVICE_OUT_VOICE_USB_HEADSET] = "usb-headphones",
243     [SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = "usb-headphones",
244     [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
245     [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
246     [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
247 
248     /* Capture sound devices */
249     [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
250     [SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = "handset-mic-ext",
251     [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
252     [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
253     [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
254     [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
255     [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
256     [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
257     [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
258     [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
259     [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
260     [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
261     [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
262     [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
263     [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
264     [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
265     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
266     [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
267     [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = "headset-mic",
268     [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
269     [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = "voice-speaker-mic-hfp",
270     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
271     [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
272     [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
273     [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
274     [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
275     [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
276     [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
277     [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
278     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
279     [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = "voice-speaker-qmic",
280     [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
281     [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
282     [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
283     [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
284     [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
285     [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
286     [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
287     [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
288     [SND_DEVICE_IN_USB_HEADSET_MIC] = "usb-headset-mic",
289     [SND_DEVICE_IN_CAPTURE_FM] = "capture-fm",
290     [SND_DEVICE_IN_AANC_HANDSET_MIC] = "aanc-handset-mic",
291     [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
292     [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = "handset-stereo-dmic-ef",
293     [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = "speaker-stereo-dmic-ef",
294     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
295     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE] = "voice-speaker-dmic-broadside",
296     [SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE] = "speaker-dmic-broadside",
297     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE] = "speaker-dmic-broadside",
298     [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = "speaker-dmic-broadside",
299     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = "speaker-dmic-broadside",
300     [SND_DEVICE_IN_HANDSET_QMIC] = "quad-mic",
301     [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = "quad-mic",
302     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
303     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
304 };
305 
306 static struct audio_effect_config \
307                effect_config_table[GET_IN_DEVICE_INDEX(SND_DEVICE_MAX)][EFFECT_COUNT] = {
308     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_AEC] = \
309                                       {TX_VOICE_FLUENCE_PROV2, 0x0, 0x10EAF, 0x01},
310     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_NS] = \
311                                       {TX_VOICE_FLUENCE_PROV2,  0x0, 0x10EAF, 0x02},
312     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)][EFFECT_AEC] = \
313                                       {TX_VOICE_DM_FV5_BROADSIDE, 0x0, 0x10EAF, 0x01},
314     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)][EFFECT_NS] = \
315                                       {TX_VOICE_DM_FV5_BROADSIDE, 0x0, 0x10EAF, 0x02},
316     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_AEC] = \
317                                       {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
318     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_NS] = \
319                                       {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
320     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_AEC] = \
321                                       {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
322     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_NS] = \
323                                       {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
324     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_AEC] = \
325                                       {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
326     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_NS] = \
327                                       {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
328     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_AEC] = \
329                                       {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
330     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_NS] = \
331                                       {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
332 };
333 
334 /* ACDB IDs (audio DSP path configuration IDs) for each sound device */
335 static int acdb_device_table[SND_DEVICE_MAX] = {
336     [SND_DEVICE_NONE] = -1,
337     [SND_DEVICE_OUT_HANDSET] = 7,
338     [SND_DEVICE_OUT_SPEAKER] = 14,
339     [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
340     [SND_DEVICE_OUT_SPEAKER_SAFE] = 14,
341     [SND_DEVICE_OUT_LINE] = 10,
342     [SND_DEVICE_OUT_HEADPHONES] = 10,
343     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
344     [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 10,
345     [SND_DEVICE_OUT_VOICE_HANDSET] = 7,
346     [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
347     [SND_DEVICE_OUT_VOICE_LINE] = 10,
348     [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
349     [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
350     [SND_DEVICE_OUT_VOICE_HEADSET] = 10,
351     [SND_DEVICE_OUT_HDMI] = 18,
352     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
353     [SND_DEVICE_OUT_BT_SCO] = 22,
354     [SND_DEVICE_OUT_BT_SCO_WB] = 39,
355     [SND_DEVICE_OUT_BT_A2DP] = 20,
356     [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = 14,
357     [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] = 14,
358     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
359     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
360     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
361     [SND_DEVICE_OUT_VOICE_TX] = 45,
362     [SND_DEVICE_OUT_VOICE_MUSIC_TX] = 3,
363     [SND_DEVICE_OUT_AFE_PROXY] = 0,
364     [SND_DEVICE_OUT_USB_HEADSET] = 45,
365     [SND_DEVICE_OUT_VOICE_USB_HEADSET] = 45,
366     [SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = 45,
367     [SND_DEVICE_OUT_USB_HEADPHONES] = 45,
368     [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
369     [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
370     [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
371     [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = 140,
372 
373     [SND_DEVICE_IN_HANDSET_MIC] = 4,
374     [SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = 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_MIC_HFP] = 141,
402     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
403     [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = 19,
404     [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
405     [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
406     [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
407     [SND_DEVICE_IN_VOICE_REC_MIC] = 4,
408     [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107,
409     [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34,
410     [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 41,
411     [SND_DEVICE_IN_VOICE_RX] = 44,
412     [SND_DEVICE_IN_USB_HEADSET_MIC] = 44,
413     [SND_DEVICE_IN_CAPTURE_FM] = 0,
414     [SND_DEVICE_IN_AANC_HANDSET_MIC] = 104,
415     [SND_DEVICE_IN_QUAD_MIC] = 46,
416     [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = 34,
417     [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = 35,
418     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
419     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE] = 12,
420     [SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE] = 12,
421     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE] = 119,
422     [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = 121,
423     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = 120,
424     [SND_DEVICE_IN_HANDSET_QMIC] = 125,
425     [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
426     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
427     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
428 };
429 
430 struct name_to_index {
431     char name[100];
432     unsigned int index;
433 };
434 
435 #define TO_NAME_INDEX(X)   #X, X
436 
437 /* Used to get index from parsed sting */
438 static struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
439     {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
440     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
441     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
442     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
443     {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
444     {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
445     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
446     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
447     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
448     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
449     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
450     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_HFP)},
451     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
452     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADSET)},
453     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
454     {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
455     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
456     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
457     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
458     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_A2DP)},
459     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP)},
460     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP)},
461     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
462     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
463     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
464     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TX)},
465     {TO_NAME_INDEX(SND_DEVICE_OUT_AFE_PROXY)},
466     {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET)},
467     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_USB_HEADSET)},
468     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_USB_HEADPHONES)},
469     {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADPHONES)},
470     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)},
471     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
472     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
473     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
474     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_EXTERNAL)},
475     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
476     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
477     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
478     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
479     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
480     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
481     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
482     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
483     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
484     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
485     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
486     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
487     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
488     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
489     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
490     {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
491     {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_FLUENCE)},
492     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
493     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP)},
494     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
495     {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
496     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
497     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
498     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
499     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
500     {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
501     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
502     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
503     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_QMIC)},
504     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
505     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
506     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
507     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
508     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
509     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
510     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
511     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_RX)},
512     {TO_NAME_INDEX(SND_DEVICE_IN_USB_HEADSET_MIC)},
513     {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_FM)},
514     {TO_NAME_INDEX(SND_DEVICE_IN_AANC_HANDSET_MIC)},
515     {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
516     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_STEREO_DMIC)},
517     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_STEREO_DMIC)},
518     {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
519     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE)},
520     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE)},
521     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE)},
522     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE)},
523     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)},
524     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
525     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
526     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
527     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
528 };
529 
530 static char * backend_table[SND_DEVICE_MAX] = {0};
531 static char * hw_interface_table[SND_DEVICE_MAX] = {0};
532 
533 static struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
534     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
535     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
536     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_HIFI)},
537     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
538     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
539     {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
540     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
541     {TO_NAME_INDEX(USECASE_VOICE_CALL)},
542     {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
543     {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
544     {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
545     {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
546     {TO_NAME_INDEX(USECASE_VOICEMMODE1_CALL)},
547     {TO_NAME_INDEX(USECASE_VOICEMMODE2_CALL)},
548     {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
549     {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO_WB)},
550     {TO_NAME_INDEX(USECASE_AUDIO_SPKR_CALIB_TX)},
551     {TO_NAME_INDEX(USECASE_AUDIO_A2DP_ABR_FEEDBACK)},
552 };
553 
554 #define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
555 #define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
556 
557 static void query_platform(const char *snd_card_name,
558                                       char *mixer_xml_path)
559 {
560     if (!strncmp(snd_card_name, "msm8x16-snd-card-mtp",
561                  sizeof("msm8x16-snd-card-mtp"))) {
562         strlcpy(mixer_xml_path, MIXER_XML_PATH_MTP,
563                 sizeof(MIXER_XML_PATH_MTP));
564     } else if (!strncmp(snd_card_name, "msm8909-pm8916-snd-card",
565                  sizeof("msm8909-pm8916-snd-card"))) {
566         strlcpy(mixer_xml_path, MIXER_XML_PATH_MSM8909_PM8916,
567                 sizeof(MIXER_XML_PATH_MSM8909_PM8916));
568     } else if (!strncmp(snd_card_name, "msm-bg-snd-card",
569                 sizeof("msm-bg-snd-card"))) {
570         strlcpy(mixer_xml_path, MIXER_XML_PATH_BG,
571                 sizeof(MIXER_XML_PATH_BG));
572     } else if (!strncmp(snd_card_name, "msm8952-snd-card-mtp",
573                  sizeof("msm8952-snd-card-mtp"))) {
574         strlcpy(mixer_xml_path, MIXER_XML_PATH_MTP,
575                 sizeof(MIXER_XML_PATH_MTP));
576     } else if (!strncmp(snd_card_name, "msm8952-l9300-snd-card",
577                  sizeof("msm8952-l9300-snd-card"))) {
578         strlcpy(mixer_xml_path, MIXER_XML_PATH_L9300,
579                 sizeof(MIXER_XML_PATH_L9300));
580     } else {
581         strlcpy(mixer_xml_path, MIXER_XML_PATH,
582                 sizeof(MIXER_XML_PATH));
583     }
584 }
585 
586 static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
587 static bool is_tmus = false;
588 
589 static void check_operator()
590 {
591     char value[PROPERTY_VALUE_MAX];
592     int mccmnc;
593     property_get("gsm.sim.operator.numeric",value,"0");
594     mccmnc = atoi(value);
595     ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
596     switch(mccmnc) {
597     /* TMUS MCC(310), MNC(490, 260, 026) */
598     case 310490:
599     case 310260:
600     case 310026:
601     /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
602     case 310800:
603     case 310660:
604     case 310580:
605     case 310310:
606     case 310270:
607     case 310250:
608     case 310240:
609     case 310230:
610     case 310220:
611     case 310210:
612     case 310200:
613     case 310160:
614         is_tmus = true;
615         break;
616     }
617 }
618 
619 bool is_operator_tmus()
620 {
621     pthread_once(&check_op_once_ctl, check_operator);
622     return is_tmus;
623 }
624 
625 static char *get_current_operator()
626 {
627     struct listnode *node;
628     struct operator_info *info_item;
629     char mccmnc[PROPERTY_VALUE_MAX];
630     char *ret = NULL;
631 
632     property_get("gsm.sim.operator.numeric",mccmnc,"00000");
633 
634     list_for_each(node, &operator_info_list) {
635         info_item = node_to_item(node, struct operator_info, list);
636         if (strstr(info_item->mccmnc, mccmnc) != NULL) {
637             ret = info_item->name;
638         }
639     }
640 
641     return ret;
642 }
643 
644 static struct operator_specific_device *get_operator_specific_device(snd_device_t snd_device)
645 {
646     struct listnode *node;
647     struct operator_specific_device *ret = NULL;
648     struct operator_specific_device *device_item;
649     char *operator_name;
650 
651     operator_name = get_current_operator();
652     if (operator_name == NULL)
653         return ret;
654 
655     list_for_each(node, operator_specific_device_table[snd_device]) {
656         device_item = node_to_item(node, struct operator_specific_device, list);
657         if (strcmp(operator_name, device_item->operator) == 0) {
658             ret = device_item;
659         }
660     }
661 
662     return ret;
663 }
664 
665 static int get_operator_specific_device_acdb_id(snd_device_t snd_device)
666 {
667     struct operator_specific_device *device;
668     int ret = acdb_device_table[snd_device];
669 
670     device = get_operator_specific_device(snd_device);
671     if (device != NULL)
672         ret = device->acdb_id;
673 
674     return ret;
675 }
676 
677 static const char *get_operator_specific_device_mixer_path(snd_device_t snd_device)
678 {
679     struct operator_specific_device *device;
680     const char *ret = device_table[snd_device];
681 
682     device = get_operator_specific_device(snd_device);
683     if (device != NULL)
684         ret = device->mixer_path;
685 
686     return ret;
687 }
688 
689 bool platform_send_gain_dep_cal(void *platform __unused, int level __unused)
690 {
691     return true;
692 }
693 
694 void platform_set_echo_reference(struct audio_device *adev, bool enable,
695     audio_devices_t out_device)
696 {
697     struct platform_data *my_data = (struct platform_data *)adev->platform;
698     snd_device_t snd_device = SND_DEVICE_NONE;
699 
700     if (strcmp(my_data->ec_ref_mixer_path, "")) {
701         ALOGV("%s: disabling %s", __func__, my_data->ec_ref_mixer_path);
702         audio_route_reset_and_update_path(adev->audio_route,
703             my_data->ec_ref_mixer_path);
704     }
705 
706     if (enable) {
707         if (out_device != AUDIO_DEVICE_NONE) {
708             snd_device = platform_get_output_snd_device(adev->platform, out_device);
709             platform_add_backend_name(adev->platform, my_data->ec_ref_mixer_path, snd_device);
710         }
711 
712         strlcpy(my_data->ec_ref_mixer_path, "echo-reference",
713             sizeof(my_data->ec_ref_mixer_path));
714 
715         ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
716         audio_route_apply_and_update_path(adev->audio_route,
717             my_data->ec_ref_mixer_path);
718     }
719 }
720 
721 static void set_platform_defaults()
722 {
723     int32_t dev;
724     for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
725         backend_table[dev] = NULL;
726         hw_interface_table[dev] = NULL;
727     }
728 
729     // TBD - do these go to the platform-info.xml file.
730     // will help in avoiding strdups here
731     backend_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
732     backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
733     backend_table[SND_DEVICE_IN_BT_SCO_MIC_NREC] = strdup("bt-sco");
734     backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = strdup("bt-sco-wb");
735     backend_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
736     backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
737     backend_table[SND_DEVICE_OUT_BT_A2DP] = strdup("bt-a2dp");
738     backend_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
739     backend_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] =
740         strdup("speaker-safe-and-bt-a2dp");
741     backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
742     backend_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
743     backend_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
744     backend_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
745     backend_table[SND_DEVICE_OUT_AFE_PROXY] = strdup("afe-proxy");
746     backend_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("usb-headphones");
747     backend_table[SND_DEVICE_OUT_VOICE_USB_HEADSET] = strdup("usb-headphones");
748     backend_table[SND_DEVICE_OUT_USB_HEADPHONES] = strdup("usb-headphones");
749     backend_table[SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = strdup("usb-headphones");
750     backend_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] =
751         strdup("speaker-and-usb-headphones");
752     backend_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
753     backend_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("capture-fm");
754 }
755 
756 void get_cvd_version(char *cvd_version, struct audio_device *adev)
757 {
758     struct mixer_ctl *ctl;
759     int count;
760     int ret = 0;
761 
762     ctl = mixer_get_ctl_by_name(adev->mixer, CVD_VERSION_MIXER_CTL);
763     if (!ctl) {
764         ALOGE("%s: Could not get ctl for mixer cmd - %s",  __func__, CVD_VERSION_MIXER_CTL);
765         goto done;
766     }
767     mixer_ctl_update(ctl);
768 
769     count = mixer_ctl_get_num_values(ctl);
770     if (count > MAX_CVD_VERSION_STRING_SIZE)
771         count = MAX_CVD_VERSION_STRING_SIZE -1;
772 
773     ret = mixer_ctl_get_array(ctl, cvd_version, count);
774     if (ret != 0) {
775         ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
776         goto done;
777     }
778 
779 done:
780     return;
781 }
782 
783 static int hw_util_open(int card_no)
784 {
785     int fd = -1;
786     char dev_name[256];
787 
788     snprintf(dev_name, sizeof(dev_name), "/dev/snd/hwC%uD%u",
789                                card_no, WCD9XXX_CODEC_HWDEP_NODE);
790     ALOGD("%s Opening device %s\n", __func__, dev_name);
791     fd = open(dev_name, O_WRONLY);
792     if (fd < 0) {
793         ALOGE("%s: cannot open device '%s'\n", __func__, dev_name);
794         return fd;
795     }
796     ALOGD("%s success", __func__);
797     return fd;
798 }
799 
800 struct param_data {
801     int    use_case;
802     int    acdb_id;
803     int    get_size;
804     int    buff_size;
805     int    data_size;
806     void   *buff;
807 };
808 
809 static int send_bg_cal(struct platform_data *plat_data,
810                         int type, int fd)
811 {
812     /*
813      * This is done to avoid compiler failure due to unused varialbes
814      * if both the below #defines are not present
815      */
816     (void)plat_data;
817     (void)type;
818     (void)fd;
819 
820 #ifdef BG_CAL_SUPPORT
821     if ((type == BG_CODEC_MIC_CAL) ||
822         (type == BG_CODEC_SPEAKER_CAL)) {
823 #ifdef BG_CODEC_CAL
824         int ret = 0, key = 0;
825         uint32_t param_len;
826         uint8_t *dptr = NULL;
827         struct wcdcal_ioctl_buffer codec_buffer;
828         acdb_audio_cal_cfg_t cal;
829 
830         memset(&cal, 0, sizeof(cal));
831         cal.persist = 1;
832         cal.cal_type = AUDIO_CORE_METAINFO_CAL_TYPE;
833         param_len = MAX_SET_CAL_BYTE_SIZE;
834         dptr = (unsigned char*) calloc(param_len, sizeof(unsigned char*));
835         if (dptr == NULL) {
836             ALOGE("%s Memory allocation failed for length %d",
837                     __func__, param_len);
838             return 0;
839         }
840         if (type == BG_CODEC_MIC_CAL) {
841             key = platform_get_meta_info_key_from_list(plat_data,
842                                                        "bg_miccal");
843             if (!key) {
844                 ALOGE("%s Failed to fetch mic metakey info", __func__);
845                 goto done;
846             }
847             ALOGV("%s BG mic with key:0x%x", __func__, key);
848             codec_buffer.cal_type = BG_CODEC_MIC_CAL;
849         } else if (type == BG_CODEC_SPEAKER_CAL) {
850             key = platform_get_meta_info_key_from_list(plat_data,
851                                                        "bg_speakercal");
852             if (!key) {
853                 ALOGE("%s Failed to fetch metakey info", __func__);
854                 goto done;
855             }
856             ALOGV("%s BG speaker with key:0x%x", __func__, key);
857             codec_buffer.cal_type = BG_CODEC_SPEAKER_CAL;
858         }
859         cal.acdb_dev_id = key;
860         ret = plat_data->acdb_get_audio_cal((void*)&cal, (void*)dptr,
861                                             &param_len);
862         if (ret) {
863             ALOGE("%s failed to get meta info for key 0x%x error %d",
864                     __func__, key, ret);
865             goto done;
866         }
867         codec_buffer.buffer = dptr;
868         codec_buffer.size = param_len;
869 
870         if (ioctl(fd, SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE, &codec_buffer) < 0)
871             ALOGE("Failed to call ioctl  for mic err=%d calib.size=%d",
872                     errno, codec_buffer.size);
873         else
874             ALOGD("%s cal sent for %d calib.size=%d",
875                     __func__, cal.acdb_dev_id, codec_buffer.size);
876     done:
877         free(dptr);
878 #endif /* #ifdef BG_CODEC_CAL */
879         return 0;
880     } else
881 #endif /* #ifdef BG_CAL_SUPPORT */
882       return -1;
883 }
884 
885 static int send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration,
886                           struct platform_data *plat_data , int fd)
887 {
888     int ret = 0, type;
889 
890     for (type = WCD9XXX_ANC_CAL; type < WCD9XXX_MAX_CAL; type++) {
891         struct wcdcal_ioctl_buffer codec_buffer;
892         struct param_data calib;
893 
894         if (send_bg_cal(plat_data, type, fd) == 0)
895             continue;
896 
897         if (type != WCD9XXX_MBHC_CAL)
898             continue;
899 
900         calib.get_size = 1;
901         ret = acdb_loader_get_calibration(cal_name_info[type], sizeof(struct param_data),
902                                                                  &calib);
903         if (ret < 0) {
904             ALOGE("%s get_calibration failed\n", __func__);
905             return ret;
906         }
907         calib.get_size = 0;
908         calib.buff = malloc(calib.buff_size);
909         if(calib.buff == NULL) {
910             ALOGE("%s mem allocation for %d bytes for %s failed\n"
911                 , __func__, calib.buff_size, cal_name_info[type]);
912             return -1;
913         }
914         ret = acdb_loader_get_calibration(cal_name_info[type],
915                               sizeof(struct param_data), &calib);
916         if (ret < 0) {
917             ALOGE("%s get_calibration failed type=%s calib.size=%d\n"
918                 , __func__, cal_name_info[type], codec_buffer.size);
919             free(calib.buff);
920             return ret;
921         }
922         codec_buffer.buffer = calib.buff;
923         codec_buffer.size = calib.data_size;
924         codec_buffer.cal_type = type;
925         if (ioctl(fd, SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE, &codec_buffer) < 0)
926             ALOGE("Failed to call ioctl  for %s err=%d calib.size=%d",
927                 cal_name_info[type], errno, codec_buffer.size);
928         ALOGD("%s cal sent for %s calib.size=%d"
929             , __func__, cal_name_info[type], codec_buffer.size);
930         free(calib.buff);
931     }
932     return ret;
933 }
934 
935 static void audio_hwdep_send_cal(struct platform_data *plat_data)
936 {
937     int fd;
938 
939     fd = hw_util_open(plat_data->adev->snd_card);
940     if (fd == -1) {
941         ALOGE("%s error open\n", __func__);
942         return;
943     }
944 
945     acdb_loader_get_calibration = (acdb_loader_get_calibration_t)
946           dlsym(plat_data->acdb_handle, "acdb_loader_get_calibration");
947 
948     if (acdb_loader_get_calibration == NULL) {
949         ALOGE("%s: ERROR. dlsym Error:%s acdb_loader_get_calibration", __func__,
950            dlerror());
951         return;
952     }
953     if (send_codec_cal(acdb_loader_get_calibration, plat_data, fd) < 0)
954         ALOGE("%s: Could not send anc cal", __FUNCTION__);
955 }
956 
957 
958 int platform_acdb_init(void *platform)
959 {
960     struct platform_data *my_data = (struct platform_data *)platform;
961     char *cvd_version = NULL;
962     int key = 0;
963     const char *snd_card_name;
964     int result = 0;
965     char value[PROPERTY_VALUE_MAX];
966     struct listnode *node;
967     struct meta_key_list *key_info;
968 
969     cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
970     if (!cvd_version)
971         ALOGE("Failed to allocate cvd version");
972     else
973         get_cvd_version(cvd_version, my_data->adev);
974 
975     property_get("audio.ds1.metainfo.key",value,"0");
976     key = atoi(value);
977     snd_card_name = mixer_get_name(my_data->adev->mixer);
978 
979     if (my_data->acdb_init_v3) {
980         result = my_data->acdb_init_v3(snd_card_name, cvd_version,
981                                            &my_data->acdb_meta_key_list);
982     } else if (my_data->acdb_init) {
983         result = my_data->acdb_init((char *)snd_card_name, cvd_version, key);
984     }
985 
986     if (cvd_version)
987         free(cvd_version);
988     if (!result) {
989         ALOGD("ACDB initialized");
990         audio_hwdep_send_cal(my_data);
991     } else {
992         ALOGD("ACDB initialization failed");
993     }
994     return result;
995 }
996 
997 // Treblized config files will be located in /odm/etc or /vendor/etc.
998 static const char *kConfigLocationList[] =
999         {"/odm/etc", "/vendor/etc", "/system/etc"};
1000 static const int kConfigLocationListSize =
1001         (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
1002 
1003 bool resolve_config_file(char file_name[MIXER_PATH_MAX_LENGTH]) {
1004     char full_config_path[MIXER_PATH_MAX_LENGTH];
1005     for (int i = 0; i < kConfigLocationListSize; i++) {
1006         snprintf(full_config_path,
1007                  MIXER_PATH_MAX_LENGTH,
1008                  "%s/%s",
1009                  kConfigLocationList[i],
1010                  file_name);
1011         if (F_OK == access(full_config_path, 0)) {
1012             strcpy(file_name, full_config_path);
1013             return true;
1014         }
1015     }
1016     return false;
1017 }
1018 
1019 void *platform_init(struct audio_device *adev)
1020 {
1021     char platform[PROPERTY_VALUE_MAX] = {0};
1022     char baseband[PROPERTY_VALUE_MAX] = {0};
1023     char value[PROPERTY_VALUE_MAX] = {0};
1024     struct platform_data *my_data = NULL;
1025     int retry_num = 0, snd_card_num = 0, key = 0;
1026     const char *snd_card_name;
1027     char mixer_xml_path[MAX_MIXER_XML_PATH] = {0};
1028     char platform_info_path[MAX_MIXER_XML_PATH] = {0};
1029     char ffspEnable[PROPERTY_VALUE_MAX] = {0};
1030     char *cvd_version = NULL;
1031     int idx;
1032 
1033     my_data = calloc(1, sizeof(struct platform_data));
1034     if (!my_data) {
1035         ALOGE("failed to allocate platform data");
1036         return NULL;
1037     }
1038 
1039     list_init(&operator_info_list);
1040     bool card_verifed[MAX_SND_CARD] = {0};
1041     const int retry_limit = property_get_int32("audio.snd_card.open.retries", RETRY_NUMBER);
1042 
1043     for (;;) {
1044         if (snd_card_num >= MAX_SND_CARD) {
1045             if (retry_num++ >= retry_limit) {
1046                 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
1047                 free(my_data);
1048                 my_data = NULL;
1049                 return NULL;
1050             }
1051 
1052             snd_card_num = 0;
1053             usleep(RETRY_US);
1054             continue;
1055         }
1056 
1057         if (card_verifed[snd_card_num]) {
1058             ++snd_card_num;
1059             continue;
1060         }
1061 
1062         adev->mixer = mixer_open(snd_card_num);
1063 
1064         if (!adev->mixer) {
1065             ALOGE("%s: Unable to open the mixer card: %d", __func__,
1066                snd_card_num);
1067             ++snd_card_num;
1068             continue;
1069         }
1070 
1071         card_verifed[snd_card_num] = true;
1072 
1073         snd_card_name = mixer_get_name(adev->mixer);
1074         ALOGV("%s: snd_card_name: %s", __func__, snd_card_name);
1075 
1076         my_data->hw_info = hw_info_init(snd_card_name);
1077         if (!my_data->hw_info) {
1078             ALOGE("%s: Failed to init hardware info", __func__);
1079         } else {
1080             query_platform(snd_card_name, mixer_xml_path);
1081             if (!resolve_config_file(mixer_xml_path)) {
1082                 memset(mixer_xml_path, 0, sizeof(mixer_xml_path));
1083                 strlcpy(mixer_xml_path, MIXER_XML_PATH, MAX_MIXER_XML_PATH);
1084                 resolve_config_file(mixer_xml_path);
1085             }
1086             ALOGD("%s: mixer path file is %s", __func__,
1087                                     mixer_xml_path);
1088             adev->audio_route = audio_route_init(snd_card_num,
1089                                                  mixer_xml_path);
1090             if (!adev->audio_route) {
1091                 ALOGE("%s: Failed to init audio route controls, aborting.",
1092                        __func__);
1093                 hw_info_deinit(my_data->hw_info);
1094                 my_data->hw_info = NULL;
1095                 free(my_data);
1096                 my_data = NULL;
1097                 mixer_close(adev->mixer);
1098                 adev->mixer = NULL;
1099                 return NULL;
1100             }
1101             adev->snd_card = snd_card_num;
1102             ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
1103             break;
1104         }
1105         ++snd_card_num;
1106         mixer_close(adev->mixer);
1107         adev->mixer = NULL;
1108     }
1109 
1110     //set max volume step for voice call
1111     property_get("ro.config.vc_call_vol_steps", value, TOSTRING(MAX_VOL_INDEX));
1112     my_data->max_vol_index = atoi(value);
1113 
1114     my_data->adev = adev;
1115     my_data->fluence_in_spkr_mode = false;
1116     my_data->fluence_in_voice_call = false;
1117     my_data->fluence_in_voice_rec = false;
1118     my_data->fluence_type = FLUENCE_NONE;
1119     my_data->fluence_mode = FLUENCE_ENDFIRE;
1120 
1121     property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
1122     if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
1123         my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
1124     } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
1125         my_data->fluence_type = FLUENCE_DUAL_MIC;
1126     } else {
1127         my_data->fluence_type = FLUENCE_NONE;
1128     }
1129 
1130     if (my_data->fluence_type != FLUENCE_NONE) {
1131         property_get("persist.audio.fluence.voicecall",value,"");
1132         if (!strncmp("true", value, sizeof("true"))) {
1133             my_data->fluence_in_voice_call = true;
1134         }
1135 
1136         property_get("persist.audio.fluence.voicerec",value,"");
1137         if (!strncmp("true", value, sizeof("true"))) {
1138             my_data->fluence_in_voice_rec = true;
1139         }
1140 
1141         property_get("persist.audio.fluence.speaker",value,"");
1142         if (!strncmp("true", value, sizeof("true"))) {
1143             my_data->fluence_in_spkr_mode = true;
1144         }
1145 
1146         property_get("persist.audio.fluence.mode",value,"");
1147         if (!strncmp("broadside", value, sizeof("broadside"))) {
1148             my_data->fluence_mode = FLUENCE_BROADSIDE;
1149         }
1150     }
1151 
1152     property_get("persist.audio.FFSP.enable", ffspEnable, "");
1153     if (!strncmp("true", ffspEnable, sizeof("true"))) {
1154         acdb_device_table[SND_DEVICE_OUT_SPEAKER] = 131;
1155         acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = 131;
1156         acdb_device_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 131;
1157         acdb_device_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 131;
1158     }
1159 
1160     list_init(&my_data->acdb_meta_key_list);
1161     set_platform_defaults();
1162     /* Initialize ACDB and PCM ID's */
1163     strlcpy(platform_info_path, PLATFORM_INFO_XML_PATH, MAX_MIXER_XML_PATH);
1164     resolve_config_file(platform_info_path);
1165     platform_info_init(platform_info_path, my_data,
1166                        true, &platform_set_parameters);
1167 
1168     my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
1169     if (my_data->acdb_handle == NULL) {
1170         ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
1171     } else {
1172         ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
1173         my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
1174                                                     "acdb_loader_deallocate_ACDB");
1175         if (!my_data->acdb_deallocate)
1176             ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
1177                   __func__, LIB_ACDB_LOADER);
1178 
1179         my_data->acdb_send_audio_cal_v3 = (acdb_send_audio_cal_v3_t)dlsym(my_data->acdb_handle,
1180                                                     "acdb_loader_send_audio_cal_v3");
1181         if (!my_data->acdb_send_audio_cal_v3)
1182             ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
1183                   __func__, LIB_ACDB_LOADER);
1184 
1185         my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
1186                                                     "acdb_loader_send_audio_cal");
1187         if (!my_data->acdb_send_audio_cal)
1188             ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
1189                   __func__, LIB_ACDB_LOADER);
1190 
1191         my_data->acdb_get_audio_cal = (acdb_get_audio_cal_t)dlsym(my_data->acdb_handle,
1192                                                   "acdb_loader_get_audio_cal_v2");
1193         if (!my_data->acdb_get_audio_cal)
1194             ALOGE("%s: Could not find the symbol acdb_get_audio_cal_v2 from %s",
1195                   __func__, LIB_ACDB_LOADER);
1196 
1197         my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
1198                                                     "acdb_loader_send_voice_cal");
1199         if (!my_data->acdb_send_voice_cal)
1200             ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
1201                   __func__, LIB_ACDB_LOADER);
1202 
1203         my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
1204                                                     "acdb_loader_reload_vocvoltable");
1205         if (!my_data->acdb_reload_vocvoltable)
1206             ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
1207                   __func__, LIB_ACDB_LOADER);
1208 
1209         my_data->acdb_init = (acdb_init_v2_cvd_t)dlsym(my_data->acdb_handle,
1210                                                     "acdb_loader_init_v2");
1211         if (my_data->acdb_init == NULL) {
1212             ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
1213             goto acdb_init_fail;
1214         }
1215 
1216         my_data->acdb_init_v3 = (acdb_init_v3_t)dlsym(my_data->acdb_handle,
1217                                                    "acdb_loader_init_v3");
1218         if (my_data->acdb_init_v3 == NULL) {
1219             ALOGI("%s: dlsym error %s for acdb_loader_init_v3", __func__, dlerror());
1220         }
1221         platform_acdb_init(my_data);
1222     }
1223 
1224 acdb_init_fail:
1225 
1226     /*init a2dp*/
1227     audio_extn_a2dp_init(adev);
1228 
1229     /* Read one time ssr property */
1230     audio_extn_spkr_prot_init(adev);
1231 
1232     return my_data;
1233 }
1234 
1235 void platform_deinit(void *platform)
1236 {
1237     struct platform_data *my_data = (struct platform_data *)platform;
1238 
1239     int32_t dev;
1240     struct operator_info *info_item;
1241     struct operator_specific_device *device_item;
1242     struct listnode *node;
1243 
1244     audio_extn_spkr_prot_deinit(my_data->adev);
1245 
1246     hw_info_deinit(my_data->hw_info);
1247 
1248     for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
1249         if (backend_table[dev]) {
1250             free(backend_table[dev]);
1251             backend_table[dev]= NULL;
1252         }
1253         if (operator_specific_device_table[dev]) {
1254             while (!list_empty(operator_specific_device_table[dev])) {
1255                 node = list_head(operator_specific_device_table[dev]);
1256                 list_remove(node);
1257                 device_item = node_to_item(node, struct operator_specific_device, list);
1258                 free(device_item->operator);
1259                 free(device_item->mixer_path);
1260                 free(device_item);
1261             }
1262             free(operator_specific_device_table[dev]);
1263         }
1264     }
1265 
1266     while (!list_empty(&operator_info_list)) {
1267         node = list_head(&operator_info_list);
1268         list_remove(node);
1269         info_item = node_to_item(node, struct operator_info, list);
1270         free(info_item->name);
1271         free(info_item->mccmnc);
1272         free(info_item);
1273     }
1274 
1275     mixer_close(my_data->adev->mixer);
1276     free(platform);
1277 }
1278 
1279 const char *platform_get_snd_device_name(snd_device_t snd_device)
1280 {
1281     if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
1282         if (operator_specific_device_table[snd_device] != NULL) {
1283             return get_operator_specific_device_mixer_path(snd_device);
1284         }
1285         return device_table[snd_device];
1286     } else
1287         return "none";
1288 }
1289 
1290 int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
1291                                       char *device_name)
1292 {
1293     struct platform_data *my_data = (struct platform_data *)platform;
1294 
1295     if (platform == NULL) {
1296         ALOGW("%s: something wrong, use legacy get_snd_device name", __func__);
1297         strlcpy(device_name, platform_get_snd_device_name(snd_device),
1298                  DEVICE_NAME_MAX_SIZE);
1299     } else if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
1300         if (operator_specific_device_table[snd_device] != NULL) {
1301             strlcpy(device_name, get_operator_specific_device_mixer_path(snd_device),
1302                      DEVICE_NAME_MAX_SIZE);
1303         } else {
1304             strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
1305         }
1306         hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
1307     } else {
1308         strlcpy(device_name, "none", DEVICE_NAME_MAX_SIZE);
1309         return -EINVAL;
1310     }
1311 
1312     return 0;
1313 }
1314 
1315 bool platform_check_and_set_playback_backend_cfg(struct audio_device* adev __unused,
1316                                               struct audio_usecase *usecase __unused,
1317                                               snd_device_t snd_device __unused)
1318 {
1319     return false;
1320 }
1321 
1322 bool platform_check_and_set_capture_backend_cfg(struct audio_device* adev __unused,
1323                                               struct audio_usecase *usecase __unused,
1324                                               snd_device_t snd_device __unused)
1325 {
1326     return false;
1327 }
1328 
1329 bool platform_add_gain_level_mapping(struct amp_db_and_gain_table *tbl_entry __unused)
1330 {
1331     return false;
1332 }
1333 
1334 int platform_get_gain_level_mapping(struct amp_db_and_gain_table *mapping_tbl __unused,
1335                                     int table_size __unused)
1336 {
1337     return 0;
1338 }
1339 
1340 void platform_add_backend_name(void *platform, char *mixer_path,
1341                                snd_device_t snd_device)
1342 {
1343 
1344     struct platform_data *my_data = (struct platform_data *)platform;
1345 
1346     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1347         ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1348         return;
1349     }
1350 
1351     const char * suffix = backend_table[snd_device];
1352 
1353     if (suffix != NULL) {
1354         strlcat(mixer_path, " ", MIXER_PATH_MAX_LENGTH);
1355         strlcat(mixer_path, suffix, MIXER_PATH_MAX_LENGTH);
1356     }
1357 }
1358 
1359 bool platform_check_backends_match(snd_device_t snd_device1, snd_device_t snd_device2)
1360 {
1361     bool result = true;
1362 
1363     ALOGV("%s: snd_device1 = %s, snd_device2 = %s", __func__,
1364                 platform_get_snd_device_name(snd_device1),
1365                 platform_get_snd_device_name(snd_device2));
1366 
1367     if ((snd_device1 < SND_DEVICE_MIN) || (snd_device1 >= SND_DEVICE_MAX)) {
1368         ALOGE("%s: Invalid snd_device = %s", __func__,
1369                 platform_get_snd_device_name(snd_device1));
1370         return false;
1371     }
1372     if ((snd_device2 < SND_DEVICE_MIN) || (snd_device2 >= SND_DEVICE_MAX)) {
1373         ALOGE("%s: Invalid snd_device = %s", __func__,
1374                 platform_get_snd_device_name(snd_device2));
1375         return false;
1376     }
1377     const char * be_itf1 = hw_interface_table[snd_device1];
1378     const char * be_itf2 = hw_interface_table[snd_device2];
1379 
1380     if (NULL != be_itf1 && NULL != be_itf2) {
1381         if ((NULL == strstr(be_itf2, be_itf1)) && (NULL == strstr(be_itf1, be_itf2)))
1382             result = false;
1383     } else if (NULL != be_itf2 && (NULL == strstr(be_itf2, DEFAULT_RX_BACKEND))) {
1384         result = false;
1385     } else if (NULL != be_itf1 && (NULL == strstr(be_itf1, DEFAULT_RX_BACKEND))) {
1386         result = false;
1387     }
1388 
1389     ALOGV("%s: be_itf1 = %s, be_itf2 = %s, match %d", __func__, be_itf1, be_itf2, result);
1390     return result;
1391 }
1392 
1393 int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
1394 {
1395     int device_id = -1;
1396 
1397     if (device_type == PCM_PLAYBACK)
1398         device_id = pcm_device_table[usecase][0];
1399     else
1400         device_id = pcm_device_table[usecase][1];
1401     return device_id;
1402 }
1403 
1404 int platform_get_haptics_pcm_device_id()
1405 {
1406     return -1;
1407 }
1408 
1409 static int find_index(struct name_to_index * table, int32_t len, const char * name)
1410 {
1411     int ret = 0;
1412     int32_t i;
1413 
1414     if (table == NULL) {
1415         ALOGE("%s: table is NULL", __func__);
1416         ret = -ENODEV;
1417         goto done;
1418     }
1419 
1420     if (name == NULL) {
1421         ALOGE("null key");
1422         ret = -ENODEV;
1423         goto done;
1424     }
1425 
1426     for (i=0; i < len; i++) {
1427         const char* tn = table[i].name;
1428         size_t len = strlen(tn);
1429         if (strncmp(tn, name, len) == 0) {
1430             if (strlen(name) != len) {
1431                 continue; // substring
1432             }
1433             ret = table[i].index;
1434             goto done;
1435         }
1436     }
1437     ALOGE("%s: Could not find index for name = %s",
1438             __func__, name);
1439     ret = -ENODEV;
1440 done:
1441     return ret;
1442 }
1443 
1444 int platform_get_snd_device_index(char *device_name)
1445 {
1446     return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
1447 }
1448 
1449 int platform_get_usecase_index(const char *usecase_name)
1450 {
1451     return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
1452 }
1453 
1454 int platform_get_effect_config_data(snd_device_t snd_device,
1455                                       struct audio_effect_config *effect_config,
1456                                       effect_type_t effect_type)
1457 {
1458     int ret = 0;
1459 
1460     if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
1461         (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_COUNT)) {
1462         ALOGE("%s: Invalid snd_device = %d or effect_type = %d",
1463             __func__, snd_device, effect_type);
1464         ret = -EINVAL;
1465         goto done;
1466     }
1467 
1468     if (effect_config == NULL) {
1469         ALOGE("%s: Invalid effect_config", __func__);
1470         ret = -EINVAL;
1471         goto done;
1472     }
1473 
1474     ALOGV("%s: snd_device = %d module_id = %d",
1475           __func__, snd_device,
1476           effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type].module_id);
1477     *effect_config = effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type];
1478 
1479 done:
1480     return ret;
1481 }
1482 
1483 void platform_add_external_specific_device(snd_device_t snd_device __unused,
1484                                            const char *name __unused,
1485                                            unsigned int acdb_id __unused)
1486 {
1487     return;
1488 }
1489 
1490 void platform_add_operator_specific_device(snd_device_t snd_device,
1491                                            const char *operator,
1492                                            const char *mixer_path,
1493                                            unsigned int acdb_id)
1494 {
1495     struct operator_specific_device *device;
1496 
1497     if (operator_specific_device_table[snd_device] == NULL) {
1498         operator_specific_device_table[snd_device] =
1499             (struct listnode *)calloc(1, sizeof(struct listnode));
1500         list_init(operator_specific_device_table[snd_device]);
1501     }
1502 
1503     device = (struct operator_specific_device *)calloc(1, sizeof(struct operator_specific_device));
1504 
1505     device->operator = strdup(operator);
1506     device->mixer_path = strdup(mixer_path);
1507     device->acdb_id = acdb_id;
1508 
1509     list_add_tail(operator_specific_device_table[snd_device], &device->list);
1510 
1511     ALOGD("%s: device[%s] -> operator[%s] mixer_path[%s] acdb_id[%d]", __func__,
1512             platform_get_snd_device_name(snd_device), operator, mixer_path, acdb_id);
1513 
1514 }
1515 
1516 int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
1517 {
1518     int ret = 0;
1519 
1520     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1521         ALOGE("%s: Invalid snd_device = %d",
1522             __func__, snd_device);
1523         ret = -EINVAL;
1524         goto done;
1525     }
1526     ALOGV("%s: acdb_device_table[%s]: old = %d new = %d", __func__,
1527           platform_get_snd_device_name(snd_device), acdb_device_table[snd_device], acdb_id);
1528     acdb_device_table[snd_device] = acdb_id;
1529 done:
1530     return ret;
1531 }
1532 
1533 int platform_set_acdb_metainfo_key(void *platform, char *name, int key)
1534 {
1535     struct meta_key_list *key_info;
1536     struct platform_data *pdata = (struct platform_data *)platform;
1537 
1538     if (key < 0) {
1539         ALOGE("%s: Incorrect Meta key\n", __func__);
1540         return -EINVAL;
1541     }
1542     key_info = (struct meta_key_list *)calloc(1, sizeof(struct meta_key_list));
1543     if (!key_info) {
1544         ALOGE("%s: Could not allocate memory for key %d", __func__, key);
1545         return -ENOMEM;
1546     }
1547 
1548     key_info->cal_info.nKey = key;
1549     strlcpy(key_info->name, name, sizeof(key_info->name));
1550     list_add_tail(&pdata->acdb_meta_key_list, &key_info->list);
1551     ALOGD("%s: successfully added module %s and key %d to the list", __func__,
1552                    key_info->name, key_info->cal_info.nKey);
1553     return 0;
1554 }
1555 
1556 static int platform_get_meta_info_key_from_list(void *platform, char *mod_name)
1557 {
1558     struct listnode *node;
1559     struct meta_key_list *key_info;
1560     struct platform_data *pdata = (struct platform_data *)platform;
1561     int key = 0;
1562 
1563     ALOGV("%s: for module %s", __func__, mod_name);
1564     list_for_each(node, &pdata->acdb_meta_key_list) {
1565         key_info = node_to_item(node, struct meta_key_list, list);
1566         if (strcmp(key_info->name, mod_name) == 0) {
1567             key = key_info->cal_info.nKey;
1568             ALOGD("%s: Found key %d for module %s", __func__, key, mod_name);
1569             break;
1570         }
1571     }
1572     return key;
1573 
1574 int platform_set_effect_config_data(snd_device_t snd_device,
1575                                       struct audio_effect_config effect_config,
1576                                       effect_type_t effect_type)
1577 {
1578     int ret = 0;
1579 
1580     if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
1581         (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_COUNT)) {
1582         ALOGE("%s: Invalid snd_device = %d or effect_type = %d",
1583             __func__, snd_device, effect_type);
1584         ret = -EINVAL;
1585         goto done;
1586     }
1587 
1588     ALOGV("%s 0x%x 0x%x 0x%x 0x%x", __func__, effect_config.module_id,
1589            effect_config.instance_id, effect_config.param_id,
1590            effect_config.param_value);
1591     effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type] = effect_config;
1592 done:
1593     return ret;
1594 }
1595 
1596 int platform_get_default_app_type_v2(void *platform, usecase_type_t type, int *app_type)
1597 {
1598     ALOGV("%s: platform: %p, type: %d", __func__, platform, type);
1599     int rc = 0;
1600     if (type == PCM_CAPTURE) {
1601         *app_type = DEFAULT_APP_TYPE_TX_PATH;
1602     } else if (type == PCM_PLAYBACK) {
1603         *app_type =  DEFAULT_APP_TYPE_RX_PATH;
1604     } else {
1605         rc = -EINVAL;
1606     }
1607     return rc;
1608 }
1609 
1610 int platform_get_snd_device_acdb_id(snd_device_t snd_device)
1611 {
1612     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1613         ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1614         return -EINVAL;
1615     }
1616 
1617     /*
1618      * If speaker protection is enabled, function returns supported
1619      * sound device for speaker. Else same sound device is returned.
1620      */
1621     snd_device = audio_extn_get_spkr_prot_snd_device(snd_device);
1622 
1623     if (operator_specific_device_table[snd_device] != NULL)
1624         return get_operator_specific_device_acdb_id(snd_device);
1625     else
1626         return acdb_device_table[snd_device];
1627 }
1628 
1629 int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
1630 {
1631     struct platform_data *my_data = (struct platform_data *)platform;
1632     int acdb_dev_id, acdb_dev_type;
1633     int sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
1634 
1635     acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
1636     if (acdb_dev_id < 0) {
1637         ALOGE("%s: Could not find acdb id for device(%d)",
1638               __func__, snd_device);
1639         return -EINVAL;
1640     }
1641         ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
1642               __func__, snd_device, acdb_dev_id);
1643     if (snd_device >= SND_DEVICE_OUT_BEGIN && snd_device < SND_DEVICE_OUT_END)
1644         acdb_dev_type = ACDB_DEV_TYPE_OUT;
1645     else
1646         acdb_dev_type = ACDB_DEV_TYPE_IN;
1647 
1648     if ((my_data->acdb_send_audio_cal_v3) &&
1649         (snd_device == SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP) &&
1650         !audio_extn_tfa_98xx_is_supported() ) {
1651             /* TX path calibration */
1652             my_data->acdb_send_audio_cal_v3(acdb_dev_id, ACDB_DEV_TYPE_IN,
1653                                 DEFAULT_APP_TYPE_TX_PATH, sample_rate, BUFF_IDX_0);
1654             my_data->acdb_send_audio_cal_v3(acdb_dev_id, ACDB_DEV_TYPE_OUT,
1655                                 DEFAULT_APP_TYPE_RX_PATH, sample_rate, BUFF_IDX_0);
1656     } else if ((my_data->acdb_send_audio_cal_v3) &&
1657                (snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_HFP) &&
1658                !audio_extn_tfa_98xx_is_supported()) {
1659             /* RX path calibration */
1660             ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
1661                        __func__, snd_device, acdb_dev_id);
1662             my_data->acdb_send_audio_cal_v3(acdb_dev_id, ACDB_DEV_TYPE_IN,
1663                                 DEFAULT_APP_TYPE_TX_PATH, sample_rate, BUFF_IDX_1);
1664             my_data->acdb_send_audio_cal_v3(acdb_dev_id, ACDB_DEV_TYPE_OUT,
1665                                 DEFAULT_APP_TYPE_RX_PATH, sample_rate, BUFF_IDX_1);
1666     } else if (my_data->acdb_send_audio_cal) {
1667         my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
1668     }
1669     return 0;
1670 }
1671 
1672 int platform_switch_voice_call_device_pre(void *platform __unused)
1673 {
1674     return 0;
1675 }
1676 
1677 int platform_switch_voice_call_enable_device_config(void *platform __unused,
1678                                                     snd_device_t out_snd_device __unused,
1679                                                     snd_device_t in_snd_device __unused)
1680 {
1681     return 0;
1682 }
1683 
1684 int platform_switch_voice_call_device_post(void *platform,
1685                                            snd_device_t out_snd_device,
1686                                            snd_device_t in_snd_device)
1687 {
1688     struct platform_data *my_data = (struct platform_data *)platform;
1689     int acdb_rx_id, acdb_tx_id;
1690 
1691     if (my_data->acdb_send_voice_cal == NULL) {
1692         ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
1693     } else {
1694         acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
1695         acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
1696 
1697         if (acdb_rx_id > 0 && acdb_tx_id > 0)
1698             my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
1699         else
1700             ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1701                   acdb_rx_id, acdb_tx_id);
1702     }
1703 
1704     return 0;
1705 }
1706 
1707 int platform_switch_voice_call_usecase_route_post(void *platform __unused,
1708                                                   snd_device_t out_snd_device __unused,
1709                                                   snd_device_t in_snd_device __unused)
1710 {
1711     return 0;
1712 }
1713 
1714 int platform_start_voice_call(void *platform __unused, uint32_t vsid __unused)
1715 {
1716     return 0;
1717 }
1718 
1719 int platform_stop_voice_call(void *platform __unused, uint32_t vsid __unused)
1720 {
1721     return 0;
1722 }
1723 
1724 int platform_set_mic_break_det(void *platform __unused, bool enable __unused)
1725 {
1726     return 0;
1727 }
1728 
1729 int platform_get_sample_rate(void *platform __unused, uint32_t *rate __unused)
1730 {
1731     return 0;
1732 }
1733 
1734 void platform_set_speaker_gain_in_combo(struct audio_device *adev __unused,
1735                                         snd_device_t snd_device __unused,
1736                                         bool enable __unused)
1737 {
1738     return;
1739 }
1740 
1741 int platform_set_voice_volume(void *platform, int volume)
1742 {
1743     struct platform_data *my_data = (struct platform_data *)platform;
1744     struct audio_device *adev = my_data->adev;
1745     struct mixer_ctl *ctl;
1746     const char *mixer_ctl_name = "Voice Rx Gain";
1747     const char *mute_mixer_ctl_name = "Voice Rx Device Mute";
1748     int vol_index = 0, ret = 0;
1749     uint32_t set_values[ ] = {0,
1750                               ALL_SESSION_VSID,
1751                               DEFAULT_VOLUME_RAMP_DURATION_MS};
1752 
1753     // Voice volume levels are mapped to adsp volume levels as follows.
1754     // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1  0 -> 0
1755     // But this values don't changed in kernel. So, below change is need.
1756     vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, my_data->max_vol_index);
1757     set_values[0] = vol_index;
1758     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1759     if (!ctl) {
1760         ALOGE("%s: Could not get ctl for mixer cmd - %s",
1761               __func__, mixer_ctl_name);
1762         return -EINVAL;
1763     }
1764     ALOGV("Setting voice volume index: %d", set_values[0]);
1765     ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1766 
1767     // Send mute command in case volume index is max since indexes are inverted
1768     // for mixer controls.
1769     if (vol_index == my_data->max_vol_index) {
1770         set_values[0] = 1;
1771     }
1772     else {
1773         set_values[0] = 0;
1774     }
1775 
1776     ctl = mixer_get_ctl_by_name(adev->mixer, mute_mixer_ctl_name);
1777     if (!ctl) {
1778         ALOGE("%s: Could not get ctl for mixer cmd - %s",
1779               __func__, mute_mixer_ctl_name);
1780         return -EINVAL;
1781     }
1782     ALOGV("%s: Setting RX Device Mute to: %d", __func__, set_values[0]);
1783     mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1784     return ret;
1785 }
1786 
1787 int platform_set_mic_mute(void *platform, bool state)
1788 {
1789     struct platform_data *my_data = (struct platform_data *)platform;
1790     struct audio_device *adev = my_data->adev;
1791     struct mixer_ctl *ctl;
1792     const char *mixer_ctl_name = "Voice Tx Mute";
1793     int ret = 0;
1794     uint32_t set_values[ ] = {0,
1795                               ALL_SESSION_VSID,
1796                               DEFAULT_MUTE_RAMP_DURATION_MS};
1797 
1798     if (audio_extn_hfp_is_active(adev))
1799         mixer_ctl_name = "HFP TX Mute";
1800 
1801     set_values[0] = state;
1802     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1803     if (!ctl) {
1804         ALOGE("%s: Could not get ctl for mixer cmd - %s",
1805               __func__, mixer_ctl_name);
1806         return -EINVAL;
1807     }
1808     ALOGV("Setting voice mute state: %d", state);
1809     // "HFP TX mute" mixer control has xcount of 1.
1810     if (audio_extn_hfp_is_active(adev))
1811         ret = mixer_ctl_set_array(ctl, set_values, 1 /*count*/);
1812     else
1813         ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1814     return ret;
1815 }
1816 
1817 int platform_set_device_mute(void *platform, bool state, char *dir)
1818 {
1819     struct platform_data *my_data = (struct platform_data *)platform;
1820     struct audio_device *adev = my_data->adev;
1821     struct mixer_ctl *ctl;
1822     char *mixer_ctl_name = NULL;
1823     int ret = 0;
1824     uint32_t set_values[ ] = {0,
1825                               ALL_SESSION_VSID,
1826                               0};
1827     if(dir == NULL) {
1828         ALOGE("%s: Invalid direction:%s", __func__, dir);
1829         return -EINVAL;
1830     }
1831 
1832     if (!strncmp("rx", dir, sizeof("rx"))) {
1833         mixer_ctl_name = "Voice Rx Device Mute";
1834     } else if (!strncmp("tx", dir, sizeof("tx"))) {
1835         mixer_ctl_name = "Voice Tx Device Mute";
1836     } else {
1837         return -EINVAL;
1838     }
1839 
1840     set_values[0] = state;
1841     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1842     if (!ctl) {
1843         ALOGE("%s: Could not get ctl for mixer cmd - %s",
1844               __func__, mixer_ctl_name);
1845         return -EINVAL;
1846     }
1847 
1848     ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
1849           __func__,state, mixer_ctl_name);
1850     mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1851 
1852     return ret;
1853 }
1854 
1855 int platform_can_split_snd_device(snd_device_t snd_device,
1856                                    int *num_devices,
1857                                    snd_device_t *new_snd_devices)
1858 {
1859     int ret = -EINVAL;
1860 
1861     if (NULL == num_devices || NULL == new_snd_devices) {
1862         ALOGE("%s: NULL pointer ..", __func__);
1863         return -EINVAL;
1864     }
1865 
1866     /*
1867      * If wired headset/headphones/line devices share the same backend
1868      * with speaker/earpiece this routine -EINVAL.
1869      */
1870     if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES &&
1871         !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HEADPHONES)) {
1872         *num_devices = 2;
1873         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
1874         new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
1875         ret = 0;
1876     } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_LINE &&
1877                !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_LINE)) {
1878         *num_devices = 2;
1879         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
1880         new_snd_devices[1] = SND_DEVICE_OUT_LINE;
1881         ret = 0;
1882     }
1883     return ret;
1884 }
1885 
1886 snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
1887 {
1888     struct platform_data *my_data = (struct platform_data *)platform;
1889     struct audio_device *adev = my_data->adev;
1890     audio_mode_t mode = adev->mode;
1891     snd_device_t snd_device = SND_DEVICE_NONE;
1892 
1893     ALOGV("%s: enter: output devices(%#x)", __func__, devices);
1894     if (devices == AUDIO_DEVICE_NONE ||
1895         devices & AUDIO_DEVICE_BIT_IN) {
1896         ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
1897         goto exit;
1898     }
1899 
1900     if (popcount(devices) == 2) {
1901         if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1902                         AUDIO_DEVICE_OUT_SPEAKER)) {
1903             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1904         } else if (devices == (AUDIO_DEVICE_OUT_LINE |
1905                                AUDIO_DEVICE_OUT_SPEAKER)) {
1906                 snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
1907         } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1908                                AUDIO_DEVICE_OUT_SPEAKER)) {
1909             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1910         } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
1911                                AUDIO_DEVICE_OUT_SPEAKER)) {
1912             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
1913         } else if (devices == (AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
1914                                AUDIO_DEVICE_OUT_SPEAKER)) {
1915             snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
1916         } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER) &&
1917                    (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
1918             snd_device = SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP;
1919         } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) &&
1920                    (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
1921             snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP;
1922         } else {
1923             ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
1924             goto exit;
1925         }
1926         if (snd_device != SND_DEVICE_NONE) {
1927             goto exit;
1928         }
1929     }
1930 
1931     if (popcount(devices) != 1) {
1932         ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
1933         goto exit;
1934     }
1935 
1936     if (mode == AUDIO_MODE_IN_CALL || audio_extn_hfp_is_active(adev)) {
1937         if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1938             devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1939             devices & AUDIO_DEVICE_OUT_LINE) {
1940             if (adev->voice.tty_mode != TTY_MODE_OFF) {
1941                 switch (adev->voice.tty_mode) {
1942                 case TTY_MODE_FULL:
1943                     snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
1944                     break;
1945                 case TTY_MODE_VCO:
1946                     snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
1947                     break;
1948                 case TTY_MODE_HCO:
1949                     snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
1950                     break;
1951                 default:
1952                     ALOGE("%s: Invalid TTY mode (%#x)",
1953                           __func__, adev->voice.tty_mode);
1954                 }
1955             } else if (devices & AUDIO_DEVICE_OUT_LINE) {
1956                 snd_device = SND_DEVICE_OUT_VOICE_LINE;
1957             } else if (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1958                 snd_device = SND_DEVICE_OUT_VOICE_HEADSET;
1959             } else {
1960                 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
1961             }
1962         } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
1963             if (adev->bt_wb_speech_enabled)
1964                 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1965             else
1966                 snd_device = SND_DEVICE_OUT_BT_SCO;
1967         } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
1968                 snd_device = SND_DEVICE_OUT_BT_A2DP;
1969         } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
1970             if (audio_extn_hfp_is_active(adev))
1971                 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_HFP;
1972             else
1973                 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
1974         } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
1975                    devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
1976             snd_device = SND_DEVICE_OUT_USB_HEADSET;
1977         } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
1978                 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
1979         } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1980             snd_device = SND_DEVICE_OUT_VOICE_TX;
1981 
1982         if (snd_device != SND_DEVICE_NONE) {
1983             goto exit;
1984         }
1985     }
1986 
1987     if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1988         devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1989                 snd_device = SND_DEVICE_OUT_HEADPHONES;
1990     } else if (devices & AUDIO_DEVICE_OUT_LINE) {
1991         snd_device = SND_DEVICE_OUT_LINE;
1992     } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
1993         /*
1994          * Perform device switch only if acdb tuning is different between SPEAKER & SPEAKER_REVERSE,
1995          * Or there will be a small pause while performing device switch.
1996          */
1997         if (my_data->speaker_lr_swap &&
1998             (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
1999             acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE]))
2000             snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
2001         else
2002             snd_device = SND_DEVICE_OUT_SPEAKER;
2003     } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2004         if (adev->bt_wb_speech_enabled)
2005             snd_device = SND_DEVICE_OUT_BT_SCO_WB;
2006         else
2007             snd_device = SND_DEVICE_OUT_BT_SCO;
2008     } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
2009         snd_device = SND_DEVICE_OUT_BT_A2DP;
2010     } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
2011         snd_device = SND_DEVICE_OUT_HDMI ;
2012     } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
2013                devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
2014         snd_device = SND_DEVICE_OUT_USB_HEADSET;
2015     } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
2016         snd_device = SND_DEVICE_OUT_HANDSET;
2017     } else {
2018         ALOGE("%s: Unknown device(s) %#x", __func__, devices);
2019     }
2020 exit:
2021     ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
2022     return snd_device;
2023 }
2024 
2025 #ifdef DYNAMIC_ECNS_ENABLED
2026 static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
2027                                                   struct stream_in *in __unused,
2028                                                   audio_devices_t out_device,
2029                                                   audio_devices_t in_device)
2030 {
2031     struct audio_device *adev = my_data->adev;
2032     snd_device_t snd_device = SND_DEVICE_NONE;
2033 
2034     if (my_data->fluence_type != FLUENCE_NONE) {
2035         switch(AUDIO_DEVICE_BIT_IN | in_device) {
2036             case AUDIO_DEVICE_IN_BACK_MIC:
2037                 if (my_data->fluence_in_spkr_mode) {
2038                     if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
2039                         snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
2040                     } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2041                         if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2042                             snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
2043                         else
2044                             snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
2045                     }
2046                     adev->acdb_settings |= DMIC_FLAG;
2047                 } else
2048                     snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
2049                 break;
2050             case AUDIO_DEVICE_IN_BUILTIN_MIC:
2051                 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2052                     snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
2053                     adev->acdb_settings |= DMIC_FLAG;
2054                 } else
2055                     snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
2056                 break;
2057             default:
2058                 ALOGE("%s: Unsupported in_device %#x", __func__, in_device);
2059                 break;
2060         }
2061         platform_set_echo_reference(adev, true, out_device);
2062     }
2063 
2064     return snd_device;
2065 }
2066 #else
2067 static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
2068                                                   struct stream_in *in,
2069                                                   audio_devices_t out_device,
2070                                                   audio_devices_t in_device)
2071 {
2072     struct audio_device *adev = my_data->adev;
2073     snd_device_t snd_device = SND_DEVICE_NONE;
2074 
2075     if (my_data->fluence_type != FLUENCE_NONE &&
2076         in->enable_aec &&
2077         in->enable_ns) {
2078         if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2079             if (my_data->fluence_in_spkr_mode) {
2080                 if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
2081                     snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
2082                 } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2083                     if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2084                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
2085                     else
2086                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
2087                 }
2088                 adev->acdb_settings |= DMIC_FLAG;
2089             } else
2090                 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
2091         } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2092             if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2093                 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
2094                 adev->acdb_settings |= DMIC_FLAG;
2095             } else
2096                 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
2097         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2098             snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
2099         }
2100         platform_set_echo_reference(adev, true, out_device);
2101     } else if (my_data->fluence_type != FLUENCE_NONE &&
2102                in->enable_aec) {
2103         if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2104             if (my_data->fluence_in_spkr_mode) {
2105                 if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
2106                     snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
2107                 } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2108                     if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2109                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
2110                     else
2111                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
2112                 }
2113                 adev->acdb_settings |= DMIC_FLAG;
2114             } else
2115                 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
2116         } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2117             if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2118                 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
2119                 adev->acdb_settings |= DMIC_FLAG;
2120             } else
2121                 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
2122         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2123             snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
2124         }
2125         platform_set_echo_reference(adev, true, out_device);
2126     } else if (my_data->fluence_type != FLUENCE_NONE &&
2127                in->enable_ns) {
2128         if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2129             if (my_data->fluence_in_spkr_mode) {
2130                 if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
2131                     snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
2132                 } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2133                     if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2134                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
2135                     else
2136                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
2137                 }
2138                 adev->acdb_settings |= DMIC_FLAG;
2139             } else
2140                 snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
2141         } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2142             if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2143                 snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
2144                 adev->acdb_settings |= DMIC_FLAG;
2145             } else
2146                 snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
2147         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2148             snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
2149         }
2150         platform_set_echo_reference(adev, false, out_device);
2151     } else
2152         platform_set_echo_reference(adev, false, out_device);
2153 
2154     return snd_device;
2155 }
2156 #endif //DYNAMIC_ECNS_ENABLED
2157 
2158 snd_device_t platform_get_input_snd_device(void *platform,
2159                                            struct stream_in *in,
2160                                            audio_devices_t out_device)
2161 {
2162     struct platform_data *my_data = (struct platform_data *)platform;
2163     struct audio_device *adev = my_data->adev;
2164     audio_mode_t mode = adev->mode;
2165     snd_device_t snd_device = SND_DEVICE_NONE;
2166 
2167     if (in == NULL) {
2168         in = adev_get_active_input(adev);
2169     }
2170 
2171     audio_source_t source = (in == NULL) ? AUDIO_SOURCE_DEFAULT : in->source;
2172     audio_devices_t in_device =
2173         ((in == NULL) ? AUDIO_DEVICE_NONE : in->device) & ~AUDIO_DEVICE_BIT_IN;
2174     audio_channel_mask_t channel_mask = (in == NULL) ? AUDIO_CHANNEL_IN_MONO : in->channel_mask;
2175     int channel_count = audio_channel_count_from_in_mask(channel_mask);
2176 
2177     ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
2178           __func__, out_device, in_device);
2179 
2180     if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
2181         audio_extn_hfp_is_active(adev))) {
2182         if (adev->voice.tty_mode != TTY_MODE_OFF) {
2183             if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
2184                 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
2185                 out_device & AUDIO_DEVICE_OUT_LINE) {
2186                 switch (adev->voice.tty_mode) {
2187                 case TTY_MODE_FULL:
2188                     snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
2189                     break;
2190                 case TTY_MODE_VCO:
2191                     snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
2192                     break;
2193                 case TTY_MODE_HCO:
2194                     snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
2195                     break;
2196                 default:
2197                     ALOGE("%s: Invalid TTY mode (%#x)",
2198                           __func__, adev->voice.tty_mode);
2199                 }
2200                 goto exit;
2201             }
2202         }
2203         if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
2204             out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
2205             out_device & AUDIO_DEVICE_OUT_LINE) {
2206             if (my_data->fluence_type == FLUENCE_NONE ||
2207                 my_data->fluence_in_voice_call == false) {
2208                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
2209                 if (audio_extn_hfp_is_active(adev))
2210                     platform_set_echo_reference(adev, true, out_device);
2211             } else {
2212                 snd_device = SND_DEVICE_IN_VOICE_DMIC;
2213                 adev->acdb_settings |= DMIC_FLAG;
2214             }
2215         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
2216             snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
2217             if (audio_extn_hfp_is_active(adev))
2218                 platform_set_echo_reference(adev, true, out_device);
2219         } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
2220             if (adev->bt_wb_speech_enabled) {
2221                 if (adev->bluetooth_nrec)
2222                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2223                 else
2224                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
2225             } else {
2226                 if (adev->bluetooth_nrec)
2227                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2228                 else
2229                     snd_device = SND_DEVICE_IN_BT_SCO_MIC;
2230             }
2231         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
2232             if (my_data->fluence_type != FLUENCE_NONE &&
2233                 my_data->fluence_in_voice_call &&
2234                 my_data->fluence_in_spkr_mode) {
2235                     if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
2236                        adev->acdb_settings |= QMIC_FLAG;
2237                        snd_device = SND_DEVICE_IN_VOICE_SPEAKER_QMIC;
2238                     } else {
2239                        adev->acdb_settings |= DMIC_FLAG;
2240                        if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2241                            snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE;
2242                        else
2243                            snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
2244                     }
2245             } else {
2246                 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
2247                 if (audio_extn_hfp_is_active(adev)) {
2248                     snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP;
2249                     platform_set_echo_reference(adev, true, out_device);
2250                 } else {
2251                     snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
2252                 }
2253             }
2254         } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
2255             snd_device = SND_DEVICE_IN_VOICE_RX;
2256     } else if (source == AUDIO_SOURCE_CAMCORDER) {
2257         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
2258             in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2259             if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
2260                 channel_count == 2)
2261                 snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
2262             else
2263                 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
2264         }
2265     } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
2266         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2267             if (channel_count == 2) {
2268                 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
2269                 adev->acdb_settings |= DMIC_FLAG;
2270             } else if (in->enable_ns)
2271                 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
2272             else if (my_data->fluence_type != FLUENCE_NONE &&
2273                      my_data->fluence_in_voice_rec) {
2274                 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
2275                 adev->acdb_settings |= DMIC_FLAG;
2276             } else {
2277                 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
2278             }
2279         }
2280     } else if ((source == AUDIO_SOURCE_VOICE_COMMUNICATION) ||
2281               (mode == AUDIO_MODE_IN_COMMUNICATION)) {
2282         if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
2283             in_device = AUDIO_DEVICE_IN_BACK_MIC;
2284 
2285         if (in) {
2286             snd_device = get_snd_device_for_voice_comm(my_data, in,
2287                                                        out_device, in_device);
2288         }
2289     } else if (source == AUDIO_SOURCE_FM_TUNER) {
2290         snd_device = SND_DEVICE_IN_CAPTURE_FM;
2291     } else if (source == AUDIO_SOURCE_DEFAULT) {
2292         goto exit;
2293     }
2294 
2295 
2296     if (snd_device != SND_DEVICE_NONE) {
2297         goto exit;
2298     }
2299 
2300     if (in_device != AUDIO_DEVICE_NONE &&
2301             !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
2302             !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
2303         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2304             if (my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC) &&
2305                     channel_count == 2)
2306                 snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
2307             else
2308                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
2309         } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2310             snd_device = SND_DEVICE_IN_SPEAKER_MIC;
2311         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2312             snd_device = SND_DEVICE_IN_HEADSET_MIC;
2313         } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
2314             if (adev->bt_wb_speech_enabled) {
2315                 if (adev->bluetooth_nrec)
2316                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2317                 else
2318                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
2319             } else {
2320                 if (adev->bluetooth_nrec)
2321                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2322                 else
2323                     snd_device = SND_DEVICE_IN_BT_SCO_MIC;
2324             }
2325         } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
2326             snd_device = SND_DEVICE_IN_HDMI_MIC;
2327         } else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
2328                    in_device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) {
2329             snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
2330         } else if (in_device & AUDIO_DEVICE_IN_FM_TUNER) {
2331             snd_device = SND_DEVICE_IN_CAPTURE_FM;
2332         } else {
2333             ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
2334             ALOGW("%s: Using default handset-mic", __func__);
2335             snd_device = SND_DEVICE_IN_HANDSET_MIC;
2336         }
2337     } else {
2338         if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
2339             snd_device = SND_DEVICE_IN_HANDSET_MIC;
2340         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
2341             snd_device = SND_DEVICE_IN_HEADSET_MIC;
2342         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
2343             if (channel_count > 1)
2344                 snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
2345             else
2346                 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
2347         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
2348                        out_device & AUDIO_DEVICE_OUT_LINE) {
2349             snd_device = SND_DEVICE_IN_HANDSET_MIC;
2350         } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
2351             if (adev->bt_wb_speech_enabled) {
2352                 if (adev->bluetooth_nrec)
2353                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2354                 else
2355                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
2356             } else {
2357                 if (adev->bluetooth_nrec)
2358                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2359                 else
2360                     snd_device = SND_DEVICE_IN_BT_SCO_MIC;
2361             }
2362         } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
2363             snd_device = SND_DEVICE_IN_HDMI_MIC;
2364         } else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
2365                    out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
2366             snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
2367         } else {
2368             ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
2369             ALOGW("%s: Using default handset-mic", __func__);
2370             snd_device = SND_DEVICE_IN_HANDSET_MIC;
2371         }
2372     }
2373 exit:
2374     ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
2375     return snd_device;
2376 }
2377 
2378 int platform_set_hdmi_channels(void *platform,  int channel_count)
2379 {
2380     struct platform_data *my_data = (struct platform_data *)platform;
2381     struct audio_device *adev = my_data->adev;
2382     struct mixer_ctl *ctl;
2383     const char *channel_cnt_str = NULL;
2384     const char *mixer_ctl_name = "HDMI_RX Channels";
2385     switch (channel_count) {
2386     case 8:
2387         channel_cnt_str = "Eight"; break;
2388     case 7:
2389         channel_cnt_str = "Seven"; break;
2390     case 6:
2391         channel_cnt_str = "Six"; break;
2392     case 5:
2393         channel_cnt_str = "Five"; break;
2394     case 4:
2395         channel_cnt_str = "Four"; break;
2396     case 3:
2397         channel_cnt_str = "Three"; break;
2398     default:
2399         channel_cnt_str = "Two"; break;
2400     }
2401     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2402     if (!ctl) {
2403         ALOGE("%s: Could not get ctl for mixer cmd - %s",
2404               __func__, mixer_ctl_name);
2405         return -EINVAL;
2406     }
2407     ALOGV("HDMI channel count: %s", channel_cnt_str);
2408     mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
2409     return 0;
2410 }
2411 
2412 int platform_edid_get_max_channels(void *platform)
2413 {
2414     struct platform_data *my_data = (struct platform_data *)platform;
2415     struct audio_device *adev = my_data->adev;
2416     char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
2417     char *sad = block;
2418     int num_audio_blocks;
2419     int channel_count;
2420     int max_channels = 0;
2421     int i, ret, count;
2422 
2423     struct mixer_ctl *ctl;
2424 
2425     ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
2426     if (!ctl) {
2427         ALOGE("%s: Could not get ctl for mixer cmd - %s",
2428               __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
2429         return 0;
2430     }
2431 
2432     mixer_ctl_update(ctl);
2433 
2434     count = mixer_ctl_get_num_values(ctl);
2435 
2436     /* Read SAD blocks, clamping the maximum size for safety */
2437     if (count > (int)sizeof(block))
2438         count = (int)sizeof(block);
2439 
2440     ret = mixer_ctl_get_array(ctl, block, count);
2441     if (ret != 0) {
2442         ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
2443         return 0;
2444     }
2445 
2446     /* Calculate the number of SAD blocks */
2447     num_audio_blocks = count / SAD_BLOCK_SIZE;
2448 
2449     for (i = 0; i < num_audio_blocks; i++) {
2450         /* Only consider LPCM blocks */
2451         if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
2452             sad += 3;
2453             continue;
2454         }
2455 
2456         channel_count = (sad[0] & 0x7) + 1;
2457         if (channel_count > max_channels)
2458             max_channels = channel_count;
2459 
2460         /* Advance to next block */
2461         sad += 3;
2462     }
2463 
2464     return max_channels;
2465 }
2466 
2467 int platform_set_incall_recording_session_id(void *platform,
2468                                              uint32_t session_id,
2469                                              int rec_mode __unused)
2470 {
2471     int ret = 0;
2472     struct platform_data *my_data = (struct platform_data *)platform;
2473     struct audio_device *adev = my_data->adev;
2474     struct mixer_ctl *ctl;
2475     const char *mixer_ctl_name = "Voc VSID";
2476     int num_ctl_values;
2477     int i;
2478 
2479     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2480     if (!ctl) {
2481         ALOGE("%s: Could not get ctl for mixer cmd - %s",
2482               __func__, mixer_ctl_name);
2483         ret = -EINVAL;
2484     } else {
2485         num_ctl_values = mixer_ctl_get_num_values(ctl);
2486         for (i = 0; i < num_ctl_values; i++) {
2487             if (mixer_ctl_set_value(ctl, i, session_id)) {
2488                 ALOGV("Error: invalid session_id: %x", session_id);
2489                 ret = -EINVAL;
2490                 break;
2491             }
2492         }
2493     }
2494     return ret;
2495 }
2496 
2497 int platform_set_incall_recording_session_channels(void *platform __unused,
2498                                              uint32_t channel_count __unused)
2499 {
2500     return 0;
2501 }
2502 
2503 
2504 int platform_stop_incall_recording_usecase(void *platform __unused)
2505 {
2506     return 0;
2507 }
2508 
2509 int platform_start_incall_music_usecase(void *platform __unused)
2510 {
2511     return 0;
2512 }
2513 
2514 int platform_stop_incall_music_usecase(void *platform __unused)
2515 {
2516     return 0;
2517 }
2518 
2519 int platform_set_parameters(void *platform, struct str_parms *parms)
2520 {
2521     struct platform_data *my_data = (struct platform_data *)platform;
2522     char value[128];
2523     char *kv_pairs = str_parms_to_str(parms);
2524     int ret = 0, err;
2525 
2526     if (kv_pairs == NULL) {
2527         ret = -EINVAL;
2528         ALOGE("%s: key-value pair is NULL",__func__);
2529         goto done;
2530     }
2531 
2532     ALOGV("%s: enter: %s", __func__, kv_pairs);
2533 
2534     err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO,
2535                             value, sizeof(value));
2536     if (err >= 0) {
2537         struct operator_info *info;
2538         char *str = value;
2539         char *name;
2540 
2541         str_parms_del(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO);
2542         info = (struct operator_info *)calloc(1, sizeof(struct operator_info));
2543         name = strtok(str, ";");
2544         info->name = strdup(name);
2545         info->mccmnc = strdup(str + strlen(name) + 1);
2546 
2547         list_add_tail(&operator_info_list, &info->list);
2548         ALOGV("%s: add operator[%s] mccmnc[%s]", __func__, info->name, info->mccmnc);
2549     }
2550 
2551     audio_extn_hfp_set_parameters(my_data->adev, parms);
2552 done:
2553     ALOGV("%s: exit with code(%d)", __func__, ret);
2554     if (kv_pairs != NULL)
2555         free(kv_pairs);
2556 
2557     return ret;
2558 }
2559 
2560 /* Delay in Us */
2561 int64_t platform_render_latency(audio_usecase_t usecase)
2562 {
2563     switch (usecase) {
2564         case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
2565             return DEEP_BUFFER_PLATFORM_DELAY;
2566         case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
2567             return LOW_LATENCY_PLATFORM_DELAY;
2568         default:
2569             return 0;
2570     }
2571 }
2572 
2573 int platform_set_snd_device_backend(snd_device_t device, const char *backend, const char * hw_interface)
2574 {
2575     int ret = 0;
2576 
2577     if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
2578         ALOGE("%s: Invalid snd_device = %d",
2579             __func__, device);
2580         ret = -EINVAL;
2581         goto done;
2582     }
2583 
2584     ALOGV("%s: backend_tag_table[%s]: old = %s new = %s", __func__,
2585           platform_get_snd_device_name(device),
2586           backend_table[device] != NULL ? backend_table[device]: "null", backend);
2587     if (backend_table[device]) {
2588         free(backend_table[device]);
2589     }
2590     backend_table[device] = strdup(backend);
2591 
2592     if (hw_interface != NULL) {
2593         if (hw_interface_table[device])
2594             free(hw_interface_table[device]);
2595         ALOGV("%s: hw_interface_table[%d] = %s", __func__, device, hw_interface);
2596         hw_interface_table[device] = strdup(hw_interface);
2597     }
2598 done:
2599     return ret;
2600 }
2601 
2602 int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
2603 {
2604     int ret = 0;
2605     if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
2606         ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
2607         ret = -EINVAL;
2608         goto done;
2609     }
2610 
2611     if ((type != 0) && (type != 1)) {
2612         ALOGE("%s: invalid usecase type", __func__);
2613         ret = -EINVAL;
2614     }
2615     pcm_device_table[usecase][type] = pcm_id;
2616 done:
2617     return ret;
2618 }
2619 
2620 #define DEFAULT_NOMINAL_SPEAKER_GAIN 20
2621 int ramp_speaker_gain(struct audio_device *adev, bool ramp_up, int target_ramp_up_gain) {
2622     // backup_gain: gain to try to set in case of an error during ramp
2623     int start_gain, end_gain, step, backup_gain, i;
2624     bool error = false;
2625     const struct mixer_ctl *ctl;
2626     const char *mixer_ctl_name_gain_left = "Left Speaker Gain";
2627     const char *mixer_ctl_name_gain_right = "Right Speaker Gain";
2628     struct mixer_ctl *ctl_left = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_left);
2629     struct mixer_ctl *ctl_right = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_right);
2630     if (!ctl_left || !ctl_right) {
2631         ALOGE("%s: Could not get ctl for mixer cmd - %s or %s, not applying speaker gain ramp",
2632                       __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
2633         return -EINVAL;
2634     } else if ((mixer_ctl_get_num_values(ctl_left) != 1)
2635             || (mixer_ctl_get_num_values(ctl_right) != 1)) {
2636         ALOGE("%s: Unexpected num values for mixer cmd - %s or %s, not applying speaker gain ramp",
2637                               __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
2638         return -EINVAL;
2639     }
2640     if (ramp_up) {
2641         start_gain = 0;
2642         end_gain = target_ramp_up_gain > 0 ? target_ramp_up_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
2643         step = +1;
2644         backup_gain = end_gain;
2645     } else {
2646         // using same gain on left and right
2647         const int left_gain = mixer_ctl_get_value(ctl_left, 0);
2648         start_gain = left_gain > 0 ? left_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
2649         end_gain = 0;
2650         step = -1;
2651         backup_gain = start_gain;
2652     }
2653     for (i = start_gain ; i != (end_gain + step) ; i += step) {
2654         //ALOGV("setting speaker gain to %d", i);
2655         if (mixer_ctl_set_value(ctl_left, 0, i)) {
2656             ALOGE("%s: error setting %s to %d during gain ramp",
2657                     __func__, mixer_ctl_name_gain_left, i);
2658             error = true;
2659             break;
2660         }
2661         if (mixer_ctl_set_value(ctl_right, 0, i)) {
2662             ALOGE("%s: error setting %s to %d during gain ramp",
2663                     __func__, mixer_ctl_name_gain_right, i);
2664             error = true;
2665             break;
2666         }
2667         usleep(1000);
2668     }
2669     if (error) {
2670         // an error occured during the ramp, let's still try to go back to a safe volume
2671         if (mixer_ctl_set_value(ctl_left, 0, backup_gain)) {
2672             ALOGE("%s: error restoring left gain to %d", __func__, backup_gain);
2673         }
2674         if (mixer_ctl_set_value(ctl_right, 0, backup_gain)) {
2675             ALOGE("%s: error restoring right gain to %d", __func__, backup_gain);
2676         }
2677     }
2678     return start_gain;
2679 }
2680 
2681 int platform_set_swap_mixer(struct audio_device *adev, bool swap_channels)
2682 {
2683     const char *mixer_ctl_name = "Swap channel";
2684     struct mixer_ctl *ctl;
2685     const char *mixer_path;
2686     struct platform_data *my_data = (struct platform_data *)adev->platform;
2687 
2688     // forced to set to swap, but device not rotated ... ignore set
2689     if (swap_channels && !my_data->speaker_lr_swap)
2690         return 0;
2691 
2692     ALOGV("%s:", __func__);
2693 
2694     if (swap_channels) {
2695         mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
2696         audio_route_apply_and_update_path(adev->audio_route, mixer_path);
2697     } else {
2698         mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
2699         audio_route_apply_and_update_path(adev->audio_route, mixer_path);
2700     }
2701 
2702     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2703     if (!ctl) {
2704         ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
2705         return -EINVAL;
2706     }
2707 
2708     if (mixer_ctl_set_value(ctl, 0, swap_channels) < 0) {
2709         ALOGE("%s: Could not set reverse cotrol %d",__func__, swap_channels);
2710         return -EINVAL;
2711     }
2712 
2713     ALOGV("platfor_force_swap_channel :: Channel orientation ( %s ) ",
2714            swap_channels?"R --> L":"L --> R");
2715 
2716     return 0;
2717 }
2718 
2719 int platform_check_and_set_swap_lr_channels(struct audio_device *adev, bool swap_channels)
2720 {
2721     // only update if there is active pcm playback on speaker
2722     struct audio_usecase *usecase;
2723     struct listnode *node;
2724     struct platform_data *my_data = (struct platform_data *)adev->platform;
2725 
2726     my_data->speaker_lr_swap = swap_channels;
2727 
2728     return platform_set_swap_channels(adev, swap_channels);
2729 }
2730 
2731 int platform_set_swap_channels(struct audio_device *adev, bool swap_channels)
2732 {
2733     // only update if there is active pcm playback on speaker
2734     struct audio_usecase *usecase;
2735     struct listnode *node;
2736     struct platform_data *my_data = (struct platform_data *)adev->platform;
2737 
2738     // do not swap channels in audio modes with concurrent capture and playback
2739     // as this may break the echo reference
2740     if ((adev->mode == AUDIO_MODE_IN_COMMUNICATION) || (adev->mode == AUDIO_MODE_IN_CALL)) {
2741         ALOGV("%s: will not swap due to audio mode %d", __func__, adev->mode);
2742         return 0;
2743     }
2744 
2745     list_for_each(node, &adev->usecase_list) {
2746         usecase = node_to_item(node, struct audio_usecase, list);
2747         if (usecase->type == PCM_PLAYBACK &&
2748                 usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
2749             /*
2750              * If acdb tuning is different for SPEAKER_REVERSE, it is must
2751              * to perform device switch to disable the current backend to
2752              * enable it with new acdb data.
2753              */
2754             if (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
2755                 acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE]) {
2756                 const int initial_skpr_gain = ramp_speaker_gain(adev, false /*ramp_up*/, -1);
2757                 select_devices(adev, usecase->id);
2758                 if (initial_skpr_gain != -EINVAL)
2759                     ramp_speaker_gain(adev, true /*ramp_up*/, initial_skpr_gain);
2760 
2761             } else {
2762                 platform_set_swap_mixer(adev, swap_channels);
2763             }
2764             break;
2765         }
2766     }
2767 
2768     return 0;
2769 }
2770 
2771 int platform_snd_card_update(void *platform __unused,
2772                              card_status_t status __unused)
2773 {
2774     return -1;
2775 }
2776 
2777 int platform_send_audio_calibration_v2(void *platform __unused,
2778                                        struct audio_usecase *usecase __unused,
2779                                        int app_type __unused,
2780                                        int sample_rate __unused)
2781 {
2782     return -ENOSYS;
2783 }
2784 
2785 void platform_check_and_update_copp_sample_rate(void* platform __unused,
2786                                                snd_device_t snd_device __unused,
2787                                                 unsigned int stream_sr __unused,
2788                                                 int* sample_rate __unused)
2789 {
2790 
2791 }
2792 
2793 int platform_get_snd_device_backend_index(snd_device_t snd_device __unused)
2794 {
2795     return -ENOSYS;
2796 }
2797 
2798 bool platform_supports_app_type_cfg() { return false; }
2799 
2800 void platform_add_app_type(const char *uc_type __unused,
2801                            const char *mode __unused,
2802                            int bw __unused, int app_type __unused,
2803                            int max_sr __unused) {}
2804 
2805 int platform_get_app_type_v2(void *platform __unused,
2806                              enum usecase_type_t type __unused,
2807                              const char *mode __unused,
2808                              int bw __unused, int sr __unused,
2809                              int *app_type __unused) {
2810     return -ENOSYS;
2811 }
2812 
2813 int platform_set_sidetone(struct audio_device *adev,
2814                           snd_device_t out_snd_device,
2815                           bool enable, char *str)
2816 {
2817     int ret;
2818     if (out_snd_device == SND_DEVICE_OUT_USB_HEADSET ||
2819         out_snd_device == SND_DEVICE_OUT_VOICE_USB_HEADSET) {
2820             ret = audio_extn_usb_enable_sidetone(out_snd_device, enable);
2821             if (ret)
2822                 ALOGI("%s: usb device %d does not support device sidetone\n",
2823                   __func__, out_snd_device);
2824     } else {
2825         ALOGV("%s: sidetone out device(%d) mixer cmd = %s\n",
2826               __func__, out_snd_device, str);
2827 
2828         if (enable)
2829             audio_route_apply_and_update_path(adev->audio_route, str);
2830         else
2831             audio_route_reset_and_update_path(adev->audio_route, str);
2832     }
2833     return 0;
2834 }
2835 
2836 int platform_get_mmap_data_fd(void *platform __unused, int fe_dev __unused, int dir __unused,
2837                               int *fd __unused, uint32_t *size __unused)
2838 {
2839     return -ENOSYS;
2840 }
2841 
2842 bool platform_sound_trigger_usecase_needs_event(audio_usecase_t uc_id __unused)
2843 {
2844     return false;
2845 }
2846 
2847 bool platform_snd_device_has_speaker(snd_device_t dev __unused) {
2848     return false;
2849 }
2850 
2851 bool platform_set_microphone_characteristic(void *platform __unused,
2852                                             struct audio_microphone_characteristic_t mic __unused) {
2853     return -ENOSYS;
2854 }
2855 
2856 int platform_get_microphones(void *platform __unused,
2857                              struct audio_microphone_characteristic_t *mic_array __unused,
2858                              size_t *mic_count __unused) {
2859     return -ENOSYS;
2860 }
2861 
2862 bool platform_set_microphone_map(void *platform __unused, snd_device_t in_snd_device __unused,
2863                                  const struct mic_info *info __unused) {
2864     return false;
2865 }
2866 
2867 int platform_get_active_microphones(void *platform __unused, unsigned int channels __unused,
2868                                     audio_usecase_t usecase __unused,
2869                                     struct audio_microphone_characteristic_t *mic_array __unused,
2870                                     size_t *mic_count __unused) {
2871     return -ENOSYS;
2872 }
2873 
2874 int platform_set_usb_service_interval(void *platform __unused,
2875                                       bool playback __unused,
2876                                       unsigned long service_interval __unused,
2877                                       bool *reconfig)
2878 {
2879     *reconfig = false;
2880     return 0;
2881 }
2882 
2883 int platform_set_backend_cfg(const struct audio_device* adev __unused,
2884                              snd_device_t snd_device __unused,
2885                              const struct audio_backend_cfg *backend_cfg __unused)
2886 {
2887     return -1;
2888 }
2889