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