• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013-2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "msm8974_platform"
18 /*#define LOG_NDEBUG 0*/
19 #define LOG_NDDEBUG 0
20 
21 #include <stdlib.h>
22 #include <dlfcn.h>
23 #include <cutils/log.h>
24 #include <cutils/str_parms.h>
25 #include <cutils/properties.h>
26 #include <audio_hw.h>
27 #include <platform_api.h>
28 #include "platform.h"
29 
30 #define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
31 #define LIB_ACDB_LOADER "libacdbloader.so"
32 #define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
33 
34 #define DUALMIC_CONFIG_NONE 0      /* Target does not contain 2 mics */
35 #define DUALMIC_CONFIG_ENDFIRE 1
36 #define DUALMIC_CONFIG_BROADSIDE 2
37 
38 /*
39  * This file will have a maximum of 38 bytes:
40  *
41  * 4 bytes: number of audio blocks
42  * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
43  * Maximum 10 * 3 bytes: SAD blocks
44  */
45 #define MAX_SAD_BLOCKS      10
46 #define SAD_BLOCK_SIZE      3
47 
48 /* EDID format ID for LPCM audio */
49 #define EDID_FORMAT_LPCM    1
50 
51 /* Retry for delay in FW loading*/
52 #define RETRY_NUMBER 10
53 #define RETRY_US 500000
54 #define MAX_SND_CARD 8
55 
56 struct audio_block_header
57 {
58     int reserved;
59     int length;
60 };
61 
62 /* Audio calibration related functions */
63 typedef void (*acdb_deallocate_t)();
64 #ifdef PLATFORM_MSM8084
65 typedef int  (*acdb_init_t)(char *);
66 #else
67 typedef int  (*acdb_init_t)();
68 #endif
69 typedef void (*acdb_send_audio_cal_t)(int, int);
70 typedef void (*acdb_send_voice_cal_t)(int, int);
71 typedef int (*acdb_reload_vocvoltable_t)(int);
72 
73 /* Audio calibration related functions */
74 struct platform_data {
75     struct audio_device *adev;
76     bool fluence_in_spkr_mode;
77     bool fluence_in_voice_call;
78     bool fluence_in_voice_comm;
79     bool fluence_in_voice_rec;
80     int  dualmic_config;
81     void *acdb_handle;
82     acdb_init_t                acdb_init;
83     acdb_deallocate_t          acdb_deallocate;
84     acdb_send_audio_cal_t      acdb_send_audio_cal;
85     acdb_send_voice_cal_t      acdb_send_voice_cal;
86     acdb_reload_vocvoltable_t  acdb_reload_vocvoltable;
87     struct csd_data *csd;
88     bool ext_speaker;
89     bool ext_earpiece;
90     char ec_ref_mixer_path[64];
91 };
92 
93 static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
94     [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
95                                             DEEP_BUFFER_PCM_DEVICE},
96     [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
97                                             LOWLATENCY_PCM_DEVICE},
98     [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
99                                          MULTIMEDIA2_PCM_DEVICE},
100     [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {PLAYBACK_OFFLOAD_DEVICE,
101                                         PLAYBACK_OFFLOAD_DEVICE},
102     [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE,
103                               AUDIO_RECORD_PCM_DEVICE},
104     [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
105                                           LOWLATENCY_PCM_DEVICE},
106     [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE,
107                             VOICE_CALL_PCM_DEVICE},
108     [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
109     [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
110     [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
111     [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
112     [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
113                                    AUDIO_RECORD_PCM_DEVICE},
114     [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
115                                      AUDIO_RECORD_PCM_DEVICE},
116     [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
117                                                 AUDIO_RECORD_PCM_DEVICE},
118     [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
119 
120     [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
121                                           AFE_PROXY_RECORD_PCM_DEVICE},
122     [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
123                                         AFE_PROXY_RECORD_PCM_DEVICE},
124 
125 };
126 
127 /* Array to store sound devices */
128 static const char * const device_table[SND_DEVICE_MAX] = {
129     [SND_DEVICE_NONE] = "none",
130     /* Playback sound devices */
131     [SND_DEVICE_OUT_HANDSET] = "handset",
132     [SND_DEVICE_OUT_SPEAKER] = "speaker",
133     [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
134     [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
135     [SND_DEVICE_OUT_HEADPHONES] = "headphones",
136     [SND_DEVICE_OUT_LINE] = "line",
137     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
138     [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
139     [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
140     [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
141     [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
142     [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
143     [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
144     [SND_DEVICE_OUT_HDMI] = "hdmi",
145     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
146     [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
147     [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
148     [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
149     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
150     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
151     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
152     [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
153 
154     /* Capture sound devices */
155     [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
156     [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
157     [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
158     [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
159     [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
160     [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
161     [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
162     [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
163     [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = "dmic-endfire",
164 
165     [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
166     [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
167     [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
168     [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
169     [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
170     [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
171     [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
172     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
173     [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = "speaker-dmic-endfire",
174 
175     [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
176     [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
177 
178     [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
179     [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
180     [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
181 
182     [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
183 
184     [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
185     [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
186     [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
187     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
188     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
189     [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
190     [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
191     [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
192 
193     [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
194     [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
195     [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
196     [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
197 
198     [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
199 };
200 
201 /* ACDB IDs (audio DSP path configuration IDs) for each sound device */
202 static int acdb_device_table[SND_DEVICE_MAX] = {
203     [SND_DEVICE_NONE] = -1,
204     [SND_DEVICE_OUT_HANDSET] = 7,
205     [SND_DEVICE_OUT_SPEAKER] = 15,
206     [SND_DEVICE_OUT_SPEAKER_REVERSE] = 15,
207     [SND_DEVICE_OUT_SPEAKER_SAFE] = 15,
208     [SND_DEVICE_OUT_HEADPHONES] = 10,
209     [SND_DEVICE_OUT_LINE] = 77,
210     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
211     [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 77,
212     [SND_DEVICE_OUT_VOICE_HANDSET] = ACDB_ID_VOICE_HANDSET,
213     [SND_DEVICE_OUT_VOICE_SPEAKER] = ACDB_ID_VOICE_SPEAKER,
214     [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
215     [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
216     [SND_DEVICE_OUT_VOICE_LINE] = 77,
217     [SND_DEVICE_OUT_HDMI] = 18,
218     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 15,
219     [SND_DEVICE_OUT_BT_SCO] = 22,
220     [SND_DEVICE_OUT_BT_SCO_WB] = 39,
221     [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = ACDB_ID_VOICE_HANDSET_TMUS,
222     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
223     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
224     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
225     [SND_DEVICE_OUT_VOICE_TX] = 45,
226 
227     [SND_DEVICE_IN_HANDSET_MIC] = 4,
228     [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
229     [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
230     [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
231     [SND_DEVICE_IN_HANDSET_DMIC] = 41,
232     [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
233     [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
234     [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
235     [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = 34,
236 
237     [SND_DEVICE_IN_SPEAKER_MIC] = 11,
238     [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
239     [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
240     [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
241     [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
242     [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
243     [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
244     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
245     [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = 35,
246 
247     [SND_DEVICE_IN_HEADSET_MIC] = 8,
248     [SND_DEVICE_IN_HEADSET_MIC_AEC] = ACDB_ID_HEADSET_MIC_AEC,
249 
250     [SND_DEVICE_IN_HDMI_MIC] = 4,
251     [SND_DEVICE_IN_BT_SCO_MIC] = 21,
252     [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
253 
254     [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
255 
256     [SND_DEVICE_IN_VOICE_DMIC] = 41,
257     [SND_DEVICE_IN_VOICE_DMIC_TMUS] = ACDB_ID_VOICE_DMIC_EF_TMUS,
258     [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
259     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
260     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
261     [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
262     [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
263     [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
264 
265     [SND_DEVICE_IN_VOICE_REC_MIC] = 62,
266     [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 113,
267     [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 35,
268     [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 43,
269 
270     [SND_DEVICE_IN_VOICE_RX] = 44,
271 };
272 
273 struct name_to_index {
274     char name[100];
275     unsigned int index;
276 };
277 
278 #define TO_NAME_INDEX(X)   #X, X
279 
280 /* Used to get index from parsed string */
281 static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
282     /* out */
283     {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
284     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
285     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
286     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
287     {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
288     {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
289     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
290     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
291     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
292     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
293     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
294     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
295     {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
296     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
297     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
298     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
299     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET_TMUS)},
300     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
301     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
302     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
303     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
304 
305     /* in */
306     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
307     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
308     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
309     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
310     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
311     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
312     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
313     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
314     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_STEREO)},
315 
316     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
317     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
318     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
319     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
320     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
321     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
322     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
323     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
324     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
325 
326     {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
327 
328     {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
329     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
330     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
331 
332     {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
333 
334     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
335     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
336     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
337     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
338     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
339     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
340     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
341     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
342 
343     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
344     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
345     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
346     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
347 };
348 
349 static char * backend_table[SND_DEVICE_MAX] = {0};
350 
351 static const struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
352     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
353     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
354     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
355     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
356     {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
357     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
358     {TO_NAME_INDEX(USECASE_VOICE_CALL)},
359     {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
360     {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
361     {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
362     {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
363     {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK)},
364     {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
365     {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
366     {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
367 };
368 
369 #define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
370 #define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
371 
372 static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
373 static bool is_tmus = false;
374 
check_operator()375 static void check_operator()
376 {
377     char value[PROPERTY_VALUE_MAX];
378     int mccmnc;
379     property_get("gsm.sim.operator.numeric",value,"0");
380     mccmnc = atoi(value);
381     ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
382     switch(mccmnc) {
383     /* TMUS MCC(310), MNC(490, 260, 026) */
384     case 310490:
385     case 310260:
386     case 310026:
387     /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
388     case 310800:
389     case 310660:
390     case 310580:
391     case 310310:
392     case 310270:
393     case 310250:
394     case 310240:
395     case 310230:
396     case 310220:
397     case 310210:
398     case 310200:
399     case 310160:
400         is_tmus = true;
401         break;
402     }
403 }
404 
is_operator_tmus()405 bool is_operator_tmus()
406 {
407     pthread_once(&check_op_once_ctl, check_operator);
408     return is_tmus;
409 }
410 
platform_set_echo_reference(struct audio_device * adev,bool enable,audio_devices_t out_device)411 void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
412 {
413     struct platform_data *my_data = (struct platform_data *)adev->platform;
414     snd_device_t snd_device = SND_DEVICE_NONE;
415 
416     if (strcmp(my_data->ec_ref_mixer_path, "")) {
417         ALOGV("%s: diabling %s", __func__, my_data->ec_ref_mixer_path);
418         audio_route_reset_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
419     }
420 
421     if (enable) {
422         strcpy(my_data->ec_ref_mixer_path, "echo-reference");
423         if (out_device != AUDIO_DEVICE_NONE) {
424             snd_device = platform_get_output_snd_device(adev->platform, out_device);
425             platform_add_backend_name(adev->platform, my_data->ec_ref_mixer_path, snd_device);
426         }
427 
428         ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
429         audio_route_apply_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
430     }
431 }
432 
open_csd_client(bool i2s_ext_modem)433 static struct csd_data *open_csd_client(bool i2s_ext_modem)
434 {
435     struct csd_data *csd = calloc(1, sizeof(struct csd_data));
436 
437     csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
438     if (csd->csd_client == NULL) {
439         ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
440         goto error;
441     } else {
442         ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
443 
444         csd->deinit = (deinit_t)dlsym(csd->csd_client,
445                                              "csd_client_deinit");
446         if (csd->deinit == NULL) {
447             ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
448                   dlerror());
449             goto error;
450         }
451         csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
452                                              "csd_client_disable_device");
453         if (csd->disable_device == NULL) {
454             ALOGE("%s: dlsym error %s for csd_client_disable_device",
455                   __func__, dlerror());
456             goto error;
457         }
458         csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
459                                                "csd_client_enable_device_config");
460         if (csd->enable_device_config == NULL) {
461             ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
462                   __func__, dlerror());
463             goto error;
464         }
465         csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
466                                              "csd_client_enable_device");
467         if (csd->enable_device == NULL) {
468             ALOGE("%s: dlsym error %s for csd_client_enable_device",
469                   __func__, dlerror());
470             goto error;
471         }
472         csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
473                                              "csd_client_start_voice");
474         if (csd->start_voice == NULL) {
475             ALOGE("%s: dlsym error %s for csd_client_start_voice",
476                   __func__, dlerror());
477             goto error;
478         }
479         csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
480                                              "csd_client_stop_voice");
481         if (csd->stop_voice == NULL) {
482             ALOGE("%s: dlsym error %s for csd_client_stop_voice",
483                   __func__, dlerror());
484             goto error;
485         }
486         csd->volume = (volume_t)dlsym(csd->csd_client,
487                                              "csd_client_volume");
488         if (csd->volume == NULL) {
489             ALOGE("%s: dlsym error %s for csd_client_volume",
490                   __func__, dlerror());
491             goto error;
492         }
493         csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
494                                              "csd_client_mic_mute");
495         if (csd->mic_mute == NULL) {
496             ALOGE("%s: dlsym error %s for csd_client_mic_mute",
497                   __func__, dlerror());
498             goto error;
499         }
500         csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
501                                              "csd_client_slow_talk");
502         if (csd->slow_talk == NULL) {
503             ALOGE("%s: dlsym error %s for csd_client_slow_talk",
504                   __func__, dlerror());
505             goto error;
506         }
507         csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
508                                              "csd_client_start_playback");
509         if (csd->start_playback == NULL) {
510             ALOGE("%s: dlsym error %s for csd_client_start_playback",
511                   __func__, dlerror());
512             goto error;
513         }
514         csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
515                                              "csd_client_stop_playback");
516         if (csd->stop_playback == NULL) {
517             ALOGE("%s: dlsym error %s for csd_client_stop_playback",
518                   __func__, dlerror());
519             goto error;
520         }
521         csd->start_record = (start_record_t)dlsym(csd->csd_client,
522                                              "csd_client_start_record");
523         if (csd->start_record == NULL) {
524             ALOGE("%s: dlsym error %s for csd_client_start_record",
525                   __func__, dlerror());
526             goto error;
527         }
528         csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
529                                              "csd_client_stop_record");
530         if (csd->stop_record == NULL) {
531             ALOGE("%s: dlsym error %s for csd_client_stop_record",
532                   __func__, dlerror());
533             goto error;
534         }
535 
536         csd->get_sample_rate = (get_sample_rate_t)dlsym(csd->csd_client,
537                                              "csd_client_get_sample_rate");
538         if (csd->get_sample_rate == NULL) {
539             ALOGE("%s: dlsym error %s for csd_client_get_sample_rate",
540                   __func__, dlerror());
541 
542             goto error;
543         }
544 
545         csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
546 
547         if (csd->init == NULL) {
548             ALOGE("%s: dlsym error %s for csd_client_init",
549                   __func__, dlerror());
550             goto error;
551         } else {
552             csd->init(i2s_ext_modem);
553         }
554     }
555     return csd;
556 
557 error:
558     free(csd);
559     csd = NULL;
560     return csd;
561 }
562 
close_csd_client(struct csd_data * csd)563 void close_csd_client(struct csd_data *csd)
564 {
565     if (csd != NULL) {
566         csd->deinit();
567         dlclose(csd->csd_client);
568         free(csd);
569         csd = NULL;
570     }
571 }
572 
platform_csd_init(struct platform_data * my_data)573 static void platform_csd_init(struct platform_data *my_data)
574 {
575 #ifdef PLATFORM_MSM8084
576     int32_t modems, (*count_modems)(void);
577     const char *name = "libdetectmodem.so";
578     const char *func = "count_modems";
579     const char *error;
580 
581     my_data->csd = NULL;
582 
583     void *lib = dlopen(name, RTLD_NOW);
584     error = dlerror();
585     if (!lib) {
586         ALOGE("%s: could not find %s: %s", __func__, name, error);
587         return;
588     }
589 
590     count_modems = NULL;
591     *(void **)(&count_modems) = dlsym(lib, func);
592     error = dlerror();
593     if (!count_modems) {
594         ALOGE("%s: could not find symbol %s in %s: %s",
595               __func__, func, name, error);
596         goto done;
597     }
598 
599     modems = count_modems();
600     if (modems < 0) {
601         ALOGE("%s: count_modems failed\n", __func__);
602         goto done;
603     }
604 
605     ALOGD("%s: num_modems %d\n", __func__, modems);
606     if (modems > 0)
607         my_data->csd = open_csd_client(false /*is_i2s_ext_modem*/);
608 
609 done:
610     dlclose(lib);
611 #else
612      my_data->csd = NULL;
613 #endif
614 }
615 
set_platform_defaults(struct platform_data * my_data)616 static void set_platform_defaults(struct platform_data * my_data)
617 {
618     int32_t dev;
619     for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
620         backend_table[dev] = NULL;
621     }
622 
623     // TBD - do these go to the platform-info.xml file.
624     // will help in avoiding strdups here
625     backend_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
626     backend_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
627     backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
628     backend_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
629     backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
630     backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
631     backend_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
632     backend_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
633 
634     if (my_data->ext_speaker) {
635         backend_table[SND_DEVICE_OUT_SPEAKER] = strdup("speaker");
636         backend_table[SND_DEVICE_OUT_SPEAKER_SAFE] = strdup("speaker");
637         backend_table[SND_DEVICE_OUT_VOICE_SPEAKER] = strdup("speaker");
638         backend_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = strdup("speaker");
639         backend_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] =
640             strdup("speaker-and-headphones");
641         backend_table[SND_DEVICE_OUT_SPEAKER_AND_LINE] =
642             strdup("speaker-and-line");
643     }
644 
645     if (my_data->ext_earpiece) {
646         backend_table[SND_DEVICE_OUT_VOICE_HANDSET] = strdup("handset");
647         backend_table[SND_DEVICE_OUT_VOICE_HAC_HANDSET] = strdup("handset");
648         backend_table[SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = strdup("handset");
649         backend_table[SND_DEVICE_OUT_HANDSET] = strdup("handset");
650         backend_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("handset");
651     }
652 }
653 
platform_init(struct audio_device * adev)654 void *platform_init(struct audio_device *adev)
655 {
656     char value[PROPERTY_VALUE_MAX];
657     struct platform_data *my_data;
658     int retry_num = 0, snd_card_num = 0;
659     const char *snd_card_name;
660 
661     while (snd_card_num < MAX_SND_CARD) {
662         adev->mixer = mixer_open(snd_card_num);
663 
664         while (!adev->mixer && retry_num < RETRY_NUMBER) {
665             usleep(RETRY_US);
666             adev->mixer = mixer_open(snd_card_num);
667             retry_num++;
668         }
669 
670         if (!adev->mixer) {
671             ALOGE("%s: Unable to open the mixer card: %d", __func__,
672                    snd_card_num);
673             retry_num = 0;
674             snd_card_num++;
675             continue;
676         }
677 
678         snd_card_name = mixer_get_name(adev->mixer);
679         ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
680 
681         adev->audio_route = audio_route_init(snd_card_num, MIXER_XML_PATH);
682         if (!adev->audio_route) {
683             ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
684             return NULL;
685         }
686         adev->snd_card = snd_card_num;
687         ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
688         break;
689     }
690 
691     if (snd_card_num >= MAX_SND_CARD) {
692         ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
693         return NULL;
694     }
695 
696     my_data = calloc(1, sizeof(struct platform_data));
697 
698     my_data->adev = adev;
699     my_data->dualmic_config = DUALMIC_CONFIG_NONE;
700     my_data->fluence_in_spkr_mode = false;
701     my_data->fluence_in_voice_call = false;
702     my_data->fluence_in_voice_comm = false;
703     my_data->fluence_in_voice_rec = false;
704 
705     /*
706      * The default assumption is that earpiece (handset), speaker and headphones
707      * devices are connected to internal HW codec and communicated through
708      * slimbus backend. If any platform communicates with speaker or earpiece
709      * or headphones through non-slimbus backend such as MI2S or AUXPCM etc.,
710      * the ext_xxxx flags must be set accordingly.
711      */
712     if (strstr(snd_card_name, "tfa9890_stereo")) {
713         my_data->ext_speaker = true;
714         my_data->ext_earpiece = true;
715     } else if (strstr(snd_card_name, "tfa9890")) {
716         my_data->ext_speaker = true;
717     }
718 
719     property_get("persist.audio.dualmic.config",value,"");
720     if (!strcmp("broadside", value)) {
721         ALOGE("%s: Unsupported dualmic configuration", __func__);
722     } else if (!strcmp("endfire", value)) {
723         my_data->dualmic_config = DUALMIC_CONFIG_ENDFIRE;
724     }
725 
726     if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
727         property_get("persist.audio.fluence.voicecall",value,"");
728         if (!strcmp("true", value)) {
729             my_data->fluence_in_voice_call = true;
730         }
731 
732         property_get("persist.audio.fluence.voicecomm",value,"");
733         if (!strcmp("true", value)) {
734             my_data->fluence_in_voice_comm = true;
735         }
736 
737         property_get("persist.audio.fluence.voicerec",value,"");
738         if (!strcmp("true", value)) {
739             my_data->fluence_in_voice_rec = true;
740         }
741 
742         property_get("persist.audio.fluence.speaker",value,"");
743         if (!strcmp("true", value)) {
744             my_data->fluence_in_spkr_mode = true;
745         }
746     }
747 
748     my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
749     if (my_data->acdb_handle == NULL) {
750         ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
751     } else {
752         ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
753         my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
754                                                     "acdb_loader_deallocate_ACDB");
755         if (!my_data->acdb_deallocate)
756             ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
757                   __func__, LIB_ACDB_LOADER);
758 
759         my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
760                                                     "acdb_loader_send_audio_cal");
761         if (!my_data->acdb_send_audio_cal)
762             ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
763                   __func__, LIB_ACDB_LOADER);
764 
765         my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
766                                                     "acdb_loader_send_voice_cal");
767         if (!my_data->acdb_send_voice_cal)
768             ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
769                   __func__, LIB_ACDB_LOADER);
770 
771         my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
772                                                     "acdb_loader_reload_vocvoltable");
773         if (!my_data->acdb_reload_vocvoltable)
774             ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
775                   __func__, LIB_ACDB_LOADER);
776 #ifdef PLATFORM_MSM8084
777         my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
778                                                     "acdb_loader_init_v2");
779         if (my_data->acdb_init == NULL)
780             ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
781         else
782             my_data->acdb_init((char *)snd_card_name);
783 #else
784         my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
785                                                     "acdb_loader_init_ACDB");
786         if (my_data->acdb_init == NULL)
787             ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
788         else
789             my_data->acdb_init();
790 #endif
791 
792     }
793 
794     set_platform_defaults(my_data);
795 
796     /* Initialize platform specific ids and/or backends*/
797     platform_info_init();
798 
799     /* load csd client */
800     platform_csd_init(my_data);
801 
802     return my_data;
803 }
804 
platform_deinit(void * platform)805 void platform_deinit(void *platform)
806 {
807     struct platform_data *my_data = (struct platform_data *)platform;
808     close_csd_client(my_data->csd);
809     free(platform);
810 }
811 
platform_get_snd_device_name(snd_device_t snd_device)812 const char *platform_get_snd_device_name(snd_device_t snd_device)
813 {
814     if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
815         return device_table[snd_device];
816     else
817         return "none";
818 }
819 
platform_add_backend_name(void * platform,char * mixer_path,snd_device_t snd_device)820 void platform_add_backend_name(void *platform, char *mixer_path,
821                                snd_device_t snd_device)
822 {
823     struct platform_data *my_data = (struct platform_data *)platform;
824 
825     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
826         ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
827         return;
828     }
829 
830     const char * suffix = backend_table[snd_device];
831 
832     if (suffix != NULL) {
833         strcat(mixer_path, " ");
834         strcat(mixer_path, suffix);
835     }
836 }
837 
platform_get_pcm_device_id(audio_usecase_t usecase,int device_type)838 int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
839 {
840     int device_id;
841     if (device_type == PCM_PLAYBACK)
842         device_id = pcm_device_table[usecase][0];
843     else
844         device_id = pcm_device_table[usecase][1];
845     return device_id;
846 }
847 
find_index(const struct name_to_index * table,int32_t len,const char * name)848 static int find_index(const struct name_to_index * table, int32_t len,
849                       const char * name)
850 {
851     int ret = 0;
852     int32_t i;
853 
854     if (table == NULL) {
855         ALOGE("%s: table is NULL", __func__);
856         ret = -ENODEV;
857         goto done;
858     }
859 
860     if (name == NULL) {
861         ALOGE("null key");
862         ret = -ENODEV;
863         goto done;
864     }
865 
866     for (i=0; i < len; i++) {
867         if (!strcmp(table[i].name, name)) {
868             ret = table[i].index;
869             goto done;
870         }
871     }
872     ALOGE("%s: Could not find index for name = %s",
873             __func__, name);
874     ret = -ENODEV;
875 done:
876     return ret;
877 }
878 
platform_get_snd_device_index(char * device_name)879 int platform_get_snd_device_index(char *device_name)
880 {
881     return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
882 }
883 
platform_get_usecase_index(const char * usecase_name)884 int platform_get_usecase_index(const char *usecase_name)
885 {
886     return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
887 }
888 
platform_set_snd_device_acdb_id(snd_device_t snd_device,unsigned int acdb_id)889 int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
890 {
891     int ret = 0;
892 
893     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
894         ALOGE("%s: Invalid snd_device = %d",
895             __func__, snd_device);
896         ret = -EINVAL;
897         goto done;
898     }
899 
900     acdb_device_table[snd_device] = acdb_id;
901 done:
902     return ret;
903 }
904 
platform_send_audio_calibration(void * platform,snd_device_t snd_device)905 int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
906 {
907     struct platform_data *my_data = (struct platform_data *)platform;
908     int acdb_dev_id, acdb_dev_type;
909 
910     acdb_dev_id = acdb_device_table[snd_device];
911     if (acdb_dev_id < 0) {
912         ALOGE("%s: Could not find acdb id for device(%d)",
913               __func__, snd_device);
914         return -EINVAL;
915     }
916     if (my_data->acdb_send_audio_cal) {
917         ALOGD("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
918               __func__, snd_device, acdb_dev_id);
919         if (snd_device >= SND_DEVICE_OUT_BEGIN &&
920                 snd_device < SND_DEVICE_OUT_END)
921             acdb_dev_type = ACDB_DEV_TYPE_OUT;
922         else
923             acdb_dev_type = ACDB_DEV_TYPE_IN;
924         my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
925     }
926     return 0;
927 }
928 
platform_switch_voice_call_device_pre(void * platform)929 int platform_switch_voice_call_device_pre(void *platform)
930 {
931     struct platform_data *my_data = (struct platform_data *)platform;
932     int ret = 0;
933 
934     if (my_data->csd != NULL &&
935         voice_is_in_call(my_data->adev)) {
936         /* This must be called before disabling mixer controls on APQ side */
937         ret = my_data->csd->disable_device();
938         if (ret < 0) {
939             ALOGE("%s: csd_client_disable_device, failed, error %d",
940                   __func__, ret);
941         }
942     }
943     return ret;
944 }
945 
platform_switch_voice_call_enable_device_config(void * platform,snd_device_t out_snd_device,snd_device_t in_snd_device)946 int platform_switch_voice_call_enable_device_config(void *platform,
947                                                     snd_device_t out_snd_device,
948                                                     snd_device_t in_snd_device)
949 {
950     struct platform_data *my_data = (struct platform_data *)platform;
951     int acdb_rx_id, acdb_tx_id;
952     int ret = 0;
953 
954     if (my_data->csd == NULL)
955         return ret;
956 
957     acdb_rx_id = acdb_device_table[out_snd_device];
958 
959     acdb_tx_id = acdb_device_table[in_snd_device];
960 
961     if (acdb_rx_id > 0 && acdb_tx_id > 0) {
962         ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
963         if (ret < 0) {
964             ALOGE("%s: csd_enable_device_config, failed, error %d",
965                   __func__, ret);
966         }
967     } else {
968         ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
969               acdb_rx_id, acdb_tx_id);
970     }
971 
972     return ret;
973 }
974 
platform_switch_voice_call_device_post(void * platform,snd_device_t out_snd_device,snd_device_t in_snd_device)975 int platform_switch_voice_call_device_post(void *platform,
976                                            snd_device_t out_snd_device,
977                                            snd_device_t in_snd_device)
978 {
979     struct platform_data *my_data = (struct platform_data *)platform;
980     int acdb_rx_id, acdb_tx_id;
981 
982     if (my_data->acdb_send_voice_cal == NULL) {
983         ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
984     } else {
985         acdb_rx_id = acdb_device_table[out_snd_device];
986         acdb_tx_id = acdb_device_table[in_snd_device];
987 
988         if (acdb_rx_id > 0 && acdb_tx_id > 0)
989             my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
990         else
991             ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
992                   acdb_rx_id, acdb_tx_id);
993     }
994 
995     return 0;
996 }
997 
platform_switch_voice_call_usecase_route_post(void * platform,snd_device_t out_snd_device,snd_device_t in_snd_device)998 int platform_switch_voice_call_usecase_route_post(void *platform,
999                                                   snd_device_t out_snd_device,
1000                                                   snd_device_t in_snd_device)
1001 {
1002     struct platform_data *my_data = (struct platform_data *)platform;
1003     int acdb_rx_id, acdb_tx_id;
1004     int ret = 0;
1005 
1006     if (my_data->csd == NULL)
1007         return ret;
1008 
1009     acdb_rx_id = acdb_device_table[out_snd_device];
1010 
1011     acdb_tx_id = acdb_device_table[in_snd_device];
1012 
1013     if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1014         ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
1015                                           my_data->adev->acdb_settings);
1016         if (ret < 0) {
1017             ALOGE("%s: csd_enable_device, failed, error %d", __func__, ret);
1018         }
1019     } else {
1020         ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1021               acdb_rx_id, acdb_tx_id);
1022     }
1023 
1024     return ret;
1025 }
1026 
platform_start_voice_call(void * platform,uint32_t vsid)1027 int platform_start_voice_call(void *platform, uint32_t vsid)
1028 {
1029     struct platform_data *my_data = (struct platform_data *)platform;
1030     int ret = 0;
1031 
1032     if (my_data->csd != NULL) {
1033         ret = my_data->csd->start_voice(vsid);
1034         if (ret < 0) {
1035             ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
1036         }
1037     }
1038     return ret;
1039 }
1040 
platform_stop_voice_call(void * platform,uint32_t vsid)1041 int platform_stop_voice_call(void *platform, uint32_t vsid)
1042 {
1043     struct platform_data *my_data = (struct platform_data *)platform;
1044     int ret = 0;
1045 
1046     if (my_data->csd != NULL) {
1047         ret = my_data->csd->stop_voice(vsid);
1048         if (ret < 0) {
1049             ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
1050         }
1051     }
1052     return ret;
1053 }
1054 
platform_get_sample_rate(void * platform,uint32_t * rate)1055 int platform_get_sample_rate(void *platform, uint32_t *rate)
1056 {
1057     struct platform_data *my_data = (struct platform_data *)platform;
1058     int ret = 0;
1059 
1060     if (my_data->csd != NULL) {
1061         ret = my_data->csd->get_sample_rate(rate);
1062         if (ret < 0) {
1063             ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret);
1064         }
1065     }
1066     return ret;
1067 }
1068 
platform_set_voice_volume(void * platform,int volume)1069 int platform_set_voice_volume(void *platform, int volume)
1070 {
1071     struct platform_data *my_data = (struct platform_data *)platform;
1072     struct audio_device *adev = my_data->adev;
1073     struct mixer_ctl *ctl;
1074     const char *mixer_ctl_name = "Voice Rx Gain";
1075     int vol_index = 0, ret = 0;
1076     uint32_t set_values[ ] = {0,
1077                               ALL_SESSION_VSID,
1078                               DEFAULT_VOLUME_RAMP_DURATION_MS};
1079 
1080     // Voice volume levels are mapped to adsp volume levels as follows.
1081     // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1  0 -> 0
1082     // But this values don't changed in kernel. So, below change is need.
1083     vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
1084     set_values[0] = vol_index;
1085 
1086     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1087     if (!ctl) {
1088         ALOGE("%s: Could not get ctl for mixer cmd - %s",
1089               __func__, mixer_ctl_name);
1090         return -EINVAL;
1091     }
1092     ALOGV("Setting voice volume index: %d", set_values[0]);
1093     mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1094 
1095     if (my_data->csd != NULL) {
1096         ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
1097                                    DEFAULT_VOLUME_RAMP_DURATION_MS);
1098         if (ret < 0) {
1099             ALOGE("%s: csd_volume error %d", __func__, ret);
1100         }
1101     }
1102     return ret;
1103 }
1104 
platform_set_mic_mute(void * platform,bool state)1105 int platform_set_mic_mute(void *platform, bool state)
1106 {
1107     struct platform_data *my_data = (struct platform_data *)platform;
1108     struct audio_device *adev = my_data->adev;
1109     struct mixer_ctl *ctl;
1110     const char *mixer_ctl_name = "Voice Tx Mute";
1111     int ret = 0;
1112     uint32_t set_values[ ] = {0,
1113                               ALL_SESSION_VSID,
1114                               DEFAULT_MUTE_RAMP_DURATION_MS};
1115 
1116     if (adev->mode != AUDIO_MODE_IN_CALL)
1117         return 0;
1118 
1119     set_values[0] = state;
1120     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1121     if (!ctl) {
1122         ALOGE("%s: Could not get ctl for mixer cmd - %s",
1123               __func__, mixer_ctl_name);
1124         return -EINVAL;
1125     }
1126     ALOGV("Setting voice mute state: %d", state);
1127     mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1128 
1129     if (my_data->csd != NULL) {
1130         ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state,
1131                                      DEFAULT_MUTE_RAMP_DURATION_MS);
1132         if (ret < 0) {
1133             ALOGE("%s: csd_mic_mute error %d", __func__, ret);
1134         }
1135     }
1136     return ret;
1137 }
1138 
platform_set_device_mute(void * platform,bool state,char * dir)1139 int platform_set_device_mute(void *platform, bool state, char *dir)
1140 {
1141     struct platform_data *my_data = (struct platform_data *)platform;
1142     struct audio_device *adev = my_data->adev;
1143     struct mixer_ctl *ctl;
1144     char *mixer_ctl_name = NULL;
1145     int ret = 0;
1146     uint32_t set_values[ ] = {0,
1147                               ALL_SESSION_VSID,
1148                               0};
1149     if(dir == NULL) {
1150         ALOGE("%s: Invalid direction:%s", __func__, dir);
1151         return -EINVAL;
1152     }
1153 
1154     if (!strncmp("rx", dir, sizeof("rx"))) {
1155         mixer_ctl_name = "Voice Rx Device Mute";
1156     } else if (!strncmp("tx", dir, sizeof("tx"))) {
1157         mixer_ctl_name = "Voice Tx Device Mute";
1158     } else {
1159         return -EINVAL;
1160     }
1161 
1162     set_values[0] = state;
1163     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1164     if (!ctl) {
1165         ALOGE("%s: Could not get ctl for mixer cmd - %s",
1166               __func__, mixer_ctl_name);
1167         return -EINVAL;
1168     }
1169 
1170     ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
1171           __func__,state, mixer_ctl_name);
1172     mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1173 
1174     return ret;
1175 }
1176 
platform_get_output_snd_device(void * platform,audio_devices_t devices)1177 snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
1178 {
1179     struct platform_data *my_data = (struct platform_data *)platform;
1180     struct audio_device *adev = my_data->adev;
1181     audio_mode_t mode = adev->mode;
1182     snd_device_t snd_device = SND_DEVICE_NONE;
1183 
1184     ALOGV("%s: enter: output devices(%#x)", __func__, devices);
1185     if (devices == AUDIO_DEVICE_NONE ||
1186         devices & AUDIO_DEVICE_BIT_IN) {
1187         ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
1188         goto exit;
1189     }
1190 
1191     if (voice_is_in_call(adev) || adev->enable_voicerx) {
1192         if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1193             devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1194             devices & AUDIO_DEVICE_OUT_LINE) {
1195             if (voice_is_in_call(adev) &&
1196                 (adev->voice.tty_mode == TTY_MODE_FULL))
1197                 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
1198             else if (voice_is_in_call(adev) &&
1199                 (adev->voice.tty_mode == TTY_MODE_VCO))
1200                 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
1201             else if (voice_is_in_call(adev) &&
1202                 (adev->voice.tty_mode == TTY_MODE_HCO))
1203                 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
1204             else {
1205                 if (devices & AUDIO_DEVICE_OUT_LINE)
1206                     snd_device = SND_DEVICE_OUT_VOICE_LINE;
1207                 else
1208                     snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
1209                 }
1210         } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
1211             if (adev->bt_wb_speech_enabled) {
1212                 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1213             } else {
1214                 snd_device = SND_DEVICE_OUT_BT_SCO;
1215             }
1216         } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
1217             snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
1218         } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
1219             if(adev->voice.hac)
1220                 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1221             else if (is_operator_tmus())
1222                 snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
1223             else
1224                 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
1225         } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1226             snd_device = SND_DEVICE_OUT_VOICE_TX;
1227 
1228         if (snd_device != SND_DEVICE_NONE) {
1229             goto exit;
1230         }
1231     }
1232 
1233     if (popcount(devices) == 2) {
1234         if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1235                         AUDIO_DEVICE_OUT_SPEAKER)) {
1236             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1237         } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1238                                AUDIO_DEVICE_OUT_SPEAKER)) {
1239             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1240         } else if (devices == (AUDIO_DEVICE_OUT_LINE |
1241                                AUDIO_DEVICE_OUT_SPEAKER)) {
1242             snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
1243         } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
1244                                AUDIO_DEVICE_OUT_SPEAKER)) {
1245             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
1246         } else {
1247             ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
1248             goto exit;
1249         }
1250         if (snd_device != SND_DEVICE_NONE) {
1251             goto exit;
1252         }
1253     }
1254 
1255     if (popcount(devices) != 1) {
1256         ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
1257         goto exit;
1258     }
1259 
1260     if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1261         devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1262         snd_device = SND_DEVICE_OUT_HEADPHONES;
1263     } else if (devices & AUDIO_DEVICE_OUT_LINE) {
1264         snd_device = SND_DEVICE_OUT_LINE;
1265     } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
1266         snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
1267     } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
1268         if (adev->speaker_lr_swap)
1269             snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
1270         else
1271             snd_device = SND_DEVICE_OUT_SPEAKER;
1272     } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
1273         if (adev->bt_wb_speech_enabled) {
1274             snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1275         } else {
1276             snd_device = SND_DEVICE_OUT_BT_SCO;
1277         }
1278     } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1279         snd_device = SND_DEVICE_OUT_HDMI ;
1280     } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
1281         /*HAC support for voice-ish audio (eg visual voicemail)*/
1282         if(adev->voice.hac)
1283             snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1284         else
1285             snd_device = SND_DEVICE_OUT_HANDSET;
1286     } else {
1287         ALOGE("%s: Unknown device(s) %#x", __func__, devices);
1288     }
1289 exit:
1290     ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
1291     return snd_device;
1292 }
1293 
platform_get_input_snd_device(void * platform,audio_devices_t out_device)1294 snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
1295 {
1296     struct platform_data *my_data = (struct platform_data *)platform;
1297     struct audio_device *adev = my_data->adev;
1298     audio_source_t  source = (adev->active_input == NULL) ?
1299                                 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
1300 
1301     audio_mode_t    mode   = adev->mode;
1302     audio_devices_t in_device = ((adev->active_input == NULL) ?
1303                                     AUDIO_DEVICE_NONE : adev->active_input->device)
1304                                 & ~AUDIO_DEVICE_BIT_IN;
1305     audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1306                                 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1307     snd_device_t snd_device = SND_DEVICE_NONE;
1308     int channel_count = popcount(channel_mask);
1309 
1310     ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
1311           __func__, out_device, in_device);
1312     if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
1313         if (adev->voice.tty_mode != TTY_MODE_OFF) {
1314             if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1315                 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1316                 out_device & AUDIO_DEVICE_OUT_LINE) {
1317                 switch (adev->voice.tty_mode) {
1318                 case TTY_MODE_FULL:
1319                     snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
1320                     break;
1321                 case TTY_MODE_VCO:
1322                     snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
1323                     break;
1324                 case TTY_MODE_HCO:
1325                     snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
1326                     break;
1327                 default:
1328                     ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
1329                 }
1330                 goto exit;
1331             }
1332         }
1333         if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
1334             if (my_data->fluence_in_voice_call == false) {
1335                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1336             } else {
1337                 if (is_operator_tmus())
1338                     snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS;
1339                 else
1340                     snd_device = SND_DEVICE_IN_VOICE_DMIC;
1341             }
1342         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1343             snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
1344         } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
1345             if (adev->bt_wb_speech_enabled) {
1346                 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1347             } else {
1348                 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1349             }
1350         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
1351             out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
1352             out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1353             out_device & AUDIO_DEVICE_OUT_LINE) {
1354             if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
1355                     my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1356                 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
1357             } else {
1358                 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
1359             }
1360         } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1361             snd_device = SND_DEVICE_IN_VOICE_RX;
1362     } else if (source == AUDIO_SOURCE_CAMCORDER) {
1363         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
1364             in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1365             snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
1366         }
1367     } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1368         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1369             if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1370                 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
1371                     snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
1372                 else if (my_data->fluence_in_voice_rec &&
1373                          adev->active_input->enable_ns)
1374                     snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
1375             }
1376 
1377             if (snd_device == SND_DEVICE_NONE) {
1378                 if (adev->active_input->enable_ns)
1379                     snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
1380                 else
1381                     snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
1382             }
1383         }
1384     } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1385         if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE))
1386             in_device = AUDIO_DEVICE_IN_BACK_MIC;
1387         if (adev->active_input) {
1388             if (adev->active_input->enable_aec &&
1389                     adev->active_input->enable_ns) {
1390                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1391                     if (my_data->fluence_in_spkr_mode &&
1392                             my_data->fluence_in_voice_comm &&
1393                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1394                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
1395                     } else
1396                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
1397                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1398                     if (my_data->fluence_in_voice_comm &&
1399                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1400                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
1401                     } else
1402                         snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
1403                 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1404                     snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
1405                 }
1406                 platform_set_echo_reference(adev, true, out_device);
1407             } else if (adev->active_input->enable_aec) {
1408                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1409                     if (my_data->fluence_in_spkr_mode &&
1410                             my_data->fluence_in_voice_comm &&
1411                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1412                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
1413                     } else
1414                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
1415                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1416                     if (my_data->fluence_in_voice_comm &&
1417                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1418                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
1419                     } else
1420                         snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
1421                } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1422                    snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
1423                }
1424                platform_set_echo_reference(adev, true, out_device);
1425             } else if (adev->active_input->enable_ns) {
1426                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1427                     if (my_data->fluence_in_spkr_mode &&
1428                             my_data->fluence_in_voice_comm &&
1429                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1430                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
1431                     } else
1432                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
1433                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1434                     if (my_data->fluence_in_voice_comm &&
1435                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1436                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
1437                     } else
1438                         snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
1439                 }
1440             }
1441         }
1442     } else if (source == AUDIO_SOURCE_DEFAULT) {
1443         goto exit;
1444     }
1445 
1446 
1447     if (snd_device != SND_DEVICE_NONE) {
1448         goto exit;
1449     }
1450 
1451     if (in_device != AUDIO_DEVICE_NONE &&
1452             !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
1453             !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
1454         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1455             if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
1456                     channel_count == 2)
1457                 snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
1458             else
1459                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1460         } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1461             if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
1462                     channel_count == 2)
1463                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
1464             else
1465                 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
1466         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1467             snd_device = SND_DEVICE_IN_HEADSET_MIC;
1468         } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
1469             if (adev->bt_wb_speech_enabled) {
1470                 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1471             } else {
1472                 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1473             }
1474         } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
1475             snd_device = SND_DEVICE_IN_HDMI_MIC;
1476         } else {
1477             ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
1478             ALOGW("%s: Using default handset-mic", __func__);
1479             snd_device = SND_DEVICE_IN_HANDSET_MIC;
1480         }
1481     } else {
1482         if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
1483             snd_device = SND_DEVICE_IN_HANDSET_MIC;
1484         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1485             snd_device = SND_DEVICE_IN_HEADSET_MIC;
1486         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
1487                    out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
1488                    out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1489                    out_device & AUDIO_DEVICE_OUT_LINE) {
1490             if (channel_count == 2)
1491                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
1492             else
1493                 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
1494         } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
1495             if (adev->bt_wb_speech_enabled) {
1496                 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1497             } else {
1498                 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1499             }
1500         } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1501             snd_device = SND_DEVICE_IN_HDMI_MIC;
1502         } else {
1503             ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
1504             ALOGW("%s: Using default handset-mic", __func__);
1505             snd_device = SND_DEVICE_IN_HANDSET_MIC;
1506         }
1507     }
1508 exit:
1509     ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
1510     return snd_device;
1511 }
1512 
platform_set_hdmi_channels(void * platform,int channel_count)1513 int platform_set_hdmi_channels(void *platform,  int channel_count)
1514 {
1515     struct platform_data *my_data = (struct platform_data *)platform;
1516     struct audio_device *adev = my_data->adev;
1517     struct mixer_ctl *ctl;
1518     const char *channel_cnt_str = NULL;
1519     const char *mixer_ctl_name = "HDMI_RX Channels";
1520     switch (channel_count) {
1521     case 8:
1522         channel_cnt_str = "Eight"; break;
1523     case 7:
1524         channel_cnt_str = "Seven"; break;
1525     case 6:
1526         channel_cnt_str = "Six"; break;
1527     case 5:
1528         channel_cnt_str = "Five"; break;
1529     case 4:
1530         channel_cnt_str = "Four"; break;
1531     case 3:
1532         channel_cnt_str = "Three"; break;
1533     default:
1534         channel_cnt_str = "Two"; break;
1535     }
1536     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1537     if (!ctl) {
1538         ALOGE("%s: Could not get ctl for mixer cmd - %s",
1539               __func__, mixer_ctl_name);
1540         return -EINVAL;
1541     }
1542     ALOGV("HDMI channel count: %s", channel_cnt_str);
1543     mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
1544     return 0;
1545 }
1546 
platform_edid_get_max_channels(void * platform)1547 int platform_edid_get_max_channels(void *platform)
1548 {
1549     struct platform_data *my_data = (struct platform_data *)platform;
1550     struct audio_device *adev = my_data->adev;
1551     char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
1552     char *sad = block;
1553     int num_audio_blocks;
1554     int channel_count;
1555     int max_channels = 0;
1556     int i, ret, count;
1557 
1558     struct mixer_ctl *ctl;
1559 
1560     ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
1561     if (!ctl) {
1562         ALOGE("%s: Could not get ctl for mixer cmd - %s",
1563               __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
1564         return 0;
1565     }
1566 
1567     mixer_ctl_update(ctl);
1568 
1569     count = mixer_ctl_get_num_values(ctl);
1570 
1571     /* Read SAD blocks, clamping the maximum size for safety */
1572     if (count > (int)sizeof(block))
1573         count = (int)sizeof(block);
1574 
1575     ret = mixer_ctl_get_array(ctl, block, count);
1576     if (ret != 0) {
1577         ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
1578         return 0;
1579     }
1580 
1581     /* Calculate the number of SAD blocks */
1582     num_audio_blocks = count / SAD_BLOCK_SIZE;
1583 
1584     for (i = 0; i < num_audio_blocks; i++) {
1585         /* Only consider LPCM blocks */
1586         if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
1587             sad += 3;
1588             continue;
1589         }
1590 
1591         channel_count = (sad[0] & 0x7) + 1;
1592         if (channel_count > max_channels)
1593             max_channels = channel_count;
1594 
1595         /* Advance to next block */
1596         sad += 3;
1597     }
1598 
1599     return max_channels;
1600 }
1601 
platform_set_incall_recording_session_id(void * platform,uint32_t session_id,int rec_mode)1602 int platform_set_incall_recording_session_id(void *platform,
1603                                              uint32_t session_id, int rec_mode)
1604 {
1605     int ret = 0;
1606     struct platform_data *my_data = (struct platform_data *)platform;
1607     struct audio_device *adev = my_data->adev;
1608     struct mixer_ctl *ctl;
1609     const char *mixer_ctl_name = "Voc VSID";
1610     int num_ctl_values;
1611     int i;
1612 
1613     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1614     if (!ctl) {
1615         ALOGE("%s: Could not get ctl for mixer cmd - %s",
1616               __func__, mixer_ctl_name);
1617         ret = -EINVAL;
1618     } else {
1619         num_ctl_values = mixer_ctl_get_num_values(ctl);
1620         for (i = 0; i < num_ctl_values; i++) {
1621             if (mixer_ctl_set_value(ctl, i, session_id)) {
1622                 ALOGV("Error: invalid session_id: %x", session_id);
1623                 ret = -EINVAL;
1624                 break;
1625             }
1626         }
1627     }
1628 
1629     if (my_data->csd != NULL) {
1630         ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
1631         if (ret < 0) {
1632             ALOGE("%s: csd_client_start_record failed, error %d",
1633                   __func__, ret);
1634         }
1635     }
1636 
1637     return ret;
1638 }
1639 
platform_stop_incall_recording_usecase(void * platform)1640 int platform_stop_incall_recording_usecase(void *platform)
1641 {
1642     int ret = 0;
1643     struct platform_data *my_data = (struct platform_data *)platform;
1644 
1645     if (my_data->csd != NULL) {
1646         ret = my_data->csd->stop_record(ALL_SESSION_VSID);
1647         if (ret < 0) {
1648             ALOGE("%s: csd_client_stop_record failed, error %d",
1649                   __func__, ret);
1650         }
1651     }
1652 
1653     return ret;
1654 }
1655 
platform_start_incall_music_usecase(void * platform)1656 int platform_start_incall_music_usecase(void *platform)
1657 {
1658     int ret = 0;
1659     struct platform_data *my_data = (struct platform_data *)platform;
1660 
1661     if (my_data->csd != NULL) {
1662         ret = my_data->csd->start_playback(ALL_SESSION_VSID);
1663         if (ret < 0) {
1664             ALOGE("%s: csd_client_start_playback failed, error %d",
1665                   __func__, ret);
1666         }
1667     }
1668 
1669     return ret;
1670 }
1671 
platform_stop_incall_music_usecase(void * platform)1672 int platform_stop_incall_music_usecase(void *platform)
1673 {
1674     int ret = 0;
1675     struct platform_data *my_data = (struct platform_data *)platform;
1676 
1677     if (my_data->csd != NULL) {
1678         ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
1679         if (ret < 0) {
1680             ALOGE("%s: csd_client_stop_playback failed, error %d",
1681                   __func__, ret);
1682         }
1683     }
1684 
1685     return ret;
1686 }
1687 
1688 /* Delay in Us */
platform_render_latency(audio_usecase_t usecase)1689 int64_t platform_render_latency(audio_usecase_t usecase)
1690 {
1691     switch (usecase) {
1692         case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
1693             return DEEP_BUFFER_PLATFORM_DELAY;
1694         case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
1695             return LOW_LATENCY_PLATFORM_DELAY;
1696         default:
1697             return 0;
1698     }
1699 }
1700 
platform_set_snd_device_backend(snd_device_t device,const char * backend)1701 int platform_set_snd_device_backend(snd_device_t device, const char *backend)
1702 {
1703     int ret = 0;
1704 
1705     if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
1706         ALOGE("%s: Invalid snd_device = %d",
1707             __func__, device);
1708         ret = -EINVAL;
1709         goto done;
1710     }
1711 
1712     if (backend_table[device]) {
1713         free(backend_table[device]);
1714     }
1715     backend_table[device] = strdup(backend);
1716 done:
1717     return ret;
1718 }
1719 
platform_set_usecase_pcm_id(audio_usecase_t usecase,int32_t type,int32_t pcm_id)1720 int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
1721 {
1722     int ret = 0;
1723     if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
1724         ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
1725         ret = -EINVAL;
1726         goto done;
1727     }
1728 
1729     if ((type != 0) && (type != 1)) {
1730         ALOGE("%s: invalid usecase type", __func__);
1731         ret = -EINVAL;
1732     }
1733     pcm_device_table[usecase][type] = pcm_id;
1734 done:
1735     return ret;
1736 }
1737