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