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 "msm8960_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/properties.h> 25 #include <audio_hw.h> 26 #include <platform_api.h> 27 #include "platform.h" 28 29 #define LIB_ACDB_LOADER "libacdbloader.so" 30 #define LIB_CSD_CLIENT "libcsd-client.so" 31 32 #define DUALMIC_CONFIG_NONE 0 /* Target does not contain 2 mics */ 33 #define DUALMIC_CONFIG_ENDFIRE 1 34 #define DUALMIC_CONFIG_BROADSIDE 2 35 36 /* 37 * This is the sysfs path for the HDMI audio data block 38 */ 39 #define AUDIO_DATA_BLOCK_PATH "/sys/class/graphics/fb1/audio_data_block" 40 #define MIXER_XML_PATH "/system/etc/mixer_paths.xml" 41 42 /* 43 * This file will have a maximum of 38 bytes: 44 * 45 * 4 bytes: number of audio blocks 46 * 4 bytes: total length of Short Audio Descriptor (SAD) blocks 47 * Maximum 10 * 3 bytes: SAD blocks 48 */ 49 #define MAX_SAD_BLOCKS 10 50 #define SAD_BLOCK_SIZE 3 51 52 /* EDID format ID for LPCM audio */ 53 #define EDID_FORMAT_LPCM 1 54 55 struct audio_block_header 56 { 57 int reserved; 58 int length; 59 }; 60 61 62 typedef void (*acdb_deallocate_t)(); 63 typedef int (*acdb_init_t)(); 64 typedef void (*acdb_send_audio_cal_t)(int, int); 65 typedef void (*acdb_send_voice_cal_t)(int, int); 66 67 typedef int (*csd_client_init_t)(); 68 typedef int (*csd_client_deinit_t)(); 69 typedef int (*csd_disable_device_t)(); 70 typedef int (*csd_enable_device_t)(int, int, uint32_t); 71 typedef int (*csd_volume_t)(int); 72 typedef int (*csd_mic_mute_t)(int); 73 typedef int (*csd_start_voice_t)(); 74 typedef int (*csd_stop_voice_t)(); 75 76 77 /* Audio calibration related functions */ 78 struct platform_data { 79 struct audio_device *adev; 80 bool fluence_in_spkr_mode; 81 bool fluence_in_voice_call; 82 bool fluence_in_voice_rec; 83 int dualmic_config; 84 bool speaker_lr_swap; 85 86 void *acdb_handle; 87 acdb_init_t acdb_init; 88 acdb_deallocate_t acdb_deallocate; 89 acdb_send_audio_cal_t acdb_send_audio_cal; 90 acdb_send_voice_cal_t acdb_send_voice_cal; 91 92 /* CSD Client related functions for voice call */ 93 void *csd_client; 94 csd_client_init_t csd_client_init; 95 csd_client_deinit_t csd_client_deinit; 96 csd_disable_device_t csd_disable_device; 97 csd_enable_device_t csd_enable_device; 98 csd_volume_t csd_volume; 99 csd_mic_mute_t csd_mic_mute; 100 csd_start_voice_t csd_start_voice; 101 csd_stop_voice_t csd_stop_voice; 102 }; 103 104 static const int pcm_device_table[AUDIO_USECASE_MAX][2] = { 105 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {0, 0}, 106 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {14, 14}, 107 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {1, 1}, 108 [USECASE_AUDIO_RECORD] = {0, 0}, 109 [USECASE_AUDIO_RECORD_LOW_LATENCY] = {14, 14}, 110 [USECASE_VOICE_CALL] = {12, 12}, 111 }; 112 113 /* Array to store sound devices */ 114 static const char * const device_table[SND_DEVICE_MAX] = { 115 [SND_DEVICE_NONE] = "none", 116 /* Playback sound devices */ 117 [SND_DEVICE_OUT_HANDSET] = "handset", 118 [SND_DEVICE_OUT_SPEAKER] = "speaker", 119 [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse", 120 [SND_DEVICE_OUT_HEADPHONES] = "headphones", 121 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones", 122 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker", 123 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones", 124 [SND_DEVICE_OUT_HDMI] = "hdmi", 125 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi", 126 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset", 127 [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb", 128 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus", 129 [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset-tmus", 130 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-handset-tmus", 131 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones", 132 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones", 133 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset", 134 135 /* Capture sound devices */ 136 [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic", 137 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic", 138 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic", 139 [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic", 140 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "voice-speaker-mic", 141 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic", 142 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic", 143 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic", 144 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic", 145 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic", 146 [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb", 147 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic", 148 [SND_DEVICE_IN_VOICE_DMIC_EF] = "voice-dmic-ef", 149 [SND_DEVICE_IN_VOICE_DMIC_BS] = "voice-dmic-bs", 150 [SND_DEVICE_IN_VOICE_DMIC_EF_TMUS] = "voice-dmic-ef-tmus", 151 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF] = "voice-speaker-dmic-ef", 152 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS] = "voice-speaker-dmic-bs", 153 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic", 154 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic", 155 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic", 156 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic", 157 [SND_DEVICE_IN_VOICE_REC_DMIC_EF] = "voice-rec-dmic-ef", 158 [SND_DEVICE_IN_VOICE_REC_DMIC_BS] = "voice-rec-dmic-bs", 159 [SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE] = "voice-rec-dmic-ef-fluence", 160 [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = "voice-rec-dmic-bs-fluence", 161 }; 162 163 /* ACDB IDs (audio DSP path configuration IDs) for each sound device */ 164 static const int acdb_device_table[SND_DEVICE_MAX] = { 165 [SND_DEVICE_NONE] = -1, 166 [SND_DEVICE_OUT_HANDSET] = 7, 167 [SND_DEVICE_OUT_SPEAKER] = 14, 168 [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14, 169 [SND_DEVICE_OUT_HEADPHONES] = 10, 170 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10, 171 [SND_DEVICE_OUT_VOICE_SPEAKER] = 14, 172 [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10, 173 [SND_DEVICE_OUT_HDMI] = 18, 174 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14, 175 [SND_DEVICE_OUT_BT_SCO] = 22, 176 [SND_DEVICE_OUT_BT_SCO_WB] = 39, 177 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = 81, 178 [SND_DEVICE_OUT_VOICE_HANDSET] = 81, 179 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 81, 180 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17, 181 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17, 182 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37, 183 184 [SND_DEVICE_IN_HANDSET_MIC] = 4, 185 [SND_DEVICE_IN_SPEAKER_MIC] = 4, 186 [SND_DEVICE_IN_HEADSET_MIC] = 8, 187 [SND_DEVICE_IN_HANDSET_MIC_AEC] = 40, 188 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 42, 189 [SND_DEVICE_IN_HEADSET_MIC_AEC] = 47, 190 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11, 191 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8, 192 [SND_DEVICE_IN_HDMI_MIC] = 4, 193 [SND_DEVICE_IN_BT_SCO_MIC] = 21, 194 [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38, 195 [SND_DEVICE_IN_CAMCORDER_MIC] = 61, 196 [SND_DEVICE_IN_VOICE_DMIC_EF] = 6, 197 [SND_DEVICE_IN_VOICE_DMIC_BS] = 5, 198 [SND_DEVICE_IN_VOICE_DMIC_EF_TMUS] = 91, 199 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF] = 13, 200 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS] = 12, 201 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16, 202 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36, 203 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16, 204 [SND_DEVICE_IN_VOICE_REC_MIC] = 62, 205 /* TODO: Update with proper acdb ids */ 206 [SND_DEVICE_IN_VOICE_REC_DMIC_EF] = 62, 207 [SND_DEVICE_IN_VOICE_REC_DMIC_BS] = 62, 208 [SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE] = 6, 209 [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = 5, 210 }; 211 212 #define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL) 213 #define LOW_LATENCY_PLATFORM_DELAY (13*1000LL) 214 215 static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT; 216 static bool is_tmus = false; 217 218 static void check_operator() 219 { 220 char value[PROPERTY_VALUE_MAX]; 221 int mccmnc; 222 property_get("gsm.sim.operator.numeric",value,"0"); 223 mccmnc = atoi(value); 224 ALOGD("%s: tmus mccmnc %d", __func__, mccmnc); 225 switch(mccmnc) { 226 /* TMUS MCC(310), MNC(490, 260, 026) */ 227 case 310490: 228 case 310260: 229 case 310026: 230 is_tmus = true; 231 break; 232 } 233 } 234 235 bool is_operator_tmus() 236 { 237 pthread_once(&check_op_once_ctl, check_operator); 238 return is_tmus; 239 } 240 241 static int set_echo_reference(struct mixer *mixer, const char* ec_ref) 242 { 243 struct mixer_ctl *ctl; 244 const char *mixer_ctl_name = "EC_REF_RX"; 245 246 ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name); 247 if (!ctl) { 248 ALOGE("%s: Could not get ctl for mixer cmd - %s", 249 __func__, mixer_ctl_name); 250 return -EINVAL; 251 } 252 ALOGV("Setting EC Reference: %s", ec_ref); 253 mixer_ctl_set_enum_by_string(ctl, ec_ref); 254 return 0; 255 } 256 257 void *platform_init(struct audio_device *adev) 258 { 259 char platform[PROPERTY_VALUE_MAX]; 260 char baseband[PROPERTY_VALUE_MAX]; 261 char value[PROPERTY_VALUE_MAX]; 262 struct platform_data *my_data; 263 264 adev->mixer = mixer_open(MIXER_CARD); 265 266 if (!adev->mixer) { 267 ALOGE("Unable to open the mixer, aborting."); 268 return NULL; 269 } 270 271 adev->audio_route = audio_route_init(MIXER_CARD, MIXER_XML_PATH); 272 if (!adev->audio_route) { 273 ALOGE("%s: Failed to init audio route controls, aborting.", __func__); 274 return NULL; 275 } 276 277 my_data = calloc(1, sizeof(struct platform_data)); 278 279 my_data->adev = adev; 280 my_data->dualmic_config = DUALMIC_CONFIG_NONE; 281 my_data->fluence_in_spkr_mode = false; 282 my_data->fluence_in_voice_call = false; 283 my_data->fluence_in_voice_rec = false; 284 285 property_get("persist.audio.dualmic.config",value,""); 286 if (!strcmp("broadside", value)) { 287 my_data->dualmic_config = DUALMIC_CONFIG_BROADSIDE; 288 adev->acdb_settings |= DMIC_FLAG; 289 } else if (!strcmp("endfire", value)) { 290 my_data->dualmic_config = DUALMIC_CONFIG_ENDFIRE; 291 adev->acdb_settings |= DMIC_FLAG; 292 } 293 294 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) { 295 property_get("persist.audio.fluence.voicecall",value,""); 296 if (!strcmp("true", value)) { 297 my_data->fluence_in_voice_call = true; 298 } 299 300 property_get("persist.audio.fluence.voicerec",value,""); 301 if (!strcmp("true", value)) { 302 my_data->fluence_in_voice_rec = true; 303 } 304 305 property_get("persist.audio.fluence.speaker",value,""); 306 if (!strcmp("true", value)) { 307 my_data->fluence_in_spkr_mode = true; 308 } 309 } 310 311 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW); 312 if (my_data->acdb_handle == NULL) { 313 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER); 314 } else { 315 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER); 316 my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle, 317 "acdb_loader_deallocate_ACDB"); 318 my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle, 319 "acdb_loader_send_audio_cal"); 320 if (!my_data->acdb_send_audio_cal) 321 ALOGW("%s: Could not find the symbol acdb_send_audio_cal from %s", 322 __func__, LIB_ACDB_LOADER); 323 my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle, 324 "acdb_loader_send_voice_cal"); 325 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle, 326 "acdb_loader_init_ACDB"); 327 if (my_data->acdb_init == NULL) 328 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror()); 329 else 330 my_data->acdb_init(); 331 } 332 333 /* If platform is Fusion3, load CSD Client specific symbols 334 * Voice call is handled by MDM and apps processor talks to 335 * MDM through CSD Client 336 */ 337 property_get("ro.board.platform", platform, ""); 338 property_get("ro.baseband", baseband, ""); 339 if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) { 340 my_data->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW); 341 if (my_data->csd_client == NULL) 342 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT); 343 } 344 345 if (my_data->csd_client) { 346 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT); 347 my_data->csd_client_deinit = (csd_client_deinit_t)dlsym(my_data->csd_client, 348 "csd_client_deinit"); 349 my_data->csd_disable_device = (csd_disable_device_t)dlsym(my_data->csd_client, 350 "csd_client_disable_device"); 351 my_data->csd_enable_device = (csd_enable_device_t)dlsym(my_data->csd_client, 352 "csd_client_enable_device"); 353 my_data->csd_start_voice = (csd_start_voice_t)dlsym(my_data->csd_client, 354 "csd_client_start_voice"); 355 my_data->csd_stop_voice = (csd_stop_voice_t)dlsym(my_data->csd_client, 356 "csd_client_stop_voice"); 357 my_data->csd_volume = (csd_volume_t)dlsym(my_data->csd_client, 358 "csd_client_volume"); 359 my_data->csd_mic_mute = (csd_mic_mute_t)dlsym(my_data->csd_client, 360 "csd_client_mic_mute"); 361 my_data->csd_client_init = (csd_client_init_t)dlsym(my_data->csd_client, 362 "csd_client_init"); 363 364 if (my_data->csd_client_init == NULL) { 365 ALOGE("%s: dlsym error %s for csd_client_init", __func__, dlerror()); 366 } else { 367 my_data->csd_client_init(); 368 } 369 } 370 371 return my_data; 372 } 373 374 void platform_deinit(void *platform) 375 { 376 free(platform); 377 } 378 379 const char *platform_get_snd_device_name(snd_device_t snd_device) 380 { 381 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) 382 return device_table[snd_device]; 383 else 384 return "none"; 385 } 386 387 void platform_add_backend_name(void *platform __unused, char *mixer_path, 388 snd_device_t snd_device) 389 { 390 if (snd_device == SND_DEVICE_IN_BT_SCO_MIC) 391 strcat(mixer_path, " bt-sco"); 392 else if(snd_device == SND_DEVICE_OUT_BT_SCO) 393 strcat(mixer_path, " bt-sco"); 394 else if (snd_device == SND_DEVICE_OUT_HDMI) 395 strcat(mixer_path, " hdmi"); 396 else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI) 397 strcat(mixer_path, " speaker-and-hdmi"); 398 else if (snd_device == SND_DEVICE_OUT_BT_SCO_WB || 399 snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB) 400 strcat(mixer_path, " bt-sco-wb"); 401 } 402 403 int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type) 404 { 405 int device_id; 406 if (device_type == PCM_PLAYBACK) 407 device_id = pcm_device_table[usecase][0]; 408 else 409 device_id = pcm_device_table[usecase][1]; 410 return device_id; 411 } 412 413 int platform_get_snd_device_index(char *snd_device_index_name __unused) 414 { 415 return -ENODEV; 416 } 417 418 int platform_set_snd_device_acdb_id(snd_device_t snd_device __unused, 419 unsigned int acdb_id __unused) 420 { 421 return -ENODEV; 422 } 423 424 int platform_get_default_app_type_v2(void *platform, usecase_type_t type __unused, 425 int *app_type __unused) 426 { 427 ALOGE("%s: Not implemented", __func__); 428 return -ENOSYS; 429 } 430 431 int platform_get_snd_device_acdb_id(snd_device_t snd_device __unused) 432 { 433 ALOGE("%s: Not implemented", __func__); 434 return -ENOSYS; 435 } 436 437 void platform_add_operator_specific_device(snd_device_t snd_device __unused, 438 const char *operator __unused, 439 const char *mixer_path __unused, 440 unsigned int acdb_id __unused) 441 { 442 } 443 444 int platform_send_audio_calibration(void *platform, snd_device_t snd_device) 445 { 446 struct platform_data *my_data = (struct platform_data *)platform; 447 int acdb_dev_id, acdb_dev_type; 448 449 acdb_dev_id = acdb_device_table[snd_device]; 450 if (acdb_dev_id < 0) { 451 ALOGE("%s: Could not find acdb id for device(%d)", 452 __func__, snd_device); 453 return -EINVAL; 454 } 455 if (my_data->acdb_send_audio_cal) { 456 ("%s: sending audio calibration for snd_device(%d) acdb_id(%d)", 457 __func__, snd_device, acdb_dev_id); 458 if (snd_device >= SND_DEVICE_OUT_BEGIN && 459 snd_device < SND_DEVICE_OUT_END) 460 acdb_dev_type = ACDB_DEV_TYPE_OUT; 461 else 462 acdb_dev_type = ACDB_DEV_TYPE_IN; 463 my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type); 464 } 465 return 0; 466 } 467 468 int platform_switch_voice_call_device_pre(void *platform) 469 { 470 struct platform_data *my_data = (struct platform_data *)platform; 471 int ret = 0; 472 473 if (my_data->csd_client != NULL && 474 voice_is_in_call(my_data->adev)) { 475 /* This must be called before disabling the mixer controls on APQ side */ 476 if (my_data->csd_disable_device == NULL) { 477 ALOGE("%s: dlsym error for csd_disable_device", __func__); 478 } else { 479 ret = my_data->csd_disable_device(); 480 if (ret < 0) { 481 ALOGE("%s: csd_client_disable_device, failed, error %d", 482 __func__, ret); 483 } 484 } 485 } 486 return ret; 487 } 488 489 int platform_switch_voice_call_device_post(void *platform, 490 snd_device_t out_snd_device, 491 snd_device_t in_snd_device) 492 { 493 struct platform_data *my_data = (struct platform_data *)platform; 494 int acdb_rx_id, acdb_tx_id; 495 int ret = 0; 496 497 if (my_data->csd_client) { 498 if (my_data->csd_enable_device == NULL) { 499 ALOGE("%s: dlsym error for csd_enable_device", 500 __func__); 501 } else { 502 acdb_rx_id = acdb_device_table[out_snd_device]; 503 acdb_tx_id = acdb_device_table[in_snd_device]; 504 505 if (acdb_rx_id > 0 || acdb_tx_id > 0) { 506 ret = my_data->csd_enable_device(acdb_rx_id, acdb_tx_id, 507 my_data->adev->acdb_settings); 508 if (ret < 0) { 509 ALOGE("%s: csd_enable_device, failed, error %d", 510 __func__, ret); 511 } 512 } else { 513 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__, 514 acdb_rx_id, acdb_tx_id); 515 } 516 } 517 } 518 519 return ret; 520 } 521 522 int platform_start_voice_call(void *platform, uint32_t vsid __unused) 523 { 524 struct platform_data *my_data = (struct platform_data *)platform; 525 int ret = 0; 526 527 if (my_data->csd_client) { 528 if (my_data->csd_start_voice == NULL) { 529 ALOGE("dlsym error for csd_client_start_voice"); 530 ret = -ENOSYS; 531 } else { 532 ret = my_data->csd_start_voice(); 533 if (ret < 0) { 534 ALOGE("%s: csd_start_voice error %d\n", __func__, ret); 535 } 536 } 537 } 538 539 return ret; 540 } 541 542 int platform_stop_voice_call(void *platform, uint32_t vsid __unused) 543 { 544 struct platform_data *my_data = (struct platform_data *)platform; 545 int ret = 0; 546 547 if (my_data->csd_client) { 548 if (my_data->csd_stop_voice == NULL) { 549 ALOGE("dlsym error for csd_stop_voice"); 550 } else { 551 ret = my_data->csd_stop_voice(); 552 if (ret < 0) { 553 ALOGE("%s: csd_stop_voice error %d\n", __func__, ret); 554 } 555 } 556 } 557 558 return ret; 559 } 560 561 void platform_set_speaker_gain_in_combo(struct audio_device *adev __unused, 562 snd_device_t snd_device __unused, 563 bool enable __unused) { 564 } 565 566 int platform_set_voice_volume(void *platform, int volume) 567 { 568 struct platform_data *my_data = (struct platform_data *)platform; 569 int ret = 0; 570 571 if (my_data->csd_client) { 572 if (my_data->csd_volume == NULL) { 573 ALOGE("%s: dlsym error for csd_volume", __func__); 574 } else { 575 ret = my_data->csd_volume(volume); 576 if (ret < 0) { 577 ALOGE("%s: csd_volume error %d", __func__, ret); 578 } 579 } 580 } else { 581 ALOGE("%s: No CSD Client present", __func__); 582 } 583 584 return ret; 585 } 586 587 int platform_set_mic_mute(void *platform, bool state) 588 { 589 struct platform_data *my_data = (struct platform_data *)platform; 590 int ret = 0; 591 592 if (my_data->adev->mode == AUDIO_MODE_IN_CALL) { 593 if (my_data->csd_client) { 594 if (my_data->csd_mic_mute == NULL) { 595 ALOGE("%s: dlsym error for csd_mic_mute", __func__); 596 } else { 597 ret = my_data->csd_mic_mute(state); 598 if (ret < 0) { 599 ALOGE("%s: csd_mic_mute error %d", __func__, ret); 600 } 601 } 602 } else { 603 ALOGE("%s: No CSD Client present", __func__); 604 } 605 } 606 607 return ret; 608 } 609 610 int platform_set_device_mute(void *platform __unused, bool state __unused, char *dir __unused) 611 { 612 ALOGE("%s: Not implemented", __func__); 613 return -ENOSYS; 614 } 615 616 snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices) 617 { 618 struct platform_data *my_data = (struct platform_data *)platform; 619 struct audio_device *adev = my_data->adev; 620 audio_mode_t mode = adev->mode; 621 snd_device_t snd_device = SND_DEVICE_NONE; 622 623 ALOGV("%s: enter: output devices(%#x)", __func__, devices); 624 if (devices == AUDIO_DEVICE_NONE || 625 devices & AUDIO_DEVICE_BIT_IN) { 626 ALOGV("%s: Invalid output devices (%#x)", __func__, devices); 627 goto exit; 628 } 629 630 if (voice_is_in_call(adev)) { 631 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || 632 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) { 633 if (adev->voice.tty_mode == TTY_MODE_FULL) 634 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES; 635 else if (adev->voice.tty_mode == TTY_MODE_VCO) 636 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES; 637 else if (adev->voice.tty_mode == TTY_MODE_HCO) 638 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET; 639 else 640 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES; 641 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) { 642 if (adev->bt_wb_speech_enabled) { 643 snd_device = SND_DEVICE_OUT_BT_SCO_WB; 644 } else { 645 snd_device = SND_DEVICE_OUT_BT_SCO; 646 } 647 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) { 648 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER; 649 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) { 650 if (is_operator_tmus()) 651 snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS; 652 else 653 snd_device = SND_DEVICE_OUT_HANDSET; 654 } 655 if (snd_device != SND_DEVICE_NONE) { 656 goto exit; 657 } 658 } 659 660 if (popcount(devices) == 2) { 661 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE | 662 AUDIO_DEVICE_OUT_SPEAKER)) { 663 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES; 664 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET | 665 AUDIO_DEVICE_OUT_SPEAKER)) { 666 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES; 667 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL | 668 AUDIO_DEVICE_OUT_SPEAKER)) { 669 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI; 670 } else { 671 ALOGE("%s: Invalid combo device(%#x)", __func__, devices); 672 goto exit; 673 } 674 if (snd_device != SND_DEVICE_NONE) { 675 goto exit; 676 } 677 } 678 679 if (popcount(devices) != 1) { 680 ALOGE("%s: Invalid output devices(%#x)", __func__, devices); 681 goto exit; 682 } 683 684 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || 685 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) { 686 snd_device = SND_DEVICE_OUT_HEADPHONES; 687 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) { 688 if (my_data->speaker_lr_swap) 689 snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE; 690 else 691 snd_device = SND_DEVICE_OUT_SPEAKER; 692 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) { 693 if (adev->bt_wb_speech_enabled) { 694 snd_device = SND_DEVICE_OUT_BT_SCO_WB; 695 } else { 696 snd_device = SND_DEVICE_OUT_BT_SCO; 697 } 698 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) { 699 snd_device = SND_DEVICE_OUT_HDMI ; 700 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) { 701 snd_device = SND_DEVICE_OUT_HANDSET; 702 } else { 703 ALOGE("%s: Unknown device(s) %#x", __func__, devices); 704 } 705 exit: 706 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]); 707 return snd_device; 708 } 709 710 snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device) 711 { 712 struct platform_data *my_data = (struct platform_data *)platform; 713 struct audio_device *adev = my_data->adev; 714 audio_source_t source = (adev->active_input == NULL) ? 715 AUDIO_SOURCE_DEFAULT : adev->active_input->source; 716 717 audio_mode_t mode = adev->mode; 718 audio_devices_t in_device = ((adev->active_input == NULL) ? 719 AUDIO_DEVICE_NONE : adev->active_input->device) 720 & ~AUDIO_DEVICE_BIT_IN; 721 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ? 722 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask; 723 snd_device_t snd_device = SND_DEVICE_NONE; 724 725 ALOGV("%s: enter: out_device(%#x) in_device(%#x)", 726 __func__, out_device, in_device); 727 if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) { 728 if (adev->voice.tty_mode != TTY_MODE_OFF) { 729 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || 730 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) { 731 switch (adev->voice.tty_mode) { 732 case TTY_MODE_FULL: 733 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC; 734 break; 735 case TTY_MODE_VCO: 736 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC; 737 break; 738 case TTY_MODE_HCO: 739 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC; 740 break; 741 default: 742 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode); 743 } 744 goto exit; 745 } 746 } 747 if (out_device & AUDIO_DEVICE_OUT_EARPIECE || 748 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) { 749 if (my_data->fluence_in_voice_call == false) { 750 snd_device = SND_DEVICE_IN_HANDSET_MIC; 751 } else { 752 if (my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) { 753 if (is_operator_tmus()) 754 snd_device = SND_DEVICE_IN_VOICE_DMIC_EF_TMUS; 755 else 756 snd_device = SND_DEVICE_IN_VOICE_DMIC_EF; 757 } else if(my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE) 758 snd_device = SND_DEVICE_IN_VOICE_DMIC_BS; 759 else 760 snd_device = SND_DEVICE_IN_HANDSET_MIC; 761 } 762 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) { 763 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC; 764 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) { 765 if (adev->bt_wb_speech_enabled) { 766 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB; 767 } else { 768 snd_device = SND_DEVICE_IN_BT_SCO_MIC; 769 } 770 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) { 771 if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode && 772 my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) { 773 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF; 774 } else if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode && 775 my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE) { 776 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS; 777 } else { 778 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC; 779 } 780 } 781 } else if (source == AUDIO_SOURCE_CAMCORDER) { 782 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC || 783 in_device & AUDIO_DEVICE_IN_BACK_MIC) { 784 snd_device = SND_DEVICE_IN_CAMCORDER_MIC; 785 } 786 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) { 787 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) { 788 if (my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) { 789 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) 790 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_EF; 791 else if (my_data->fluence_in_voice_rec) 792 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE; 793 } else if (my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE) { 794 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) 795 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_BS; 796 else if (my_data->fluence_in_voice_rec) 797 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE; 798 } 799 800 if (snd_device == SND_DEVICE_NONE) { 801 snd_device = SND_DEVICE_IN_VOICE_REC_MIC; 802 } 803 } 804 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION || 805 mode == AUDIO_MODE_IN_COMMUNICATION) { 806 if (out_device & AUDIO_DEVICE_OUT_SPEAKER) 807 in_device = AUDIO_DEVICE_IN_BACK_MIC; 808 if (adev->active_input) { 809 if (adev->active_input->enable_aec) { 810 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) { 811 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC; 812 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) { 813 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC; 814 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) { 815 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC; 816 } 817 set_echo_reference(adev->mixer, "SLIM_RX"); 818 } else 819 set_echo_reference(adev->mixer, "NONE"); 820 } 821 } else if (source == AUDIO_SOURCE_DEFAULT) { 822 goto exit; 823 } 824 825 826 if (snd_device != SND_DEVICE_NONE) { 827 goto exit; 828 } 829 830 if (in_device != AUDIO_DEVICE_NONE && 831 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) && 832 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) { 833 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) { 834 snd_device = SND_DEVICE_IN_HANDSET_MIC; 835 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) { 836 snd_device = SND_DEVICE_IN_SPEAKER_MIC; 837 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) { 838 snd_device = SND_DEVICE_IN_HEADSET_MIC; 839 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 840 if (adev->bt_wb_speech_enabled) { 841 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB; 842 } else { 843 snd_device = SND_DEVICE_IN_BT_SCO_MIC; 844 } 845 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) { 846 snd_device = SND_DEVICE_IN_HDMI_MIC; 847 } else { 848 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device); 849 ALOGW("%s: Using default handset-mic", __func__); 850 snd_device = SND_DEVICE_IN_HANDSET_MIC; 851 } 852 } else { 853 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) { 854 snd_device = SND_DEVICE_IN_HANDSET_MIC; 855 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) { 856 snd_device = SND_DEVICE_IN_HEADSET_MIC; 857 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) { 858 snd_device = SND_DEVICE_IN_SPEAKER_MIC; 859 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) { 860 snd_device = SND_DEVICE_IN_HANDSET_MIC; 861 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) { 862 if (adev->bt_wb_speech_enabled) { 863 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB; 864 } else { 865 snd_device = SND_DEVICE_IN_BT_SCO_MIC; 866 } 867 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) { 868 snd_device = SND_DEVICE_IN_HDMI_MIC; 869 } else { 870 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device); 871 ALOGW("%s: Using default handset-mic", __func__); 872 snd_device = SND_DEVICE_IN_HANDSET_MIC; 873 } 874 } 875 exit: 876 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]); 877 return snd_device; 878 } 879 880 int platform_set_hdmi_channels(void *platform, int channel_count) 881 { 882 struct platform_data *my_data = (struct platform_data *)platform; 883 struct audio_device *adev = my_data->adev; 884 struct mixer_ctl *ctl; 885 const char *channel_cnt_str = NULL; 886 const char *mixer_ctl_name = "HDMI_RX Channels"; 887 switch (channel_count) { 888 case 8: 889 channel_cnt_str = "Eight"; break; 890 case 7: 891 channel_cnt_str = "Seven"; break; 892 case 6: 893 channel_cnt_str = "Six"; break; 894 case 5: 895 channel_cnt_str = "Five"; break; 896 case 4: 897 channel_cnt_str = "Four"; break; 898 case 3: 899 channel_cnt_str = "Three"; break; 900 default: 901 channel_cnt_str = "Two"; break; 902 } 903 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name); 904 if (!ctl) { 905 ALOGE("%s: Could not get ctl for mixer cmd - %s", 906 __func__, mixer_ctl_name); 907 return -EINVAL; 908 } 909 ALOGV("HDMI channel count: %s", channel_cnt_str); 910 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str); 911 return 0; 912 } 913 914 int platform_edid_get_max_channels(void *platform __unused) 915 { 916 FILE *file; 917 struct audio_block_header header; 918 char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE]; 919 char *sad = block; 920 int num_audio_blocks; 921 int channel_count; 922 int max_channels = 0; 923 int i; 924 925 file = fopen(AUDIO_DATA_BLOCK_PATH, "rb"); 926 if (file == NULL) { 927 ALOGE("Unable to open '%s'", AUDIO_DATA_BLOCK_PATH); 928 return 0; 929 } 930 931 /* Read audio block header */ 932 fread(&header, 1, sizeof(header), file); 933 934 /* Read SAD blocks, clamping the maximum size for safety */ 935 if (header.length > (int)sizeof(block)) 936 header.length = (int)sizeof(block); 937 fread(&block, header.length, 1, file); 938 939 fclose(file); 940 941 /* Calculate the number of SAD blocks */ 942 num_audio_blocks = header.length / SAD_BLOCK_SIZE; 943 944 for (i = 0; i < num_audio_blocks; i++) { 945 /* Only consider LPCM blocks */ 946 if ((sad[0] >> 3) != EDID_FORMAT_LPCM) 947 continue; 948 949 channel_count = (sad[0] & 0x7) + 1; 950 if (channel_count > max_channels) 951 max_channels = channel_count; 952 953 /* Advance to next block */ 954 sad += 3; 955 } 956 957 return max_channels; 958 } 959 960 int platform_set_incall_recording_session_id(void *platform __unused, 961 uint32_t session_id __unused, int rec_mode __unused) 962 { 963 ALOGE("%s: Not implemented", __func__); 964 return -ENOSYS; 965 } 966 967 int platform_stop_incall_recording_usecase(void *platform __unused) 968 { 969 ALOGE("%s: Not implemented", __func__); 970 return -ENOSYS; 971 } 972 973 int platform_start_incall_music_usecase(void *platform __unused) 974 { 975 ALOGE("%s: Not implemented", __func__); 976 return -ENOSYS; 977 } 978 979 int platform_stop_incall_music_usecase(void *platform __unused) 980 { 981 ALOGE("%s: Not implemented", __func__); 982 return -ENOSYS; 983 } 984 985 int platform_set_parameters(void *platform __unused, 986 struct str_parms *parms __unused) 987 { 988 ALOGE("%s: Not implemented", __func__); 989 return -ENOSYS; 990 } 991 992 /* Delay in Us */ 993 int64_t platform_render_latency(audio_usecase_t usecase) 994 { 995 switch (usecase) { 996 case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER: 997 return DEEP_BUFFER_PLATFORM_DELAY; 998 case USECASE_AUDIO_PLAYBACK_LOW_LATENCY: 999 return LOW_LATENCY_PLATFORM_DELAY; 1000 default: 1001 return 0; 1002 } 1003 } 1004 1005 int platform_switch_voice_call_enable_device_config(void *platform __unused, 1006 snd_device_t out_snd_device __unused, 1007 snd_device_t in_snd_device __unused) 1008 { 1009 return 0; 1010 } 1011 1012 int platform_switch_voice_call_usecase_route_post(void *platform __unused, 1013 snd_device_t out_snd_device __unused, 1014 snd_device_t in_snd_device __unused) 1015 { 1016 return 0; 1017 } 1018 1019 int platform_get_sample_rate(void *platform __unused, uint32_t *rate __unused) 1020 { 1021 return -ENOSYS; 1022 } 1023 1024 int platform_get_usecase_index(const char * usecase __unused) 1025 { 1026 return -ENOSYS; 1027 } 1028 1029 int platform_set_usecase_pcm_id(audio_usecase_t usecase __unused, int32_t type __unused, 1030 int32_t pcm_id __unused) 1031 { 1032 return -ENOSYS; 1033 } 1034 1035 int platform_set_snd_device_backend(snd_device_t device __unused, 1036 const char *backend __unused, 1037 const char *hw_interface __unused) 1038 { 1039 return -ENOSYS; 1040 } 1041 1042 void platform_set_echo_reference(struct audio_device *adev __unused, 1043 bool enable __unused, 1044 audio_devices_t out_device __unused) 1045 { 1046 return; 1047 } 1048 1049 int platform_swap_lr_channels(struct audio_device *adev, bool swap_channels) 1050 { 1051 // only update the selected device if there is active pcm playback 1052 struct audio_usecase *usecase; 1053 struct listnode *node; 1054 struct platform_data *my_data = (struct platform_data *)adev->platform; 1055 int status = 0; 1056 1057 if (my_data->speaker_lr_swap != swap_channels) { 1058 my_data->speaker_lr_swap = swap_channels; 1059 1060 list_for_each(node, &adev->usecase_list) { 1061 usecase = node_to_item(node, struct audio_usecase, list); 1062 if (usecase->type == PCM_PLAYBACK && 1063 usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) { 1064 const char *mixer_path; 1065 if (swap_channels) { 1066 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE); 1067 audio_route_apply_and_update_path(adev->audio_route, mixer_path); 1068 } else { 1069 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER); 1070 audio_route_apply_and_update_path(adev->audio_route, mixer_path); 1071 } 1072 break; 1073 } 1074 } 1075 } 1076 return status; 1077 } 1078 1079 bool platform_send_gain_dep_cal(void *platform __unused, 1080 int level __unused) 1081 { 1082 return true; 1083 } 1084 1085 int platform_can_split_snd_device(snd_device_t in_snd_device __unused, 1086 int *num_devices __unused, 1087 snd_device_t *out_snd_devices __unused) 1088 { 1089 return -ENOSYS; 1090 } 1091 1092 bool platform_check_backends_match(snd_device_t snd_device1 __unused, 1093 snd_device_t snd_device2 __unused) 1094 { 1095 return true; 1096 } 1097 1098 int platform_get_snd_device_name_extn(void *platform __unused, 1099 snd_device_t snd_device, 1100 char *device_name) 1101 { 1102 strlcpy(device_name, platform_get_snd_device_name(snd_device), 1103 DEVICE_NAME_MAX_SIZE); 1104 return 0; 1105 } 1106 1107 bool platform_check_and_set_playback_backend_cfg(struct audio_device* adev __unused, 1108 struct audio_usecase *usecase __unused, 1109 snd_device_t snd_device __unused) 1110 { 1111 return false; 1112 } 1113 1114 bool platform_check_and_set_capture_backend_cfg(struct audio_device* adev __unused, 1115 struct audio_usecase *usecase __unused) 1116 { 1117 return false; 1118 } 1119 1120 bool platform_add_gain_level_mapping(struct amp_db_and_gain_table *tbl_entry __unused) 1121 { 1122 return false; 1123 } 1124 1125 int platform_get_gain_level_mapping(struct amp_db_and_gain_table *mapping_tbl __unused, 1126 int table_size __unused) 1127 { 1128 return 0; 1129 } 1130 1131 int platform_snd_card_update(void *platform __unused, 1132 card_status_t status __unused) 1133 { 1134 return -1; 1135 } 1136