1/* 2 * Copyright (C) 2016 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 "audio_hw_utils" 18//#define LOG_NDEBUG 0 19 20#include <errno.h> 21#include <cutils/properties.h> 22#include <cutils/config_utils.h> 23#include <stdlib.h> 24#include <dlfcn.h> 25#include <cutils/str_parms.h> 26#include <cutils/log.h> 27#include <cutils/misc.h> 28 29#include "audio_hw.h" 30#include "platform.h" 31#include "platform_api.h" 32#include "audio_extn.h" 33 34#define MAX_LENGTH_MIXER_CONTROL_IN_INT 128 35 36static int set_mixer_ctrl(struct audio_device *adev, 37 int pcm_device_id, int app_type, 38 int acdb_dev_id, int sample_rate, int stream_type) 39{ 40 41 char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT]; 42 struct mixer_ctl *ctl; 43 int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc = 0; 44 45 if (stream_type == PCM_PLAYBACK) { 46 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), 47 "Audio Stream %d App Type Cfg", pcm_device_id); 48 } else if (stream_type == PCM_CAPTURE) { 49 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), 50 "Audio Stream Capture %d App Type Cfg", pcm_device_id); 51 } 52 53 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name); 54 if (!ctl) { 55 ALOGE("%s: Could not get ctl for mixer cmd - %s", 56 __func__, mixer_ctl_name); 57 rc = -EINVAL; 58 goto exit; 59 } 60 app_type_cfg[len++] = app_type; 61 app_type_cfg[len++] = acdb_dev_id; 62 app_type_cfg[len++] = sample_rate; 63 ALOGV("%s: stream type %d app_type %d, acdb_dev_id %d sample rate %d", 64 __func__, stream_type, app_type, acdb_dev_id, sample_rate); 65 mixer_ctl_set_array(ctl, app_type_cfg, len); 66 67exit: 68 return rc; 69} 70 71void audio_extn_utils_send_default_app_type_cfg(void *platform, struct mixer *mixer) 72{ 73 int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {-1}; 74 int length = 0, app_type = 0,rc = 0; 75 struct mixer_ctl *ctl = NULL; 76 const char *mixer_ctl_name = "App Type Config"; 77 78 ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name); 79 if (!ctl) { 80 ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name); 81 return; 82 } 83 rc = platform_get_default_app_type_v2(platform, PCM_PLAYBACK, &app_type); 84 if (rc == 0) { 85 app_type_cfg[length++] = 1; 86 app_type_cfg[length++] = app_type; 87 app_type_cfg[length++] = 48000; 88 app_type_cfg[length++] = 16; 89 mixer_ctl_set_array(ctl, app_type_cfg, length); 90 } 91 return; 92} 93 94int audio_extn_utils_send_app_type_cfg(struct audio_device *adev, 95 struct audio_usecase *usecase) 96{ 97 struct mixer_ctl *ctl; 98 int pcm_device_id, acdb_dev_id = 0, snd_device = usecase->out_snd_device; 99 int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE; 100 int app_type = 0, rc = 0; 101 102 ALOGV("%s", __func__); 103 104 if (usecase->type != PCM_HFP_CALL) { 105 ALOGV("%s: not a playback or HFP path, no need to cfg app type", __func__); 106 rc = 0; 107 goto exit_send_app_type_cfg; 108 } 109 if ((usecase->id != USECASE_AUDIO_HFP_SCO) && 110 (usecase->id != USECASE_AUDIO_HFP_SCO_WB)) { 111 ALOGV("%s: a playback path where app type cfg is not required", __func__); 112 rc = 0; 113 goto exit_send_app_type_cfg; 114 } 115 116 snd_device = usecase->out_snd_device; 117 pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK); 118 119 snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ? 120 audio_extn_get_spkr_prot_snd_device(snd_device) : snd_device; 121 acdb_dev_id = platform_get_snd_device_acdb_id(snd_device); 122 if (acdb_dev_id < 0) { 123 ALOGE("%s: Couldn't get the acdb dev id", __func__); 124 rc = -EINVAL; 125 goto exit_send_app_type_cfg; 126 } 127 128 if (usecase->type == PCM_HFP_CALL) { 129 130 /* config HFP session:1 playback path */ 131 rc = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK, &app_type); 132 if (rc < 0) 133 goto exit_send_app_type_cfg; 134 135 sample_rate= CODEC_BACKEND_DEFAULT_SAMPLE_RATE; 136 rc = set_mixer_ctrl(adev, pcm_device_id, app_type, 137 acdb_dev_id, sample_rate, PCM_PLAYBACK); 138 if (rc < 0) 139 goto exit_send_app_type_cfg; 140 /* config HFP session:1 capture path */ 141 rc = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE, &app_type); 142 143 if (rc == 0) { 144 rc = set_mixer_ctrl(adev, pcm_device_id, app_type, 145 acdb_dev_id, sample_rate, PCM_CAPTURE); 146 if (rc < 0) 147 goto exit_send_app_type_cfg; 148 } 149 /* config HFP session:2 capture path */ 150 pcm_device_id = HFP_ASM_RX_TX; 151 snd_device = usecase->in_snd_device; 152 acdb_dev_id = platform_get_snd_device_acdb_id(snd_device); 153 if (acdb_dev_id <= 0) { 154 ALOGE("%s: Couldn't get the acdb dev id", __func__); 155 rc = -EINVAL; 156 goto exit_send_app_type_cfg; 157 } 158 rc = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE, &app_type); 159 if (rc == 0) { 160 rc = set_mixer_ctrl(adev, pcm_device_id, app_type, 161 acdb_dev_id, sample_rate, PCM_CAPTURE); 162 if (rc < 0) 163 goto exit_send_app_type_cfg; 164 } 165 166 /* config HFP session:2 playback path */ 167 rc = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK, &app_type); 168 if (rc == 0) { 169 rc = set_mixer_ctrl(adev, pcm_device_id, app_type, 170 acdb_dev_id, sample_rate, PCM_PLAYBACK); 171 if (rc < 0) 172 goto exit_send_app_type_cfg; 173 } 174 } 175 176 rc = 0; 177exit_send_app_type_cfg: 178 return rc; 179} 180