platform.c revision cefbbac40220d4e7690d204eecff5f6ae3f63069
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_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 */ 201static 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 272struct 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 */ 280static 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 348static char * backend_table[SND_DEVICE_MAX] = {0}; 349 350static 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 371static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT; 372static bool is_tmus = false; 373 374static 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 404bool is_operator_tmus() 405{ 406 pthread_once(&check_op_once_ctl, check_operator); 407 return is_tmus; 408} 409 410void 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 431static 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 555error: 556 free(csd); 557 csd = NULL; 558 return csd; 559} 560 561void 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 571static 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 607done: 608 dlclose(lib); 609#else 610 my_data->csd = NULL; 611#endif 612} 613 614static 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 652void *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 803void 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 810const 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 818void 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 836int 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 846static 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; 873done: 874 return ret; 875} 876 877int platform_get_snd_device_index(char *device_name) 878{ 879 return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name); 880} 881 882int platform_get_usecase_index(const char *usecase_name) 883{ 884 return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name); 885} 886 887int 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; 899done: 900 return ret; 901} 902 903int 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 927int 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 my_data->adev->mode == AUDIO_MODE_IN_CALL) { 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 944int 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 973int 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 996int 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 1025int 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 1039int 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 1053int 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 1067int 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 1103int 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 1137int 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 1175snd_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 ((mode == AUDIO_MODE_IN_CALL) || 1190 (adev->enable_voicerx)) { 1191 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || 1192 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET || 1193 devices & AUDIO_DEVICE_OUT_LINE) { 1194 if ((mode == AUDIO_MODE_IN_CALL) && 1195 (adev->voice.tty_mode == TTY_MODE_FULL)) 1196 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES; 1197 else if ((mode == AUDIO_MODE_IN_CALL) && 1198 (adev->voice.tty_mode == TTY_MODE_VCO)) 1199 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES; 1200 else if ((mode == AUDIO_MODE_IN_CALL) && 1201 (adev->voice.tty_mode == TTY_MODE_HCO)) 1202 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET; 1203 else { 1204 if (devices & AUDIO_DEVICE_OUT_LINE) 1205 snd_device = SND_DEVICE_OUT_VOICE_LINE; 1206 else 1207 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES; 1208 } 1209 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) { 1210 if (adev->bt_wb_speech_enabled) { 1211 snd_device = SND_DEVICE_OUT_BT_SCO_WB; 1212 } else { 1213 snd_device = SND_DEVICE_OUT_BT_SCO; 1214 } 1215 } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) { 1216 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER; 1217 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) { 1218 if(adev->voice.hac) 1219 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET; 1220 else if (is_operator_tmus()) 1221 snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS; 1222 else 1223 snd_device = SND_DEVICE_OUT_VOICE_HANDSET; 1224 } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX) 1225 snd_device = SND_DEVICE_OUT_VOICE_TX; 1226 1227 if (snd_device != SND_DEVICE_NONE) { 1228 goto exit; 1229 } 1230 } 1231 1232 if (popcount(devices) == 2) { 1233 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE | 1234 AUDIO_DEVICE_OUT_SPEAKER)) { 1235 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES; 1236 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET | 1237 AUDIO_DEVICE_OUT_SPEAKER)) { 1238 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES; 1239 } else if (devices == (AUDIO_DEVICE_OUT_LINE | 1240 AUDIO_DEVICE_OUT_SPEAKER)) { 1241 snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE; 1242 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL | 1243 AUDIO_DEVICE_OUT_SPEAKER)) { 1244 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI; 1245 } else { 1246 ALOGE("%s: Invalid combo device(%#x)", __func__, devices); 1247 goto exit; 1248 } 1249 if (snd_device != SND_DEVICE_NONE) { 1250 goto exit; 1251 } 1252 } 1253 1254 if (popcount(devices) != 1) { 1255 ALOGE("%s: Invalid output devices(%#x)", __func__, devices); 1256 goto exit; 1257 } 1258 1259 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || 1260 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) { 1261 snd_device = SND_DEVICE_OUT_HEADPHONES; 1262 } else if (devices & AUDIO_DEVICE_OUT_LINE) { 1263 snd_device = SND_DEVICE_OUT_LINE; 1264 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) { 1265 snd_device = SND_DEVICE_OUT_SPEAKER_SAFE; 1266 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) { 1267 if (adev->speaker_lr_swap) 1268 snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE; 1269 else 1270 snd_device = SND_DEVICE_OUT_SPEAKER; 1271 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) { 1272 if (adev->bt_wb_speech_enabled) { 1273 snd_device = SND_DEVICE_OUT_BT_SCO_WB; 1274 } else { 1275 snd_device = SND_DEVICE_OUT_BT_SCO; 1276 } 1277 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) { 1278 snd_device = SND_DEVICE_OUT_HDMI ; 1279 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) { 1280 /*HAC support for voice-ish audio (eg visual voicemail)*/ 1281 if(adev->voice.hac) 1282 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET; 1283 else 1284 snd_device = SND_DEVICE_OUT_HANDSET; 1285 } else { 1286 ALOGE("%s: Unknown device(s) %#x", __func__, devices); 1287 } 1288exit: 1289 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]); 1290 return snd_device; 1291} 1292 1293snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device) 1294{ 1295 struct platform_data *my_data = (struct platform_data *)platform; 1296 struct audio_device *adev = my_data->adev; 1297 audio_source_t source = (adev->active_input == NULL) ? 1298 AUDIO_SOURCE_DEFAULT : adev->active_input->source; 1299 1300 audio_mode_t mode = adev->mode; 1301 audio_devices_t in_device = ((adev->active_input == NULL) ? 1302 AUDIO_DEVICE_NONE : adev->active_input->device) 1303 & ~AUDIO_DEVICE_BIT_IN; 1304 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ? 1305 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask; 1306 snd_device_t snd_device = SND_DEVICE_NONE; 1307 int channel_count = popcount(channel_mask); 1308 1309 ALOGV("%s: enter: out_device(%#x) in_device(%#x)", 1310 __func__, out_device, in_device); 1311 if (mode == AUDIO_MODE_IN_CALL) { 1312 if (out_device == AUDIO_DEVICE_NONE) { 1313 ALOGE("%s: No output device set for voice call", __func__); 1314 goto exit; 1315 } 1316 if (adev->voice.tty_mode != TTY_MODE_OFF) { 1317 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || 1318 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET || 1319 out_device & AUDIO_DEVICE_OUT_LINE) { 1320 switch (adev->voice.tty_mode) { 1321 case TTY_MODE_FULL: 1322 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC; 1323 break; 1324 case TTY_MODE_VCO: 1325 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC; 1326 break; 1327 case TTY_MODE_HCO: 1328 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC; 1329 break; 1330 default: 1331 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode); 1332 } 1333 goto exit; 1334 } 1335 } 1336 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) { 1337 if (my_data->fluence_in_voice_call == false) { 1338 snd_device = SND_DEVICE_IN_HANDSET_MIC; 1339 } else { 1340 if (is_operator_tmus()) 1341 snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS; 1342 else 1343 snd_device = SND_DEVICE_IN_VOICE_DMIC; 1344 } 1345 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) { 1346 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC; 1347 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) { 1348 if (adev->bt_wb_speech_enabled) { 1349 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB; 1350 } else { 1351 snd_device = SND_DEVICE_IN_BT_SCO_MIC; 1352 } 1353 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER || 1354 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE || 1355 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || 1356 out_device & AUDIO_DEVICE_OUT_LINE) { 1357 if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode && 1358 my_data->dualmic_config != DUALMIC_CONFIG_NONE) { 1359 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC; 1360 } else { 1361 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC; 1362 } 1363 } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX) 1364 snd_device = SND_DEVICE_IN_VOICE_RX; 1365 } else if (source == AUDIO_SOURCE_CAMCORDER) { 1366 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC || 1367 in_device & AUDIO_DEVICE_IN_BACK_MIC) { 1368 snd_device = SND_DEVICE_IN_CAMCORDER_MIC; 1369 } 1370 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) { 1371 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) { 1372 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) { 1373 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) 1374 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO; 1375 else if (my_data->fluence_in_voice_rec && 1376 adev->active_input->enable_ns) 1377 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE; 1378 } 1379 1380 if (snd_device == SND_DEVICE_NONE) { 1381 if (adev->active_input->enable_ns) 1382 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS; 1383 else 1384 snd_device = SND_DEVICE_IN_VOICE_REC_MIC; 1385 } 1386 } 1387 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) { 1388 if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) 1389 in_device = AUDIO_DEVICE_IN_BACK_MIC; 1390 if (adev->active_input) { 1391 if (adev->active_input->enable_aec && 1392 adev->active_input->enable_ns) { 1393 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) { 1394 if (my_data->fluence_in_spkr_mode && 1395 my_data->fluence_in_voice_comm && 1396 my_data->dualmic_config != DUALMIC_CONFIG_NONE) { 1397 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS; 1398 } else 1399 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS; 1400 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) { 1401 if (my_data->fluence_in_voice_comm && 1402 my_data->dualmic_config != DUALMIC_CONFIG_NONE) { 1403 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS; 1404 } else 1405 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS; 1406 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) { 1407 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC; 1408 } 1409 platform_set_echo_reference(adev, true, out_device); 1410 } else if (adev->active_input->enable_aec) { 1411 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) { 1412 if (my_data->fluence_in_spkr_mode && 1413 my_data->fluence_in_voice_comm && 1414 my_data->dualmic_config != DUALMIC_CONFIG_NONE) { 1415 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC; 1416 } else 1417 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC; 1418 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) { 1419 if (my_data->fluence_in_voice_comm && 1420 my_data->dualmic_config != DUALMIC_CONFIG_NONE) { 1421 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC; 1422 } else 1423 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC; 1424 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) { 1425 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC; 1426 } 1427 platform_set_echo_reference(adev, true, out_device); 1428 } else if (adev->active_input->enable_ns) { 1429 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) { 1430 if (my_data->fluence_in_spkr_mode && 1431 my_data->fluence_in_voice_comm && 1432 my_data->dualmic_config != DUALMIC_CONFIG_NONE) { 1433 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS; 1434 } else 1435 snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS; 1436 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) { 1437 if (my_data->fluence_in_voice_comm && 1438 my_data->dualmic_config != DUALMIC_CONFIG_NONE) { 1439 snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS; 1440 } else 1441 snd_device = SND_DEVICE_IN_HANDSET_MIC_NS; 1442 } 1443 } 1444 } 1445 } else if (source == AUDIO_SOURCE_DEFAULT) { 1446 goto exit; 1447 } 1448 1449 1450 if (snd_device != SND_DEVICE_NONE) { 1451 goto exit; 1452 } 1453 1454 if (in_device != AUDIO_DEVICE_NONE && 1455 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) && 1456 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) { 1457 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) { 1458 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE && 1459 channel_count == 2) 1460 snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO; 1461 else 1462 snd_device = SND_DEVICE_IN_HANDSET_MIC; 1463 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) { 1464 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE && 1465 channel_count == 2) 1466 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO; 1467 else 1468 snd_device = SND_DEVICE_IN_SPEAKER_MIC; 1469 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) { 1470 snd_device = SND_DEVICE_IN_HEADSET_MIC; 1471 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 1472 if (adev->bt_wb_speech_enabled) { 1473 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB; 1474 } else { 1475 snd_device = SND_DEVICE_IN_BT_SCO_MIC; 1476 } 1477 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) { 1478 snd_device = SND_DEVICE_IN_HDMI_MIC; 1479 } else { 1480 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device); 1481 ALOGW("%s: Using default handset-mic", __func__); 1482 snd_device = SND_DEVICE_IN_HANDSET_MIC; 1483 } 1484 } else { 1485 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) { 1486 snd_device = SND_DEVICE_IN_HANDSET_MIC; 1487 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) { 1488 snd_device = SND_DEVICE_IN_HEADSET_MIC; 1489 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER || 1490 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE || 1491 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || 1492 out_device & AUDIO_DEVICE_OUT_LINE) { 1493 if (channel_count == 2) 1494 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO; 1495 else 1496 snd_device = SND_DEVICE_IN_SPEAKER_MIC; 1497 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) { 1498 if (adev->bt_wb_speech_enabled) { 1499 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB; 1500 } else { 1501 snd_device = SND_DEVICE_IN_BT_SCO_MIC; 1502 } 1503 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) { 1504 snd_device = SND_DEVICE_IN_HDMI_MIC; 1505 } else { 1506 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device); 1507 ALOGW("%s: Using default handset-mic", __func__); 1508 snd_device = SND_DEVICE_IN_HANDSET_MIC; 1509 } 1510 } 1511exit: 1512 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]); 1513 return snd_device; 1514} 1515 1516int platform_set_hdmi_channels(void *platform, int channel_count) 1517{ 1518 struct platform_data *my_data = (struct platform_data *)platform; 1519 struct audio_device *adev = my_data->adev; 1520 struct mixer_ctl *ctl; 1521 const char *channel_cnt_str = NULL; 1522 const char *mixer_ctl_name = "HDMI_RX Channels"; 1523 switch (channel_count) { 1524 case 8: 1525 channel_cnt_str = "Eight"; break; 1526 case 7: 1527 channel_cnt_str = "Seven"; break; 1528 case 6: 1529 channel_cnt_str = "Six"; break; 1530 case 5: 1531 channel_cnt_str = "Five"; break; 1532 case 4: 1533 channel_cnt_str = "Four"; break; 1534 case 3: 1535 channel_cnt_str = "Three"; break; 1536 default: 1537 channel_cnt_str = "Two"; break; 1538 } 1539 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name); 1540 if (!ctl) { 1541 ALOGE("%s: Could not get ctl for mixer cmd - %s", 1542 __func__, mixer_ctl_name); 1543 return -EINVAL; 1544 } 1545 ALOGV("HDMI channel count: %s", channel_cnt_str); 1546 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str); 1547 return 0; 1548} 1549 1550int platform_edid_get_max_channels(void *platform) 1551{ 1552 struct platform_data *my_data = (struct platform_data *)platform; 1553 struct audio_device *adev = my_data->adev; 1554 char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE]; 1555 char *sad = block; 1556 int num_audio_blocks; 1557 int channel_count; 1558 int max_channels = 0; 1559 int i, ret, count; 1560 1561 struct mixer_ctl *ctl; 1562 1563 ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL); 1564 if (!ctl) { 1565 ALOGE("%s: Could not get ctl for mixer cmd - %s", 1566 __func__, AUDIO_DATA_BLOCK_MIXER_CTL); 1567 return 0; 1568 } 1569 1570 mixer_ctl_update(ctl); 1571 1572 count = mixer_ctl_get_num_values(ctl); 1573 1574 /* Read SAD blocks, clamping the maximum size for safety */ 1575 if (count > (int)sizeof(block)) 1576 count = (int)sizeof(block); 1577 1578 ret = mixer_ctl_get_array(ctl, block, count); 1579 if (ret != 0) { 1580 ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__); 1581 return 0; 1582 } 1583 1584 /* Calculate the number of SAD blocks */ 1585 num_audio_blocks = count / SAD_BLOCK_SIZE; 1586 1587 for (i = 0; i < num_audio_blocks; i++) { 1588 /* Only consider LPCM blocks */ 1589 if ((sad[0] >> 3) != EDID_FORMAT_LPCM) { 1590 sad += 3; 1591 continue; 1592 } 1593 1594 channel_count = (sad[0] & 0x7) + 1; 1595 if (channel_count > max_channels) 1596 max_channels = channel_count; 1597 1598 /* Advance to next block */ 1599 sad += 3; 1600 } 1601 1602 return max_channels; 1603} 1604 1605int platform_set_incall_recording_session_id(void *platform, 1606 uint32_t session_id, int rec_mode) 1607{ 1608 int ret = 0; 1609 struct platform_data *my_data = (struct platform_data *)platform; 1610 struct audio_device *adev = my_data->adev; 1611 struct mixer_ctl *ctl; 1612 const char *mixer_ctl_name = "Voc VSID"; 1613 int num_ctl_values; 1614 int i; 1615 1616 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name); 1617 if (!ctl) { 1618 ALOGE("%s: Could not get ctl for mixer cmd - %s", 1619 __func__, mixer_ctl_name); 1620 ret = -EINVAL; 1621 } else { 1622 num_ctl_values = mixer_ctl_get_num_values(ctl); 1623 for (i = 0; i < num_ctl_values; i++) { 1624 if (mixer_ctl_set_value(ctl, i, session_id)) { 1625 ALOGV("Error: invalid session_id: %x", session_id); 1626 ret = -EINVAL; 1627 break; 1628 } 1629 } 1630 } 1631 1632 if (my_data->csd != NULL) { 1633 ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode); 1634 if (ret < 0) { 1635 ALOGE("%s: csd_client_start_record failed, error %d", 1636 __func__, ret); 1637 } 1638 } 1639 1640 return ret; 1641} 1642 1643int platform_stop_incall_recording_usecase(void *platform) 1644{ 1645 int ret = 0; 1646 struct platform_data *my_data = (struct platform_data *)platform; 1647 1648 if (my_data->csd != NULL) { 1649 ret = my_data->csd->stop_record(ALL_SESSION_VSID); 1650 if (ret < 0) { 1651 ALOGE("%s: csd_client_stop_record failed, error %d", 1652 __func__, ret); 1653 } 1654 } 1655 1656 return ret; 1657} 1658 1659int platform_start_incall_music_usecase(void *platform) 1660{ 1661 int ret = 0; 1662 struct platform_data *my_data = (struct platform_data *)platform; 1663 1664 if (my_data->csd != NULL) { 1665 ret = my_data->csd->start_playback(ALL_SESSION_VSID); 1666 if (ret < 0) { 1667 ALOGE("%s: csd_client_start_playback failed, error %d", 1668 __func__, ret); 1669 } 1670 } 1671 1672 return ret; 1673} 1674 1675int platform_stop_incall_music_usecase(void *platform) 1676{ 1677 int ret = 0; 1678 struct platform_data *my_data = (struct platform_data *)platform; 1679 1680 if (my_data->csd != NULL) { 1681 ret = my_data->csd->stop_playback(ALL_SESSION_VSID); 1682 if (ret < 0) { 1683 ALOGE("%s: csd_client_stop_playback failed, error %d", 1684 __func__, ret); 1685 } 1686 } 1687 1688 return ret; 1689} 1690 1691/* Delay in Us */ 1692int64_t platform_render_latency(audio_usecase_t usecase) 1693{ 1694 switch (usecase) { 1695 case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER: 1696 return DEEP_BUFFER_PLATFORM_DELAY; 1697 case USECASE_AUDIO_PLAYBACK_LOW_LATENCY: 1698 return LOW_LATENCY_PLATFORM_DELAY; 1699 default: 1700 return 0; 1701 } 1702} 1703 1704int platform_set_snd_device_backend(snd_device_t device, const char *backend) 1705{ 1706 int ret = 0; 1707 1708 if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) { 1709 ALOGE("%s: Invalid snd_device = %d", 1710 __func__, device); 1711 ret = -EINVAL; 1712 goto done; 1713 } 1714 1715 if (backend_table[device]) { 1716 free(backend_table[device]); 1717 } 1718 backend_table[device] = strdup(backend); 1719done: 1720 return ret; 1721} 1722 1723int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id) 1724{ 1725 int ret = 0; 1726 if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) { 1727 ALOGE("%s: invalid usecase case idx %d", __func__, usecase); 1728 ret = -EINVAL; 1729 goto done; 1730 } 1731 1732 if ((type != 0) && (type != 1)) { 1733 ALOGE("%s: invalid usecase type", __func__); 1734 ret = -EINVAL; 1735 } 1736 pcm_device_table[usecase][type] = pcm_id; 1737done: 1738 return ret; 1739} 1740