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