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