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