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