1e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta/* 2e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * Copyright (C) 2016 The Android Open Source Project 3e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * 4e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * Licensed under the Apache License, Version 2.0 (the "License"); 5e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * you may not use this file except in compliance with the License. 6e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * You may obtain a copy of the License at 7e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * 8e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * http://www.apache.org/licenses/LICENSE-2.0 9e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * 10e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * Unless required by applicable law or agreed to in writing, software 11e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * distributed under the License is distributed on an "AS IS" BASIS, 12e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * See the License for the specific language governing permissions and 14e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta * limitations under the License. 15e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta */ 16e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 17e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#define LOG_TAG "audio_hw_utils" 18e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta//#define LOG_NDEBUG 0 19e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 20e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#include <errno.h> 21e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#include <cutils/properties.h> 22e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#include <cutils/config_utils.h> 23e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#include <stdlib.h> 24e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#include <dlfcn.h> 256431fe63703982df8e83644a168c7432e3fd855cJiyong Park#include <unistd.h> 26e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#include <cutils/str_parms.h> 27e6e2d441c567d5da185b787d6c10ca2c8b36a694Haynes Mathew George#include <log/log.h> 28e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#include <cutils/misc.h> 29e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 300fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta#include "acdb.h" 31e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#include "audio_hw.h" 32e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#include "platform.h" 33e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#include "platform_api.h" 34e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#include "audio_extn.h" 35e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 36e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta#define MAX_LENGTH_MIXER_CONTROL_IN_INT 128 37e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 38a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehtastatic int set_stream_app_type_mixer_ctrl(struct audio_device *adev, 39a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int pcm_device_id, int app_type, 40a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int acdb_dev_id, int sample_rate, 41a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int stream_type, 42a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta snd_device_t snd_device) 43e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta{ 44e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 45e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT]; 46e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta struct mixer_ctl *ctl; 47e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc = 0; 48a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int snd_device_be_idx = -1; 49e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 50e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (stream_type == PCM_PLAYBACK) { 51e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), 52e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta "Audio Stream %d App Type Cfg", pcm_device_id); 53e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } else if (stream_type == PCM_CAPTURE) { 54e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), 55e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta "Audio Stream Capture %d App Type Cfg", pcm_device_id); 56e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 57e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 58e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name); 59e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (!ctl) { 60e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta ALOGE("%s: Could not get ctl for mixer cmd - %s", 61e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta __func__, mixer_ctl_name); 62e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta rc = -EINVAL; 63e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta goto exit; 64e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 65e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta app_type_cfg[len++] = app_type; 66e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta app_type_cfg[len++] = acdb_dev_id; 67e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta app_type_cfg[len++] = sample_rate; 68a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 69a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta snd_device_be_idx = platform_get_snd_device_backend_index(snd_device); 70a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (snd_device_be_idx > 0) 71a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg[len++] = snd_device_be_idx; 72a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta ALOGV("%s: stream type %d app_type %d, acdb_dev_id %d " 73a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta "sample rate %d, snd_device_be_idx %d", 74a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta __func__, stream_type, app_type, acdb_dev_id, sample_rate, 75a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta snd_device_be_idx); 76e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta mixer_ctl_set_array(ctl, app_type_cfg, len); 77e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 78e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehtaexit: 79e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta return rc; 80e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta} 81e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 82e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehtavoid audio_extn_utils_send_default_app_type_cfg(void *platform, struct mixer *mixer) 83e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta{ 84e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {-1}; 85e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta int length = 0, app_type = 0,rc = 0; 86e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta struct mixer_ctl *ctl = NULL; 87e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta const char *mixer_ctl_name = "App Type Config"; 88e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 89e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name); 90e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (!ctl) { 91e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name); 92e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta return; 93e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 94e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta rc = platform_get_default_app_type_v2(platform, PCM_PLAYBACK, &app_type); 95e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (rc == 0) { 96e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta app_type_cfg[length++] = 1; 97e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta app_type_cfg[length++] = app_type; 98e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta app_type_cfg[length++] = 48000; 99e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta app_type_cfg[length++] = 16; 100e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta mixer_ctl_set_array(ctl, app_type_cfg, length); 101e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 102e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta return; 103e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta} 104e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 105a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehtastatic const char *flags_to_mode(int dir, uint32_t flags) 106a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta{ 107a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (dir == 0) { 108a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (flags & AUDIO_OUTPUT_FLAG_VOIP_RX) { 109a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return "voip"; 110a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } 111a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } else if (dir == 1) { 112a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (flags & AUDIO_INPUT_FLAG_VOIP_TX) { 113a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return "voip"; 114a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } 115a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } 116a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return "default"; 117a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta} 118a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 119e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew Georgestatic int audio_extn_utils_send_app_type_cfg_hfp(struct audio_device *adev, 120e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta struct audio_usecase *usecase) 121e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta{ 122e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta struct mixer_ctl *ctl; 123e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta int pcm_device_id, acdb_dev_id = 0, snd_device = usecase->out_snd_device; 124e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; 125e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta int app_type = 0, rc = 0; 126e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 127e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta ALOGV("%s", __func__); 128e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 129e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (usecase->type != PCM_HFP_CALL) { 130e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta ALOGV("%s: not a playback or HFP path, no need to cfg app type", __func__); 131e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta rc = 0; 132e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta goto exit_send_app_type_cfg; 133e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 134e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if ((usecase->id != USECASE_AUDIO_HFP_SCO) && 135e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta (usecase->id != USECASE_AUDIO_HFP_SCO_WB)) { 136e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta ALOGV("%s: a playback path where app type cfg is not required", __func__); 137e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta rc = 0; 138e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta goto exit_send_app_type_cfg; 139e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 140e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 141e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta snd_device = usecase->out_snd_device; 142e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK); 143e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 144e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta acdb_dev_id = platform_get_snd_device_acdb_id(snd_device); 145e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (acdb_dev_id < 0) { 146e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta ALOGE("%s: Couldn't get the acdb dev id", __func__); 147e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta rc = -EINVAL; 148e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta goto exit_send_app_type_cfg; 149e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 150e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 151e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (usecase->type == PCM_HFP_CALL) { 152e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 153e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta /* config HFP session:1 playback path */ 154e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta rc = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK, &app_type); 155e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (rc < 0) 156e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta goto exit_send_app_type_cfg; 157e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 158e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta sample_rate= CODEC_BACKEND_DEFAULT_SAMPLE_RATE; 159a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type, 160a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta acdb_dev_id, sample_rate, 161a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta PCM_PLAYBACK, 162a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta SND_DEVICE_NONE); // use legacy behavior 163e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (rc < 0) 164e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta goto exit_send_app_type_cfg; 165e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta /* config HFP session:1 capture path */ 166e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta rc = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE, &app_type); 167e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 168e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (rc == 0) { 169a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type, 170a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta acdb_dev_id, sample_rate, 171a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta PCM_CAPTURE, 172a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta SND_DEVICE_NONE); 173e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (rc < 0) 174e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta goto exit_send_app_type_cfg; 175e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 176e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta /* config HFP session:2 capture path */ 177e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta pcm_device_id = HFP_ASM_RX_TX; 178e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta snd_device = usecase->in_snd_device; 179e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta acdb_dev_id = platform_get_snd_device_acdb_id(snd_device); 180e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (acdb_dev_id <= 0) { 181e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta ALOGE("%s: Couldn't get the acdb dev id", __func__); 182e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta rc = -EINVAL; 183e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta goto exit_send_app_type_cfg; 184e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 185e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta rc = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE, &app_type); 186e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (rc == 0) { 187a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type, 188a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta acdb_dev_id, sample_rate, PCM_CAPTURE, 189a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta SND_DEVICE_NONE); 190e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (rc < 0) 191e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta goto exit_send_app_type_cfg; 192e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 193e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 194e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta /* config HFP session:2 playback path */ 195e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta rc = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK, &app_type); 196e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (rc == 0) { 197a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type, 198a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta acdb_dev_id, sample_rate, 199a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta PCM_PLAYBACK, SND_DEVICE_NONE); 200e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta if (rc < 0) 201e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta goto exit_send_app_type_cfg; 202e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 203e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta } 204e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta 205e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta rc = 0; 206e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehtaexit_send_app_type_cfg: 207e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta return rc; 208e3b9956373beb54b67957675b6e6d99fd3280edaYamit Mehta} 209e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George 210a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 211a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehtastatic int derive_capture_app_type_cfg(struct audio_device *adev, 212a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct audio_usecase *usecase, 213a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int *app_type, 214a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int *sample_rate) 215e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George{ 2162e259979b6459235e527ef8283f28f1f08498b51Mark Urbanus if (usecase->stream.in == NULL) { 2172e259979b6459235e527ef8283f28f1f08498b51Mark Urbanus return -1; 2182e259979b6459235e527ef8283f28f1f08498b51Mark Urbanus } 219a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct stream_in *in = usecase->stream.in; 220a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct stream_app_type_cfg *app_type_cfg = &in->app_type_cfg; 221a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 222a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta *sample_rate = DEFAULT_INPUT_SAMPLING_RATE; 2234a824779a3f91eea626ab015975ede392f84ec38vivek mehta if (audio_is_usb_in_device(in->device)) { 224a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta platform_check_and_update_copp_sample_rate(adev->platform, 225a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta usecase->in_snd_device, 226a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta in->sample_rate, 227a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta sample_rate); 228e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George } 229e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George 230a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->mode = flags_to_mode(1 /*capture*/, in->flags); 231a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta ALOGV("%s mode %s", __func__, app_type_cfg->mode); 232a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (in->format == AUDIO_FORMAT_PCM_16_BIT) { 233a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta platform_get_app_type_v2(adev->platform, 234a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta PCM_CAPTURE, 235a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->mode, 236a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 16, 237a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->sample_rate, 238a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type); 239a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } else if (in->format == AUDIO_FORMAT_PCM_24_BIT_PACKED || 240a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta in->format == AUDIO_FORMAT_PCM_8_24_BIT) { 241a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta platform_get_app_type_v2(adev->platform, 242a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta PCM_CAPTURE, 243a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->mode, 244a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 24, 245a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->sample_rate, 246a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type); 247a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } else if (in->format == AUDIO_FORMAT_PCM_32_BIT) { 248a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta platform_get_app_type_v2(adev->platform, 249a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta PCM_CAPTURE, 250a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->mode, 251a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 32, 252a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->sample_rate, 253a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type); 254a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } else { 255a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta ALOGE("%s bad format\n", __func__); 256e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George return -1; 257e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George } 258e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George 259a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->app_type = *app_type; 260a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->sample_rate = *sample_rate; 261a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return 0; 262a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta} 263e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George 264a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehtastatic int derive_playback_app_type_cfg(struct audio_device *adev, 265a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct audio_usecase *usecase, 266a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int *app_type, 267a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int *sample_rate) 268a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta{ 2692e259979b6459235e527ef8283f28f1f08498b51Mark Urbanus if (usecase->stream.out == NULL) { 2702e259979b6459235e527ef8283f28f1f08498b51Mark Urbanus return -1; 2712e259979b6459235e527ef8283f28f1f08498b51Mark Urbanus } 272a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct stream_out *out = usecase->stream.out; 273a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct stream_app_type_cfg *app_type_cfg = &out->app_type_cfg; 274a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 275a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta *sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; 276a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 277a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta // add speaker prot changes if needed 278a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta // and use that to check for device 2794a824779a3f91eea626ab015975ede392f84ec38vivek mehta if (audio_is_usb_out_device(out->devices)) { 280a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta platform_check_and_update_copp_sample_rate(adev->platform, 281a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta usecase->out_snd_device, 282a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta out->sample_rate, 283a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta sample_rate); 284e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George } 285e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George 286a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->mode = flags_to_mode(0 /*playback*/, out->flags); 287a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (!audio_is_linear_pcm(out->format)) { 288df0f886b586a878615280ca34b40a3671bbac316Haynes Mathew George platform_get_app_type_v2(adev->platform, 289df0f886b586a878615280ca34b40a3671bbac316Haynes Mathew George PCM_PLAYBACK, 290df0f886b586a878615280ca34b40a3671bbac316Haynes Mathew George app_type_cfg->mode, 291df0f886b586a878615280ca34b40a3671bbac316Haynes Mathew George 24, 292df0f886b586a878615280ca34b40a3671bbac316Haynes Mathew George *sample_rate, 293df0f886b586a878615280ca34b40a3671bbac316Haynes Mathew George app_type); 294df0f886b586a878615280ca34b40a3671bbac316Haynes Mathew George ALOGV("Non pcm got app type %d", *app_type); 295a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } else if (out->format == AUDIO_FORMAT_PCM_16_BIT) { 296e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George platform_get_app_type_v2(adev->platform, 297e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George PCM_PLAYBACK, 298a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->mode, 299a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 16, 300a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta *sample_rate, 301a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type); 302a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } else if (out->format == AUDIO_FORMAT_PCM_24_BIT_PACKED || 303a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta out->format == AUDIO_FORMAT_PCM_8_24_BIT) { 304e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George platform_get_app_type_v2(adev->platform, 305e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George PCM_PLAYBACK, 306a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->mode, 307a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 24, 308a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta *sample_rate, 309a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type); 310a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } else if (out->format == AUDIO_FORMAT_PCM_32_BIT) { 311e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George platform_get_app_type_v2(adev->platform, 312e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George PCM_PLAYBACK, 313a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->mode, 314a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 32, 315a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta *sample_rate, 316a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type); 317e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George } else { 318e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George ALOGE("%s bad format\n", __func__); 319e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George return -1; 320e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George } 321e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George 322a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->app_type = *app_type; 323a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta app_type_cfg->sample_rate = *sample_rate; 324a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return 0; 325a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta} 326e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George 327a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehtastatic int derive_acdb_dev_id(struct audio_device *adev __unused, 328a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct audio_usecase *usecase) 329a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta{ 330a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct stream_out *out; 331a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct stream_in *in; 332e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George 333a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (usecase->type == PCM_PLAYBACK) { 3349d6679a89ddf23452bb7d370e6fc62ec1183c456Aniket Kumar Lata return platform_get_snd_device_acdb_id(usecase->out_snd_device); 335a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } else if(usecase->type == PCM_CAPTURE) { 336a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return platform_get_snd_device_acdb_id(usecase->in_snd_device); 337a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } 338a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return -1; 339a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta} 340e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George 341a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehtaint audio_extn_utils_send_app_type_cfg(struct audio_device *adev, 342a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct audio_usecase *usecase) 343a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta{ 344a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int len = 0; 345a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int sample_rate; 346a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int app_type; 347a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int acdb_dev_id; 348a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta size_t app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0}; 349a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0}; 350a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int pcm_device_id; 351a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct mixer_ctl *ctl; 352a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta int ret; 353a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 354a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (usecase->type == PCM_HFP_CALL) { 355a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return audio_extn_utils_send_app_type_cfg_hfp(adev, usecase); 356a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } 357a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 358a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (!platform_supports_app_type_cfg()) 359a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return -1; 360a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 361a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (usecase->type == PCM_PLAYBACK) { 362a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta ret = derive_playback_app_type_cfg(adev, 363a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta usecase, 364a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta &app_type, 365a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta &sample_rate); 366a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } else if (usecase->type == PCM_CAPTURE) { 367a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta ret = derive_capture_app_type_cfg(adev, 368a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta usecase, 369a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta &app_type, 370a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta &sample_rate); 371a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } else { 372a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta ALOGE("%s: Invalid uc type : 0x%x", __func__, usecase->type); 373a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return -1; 374a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } 375a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 376a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (ret < 0) { 377a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta ALOGE("%s: Failed to derive app_type for uc type : 0x%x", __func__, 378a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta usecase->type); 379a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return -1; 380a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } 381a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 382a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta acdb_dev_id = derive_acdb_dev_id(adev, usecase); 383a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta if (acdb_dev_id <= 0) { 384a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta ALOGE("%s: Couldn't get the acdb dev id", __func__); 385a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta return -1; 386a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta } 387a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 388a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta pcm_device_id = platform_get_pcm_device_id(usecase->id, usecase->type); 389a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type, acdb_dev_id, 390a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta sample_rate, 391a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta usecase->type, 392a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta usecase->type == PCM_PLAYBACK ? usecase->out_snd_device : 393a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta usecase->in_snd_device); 394e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George return 0; 395e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George} 396e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George 3974a824779a3f91eea626ab015975ede392f84ec38vivek mehtaint audio_extn_utils_send_app_type_gain(struct audio_device *adev, 3984a824779a3f91eea626ab015975ede392f84ec38vivek mehta int app_type, 3994a824779a3f91eea626ab015975ede392f84ec38vivek mehta int *gain) 4004a824779a3f91eea626ab015975ede392f84ec38vivek mehta{ 4014a824779a3f91eea626ab015975ede392f84ec38vivek mehta int gain_cfg[4]; 4024a824779a3f91eea626ab015975ede392f84ec38vivek mehta const char *mixer_ctl_name = "App Type Gain"; 4034a824779a3f91eea626ab015975ede392f84ec38vivek mehta struct mixer_ctl *ctl; 4044a824779a3f91eea626ab015975ede392f84ec38vivek mehta ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name); 4054a824779a3f91eea626ab015975ede392f84ec38vivek mehta if (!ctl) { 4064a824779a3f91eea626ab015975ede392f84ec38vivek mehta ALOGE("%s: Could not get volume ctl mixer %s", __func__, 4074a824779a3f91eea626ab015975ede392f84ec38vivek mehta mixer_ctl_name); 4084a824779a3f91eea626ab015975ede392f84ec38vivek mehta return -EINVAL; 4094a824779a3f91eea626ab015975ede392f84ec38vivek mehta } 4104a824779a3f91eea626ab015975ede392f84ec38vivek mehta gain_cfg[0] = 0; 4114a824779a3f91eea626ab015975ede392f84ec38vivek mehta gain_cfg[1] = app_type; 4124a824779a3f91eea626ab015975ede392f84ec38vivek mehta gain_cfg[2] = gain[0]; 4134a824779a3f91eea626ab015975ede392f84ec38vivek mehta gain_cfg[3] = gain[1]; 4144a824779a3f91eea626ab015975ede392f84ec38vivek mehta ALOGV("%s app_type %d l(%d) r(%d)", __func__, app_type, gain[0], gain[1]); 4154a824779a3f91eea626ab015975ede392f84ec38vivek mehta return mixer_ctl_set_array(ctl, gain_cfg, 4164a824779a3f91eea626ab015975ede392f84ec38vivek mehta sizeof(gain_cfg)/sizeof(gain_cfg[0])); 4174a824779a3f91eea626ab015975ede392f84ec38vivek mehta} 4184a824779a3f91eea626ab015975ede392f84ec38vivek mehta 419a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta// this assumes correct app_type and sample_rate fields 420a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta// have been set for the stream using audio_extn_utils_send_app_type_cfg 421e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew Georgevoid audio_extn_utils_send_audio_calibration(struct audio_device *adev, 422e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George struct audio_usecase *usecase) 423e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George{ 424e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George int type = usecase->type; 425e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George int app_type = 0; 426e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George 427e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George if (type == PCM_PLAYBACK && usecase->stream.out != NULL) { 428e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George struct stream_out *out = usecase->stream.out; 429a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta ALOGV("%s send cal for app_type %d, rate %d", __func__, 430a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta out->app_type_cfg.app_type, 431a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta out->app_type_cfg.sample_rate); 432e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George platform_send_audio_calibration_v2(adev->platform, usecase, 433a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta out->app_type_cfg.app_type, 434a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta out->app_type_cfg.sample_rate); 435e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George } else if (type == PCM_CAPTURE && usecase->stream.in != NULL) { 436a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta struct stream_in *in = usecase->stream.in; 437a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta ALOGV("%s send cal for capture app_type %d, rate %d", __func__, 438a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta in->app_type_cfg.app_type, 439a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta in->app_type_cfg.sample_rate); 440a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta platform_send_audio_calibration_v2(adev->platform, usecase, 441a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta in->app_type_cfg.app_type, 442a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta in->app_type_cfg.sample_rate); 443e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George } else { 444e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George /* when app type is default. the sample rate is not used to send cal */ 445e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George platform_get_default_app_type_v2(adev->platform, type, &app_type); 446a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta platform_send_audio_calibration_v2(adev->platform, usecase, app_type, 447a68fea653241619e8b4b5ad5f21a2415a03a06dbvivek mehta 48000); 448e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George } 449e5ff0fc8e7126cdd2535641e9463ee8065b6149eHaynes Mathew George} 4500fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 4510fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta#define MAX_SND_CARD 8 4520fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta#define RETRY_US 500000 4530fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta#define RETRY_NUMBER 10 4540fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 4550fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta#define min(a, b) ((a) < (b) ? (a) : (b)) 4560fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 4570fb113194399805a0fdbf5bb3f812e98047272bdvivek mehtastatic const char *kConfigLocationList[] = 4580fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta {"/odm/etc", "/vendor/etc", "/system/etc"}; 4590fb113194399805a0fdbf5bb3f812e98047272bdvivek mehtastatic const int kConfigLocationListSize = 4600fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0])); 4610fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 4620fb113194399805a0fdbf5bb3f812e98047272bdvivek mehtabool audio_extn_utils_resolve_config_file(char file_name[MIXER_PATH_MAX_LENGTH]) 4630fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta{ 4640fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta char full_config_path[MIXER_PATH_MAX_LENGTH]; 4650fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta for (int i = 0; i < kConfigLocationListSize; i++) { 4660fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta snprintf(full_config_path, 4670fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta MIXER_PATH_MAX_LENGTH, 4680fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta "%s/%s", 4690fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta kConfigLocationList[i], 4700fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta file_name); 4710fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta if (F_OK == access(full_config_path, 0)) { 4720fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta strcpy(file_name, full_config_path); 4730fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta return true; 4740fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta } 4750fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta } 4760fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta return false; 4770fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta} 4780fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 4790fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta/* platform_info_file should be size 'MIXER_PATH_MAX_LENGTH' */ 48066ff30c81a8c561db01217297f849614a9599533Haynes Mathew Georgeint audio_extn_utils_get_platform_info(const char* snd_card_name, char* platform_info_file) 4810fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta{ 4820fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta if (NULL == snd_card_name) { 48366ff30c81a8c561db01217297f849614a9599533Haynes Mathew George return -1; 4840fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta } 4850fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 4860fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta struct snd_card_split *snd_split_handle = NULL; 48766ff30c81a8c561db01217297f849614a9599533Haynes Mathew George int ret = 0; 4880fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta audio_extn_set_snd_card_split(snd_card_name); 4890fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta snd_split_handle = audio_extn_get_snd_card_split(); 4900fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 4910fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s_%s.xml", 4920fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card, 4930fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta snd_split_handle->form_factor); 4940fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 4950fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta if (!audio_extn_utils_resolve_config_file(platform_info_file)) { 4960fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH); 4970fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s.xml", 4980fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card); 4990fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5000fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta if (!audio_extn_utils_resolve_config_file(platform_info_file)) { 5010fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH); 5020fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta strlcpy(platform_info_file, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH); 50366ff30c81a8c561db01217297f849614a9599533Haynes Mathew George ret = audio_extn_utils_resolve_config_file(platform_info_file) ? 0 : -1; 5040fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta } 5050fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta } 50666ff30c81a8c561db01217297f849614a9599533Haynes Mathew George 50766ff30c81a8c561db01217297f849614a9599533Haynes Mathew George return ret; 5080fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta} 5090fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5100fb113194399805a0fdbf5bb3f812e98047272bdvivek mehtaint audio_extn_utils_get_snd_card_num() 5110fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta{ 5120fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5130fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta void *hw_info = NULL; 5140fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta struct mixer *mixer = NULL; 5150fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta int retry_num = 0; 5160fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta int snd_card_num = 0; 5170fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta const char* snd_card_name = NULL; 5180fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta char platform_info_file[MIXER_PATH_MAX_LENGTH]= {0}; 5190fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5200fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta struct acdb_platform_data *my_data = calloc(1, sizeof(struct acdb_platform_data)); 5210fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5220fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta bool card_verifed[MAX_SND_CARD] = {0}; 5230fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta const int retry_limit = property_get_int32("audio.snd_card.open.retries", RETRY_NUMBER); 5240fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5250fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta for (;;) { 5260fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta if (snd_card_num >= MAX_SND_CARD) { 5270fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta if (retry_num++ >= retry_limit) { 5280fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta ALOGE("%s: Unable to find correct sound card, aborting.", __func__); 5290fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta snd_card_num = -1; 5300fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta goto done; 5310fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta } 5320fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5330fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta snd_card_num = 0; 5340fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta usleep(RETRY_US); 5350fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta continue; 5360fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta } 5370fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5380fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta if (card_verifed[snd_card_num]) { 5390fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta ++snd_card_num; 5400fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta continue; 5410fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta } 5420fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5430fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta mixer = mixer_open(snd_card_num); 5440fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5450fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta if (!mixer) { 5460fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta ALOGE("%s: Unable to open the mixer card: %d", __func__, 5470fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta snd_card_num); 5480fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta ++snd_card_num; 5490fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta continue; 5500fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta } 5510fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5520fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta card_verifed[snd_card_num] = true; 5530fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5540fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta snd_card_name = mixer_get_name(mixer); 5550fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta hw_info = hw_info_init(snd_card_name); 5560fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 55766ff30c81a8c561db01217297f849614a9599533Haynes Mathew George if (audio_extn_utils_get_platform_info(snd_card_name, platform_info_file) < 0) { 55866ff30c81a8c561db01217297f849614a9599533Haynes Mathew George ALOGE("Failed to find platform_info_file"); 55966ff30c81a8c561db01217297f849614a9599533Haynes Mathew George goto cleanup; 56066ff30c81a8c561db01217297f849614a9599533Haynes Mathew George } 5610fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5620fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta /* Initialize snd card name specific ids and/or backends*/ 56366ff30c81a8c561db01217297f849614a9599533Haynes Mathew George if (snd_card_info_init(platform_info_file, my_data, 56466ff30c81a8c561db01217297f849614a9599533Haynes Mathew George &acdb_set_parameters) < 0) { 56566ff30c81a8c561db01217297f849614a9599533Haynes Mathew George ALOGE("Failed to find platform_info_file"); 56666ff30c81a8c561db01217297f849614a9599533Haynes Mathew George goto cleanup; 56766ff30c81a8c561db01217297f849614a9599533Haynes Mathew George } 5680fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5690fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta /* validate the sound card name 5700fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta * my_data->snd_card_name can contain 5710fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta * <a> complete sound card name, i.e. <device>-<codec>-<form_factor>-snd-card 5720fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta * example: msm8994-tomtom-mtp-snd-card 5730fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta * <b> or sub string of the card name, i.e. <device>-<codec> 5740fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta * example: msm8994-tomtom 5750fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta * snd_card_name is truncated to 32 charaters as per mixer_get_name() implementation 5760fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta * so use min of my_data->snd_card_name and snd_card_name length for comparison 5770fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta */ 5780fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5790fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta if (my_data->snd_card_name != NULL && 5800fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta strncmp(snd_card_name, my_data->snd_card_name, 5810fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta min(strlen(snd_card_name), strlen(my_data->snd_card_name))) != 0) { 5820fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta ALOGI("%s: found valid sound card %s, but not primary sound card %s", 5830fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta __func__, snd_card_name, my_data->snd_card_name); 58466ff30c81a8c561db01217297f849614a9599533Haynes Mathew George goto cleanup; 5850fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta } 5860fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 58766ff30c81a8c561db01217297f849614a9599533Haynes Mathew George ALOGI("%s: found sound card %s, primary sound card expected is %s", 5880fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta __func__, snd_card_name, my_data->snd_card_name); 5890fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta break; 59066ff30c81a8c561db01217297f849614a9599533Haynes Mathew George cleanup: 59166ff30c81a8c561db01217297f849614a9599533Haynes Mathew George ++snd_card_num; 59266ff30c81a8c561db01217297f849614a9599533Haynes Mathew George mixer_close(mixer); 59366ff30c81a8c561db01217297f849614a9599533Haynes Mathew George mixer = NULL; 59466ff30c81a8c561db01217297f849614a9599533Haynes Mathew George hw_info_deinit(hw_info); 59566ff30c81a8c561db01217297f849614a9599533Haynes Mathew George hw_info = NULL; 5960fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta } 5970fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 5980fb113194399805a0fdbf5bb3f812e98047272bdvivek mehtadone: 5990fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta mixer_close(mixer); 6000fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta hw_info_deinit(hw_info); 6010fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 6020fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta if (my_data) 6030fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta free(my_data); 6040fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta 6050fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta return snd_card_num; 6060fb113194399805a0fdbf5bb3f812e98047272bdvivek mehta} 607