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