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