blob: 9baf176586cf9dcb00236d63436d99b8d6033044 [file] [log] [blame]
Eric Laurentb23d5282013-05-14 15:27:20 -07001/*
vivek mehtaa6b79742017-03-09 15:40:43 -08002 * Copyright (C) 2013-2017 The Android Open Source Project
Eric Laurentb23d5282013-05-14 15:27:20 -07003 *
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 */
Eric Laurentb23d5282013-05-14 15:27:20 -070016#define LOG_TAG "msm8974_platform"
17/*#define LOG_NDEBUG 0*/
18#define LOG_NDDEBUG 0
19
20#include <stdlib.h>
21#include <dlfcn.h>
22#include <cutils/log.h>
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -070023#include <cutils/str_parms.h>
Eric Laurentb23d5282013-05-14 15:27:20 -070024#include <cutils/properties.h>
25#include <audio_hw.h>
26#include <platform_api.h>
27#include "platform.h"
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -070028#include "audio_extn.h"
vivek mehta1a9b7c02015-06-25 11:49:38 -070029#include <linux/msm_audio.h>
Eric Laurentb23d5282013-05-14 15:27:20 -070030
Jaekyun Seokf62e17d2017-03-08 17:15:28 +090031#define MIXER_XML_DEFAULT_PATH "mixer_paths.xml"
32#define MIXER_XML_BASE_STRING "mixer_paths"
vivek mehta60ea4152016-02-18 17:10:26 -080033#define TOMTOM_8226_SND_CARD_NAME "msm8226-tomtom-snd-card"
34#define TOMTOM_MIXER_FILE_SUFFIX "wcd9330"
35
Eric Laurentb23d5282013-05-14 15:27:20 -070036#define LIB_ACDB_LOADER "libacdbloader.so"
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070037#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +090038#define CVD_VERSION_MIXER_CTL "CVD Version"
Eric Laurentb23d5282013-05-14 15:27:20 -070039
Eric Laurentf9583c32016-03-28 13:50:50 -070040#define min(a, b) ((a) < (b) ? (a) : (b))
Eric Laurentb23d5282013-05-14 15:27:20 -070041
42/*
Eric Laurentb23d5282013-05-14 15:27:20 -070043 * 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
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +090052#define MAX_CVD_VERSION_STRING_SIZE 100
53
Eric Laurentb23d5282013-05-14 15:27:20 -070054/* EDID format ID for LPCM audio */
55#define EDID_FORMAT_LPCM 1
56
sangwoo1b9f4b32013-06-21 18:22:55 -070057/* Retry for delay in FW loading*/
58#define RETRY_NUMBER 10
59#define RETRY_US 500000
Vineeta Srivastava4b89e372014-06-19 14:21:42 -070060#define MAX_SND_CARD 8
sangwoo53b2cf02013-07-25 19:18:44 -070061
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -070062#define MAX_SND_CARD_NAME_LEN 31
63
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -080064#define DEFAULT_APP_TYPE_RX_PATH 69936
65#define DEFAULT_APP_TYPE_TX_PATH 69938
vivek mehta1a9b7c02015-06-25 11:49:38 -070066
keunhui.parkc5aaa0e2015-07-13 10:57:37 +090067#define TOSTRING_(x) #x
68#define TOSTRING(x) TOSTRING_(x)
69
Eric Laurentb23d5282013-05-14 15:27:20 -070070struct audio_block_header
71{
72 int reserved;
73 int length;
74};
75
vivek mehta1a9b7c02015-06-25 11:49:38 -070076enum {
77 CAL_MODE_SEND = 0x1,
78 CAL_MODE_PERSIST = 0x2,
79 CAL_MODE_RTAC = 0x4
80};
81
keunhui.park2f7306a2015-07-16 16:48:06 +090082#define PLATFORM_CONFIG_KEY_OPERATOR_INFO "operator_info"
83
84struct operator_info {
85 struct listnode list;
86 char *name;
87 char *mccmnc;
88};
89
90struct operator_specific_device {
91 struct listnode list;
92 char *operator;
93 char *mixer_path;
94 int acdb_id;
95};
96
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -080097#define BE_DAI_NAME_MAX_LENGTH 24
98struct be_dai_name_struct {
99 unsigned int be_id;
100 char be_name[BE_DAI_NAME_MAX_LENGTH];
101};
102
keunhui.park2f7306a2015-07-16 16:48:06 +0900103static struct listnode operator_info_list;
104static struct listnode *operator_specific_device_table[SND_DEVICE_MAX];
105
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700106/* Audio calibration related functions */
Eric Laurentb23d5282013-05-14 15:27:20 -0700107typedef void (*acdb_deallocate_t)();
vivek mehtac698f132016-02-25 18:50:35 -0800108typedef int (*acdb_init_v2_cvd_t)(char *, char *, int);
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +0900109typedef int (*acdb_init_v2_t)(char *);
Eric Laurentb23d5282013-05-14 15:27:20 -0700110typedef int (*acdb_init_t)();
111typedef void (*acdb_send_audio_cal_t)(int, int);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800112typedef void (*acdb_send_audio_cal_v3_t)(int, int, int, int, int);
Eric Laurentb23d5282013-05-14 15:27:20 -0700113typedef void (*acdb_send_voice_cal_t)(int, int);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700114typedef int (*acdb_reload_vocvoltable_t)(int);
vivek mehta1a9b7c02015-06-25 11:49:38 -0700115typedef int (*acdb_send_gain_dep_cal_t)(int, int, int, int, int);
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -0700116typedef int (*acdb_send_custom_top_t) (void);
Eric Laurentb23d5282013-05-14 15:27:20 -0700117
118/* Audio calibration related functions */
119struct platform_data {
120 struct audio_device *adev;
121 bool fluence_in_spkr_mode;
122 bool fluence_in_voice_call;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700123 bool fluence_in_voice_comm;
Eric Laurentb23d5282013-05-14 15:27:20 -0700124 bool fluence_in_voice_rec;
Prashant Malanic92c5962015-08-11 15:10:18 -0700125 /* 0 = no fluence, 1 = fluence, 2 = fluence pro */
126 int fluence_type;
127 int source_mic_type;
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -0700128 bool speaker_lr_swap;
129
Eric Laurentb23d5282013-05-14 15:27:20 -0700130 void *acdb_handle;
Thierry Strudel92232b42017-01-26 10:51:48 -0800131#if defined (PLATFORM_MSM8994) || (PLATFORM_MSM8996) || (PLATFORM_MSM8998)
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -0700132 acdb_init_v2_cvd_t acdb_init;
133#elif defined (PLATFORM_MSM8084)
134 acdb_init_v2_t acdb_init;
135#else
136 acdb_init_t acdb_init;
137#endif
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700138 acdb_deallocate_t acdb_deallocate;
139 acdb_send_audio_cal_t acdb_send_audio_cal;
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800140 acdb_send_audio_cal_v3_t acdb_send_audio_cal_v3;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700141 acdb_send_voice_cal_t acdb_send_voice_cal;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700142 acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
vivek mehta1a9b7c02015-06-25 11:49:38 -0700143 acdb_send_gain_dep_cal_t acdb_send_gain_dep_cal;
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -0700144 acdb_send_custom_top_t acdb_send_custom_top;
145 bool acdb_initialized;
146
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700147 struct csd_data *csd;
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800148 char ec_ref_mixer_path[64];
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -0700149
David Linee3fe402017-03-13 10:00:42 -0700150 codec_backend_cfg_t current_backend_cfg[MAX_CODEC_BACKENDS];
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -0700151 char *snd_card_name;
keunhui.parkc5aaa0e2015-07-13 10:57:37 +0900152 int max_vol_index;
Prashant Malanic92c5962015-08-11 15:10:18 -0700153 int max_mic_count;
vivek mehtade4849c2016-03-03 17:23:38 -0800154
155 void *hw_info;
Eric Laurentb23d5282013-05-14 15:27:20 -0700156};
157
Haynes Mathew George98c95622014-06-20 19:14:25 -0700158static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700159 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
160 DEEP_BUFFER_PCM_DEVICE},
161 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
162 LOWLATENCY_PCM_DEVICE},
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800163 [USECASE_AUDIO_PLAYBACK_HIFI] = {MULTIMEDIA2_PCM_DEVICE,
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700164 MULTIMEDIA2_PCM_DEVICE},
165 [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {PLAYBACK_OFFLOAD_DEVICE,
166 PLAYBACK_OFFLOAD_DEVICE},
Ravi Kumar Alamanda2bc7b022015-06-25 20:08:01 -0700167 [USECASE_AUDIO_PLAYBACK_TTS] = {MULTIMEDIA2_PCM_DEVICE,
168 MULTIMEDIA2_PCM_DEVICE},
169 [USECASE_AUDIO_PLAYBACK_ULL] = {MULTIMEDIA3_PCM_DEVICE,
170 MULTIMEDIA3_PCM_DEVICE},
Eric Laurent0e46adf2016-12-16 12:49:24 -0800171 [USECASE_AUDIO_PLAYBACK_MMAP] = {MMAP_PLAYBACK_PCM_DEVICE,
172 MMAP_PLAYBACK_PCM_DEVICE},
Ravi Kumar Alamanda2bc7b022015-06-25 20:08:01 -0700173
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700174 [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE,
175 AUDIO_RECORD_PCM_DEVICE},
176 [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
177 LOWLATENCY_PCM_DEVICE},
Ravi Kumar Alamanda2bc7b022015-06-25 20:08:01 -0700178
Eric Laurent0e46adf2016-12-16 12:49:24 -0800179 [USECASE_AUDIO_RECORD_MMAP] = {MMAP_RECORD_PCM_DEVICE,
180 MMAP_RECORD_PCM_DEVICE},
181
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700182 [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE,
183 VOICE_CALL_PCM_DEVICE},
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700184 [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
185 [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
186 [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
187 [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
vivek mehtaa51fd402016-02-04 19:49:33 -0800188 [USECASE_VOICEMMODE1_CALL] = {VOICEMMODE1_CALL_PCM_DEVICE,
189 VOICEMMODE1_CALL_PCM_DEVICE},
190 [USECASE_VOICEMMODE2_CALL] = {VOICEMMODE2_CALL_PCM_DEVICE,
191 VOICEMMODE2_CALL_PCM_DEVICE},
192
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700193 [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
194 AUDIO_RECORD_PCM_DEVICE},
195 [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
196 AUDIO_RECORD_PCM_DEVICE},
197 [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
198 AUDIO_RECORD_PCM_DEVICE},
Ravi Kumar Alamanda8e6e98f2013-11-05 15:57:39 -0800199 [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700200
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700201 [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
202 [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
203
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700204 [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
205 AFE_PROXY_RECORD_PCM_DEVICE},
206 [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
207 AFE_PROXY_RECORD_PCM_DEVICE},
zhaoyang yin4211fad2015-06-04 21:13:25 +0800208 [USECASE_AUDIO_DSM_FEEDBACK] = {QUAT_MI2S_PCM_DEVICE, QUAT_MI2S_PCM_DEVICE},
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700209
Eric Laurentb23d5282013-05-14 15:27:20 -0700210};
211
212/* Array to store sound devices */
213static const char * const device_table[SND_DEVICE_MAX] = {
214 [SND_DEVICE_NONE] = "none",
215 /* Playback sound devices */
216 [SND_DEVICE_OUT_HANDSET] = "handset",
217 [SND_DEVICE_OUT_SPEAKER] = "speaker",
218 [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700219 [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
Eric Laurentb23d5282013-05-14 15:27:20 -0700220 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500221 [SND_DEVICE_OUT_LINE] = "line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700222 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700223 [SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = "speaker-safe-and-headphones",
Eric Laurent744996b2014-10-01 11:40:40 -0500224 [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700225 [SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = "speaker-safe-and-line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700226 [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500227 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
Eric Laurentb23d5282013-05-14 15:27:20 -0700228 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
229 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500230 [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700231 [SND_DEVICE_OUT_HDMI] = "hdmi",
232 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
233 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700234 [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700235 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
236 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
237 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
238 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
vivek mehtaa6b79742017-03-09 15:40:43 -0800239 [SND_DEVICE_OUT_VOICE_TTY_FULL_USB] = "voice-tty-full-usb",
240 [SND_DEVICE_OUT_VOICE_TTY_VCO_USB] = "voice-tty-vco-usb",
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700241 [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
David Linee3fe402017-03-13 10:00:42 -0700242 [SND_DEVICE_OUT_USB_HEADSET] = "usb-headset",
Haynes Mathew George9a29f372017-04-11 19:19:07 -0700243 [SND_DEVICE_OUT_VOICE_USB_HEADSET] = "usb-headset",
David Linee3fe402017-03-13 10:00:42 -0700244 [SND_DEVICE_OUT_USB_HEADPHONES] = "usb-headphones",
Haynes Mathew George9a29f372017-04-11 19:19:07 -0700245 [SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = "usb-headphones",
David Linee3fe402017-03-13 10:00:42 -0700246 [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700247 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
248 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
Uday Kishore Pasupuleti76297192015-09-18 08:39:43 -0700249 [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = "voice-speaker-hfp",
Haynes Mathew George6dcb1a82016-12-21 12:38:55 -0800250 [SND_DEVICE_OUT_SPEAKER_AND_BT_SCO] = "speaker-and-bt-sco",
251 [SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB] = "speaker-and-bt-sco-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700252
253 /* Capture sound devices */
254 [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700255 [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700256 [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
257 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
258 [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
259 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
260 [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
261 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
262 [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = "dmic-endfire",
263
264 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
265 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
266 [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
267 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
268 [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
269 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
270 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
271 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
272 [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = "speaker-dmic-endfire",
273
274 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
Eric Laurentcefbbac2014-09-04 13:54:10 -0500275 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700276
Eric Laurentb23d5282013-05-14 15:27:20 -0700277 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
278 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700279 [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700280 [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700281 [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700282 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700283
284 [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
285 [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
286 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
287 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
Uday Kishore Pasupuleti76297192015-09-18 08:39:43 -0700288 [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = "voice-speaker-mic-hfp",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700289 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700290 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
291 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
292 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
vivek mehtaa6b79742017-03-09 15:40:43 -0800293 [SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC] = "voice-tty-full-usb-mic",
294 [SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC] = "voice-tty-hco-usb-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700295
Eric Laurentb23d5282013-05-14 15:27:20 -0700296 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700297 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
vivek mehta733c1df2016-04-04 15:09:24 -0700298 [SND_DEVICE_IN_VOICE_REC_MIC_AEC] = "voice-rec-mic",
vivek mehtaf3440682016-05-11 14:24:37 -0700299 [SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS] = "voice-rec-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700300 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
301 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
David Linee3fe402017-03-13 10:00:42 -0700302 [SND_DEVICE_IN_USB_HEADSET_MIC] = "usb-headset-mic",
Haynes Mathew George9a29f372017-04-11 19:19:07 -0700303 [SND_DEVICE_IN_VOICE_USB_HEADSET_MIC] ="usb-headset-mic",
304 [SND_DEVICE_IN_USB_HEADSET_MIC_AEC] = "usb-headset-mic",
305 [SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC] = "usb-headset-mic",
306 [SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC] = "usb-headset-mic",
Jean-Michel Trivi8c83fe82015-09-25 15:06:53 -0700307 [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "headset-mic",
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700308
Ricardo Garcia9034bc42016-04-04 07:11:46 -0700309 [SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
vivek mehta0125e782016-06-16 18:03:11 -0700310 [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = "unprocessed-stereo-mic",
311 [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "unprocessed-three-mic",
312 [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = "unprocessed-quad-mic",
313 [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = "unprocessed-headset-mic",
rago90fb9612015-12-02 11:37:53 -0800314
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700315 [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700316
Prashant Malanic92c5962015-08-11 15:10:18 -0700317 [SND_DEVICE_IN_THREE_MIC] = "three-mic",
318 [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700319 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
Prashant Malanic92c5962015-08-11 15:10:18 -0700320 [SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
321 [SND_DEVICE_IN_HANDSET_QMIC] = "quad-mic",
vivek mehta733c1df2016-04-04 15:09:24 -0700322 [SND_DEVICE_IN_HANDSET_TMIC_AEC] = "three-mic",
323 [SND_DEVICE_IN_HANDSET_QMIC_AEC] = "quad-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700324};
325
326/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700327static int acdb_device_table[SND_DEVICE_MAX] = {
Eric Laurentb23d5282013-05-14 15:27:20 -0700328 [SND_DEVICE_NONE] = -1,
329 [SND_DEVICE_OUT_HANDSET] = 7,
330 [SND_DEVICE_OUT_SPEAKER] = 15,
331 [SND_DEVICE_OUT_SPEAKER_REVERSE] = 15,
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700332 [SND_DEVICE_OUT_SPEAKER_SAFE] = 15,
Eric Laurentb23d5282013-05-14 15:27:20 -0700333 [SND_DEVICE_OUT_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500334 [SND_DEVICE_OUT_LINE] = 77,
Eric Laurentb23d5282013-05-14 15:27:20 -0700335 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700336 [SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500337 [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 77,
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700338 [SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = 77,
Ravi Kumar Alamanda235c3482014-08-21 17:32:44 -0700339 [SND_DEVICE_OUT_VOICE_HANDSET] = ACDB_ID_VOICE_HANDSET,
340 [SND_DEVICE_OUT_VOICE_SPEAKER] = ACDB_ID_VOICE_SPEAKER,
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500341 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
Eric Laurentb23d5282013-05-14 15:27:20 -0700342 [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500343 [SND_DEVICE_OUT_VOICE_LINE] = 77,
Eric Laurentb23d5282013-05-14 15:27:20 -0700344 [SND_DEVICE_OUT_HDMI] = 18,
345 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 15,
346 [SND_DEVICE_OUT_BT_SCO] = 22,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700347 [SND_DEVICE_OUT_BT_SCO_WB] = 39,
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700348 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = ACDB_ID_VOICE_HANDSET_TMUS,
Eric Laurentb23d5282013-05-14 15:27:20 -0700349 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
350 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
351 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
vivek mehtaa6b79742017-03-09 15:40:43 -0800352 [SND_DEVICE_OUT_VOICE_TTY_FULL_USB] = 17,
353 [SND_DEVICE_OUT_VOICE_TTY_VCO_USB] = 17,
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700354 [SND_DEVICE_OUT_VOICE_TX] = 45,
David Linee3fe402017-03-13 10:00:42 -0700355 [SND_DEVICE_OUT_USB_HEADSET] = 45,
Haynes Mathew George9a29f372017-04-11 19:19:07 -0700356 [SND_DEVICE_OUT_VOICE_USB_HEADSET] = 45,
David Linee3fe402017-03-13 10:00:42 -0700357 [SND_DEVICE_OUT_USB_HEADPHONES] = 45,
Haynes Mathew George9a29f372017-04-11 19:19:07 -0700358 [SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = 45,
David Linee3fe402017-03-13 10:00:42 -0700359 [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700360 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
361 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
Uday Kishore Pasupuletie9ef4782015-09-21 08:33:55 -0700362 [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = ACDB_ID_VOICE_SPEAKER,
Eric Laurentb23d5282013-05-14 15:27:20 -0700363
364 [SND_DEVICE_IN_HANDSET_MIC] = 4,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700365 [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
366 [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
367 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
368 [SND_DEVICE_IN_HANDSET_DMIC] = 41,
369 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
370 [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
371 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
372 [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = 34,
373
374 [SND_DEVICE_IN_SPEAKER_MIC] = 11,
375 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
376 [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
377 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
378 [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
379 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
380 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
381 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
382 [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = 35,
383
rago90fb9612015-12-02 11:37:53 -0800384 [SND_DEVICE_IN_HEADSET_MIC] = ACDB_ID_HEADSET_MIC_AEC,
Eric Laurentcefbbac2014-09-04 13:54:10 -0500385 [SND_DEVICE_IN_HEADSET_MIC_AEC] = ACDB_ID_HEADSET_MIC_AEC,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700386
Eric Laurentb23d5282013-05-14 15:27:20 -0700387 [SND_DEVICE_IN_HDMI_MIC] = 4,
388 [SND_DEVICE_IN_BT_SCO_MIC] = 21,
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700389 [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 21,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700390 [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700391 [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 38,
Eric Laurentb23d5282013-05-14 15:27:20 -0700392 [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700393
394 [SND_DEVICE_IN_VOICE_DMIC] = 41,
395 [SND_DEVICE_IN_VOICE_DMIC_TMUS] = ACDB_ID_VOICE_DMIC_EF_TMUS,
396 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
Uday Kishore Pasupuletie9ef4782015-09-21 08:33:55 -0700397 [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = 11,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700398 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
rago90fb9612015-12-02 11:37:53 -0800399 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = ACDB_ID_HEADSET_MIC_AEC,
Eric Laurentb23d5282013-05-14 15:27:20 -0700400 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
401 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
402 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
vivek mehtaa6b79742017-03-09 15:40:43 -0800403 [SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC] = 16,
404 [SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC] = 16,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700405
rago90fb9612015-12-02 11:37:53 -0800406 [SND_DEVICE_IN_VOICE_REC_MIC] = ACDB_ID_VOICE_REC_MIC,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700407 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 113,
vivek mehta733c1df2016-04-04 15:09:24 -0700408 [SND_DEVICE_IN_VOICE_REC_MIC_AEC] = 112,
vivek mehtaf3440682016-05-11 14:24:37 -0700409 [SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS] = 114,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700410 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 35,
411 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 43,
rago90fb9612015-12-02 11:37:53 -0800412 [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = ACDB_ID_HEADSET_MIC_AEC,
413
414 [SND_DEVICE_IN_UNPROCESSED_MIC] = ACDB_ID_VOICE_REC_MIC,
415 [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = ACDB_ID_HEADSET_MIC_AEC,
vivek mehta4ed66e62016-04-15 23:33:34 -0700416 [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = 35,
417 [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = 125,
418 [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = 125,
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700419
420 [SND_DEVICE_IN_VOICE_RX] = 44,
David Linee3fe402017-03-13 10:00:42 -0700421 [SND_DEVICE_IN_USB_HEADSET_MIC] = 44,
Haynes Mathew George9a29f372017-04-11 19:19:07 -0700422 [SND_DEVICE_IN_VOICE_USB_HEADSET_MIC] = 44,
423 [SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC] = 44,
424 [SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC] = 44,
425 [SND_DEVICE_IN_USB_HEADSET_MIC_AEC] = 44,
Prashant Malanic92c5962015-08-11 15:10:18 -0700426 [SND_DEVICE_IN_THREE_MIC] = 46,
427 [SND_DEVICE_IN_QUAD_MIC] = 46,
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700428 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
Prashant Malanic92c5962015-08-11 15:10:18 -0700429 [SND_DEVICE_IN_HANDSET_TMIC] = 125,
430 [SND_DEVICE_IN_HANDSET_QMIC] = 125,
vivek mehta733c1df2016-04-04 15:09:24 -0700431 [SND_DEVICE_IN_HANDSET_TMIC_AEC] = 125, /* override this for new target to 140 */
432 [SND_DEVICE_IN_HANDSET_QMIC_AEC] = 125, /* override this for new target to 140 */
Eric Laurentb23d5282013-05-14 15:27:20 -0700433};
434
David Linee3fe402017-03-13 10:00:42 -0700435// Platform specific backend bit width table
436static int backend_bit_width_table[SND_DEVICE_MAX] = {0};
437
Haynes Mathew George98c95622014-06-20 19:14:25 -0700438struct name_to_index {
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700439 char name[100];
440 unsigned int index;
441};
442
443#define TO_NAME_INDEX(X) #X, X
444
Haynes Mathew George98c95622014-06-20 19:14:25 -0700445/* Used to get index from parsed string */
446static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
447 /* out */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700448 {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
449 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
450 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700451 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700452 {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500453 {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700454 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700455 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES)},
Eric Laurent744996b2014-10-01 11:40:40 -0500456 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700457 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700458 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
459 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
Uday Kishore Pasupuletie9ef4782015-09-21 08:33:55 -0700460 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_HFP)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700461 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500462 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700463 {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
464 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
465 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
466 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700467 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET_TMUS)},
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500468 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700469 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
470 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
471 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
Haynes Mathew George6dcb1a82016-12-21 12:38:55 -0800472 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_SCO)},
473 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB)},
vivek mehtaa6b79742017-03-09 15:40:43 -0800474 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_USB)},
475 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_USB)},
David Linee3fe402017-03-13 10:00:42 -0700476 {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET)},
Haynes Mathew George9a29f372017-04-11 19:19:07 -0700477 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_USB_HEADSET)},
David Linee3fe402017-03-13 10:00:42 -0700478 {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADPHONES)},
Haynes Mathew George9a29f372017-04-11 19:19:07 -0700479 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_USB_HEADPHONES)},
David Linee3fe402017-03-13 10:00:42 -0700480 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)},
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700481 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
482 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
vivek mehtaa6b79742017-03-09 15:40:43 -0800483
484 /* in */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700485 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700486 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700487 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
488 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
489 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
490 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
491 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
492 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
493 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_STEREO)},
494
495 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700496 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700497 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
498 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
499 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
500 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
501 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
502 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
503 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
504
505 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700506 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700507
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700508 {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
509 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700510 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700511 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700512 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700513 {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700514
515 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
516 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
517 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
Uday Kishore Pasupuletie9ef4782015-09-21 08:33:55 -0700518 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700519 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
520 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700521 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
522 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
523 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
vivek mehtaa6b79742017-03-09 15:40:43 -0800524 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC)},
525 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC)},
526
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700527
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700528 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700529 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
vivek mehta733c1df2016-04-04 15:09:24 -0700530 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_AEC)},
vivek mehtaf3440682016-05-11 14:24:37 -0700531 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700532 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
533 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
Jean-Michel Trivi8c83fe82015-09-25 15:06:53 -0700534 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_HEADSET_MIC)},
David Linee3fe402017-03-13 10:00:42 -0700535 {TO_NAME_INDEX(SND_DEVICE_IN_USB_HEADSET_MIC)},
Haynes Mathew George9a29f372017-04-11 19:19:07 -0700536 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_USB_HEADSET_MIC)},
537 {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC)},
538 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC)},
539 {TO_NAME_INDEX(SND_DEVICE_IN_USB_HEADSET_MIC_AEC)},
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700540
rago90fb9612015-12-02 11:37:53 -0800541 {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_MIC)},
542 {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC)},
vivek mehta4ed66e62016-04-15 23:33:34 -0700543 {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_STEREO_MIC)},
544 {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_THREE_MIC)},
545 {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_QUAD_MIC)},
rago90fb9612015-12-02 11:37:53 -0800546
Prashant Malanic92c5962015-08-11 15:10:18 -0700547 {TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
548 {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700549 {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
Prashant Malanic92c5962015-08-11 15:10:18 -0700550 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
551 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
vivek mehta733c1df2016-04-04 15:09:24 -0700552 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC_AEC)},
553 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC_AEC)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700554};
555
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700556static char * backend_tag_table[SND_DEVICE_MAX] = {0};
557static char * hw_interface_table[SND_DEVICE_MAX] = {0};
Haynes Mathew George98c95622014-06-20 19:14:25 -0700558
559static const struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
560 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
561 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800562 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_HIFI)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700563 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
Ravi Kumar Alamanda2bc7b022015-06-25 20:08:01 -0700564 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_TTS)},
565 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
Eric Laurent0e46adf2016-12-16 12:49:24 -0800566 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MMAP)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700567 {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
568 {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
Eric Laurent0e46adf2016-12-16 12:49:24 -0800569 {TO_NAME_INDEX(USECASE_AUDIO_RECORD_MMAP)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700570 {TO_NAME_INDEX(USECASE_VOICE_CALL)},
571 {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
572 {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
573 {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
574 {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
John Muirf1346ce2016-12-06 00:03:41 -0800575 {TO_NAME_INDEX(USECASE_VOICEMMODE1_CALL)},
576 {TO_NAME_INDEX(USECASE_VOICEMMODE2_CALL)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700577 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK)},
578 {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
579 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
580 {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
John Muirf1346ce2016-12-06 00:03:41 -0800581 {TO_NAME_INDEX(USECASE_AUDIO_SPKR_CALIB_RX)},
582 {TO_NAME_INDEX(USECASE_AUDIO_SPKR_CALIB_TX)},
583 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_AFE_PROXY)},
584 {TO_NAME_INDEX(USECASE_AUDIO_RECORD_AFE_PROXY)},
585 {TO_NAME_INDEX(USECASE_AUDIO_DSM_FEEDBACK)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700586};
587
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800588static const struct name_to_index usecase_type_index[USECASE_TYPE_MAX] = {
589 {TO_NAME_INDEX(PCM_PLAYBACK)},
590 {TO_NAME_INDEX(PCM_CAPTURE)},
591 {TO_NAME_INDEX(VOICE_CALL)},
592 {TO_NAME_INDEX(PCM_HFP_CALL)},
593};
594
595struct app_type_entry {
596 int uc_type;
597 int bit_width;
598 int app_type;
599 int max_rate;
600 struct listnode node; // membership in app_type_entry_list;
601};
602
603static struct listnode app_type_entry_list;
604
Haynes Mathew George7ff216f2013-09-11 19:51:41 -0700605#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
606#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
Eric Laurent0e46adf2016-12-16 12:49:24 -0800607#define ULL_PLATFORM_DELAY (3*1000LL)
608#define MMAP_PLATFORM_DELAY (3*1000LL)
Haynes Mathew George7ff216f2013-09-11 19:51:41 -0700609
Eric Laurentb23d5282013-05-14 15:27:20 -0700610static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
611static bool is_tmus = false;
612
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800613static int init_be_dai_name_table(struct audio_device *adev);
614
Eric Laurentb23d5282013-05-14 15:27:20 -0700615static void check_operator()
616{
617 char value[PROPERTY_VALUE_MAX];
618 int mccmnc;
619 property_get("gsm.sim.operator.numeric",value,"0");
620 mccmnc = atoi(value);
Eric Laurent2bafff12016-03-17 12:17:23 -0700621 ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
Eric Laurentb23d5282013-05-14 15:27:20 -0700622 switch(mccmnc) {
623 /* TMUS MCC(310), MNC(490, 260, 026) */
624 case 310490:
625 case 310260:
626 case 310026:
sangwon.jeonb891db52013-09-14 17:39:15 +0900627 /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
628 case 310800:
629 case 310660:
630 case 310580:
631 case 310310:
632 case 310270:
633 case 310250:
634 case 310240:
635 case 310230:
636 case 310220:
637 case 310210:
638 case 310200:
639 case 310160:
Eric Laurentb23d5282013-05-14 15:27:20 -0700640 is_tmus = true;
641 break;
642 }
643}
644
645bool is_operator_tmus()
646{
647 pthread_once(&check_op_once_ctl, check_operator);
648 return is_tmus;
649}
650
keunhui.park2f7306a2015-07-16 16:48:06 +0900651static char *get_current_operator()
652{
653 struct listnode *node;
654 struct operator_info *info_item;
655 char mccmnc[PROPERTY_VALUE_MAX];
656 char *ret = NULL;
657
Tom Cherry7fea2042016-11-10 18:05:59 -0800658 property_get("gsm.sim.operator.numeric",mccmnc,"00000");
keunhui.park2f7306a2015-07-16 16:48:06 +0900659
660 list_for_each(node, &operator_info_list) {
661 info_item = node_to_item(node, struct operator_info, list);
662 if (strstr(info_item->mccmnc, mccmnc) != NULL) {
663 ret = info_item->name;
664 }
665 }
666
667 return ret;
668}
669
670static struct operator_specific_device *get_operator_specific_device(snd_device_t snd_device)
671{
672 struct listnode *node;
673 struct operator_specific_device *ret = NULL;
674 struct operator_specific_device *device_item;
675 char *operator_name;
676
677 operator_name = get_current_operator();
678 if (operator_name == NULL)
679 return ret;
680
681 list_for_each(node, operator_specific_device_table[snd_device]) {
682 device_item = node_to_item(node, struct operator_specific_device, list);
683 if (strcmp(operator_name, device_item->operator) == 0) {
684 ret = device_item;
685 }
686 }
687
688 return ret;
689}
690
691
692static int get_operator_specific_device_acdb_id(snd_device_t snd_device)
693{
694 struct operator_specific_device *device;
695 int ret = acdb_device_table[snd_device];
696
697 device = get_operator_specific_device(snd_device);
698 if (device != NULL)
699 ret = device->acdb_id;
700
701 return ret;
702}
703
704static const char *get_operator_specific_device_mixer_path(snd_device_t snd_device)
705{
706 struct operator_specific_device *device;
707 const char *ret = device_table[snd_device];
708
709 device = get_operator_specific_device(snd_device);
710 if (device != NULL)
711 ret = device->mixer_path;
712
713 return ret;
714}
715
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800716inline bool platform_supports_app_type_cfg()
717{
718#ifdef PLATFORM_MSM8998
719 return true;
720#else
721 return false;
722#endif
723}
724
vivek mehta1a9b7c02015-06-25 11:49:38 -0700725bool platform_send_gain_dep_cal(void *platform, int level)
726{
727 bool ret_val = false;
728 struct platform_data *my_data = (struct platform_data *)platform;
729 struct audio_device *adev = my_data->adev;
730 int acdb_dev_id, app_type;
731 int acdb_dev_type = MSM_SNDDEV_CAP_RX;
732 int mode = CAL_MODE_RTAC;
733 struct listnode *node;
734 struct audio_usecase *usecase;
vivek mehta1a9b7c02015-06-25 11:49:38 -0700735
736 if (my_data->acdb_send_gain_dep_cal == NULL) {
737 ALOGE("%s: dlsym error for acdb_send_gain_dep_cal", __func__);
738 return ret_val;
739 }
740
741 if (!voice_is_in_call(adev)) {
742 ALOGV("%s: Not Voice call usecase, apply new cal for level %d",
743 __func__, level);
744 app_type = DEFAULT_APP_TYPE_RX_PATH;
745
746 // find the current active sound device
747 list_for_each(node, &adev->usecase_list) {
748 usecase = node_to_item(node, struct audio_usecase, list);
749
750 if (usecase != NULL &&
751 usecase->type == PCM_PLAYBACK &&
752 (usecase->stream.out->devices == AUDIO_DEVICE_OUT_SPEAKER)) {
753
754 ALOGV("%s: out device is %d", __func__, usecase->out_snd_device);
vivek mehta4cb82982015-07-13 12:05:49 -0700755 if (audio_extn_spkr_prot_is_enabled()) {
756 acdb_dev_id = audio_extn_spkr_prot_get_acdb_id(usecase->out_snd_device);
757 } else {
758 acdb_dev_id = acdb_device_table[usecase->out_snd_device];
759 }
760
vivek mehta1a9b7c02015-06-25 11:49:38 -0700761 if (!my_data->acdb_send_gain_dep_cal(acdb_dev_id, app_type,
762 acdb_dev_type, mode, level)) {
763 // set ret_val true if at least one calibration is set successfully
764 ret_val = true;
765 } else {
766 ALOGE("%s: my_data->acdb_send_gain_dep_cal failed ", __func__);
767 }
768 } else {
769 ALOGW("%s: Usecase list is empty", __func__);
770 }
771 }
772 } else {
773 ALOGW("%s: Voice call in progress .. ignore setting new cal",
774 __func__);
775 }
776 return ret_val;
777}
778
Eric Laurentcefbbac2014-09-04 13:54:10 -0500779void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
Eric Laurentb23d5282013-05-14 15:27:20 -0700780{
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800781 struct platform_data *my_data = (struct platform_data *)adev->platform;
Eric Laurentcefbbac2014-09-04 13:54:10 -0500782 snd_device_t snd_device = SND_DEVICE_NONE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700783
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800784 if (strcmp(my_data->ec_ref_mixer_path, "")) {
785 ALOGV("%s: diabling %s", __func__, my_data->ec_ref_mixer_path);
786 audio_route_reset_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
Eric Laurentcefbbac2014-09-04 13:54:10 -0500787 }
788
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800789 if (enable) {
790 strcpy(my_data->ec_ref_mixer_path, "echo-reference");
791 if (out_device != AUDIO_DEVICE_NONE) {
792 snd_device = platform_get_output_snd_device(adev->platform, out_device);
793 platform_add_backend_name(adev->platform, my_data->ec_ref_mixer_path, snd_device);
794 }
Eric Laurentcefbbac2014-09-04 13:54:10 -0500795
Joe Onorato188b6222016-03-01 11:02:27 -0800796 ALOGV("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800797 audio_route_apply_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
798 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700799}
800
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700801static struct csd_data *open_csd_client(bool i2s_ext_modem)
802{
803 struct csd_data *csd = calloc(1, sizeof(struct csd_data));
804
805 csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
806 if (csd->csd_client == NULL) {
807 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
808 goto error;
809 } else {
810 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
811
812 csd->deinit = (deinit_t)dlsym(csd->csd_client,
813 "csd_client_deinit");
814 if (csd->deinit == NULL) {
815 ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
816 dlerror());
817 goto error;
818 }
819 csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
820 "csd_client_disable_device");
821 if (csd->disable_device == NULL) {
822 ALOGE("%s: dlsym error %s for csd_client_disable_device",
823 __func__, dlerror());
824 goto error;
825 }
826 csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
827 "csd_client_enable_device_config");
828 if (csd->enable_device_config == NULL) {
829 ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
830 __func__, dlerror());
831 goto error;
832 }
833 csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
834 "csd_client_enable_device");
835 if (csd->enable_device == NULL) {
836 ALOGE("%s: dlsym error %s for csd_client_enable_device",
837 __func__, dlerror());
838 goto error;
839 }
840 csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
841 "csd_client_start_voice");
842 if (csd->start_voice == NULL) {
843 ALOGE("%s: dlsym error %s for csd_client_start_voice",
844 __func__, dlerror());
845 goto error;
846 }
847 csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
848 "csd_client_stop_voice");
849 if (csd->stop_voice == NULL) {
850 ALOGE("%s: dlsym error %s for csd_client_stop_voice",
851 __func__, dlerror());
852 goto error;
853 }
854 csd->volume = (volume_t)dlsym(csd->csd_client,
855 "csd_client_volume");
856 if (csd->volume == NULL) {
857 ALOGE("%s: dlsym error %s for csd_client_volume",
858 __func__, dlerror());
859 goto error;
860 }
861 csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
862 "csd_client_mic_mute");
863 if (csd->mic_mute == NULL) {
864 ALOGE("%s: dlsym error %s for csd_client_mic_mute",
865 __func__, dlerror());
866 goto error;
867 }
868 csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
869 "csd_client_slow_talk");
870 if (csd->slow_talk == NULL) {
871 ALOGE("%s: dlsym error %s for csd_client_slow_talk",
872 __func__, dlerror());
873 goto error;
874 }
875 csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
876 "csd_client_start_playback");
877 if (csd->start_playback == NULL) {
878 ALOGE("%s: dlsym error %s for csd_client_start_playback",
879 __func__, dlerror());
880 goto error;
881 }
882 csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
883 "csd_client_stop_playback");
884 if (csd->stop_playback == NULL) {
885 ALOGE("%s: dlsym error %s for csd_client_stop_playback",
886 __func__, dlerror());
887 goto error;
888 }
889 csd->start_record = (start_record_t)dlsym(csd->csd_client,
890 "csd_client_start_record");
891 if (csd->start_record == NULL) {
892 ALOGE("%s: dlsym error %s for csd_client_start_record",
893 __func__, dlerror());
894 goto error;
895 }
896 csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
897 "csd_client_stop_record");
898 if (csd->stop_record == NULL) {
899 ALOGE("%s: dlsym error %s for csd_client_stop_record",
900 __func__, dlerror());
901 goto error;
902 }
903
904 csd->get_sample_rate = (get_sample_rate_t)dlsym(csd->csd_client,
905 "csd_client_get_sample_rate");
906 if (csd->get_sample_rate == NULL) {
907 ALOGE("%s: dlsym error %s for csd_client_get_sample_rate",
908 __func__, dlerror());
909
910 goto error;
911 }
912
913 csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
914
915 if (csd->init == NULL) {
916 ALOGE("%s: dlsym error %s for csd_client_init",
917 __func__, dlerror());
918 goto error;
919 } else {
920 csd->init(i2s_ext_modem);
921 }
922 }
923 return csd;
924
925error:
926 free(csd);
927 csd = NULL;
928 return csd;
929}
930
931void close_csd_client(struct csd_data *csd)
932{
933 if (csd != NULL) {
934 csd->deinit();
935 dlclose(csd->csd_client);
936 free(csd);
937 csd = NULL;
938 }
939}
940
941static void platform_csd_init(struct platform_data *my_data)
942{
943#ifdef PLATFORM_MSM8084
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700944 int32_t modems, (*count_modems)(void);
945 const char *name = "libdetectmodem.so";
946 const char *func = "count_modems";
947 const char *error;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700948
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700949 my_data->csd = NULL;
950
951 void *lib = dlopen(name, RTLD_NOW);
952 error = dlerror();
953 if (!lib) {
954 ALOGE("%s: could not find %s: %s", __func__, name, error);
955 return;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700956 }
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700957
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700958 count_modems = NULL;
959 *(void **)(&count_modems) = dlsym(lib, func);
960 error = dlerror();
961 if (!count_modems) {
962 ALOGE("%s: could not find symbol %s in %s: %s",
963 __func__, func, name, error);
964 goto done;
965 }
966
967 modems = count_modems();
968 if (modems < 0) {
969 ALOGE("%s: count_modems failed\n", __func__);
970 goto done;
971 }
972
Eric Laurent2bafff12016-03-17 12:17:23 -0700973 ALOGD("%s: num_modems %d\n", __func__, modems);
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700974 if (modems > 0)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700975 my_data->csd = open_csd_client(false /*is_i2s_ext_modem*/);
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700976
977done:
978 dlclose(lib);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700979#else
980 my_data->csd = NULL;
981#endif
982}
983
Eric Laurentc6333382015-09-14 12:43:44 -0700984static void set_platform_defaults(struct platform_data * my_data)
Haynes Mathew George98c95622014-06-20 19:14:25 -0700985{
986 int32_t dev;
987 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700988 backend_tag_table[dev] = NULL;
989 hw_interface_table[dev] = NULL;
keunhui.park2f7306a2015-07-16 16:48:06 +0900990 operator_specific_device_table[dev] = NULL;
Haynes Mathew George98c95622014-06-20 19:14:25 -0700991 }
992
David Linee3fe402017-03-13 10:00:42 -0700993 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
994 backend_bit_width_table[dev] = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
995 }
996
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700997 // To overwrite these go to the audio_platform_info.xml file.
998 backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700999 backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_NREC] = strdup("bt-sco");
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001000 backend_tag_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
1001 backend_tag_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
1002 backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
1003 backend_tag_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
1004 backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07001005 backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = strdup("bt-sco-wb");
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001006 backend_tag_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
1007 backend_tag_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
Haynes Mathew George98c95622014-06-20 19:14:25 -07001008
David Linee3fe402017-03-13 10:00:42 -07001009 backend_tag_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("usb-headset");
Haynes Mathew George9a29f372017-04-11 19:19:07 -07001010 backend_tag_table[SND_DEVICE_OUT_VOICE_USB_HEADSET] = strdup("usb-headset");
David Linee3fe402017-03-13 10:00:42 -07001011 backend_tag_table[SND_DEVICE_OUT_USB_HEADPHONES] = strdup("usb-headphones");
Haynes Mathew George9a29f372017-04-11 19:19:07 -07001012 backend_tag_table[SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = strdup("usb-headphones");
David Linee3fe402017-03-13 10:00:42 -07001013 backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] =
1014 strdup("speaker-and-usb-headphones");
1015 backend_tag_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
Haynes Mathew George9a29f372017-04-11 19:19:07 -07001016 backend_tag_table[SND_DEVICE_IN_VOICE_USB_HEADSET_MIC] = strdup("usb-headset-mic");
1017 backend_tag_table[SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC] = strdup("usb-headset-mic");
1018 backend_tag_table[SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC] = strdup("usb-headset-mic");
1019 backend_tag_table[SND_DEVICE_IN_USB_HEADSET_MIC_AEC] = strdup("usb-headset-mic");
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001020 hw_interface_table[SND_DEVICE_OUT_HANDSET] = strdup("SLIMBUS_0_RX");
1021 hw_interface_table[SND_DEVICE_OUT_SPEAKER] = strdup("SLIMBUS_0_RX");
1022 hw_interface_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = strdup("SLIMBUS_0_RX");
1023 hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE] = strdup("SLIMBUS_0_RX");
1024 hw_interface_table[SND_DEVICE_OUT_HEADPHONES] = strdup("SLIMBUS_0_RX");
1025 hw_interface_table[SND_DEVICE_OUT_LINE] = strdup("SLIMBUS_0_RX");
1026 hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = strdup("SLIMBUS_0_RX");
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -07001027 hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = strdup("SLIMBUS_0_RX");
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001028 hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_LINE] = strdup("SLIMBUS_0_RX");
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -07001029 hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = strdup("SLIMBUS_0_RX");
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001030 hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET] = strdup("SLIMBUS_0_RX");
1031 hw_interface_table[SND_DEVICE_OUT_VOICE_HAC_HANDSET] = strdup("SLIMBUS_0_RX");
1032 hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER] = strdup("SLIMBUS_0_RX");
1033 hw_interface_table[SND_DEVICE_OUT_VOICE_HEADPHONES] = strdup("SLIMBUS_0_RX");
1034 hw_interface_table[SND_DEVICE_OUT_VOICE_LINE] = strdup("SLIMBUS_0_RX");
1035 hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI_RX");
1036 hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
1037 hw_interface_table[SND_DEVICE_OUT_BT_SCO] = strdup("SEC_AUX_PCM_RX");
1038 hw_interface_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("SEC_AUX_PCM_RX");
1039 hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = strdup("SLIMBUS_0_RX");
1040 hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = strdup("SLIMBUS_0_RX");
1041 hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = strdup("SLIMBUS_0_RX");
1042 hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("SLIMBUS_0_RX");
David Linee3fe402017-03-13 10:00:42 -07001043 hw_interface_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("USB_AUDIO_RX");
Haynes Mathew George9a29f372017-04-11 19:19:07 -07001044 hw_interface_table[SND_DEVICE_OUT_VOICE_USB_HEADSET] = strdup("USB_AUDIO_RX");
David Linee3fe402017-03-13 10:00:42 -07001045 hw_interface_table[SND_DEVICE_OUT_USB_HEADPHONES] = strdup("USB_AUDIO_RX");
Haynes Mathew George9a29f372017-04-11 19:19:07 -07001046 hw_interface_table[SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = strdup("USB_AUDIO_RX");
David Linee3fe402017-03-13 10:00:42 -07001047 hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = strdup("SLIMBUS_0_RX-and-USB_AUDIO_RX");
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001048 hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
1049 hw_interface_table[SND_DEVICE_OUT_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
1050 hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
Eric Laurentc6333382015-09-14 12:43:44 -07001051
1052 my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
Haynes Mathew George98c95622014-06-20 19:14:25 -07001053}
1054
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +09001055void get_cvd_version(char *cvd_version, struct audio_device *adev)
1056{
1057 struct mixer_ctl *ctl;
1058 int count;
1059 int ret = 0;
1060
1061 ctl = mixer_get_ctl_by_name(adev->mixer, CVD_VERSION_MIXER_CTL);
1062 if (!ctl) {
1063 ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, CVD_VERSION_MIXER_CTL);
1064 goto done;
1065 }
1066 mixer_ctl_update(ctl);
1067
1068 count = mixer_ctl_get_num_values(ctl);
1069 if (count > MAX_CVD_VERSION_STRING_SIZE)
1070 count = MAX_CVD_VERSION_STRING_SIZE - 1;
1071
1072 ret = mixer_ctl_get_array(ctl, cvd_version, count);
1073 if (ret != 0) {
1074 ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
1075 goto done;
1076 }
1077
1078done:
1079 return;
1080}
1081
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -07001082static int platform_acdb_init(void *platform)
1083{
1084 struct platform_data *my_data = (struct platform_data *)platform;
1085 struct audio_device *adev = my_data->adev;
1086
1087 if (!my_data->acdb_init) {
1088 ALOGE("%s: no acdb_init fn provided", __func__);
1089 return -1;
1090 }
1091
1092 if (my_data->acdb_initialized) {
1093 ALOGW("acdb is already initialized");
1094 return 0;
1095 }
1096
Thierry Strudel92232b42017-01-26 10:51:48 -08001097#if defined (PLATFORM_MSM8994) || (PLATFORM_MSM8996) || (PLATFORM_MSM8998)
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -07001098 char *cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
1099 if (!cvd_version)
1100 ALOGE("failed to allocate cvd_version");
1101 else {
1102 get_cvd_version(cvd_version, adev);
1103 my_data->acdb_init((char *)my_data->snd_card_name, cvd_version, 0);
1104 free(cvd_version);
1105 }
1106#elif defined (PLATFORM_MSM8084)
1107 my_data->acdb_init((char *)my_data->snd_card_name);
1108#else
1109 my_data->acdb_init();
1110#endif
1111 my_data->acdb_initialized = true;
1112 return 0;
1113}
1114
David Linee3fe402017-03-13 10:00:42 -07001115static void
1116platform_backend_config_init(struct platform_data *pdata)
1117{
1118 int i;
1119
1120 /* initialize backend config */
1121 for (i = 0; i < MAX_CODEC_BACKENDS; i++) {
1122 pdata->current_backend_cfg[i].sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
1123 pdata->current_backend_cfg[i].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
1124 pdata->current_backend_cfg[i].channels = CODEC_BACKEND_DEFAULT_CHANNELS;
1125
1126 if (i > MAX_RX_CODEC_BACKENDS)
1127 pdata->current_backend_cfg[i].channels = CODEC_BACKEND_DEFAULT_TX_CHANNELS;
1128
1129 pdata->current_backend_cfg[i].bitwidth_mixer_ctl = NULL;
1130 pdata->current_backend_cfg[i].samplerate_mixer_ctl = NULL;
1131 pdata->current_backend_cfg[i].channels_mixer_ctl = NULL;
1132 }
1133
1134 pdata->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl =
1135 strdup("SLIM_0_RX Format");
1136 pdata->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl =
1137 strdup("SLIM_0_RX SampleRate");
1138
1139 pdata->current_backend_cfg[DEFAULT_CODEC_TX_BACKEND].bitwidth_mixer_ctl =
1140 strdup("SLIM_0_TX Format");
1141 pdata->current_backend_cfg[DEFAULT_CODEC_TX_BACKEND].samplerate_mixer_ctl =
1142 strdup("SLIM_0_TX SampleRate");
1143
1144 pdata->current_backend_cfg[USB_AUDIO_TX_BACKEND].bitwidth_mixer_ctl =
1145 strdup("USB_AUDIO_TX Format");
1146 pdata->current_backend_cfg[USB_AUDIO_TX_BACKEND].samplerate_mixer_ctl =
1147 strdup("USB_AUDIO_TX SampleRate");
1148 pdata->current_backend_cfg[USB_AUDIO_TX_BACKEND].channels_mixer_ctl =
1149 strdup("USB_AUDIO_TX Channels");
1150
1151 pdata->current_backend_cfg[HEADPHONE_BACKEND].bitwidth_mixer_ctl =
1152 strdup("SLIM_6_RX Format");
1153 pdata->current_backend_cfg[HEADPHONE_BACKEND].samplerate_mixer_ctl =
1154 strdup("SLIM_6_RX SampleRate");
1155
1156 pdata->current_backend_cfg[USB_AUDIO_RX_BACKEND].bitwidth_mixer_ctl =
1157 strdup("USB_AUDIO_RX Format");
1158 pdata->current_backend_cfg[USB_AUDIO_RX_BACKEND].samplerate_mixer_ctl =
1159 strdup("USB_AUDIO_RX SampleRate");
1160
1161 pdata->current_backend_cfg[USB_AUDIO_RX_BACKEND].channels = 1;
1162 pdata->current_backend_cfg[USB_AUDIO_RX_BACKEND].channels_mixer_ctl =
1163 strdup("USB_AUDIO_RX Channels");
1164}
1165
Jaekyun Seokf62e17d2017-03-08 17:15:28 +09001166// Treblized config files will be located in /odm/etc or /vendor/etc.
1167static const char *kConfigLocationList[] =
1168 {"/odm/etc", "/vendor/etc", "/system/etc"};
1169static const int kConfigLocationListSize =
1170 (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
1171
1172bool resolveConfigFile(char file_name[MIXER_PATH_MAX_LENGTH]) {
1173 char full_config_path[MIXER_PATH_MAX_LENGTH];
1174 for (int i = 0; i < kConfigLocationListSize; i++) {
1175 snprintf(full_config_path,
1176 MIXER_PATH_MAX_LENGTH,
1177 "%s/%s",
1178 kConfigLocationList[i],
1179 file_name);
1180 if (F_OK == access(full_config_path, 0)) {
1181 strcpy(file_name, full_config_path);
1182 return true;
1183 }
1184 }
1185 return false;
1186}
1187
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001188static int
1189platform_backend_app_type_cfg_init(struct platform_data *pdata,
1190 struct mixer *mixer)
1191{
1192 size_t app_type_cfg[128] = {0};
1193 int length, num_app_types = 0;
1194 struct mixer_ctl *ctl = NULL;
1195
1196 const char *mixer_ctl_name = "App Type Config";
1197 ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
1198 if (!ctl) {
1199 ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
1200 return -1;
1201 }
1202
1203 length = 1; // reserve index 0 for number of app types
1204
1205 struct listnode *node;
1206 struct app_type_entry *entry;
1207 list_for_each(node, &app_type_entry_list) {
1208 entry = node_to_item(node, struct app_type_entry, node);
1209 app_type_cfg[length++] = entry->app_type;
1210 app_type_cfg[length++] = entry->max_rate;
1211 app_type_cfg[length++] = entry->bit_width;
1212 ALOGI("%s add entry %d %d", __func__, entry->app_type, entry->bit_width);
1213 num_app_types += 1;
1214 }
1215
1216 // default for capture
1217 int t;
1218 platform_get_default_app_type_v2(pdata,
1219 PCM_CAPTURE,
1220 &t);
1221 app_type_cfg[length++] = t;
1222 app_type_cfg[length++] = 48000;
1223 app_type_cfg[length++] = 16;
1224 num_app_types += 1;
1225
1226 if (num_app_types) {
1227 app_type_cfg[0] = num_app_types;
1228 if (mixer_ctl_set_array(ctl, app_type_cfg, length) < 0) {
1229 ALOGE("Failed to set app type cfg");
1230 }
1231 }
1232 return 0;
1233}
1234
Eric Laurentb23d5282013-05-14 15:27:20 -07001235void *platform_init(struct audio_device *adev)
1236{
1237 char value[PROPERTY_VALUE_MAX];
vivek mehta60ea4152016-02-18 17:10:26 -08001238 struct platform_data *my_data = NULL;
1239 int retry_num = 0, snd_card_num = 0, key = 0, ret = 0;
1240 bool dual_mic_config = false, use_default_mixer_path = true;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001241 const char *snd_card_name;
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +09001242 char *cvd_version = NULL;
vivek mehta60ea4152016-02-18 17:10:26 -08001243 char *snd_internal_name = NULL;
1244 char *tmp = NULL;
1245 char mixer_xml_file[MIXER_PATH_MAX_LENGTH]= {0};
vivek mehtade4849c2016-03-03 17:23:38 -08001246 char platform_info_file[MIXER_PATH_MAX_LENGTH]= {0};
1247 struct snd_card_split *snd_split_handle = NULL;
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001248 my_data = calloc(1, sizeof(struct platform_data));
1249
1250 my_data->adev = adev;
1251
keunhui.park2f7306a2015-07-16 16:48:06 +09001252 list_init(&operator_info_list);
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001253 list_init(&app_type_entry_list);
keunhui.park2f7306a2015-07-16 16:48:06 +09001254
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001255 set_platform_defaults(my_data);
vivek mehta2b0e5a62016-09-02 17:31:58 -07001256 bool card_verifed[MAX_SND_CARD] = {0};
1257 const int retry_limit = property_get_int32("audio.snd_card.open.retries", RETRY_NUMBER);
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001258
vivek mehta2b0e5a62016-09-02 17:31:58 -07001259 for (;;) {
1260 if (snd_card_num >= MAX_SND_CARD) {
1261 if (retry_num++ >= retry_limit) {
1262 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
1263 goto init_failed;
1264 }
sangwoo1b9f4b32013-06-21 18:22:55 -07001265
vivek mehta2b0e5a62016-09-02 17:31:58 -07001266 snd_card_num = 0;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001267 usleep(RETRY_US);
vivek mehta2b0e5a62016-09-02 17:31:58 -07001268 continue;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001269 }
1270
vivek mehta2b0e5a62016-09-02 17:31:58 -07001271 if (card_verifed[snd_card_num]) {
1272 ++snd_card_num;
1273 continue;
1274 }
1275
1276 adev->mixer = mixer_open(snd_card_num);
1277
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001278 if (!adev->mixer) {
1279 ALOGE("%s: Unable to open the mixer card: %d", __func__,
vivek mehta2b0e5a62016-09-02 17:31:58 -07001280 snd_card_num);
1281 ++snd_card_num;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001282 continue;
1283 }
1284
vivek mehta2b0e5a62016-09-02 17:31:58 -07001285 card_verifed[snd_card_num] = true;
1286
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001287 snd_card_name = mixer_get_name(adev->mixer);
vivek mehtade4849c2016-03-03 17:23:38 -08001288 my_data->hw_info = hw_info_init(snd_card_name);
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001289
vivek mehtade4849c2016-03-03 17:23:38 -08001290 audio_extn_set_snd_card_split(snd_card_name);
1291 snd_split_handle = audio_extn_get_snd_card_split();
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001292
vivek mehtade4849c2016-03-03 17:23:38 -08001293 /* Get the codec internal name from the sound card and/or form factor
1294 * name and form the mixer paths and platfor info file name dynamically.
1295 * This is generic way of picking any codec and forma factor name based
1296 * mixer and platform info files in future with no code change.
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001297
vivek mehtade4849c2016-03-03 17:23:38 -08001298 * current code extends and looks for any of the exteneded mixer path and
1299 * platform info file present based on codec and form factor.
vivek mehta60ea4152016-02-18 17:10:26 -08001300
vivek mehtade4849c2016-03-03 17:23:38 -08001301 * order of picking appropriate file is
1302 * <i> mixer_paths_<codec_name>_<form_factor>.xml, if file not present
1303 * <ii> mixer_paths_<codec_name>.xml, if file not present
1304 * <iii> mixer_paths.xml
1305
1306 * same order is followed for audio_platform_info.xml as well
1307 */
1308
1309 // need to carryforward old file name
1310 if (!strncmp(snd_card_name, TOMTOM_8226_SND_CARD_NAME,
Eric Laurentf9583c32016-03-28 13:50:50 -07001311 min(strlen(TOMTOM_8226_SND_CARD_NAME), strlen(snd_card_name)))) {
vivek mehtade4849c2016-03-03 17:23:38 -08001312 snprintf(mixer_xml_file, sizeof(mixer_xml_file), "%s_%s.xml",
vivek mehta60ea4152016-02-18 17:10:26 -08001313 MIXER_XML_BASE_STRING, TOMTOM_MIXER_FILE_SUFFIX );
vivek mehtade4849c2016-03-03 17:23:38 -08001314 } else {
Ed Tamb0b0d572016-03-21 10:45:37 -07001315
vivek mehtade4849c2016-03-03 17:23:38 -08001316 snprintf(mixer_xml_file, sizeof(mixer_xml_file), "%s_%s_%s.xml",
1317 MIXER_XML_BASE_STRING, snd_split_handle->snd_card,
1318 snd_split_handle->form_factor);
Jaekyun Seokf62e17d2017-03-08 17:15:28 +09001319 if (!resolveConfigFile(mixer_xml_file)) {
vivek mehtade4849c2016-03-03 17:23:38 -08001320 memset(mixer_xml_file, 0, sizeof(mixer_xml_file));
1321 snprintf(mixer_xml_file, sizeof(mixer_xml_file), "%s_%s.xml",
1322 MIXER_XML_BASE_STRING, snd_split_handle->snd_card);
1323
Jaekyun Seokf62e17d2017-03-08 17:15:28 +09001324 if (!resolveConfigFile(mixer_xml_file)) {
vivek mehtade4849c2016-03-03 17:23:38 -08001325 memset(mixer_xml_file, 0, sizeof(mixer_xml_file));
1326 strlcpy(mixer_xml_file, MIXER_XML_DEFAULT_PATH, MIXER_PATH_MAX_LENGTH);
Jaekyun Seokf62e17d2017-03-08 17:15:28 +09001327 resolveConfigFile(mixer_xml_file);
vivek mehtade4849c2016-03-03 17:23:38 -08001328 }
1329 }
1330
1331 snprintf(platform_info_file, sizeof(platform_info_file), "%s_%s_%s.xml",
1332 PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card,
1333 snd_split_handle->form_factor);
1334
Jaekyun Seokf62e17d2017-03-08 17:15:28 +09001335 if (!resolveConfigFile(platform_info_file)) {
vivek mehtade4849c2016-03-03 17:23:38 -08001336 memset(platform_info_file, 0, sizeof(platform_info_file));
1337 snprintf(platform_info_file, sizeof(platform_info_file), "%s_%s.xml",
1338 PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card);
1339
Jaekyun Seokf62e17d2017-03-08 17:15:28 +09001340 if (!resolveConfigFile(platform_info_file)) {
vivek mehtade4849c2016-03-03 17:23:38 -08001341 memset(platform_info_file, 0, sizeof(platform_info_file));
1342 strlcpy(platform_info_file, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH);
Jaekyun Seokf62e17d2017-03-08 17:15:28 +09001343 resolveConfigFile(platform_info_file);
vivek mehta60ea4152016-02-18 17:10:26 -08001344 }
1345 }
Uday Kishore Pasupuleti11dd2232015-06-24 14:18:01 -07001346 }
1347
vivek mehtade4849c2016-03-03 17:23:38 -08001348 /* Initialize platform specific ids and/or backends*/
1349 platform_info_init(platform_info_file, my_data);
1350
1351 /* validate the sound card name
1352 * my_data->snd_card_name can contain
1353 * <a> complete sound card name, i.e. <device>-<codec>-<form_factor>-snd-card
1354 * example: msm8994-tomtom-mtp-snd-card
1355 * <b> or sub string of the card name, i.e. <device>-<codec>
1356 * example: msm8994-tomtom
Eric Laurentf9583c32016-03-28 13:50:50 -07001357 * snd_card_name is truncated to 32 charaters as per mixer_get_name() implementation
1358 * so use min of my_data->snd_card_name and snd_card_name length for comparison
vivek mehtade4849c2016-03-03 17:23:38 -08001359 */
1360
1361 if (my_data->snd_card_name != NULL &&
Eric Laurentf9583c32016-03-28 13:50:50 -07001362 strncmp(snd_card_name, my_data->snd_card_name,
1363 min(strlen(snd_card_name), strlen(my_data->snd_card_name))) != 0) {
vivek mehtade4849c2016-03-03 17:23:38 -08001364 ALOGI("%s: found valid sound card %s, but not primary sound card %s",
1365 __func__, snd_card_name, my_data->snd_card_name);
vivek mehta2b0e5a62016-09-02 17:31:58 -07001366 ++snd_card_num;
1367 mixer_close(adev->mixer);
1368 adev->mixer = NULL;
vivek mehtade4849c2016-03-03 17:23:38 -08001369 hw_info_deinit(my_data->hw_info);
1370 my_data->hw_info = NULL;
1371 continue;
Ed Tam70b5c142016-03-21 19:14:29 -07001372 }
vivek mehtade4849c2016-03-03 17:23:38 -08001373 ALOGI("%s: found sound card %s, primary sound card expeted is %s",
1374 __func__, snd_card_name, my_data->snd_card_name);
vivek mehta60ea4152016-02-18 17:10:26 -08001375
1376 ALOGD("%s: Loading mixer file: %s", __func__, mixer_xml_file);
1377 adev->audio_route = audio_route_init(snd_card_num, mixer_xml_file);
1378
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001379 if (!adev->audio_route) {
1380 ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
vivek mehta2b0e5a62016-09-02 17:31:58 -07001381 mixer_close(adev->mixer);
1382 adev->mixer = NULL;
1383 hw_info_deinit(my_data->hw_info);
1384 my_data->hw_info = NULL;
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001385 goto init_failed;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001386 }
1387 adev->snd_card = snd_card_num;
Eric Laurent2bafff12016-03-17 12:17:23 -07001388 ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001389 break;
sangwoo1b9f4b32013-06-21 18:22:55 -07001390 }
1391
keunhui.parkc5aaa0e2015-07-13 10:57:37 +09001392 //set max volume step for voice call
1393 property_get("ro.config.vc_call_vol_steps", value, TOSTRING(MAX_VOL_INDEX));
1394 my_data->max_vol_index = atoi(value);
1395
vivek mehta65ad12d2015-08-13 18:32:48 -07001396 property_get("persist.audio.dualmic.config",value,"");
1397 if (!strcmp("endfire", value)) {
1398 dual_mic_config = true;
1399 }
1400
Prashant Malanic92c5962015-08-11 15:10:18 -07001401 my_data->source_mic_type = SOURCE_DUAL_MIC;
1402
Eric Laurentb23d5282013-05-14 15:27:20 -07001403 my_data->fluence_in_spkr_mode = false;
1404 my_data->fluence_in_voice_call = false;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001405 my_data->fluence_in_voice_comm = false;
Eric Laurentb23d5282013-05-14 15:27:20 -07001406 my_data->fluence_in_voice_rec = false;
1407
vivek mehta65ad12d2015-08-13 18:32:48 -07001408 property_get("ro.qc.sdk.audio.fluencetype", value, "none");
Prashant Malanic92c5962015-08-11 15:10:18 -07001409 if (!strcmp("fluencepro", value)) {
1410 my_data->fluence_type = FLUENCE_PRO_ENABLE;
vivek mehta65ad12d2015-08-13 18:32:48 -07001411 } else if (!strcmp("fluence", value) || (dual_mic_config)) {
Prashant Malanic92c5962015-08-11 15:10:18 -07001412 my_data->fluence_type = FLUENCE_ENABLE;
1413 } else if (!strcmp("none", value)) {
1414 my_data->fluence_type = FLUENCE_DISABLE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001415 }
1416
Prashant Malanic92c5962015-08-11 15:10:18 -07001417 if (my_data->fluence_type != FLUENCE_DISABLE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001418 property_get("persist.audio.fluence.voicecall",value,"");
1419 if (!strcmp("true", value)) {
1420 my_data->fluence_in_voice_call = true;
1421 }
1422
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001423 property_get("persist.audio.fluence.voicecomm",value,"");
1424 if (!strcmp("true", value)) {
1425 my_data->fluence_in_voice_comm = true;
1426 }
1427
Eric Laurentb23d5282013-05-14 15:27:20 -07001428 property_get("persist.audio.fluence.voicerec",value,"");
1429 if (!strcmp("true", value)) {
1430 my_data->fluence_in_voice_rec = true;
1431 }
1432
1433 property_get("persist.audio.fluence.speaker",value,"");
1434 if (!strcmp("true", value)) {
1435 my_data->fluence_in_spkr_mode = true;
1436 }
1437 }
1438
Prashant Malanic92c5962015-08-11 15:10:18 -07001439 // support max to mono, example if max count is 3, usecase supports Three, dual and mono mic
1440 switch (my_data->max_mic_count) {
1441 case 4:
1442 my_data->source_mic_type |= SOURCE_QUAD_MIC;
1443 case 3:
1444 my_data->source_mic_type |= SOURCE_THREE_MIC;
1445 case 2:
1446 my_data->source_mic_type |= SOURCE_DUAL_MIC;
1447 case 1:
1448 my_data->source_mic_type |= SOURCE_MONO_MIC;
1449 break;
1450 default:
1451 ALOGE("%s: max_mic_count (%d), is not supported, setting to default",
1452 __func__, my_data->max_mic_count);
1453 my_data->source_mic_type = SOURCE_MONO_MIC|SOURCE_DUAL_MIC;
1454 break;
1455 }
1456
1457 ALOGV("%s: Fluence_Type(%d) max_mic_count(%d) mic_type(0x%x) fluence_in_voice_call(%d)"
1458 " fluence_in_voice_comm(%d) fluence_in_voice_rec(%d) fluence_in_spkr_mode(%d) ",
1459 __func__, my_data->fluence_type, my_data->max_mic_count, my_data->source_mic_type,
1460 my_data->fluence_in_voice_call, my_data->fluence_in_voice_comm,
1461 my_data->fluence_in_voice_rec, my_data->fluence_in_spkr_mode);
1462
Eric Laurentb23d5282013-05-14 15:27:20 -07001463 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
1464 if (my_data->acdb_handle == NULL) {
1465 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
1466 } else {
1467 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
1468 my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
1469 "acdb_loader_deallocate_ACDB");
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001470 if (!my_data->acdb_deallocate)
1471 ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
1472 __func__, LIB_ACDB_LOADER);
1473
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001474 my_data->acdb_send_audio_cal_v3 = (acdb_send_audio_cal_v3_t)dlsym(my_data->acdb_handle,
1475 "acdb_loader_send_audio_cal_v3");
1476 if (!my_data->acdb_send_audio_cal_v3)
1477 ALOGE("%s: Could not find the symbol acdb_send_audio_cal_v3 from %s",
1478 __func__, LIB_ACDB_LOADER);
1479
Eric Laurentb23d5282013-05-14 15:27:20 -07001480 my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
1481 "acdb_loader_send_audio_cal");
1482 if (!my_data->acdb_send_audio_cal)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001483 ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
Eric Laurentb23d5282013-05-14 15:27:20 -07001484 __func__, LIB_ACDB_LOADER);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001485
Eric Laurentb23d5282013-05-14 15:27:20 -07001486 my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
1487 "acdb_loader_send_voice_cal");
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001488 if (!my_data->acdb_send_voice_cal)
1489 ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
1490 __func__, LIB_ACDB_LOADER);
1491
1492 my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
1493 "acdb_loader_reload_vocvoltable");
1494 if (!my_data->acdb_reload_vocvoltable)
1495 ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
1496 __func__, LIB_ACDB_LOADER);
vivek mehta1a9b7c02015-06-25 11:49:38 -07001497
1498 my_data->acdb_send_gain_dep_cal = (acdb_send_gain_dep_cal_t)dlsym(my_data->acdb_handle,
1499 "acdb_loader_send_gain_dep_cal");
1500 if (!my_data->acdb_send_gain_dep_cal)
1501 ALOGV("%s: Could not find the symbol acdb_loader_send_gain_dep_cal from %s",
1502 __func__, LIB_ACDB_LOADER);
1503
Thierry Strudel92232b42017-01-26 10:51:48 -08001504#if defined (PLATFORM_MSM8994) || (PLATFORM_MSM8996) || (PLATFORM_MSM8998)
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +09001505 acdb_init_v2_cvd_t acdb_init;
1506 acdb_init = (acdb_init_v2_cvd_t)dlsym(my_data->acdb_handle,
1507 "acdb_loader_init_v2");
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -07001508 if (acdb_init == NULL)
1509 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__,
1510 dlerror());
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +09001511
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +09001512#elif defined (PLATFORM_MSM8084)
1513 acdb_init_v2_t acdb_init;
1514 acdb_init = (acdb_init_v2_t)dlsym(my_data->acdb_handle,
1515 "acdb_loader_init_v2");
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -07001516 if (acdb_init == NULL)
1517 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__,
1518 dlerror());
1519
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001520#else
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +09001521 acdb_init_t acdb_init;
1522 acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
Eric Laurentb23d5282013-05-14 15:27:20 -07001523 "acdb_loader_init_ACDB");
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +09001524 if (acdb_init == NULL)
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -07001525 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__,
1526 dlerror());
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001527#endif
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -07001528 my_data->acdb_init = acdb_init;
Eric Laurentb23d5282013-05-14 15:27:20 -07001529
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -07001530 my_data->acdb_send_custom_top = (acdb_send_custom_top_t)
1531 dlsym(my_data->acdb_handle,
1532 "acdb_loader_send_common_custom_topology");
1533
1534 if (!my_data->acdb_send_custom_top)
1535 ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
1536 __func__, LIB_ACDB_LOADER);
1537
1538 platform_acdb_init(my_data);
1539 }
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +09001540
David Linee3fe402017-03-13 10:00:42 -07001541 /* init usb */
1542 audio_extn_usb_init(adev);
1543
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001544 audio_extn_spkr_prot_init(adev);
Haynes Mathew George98c95622014-06-20 19:14:25 -07001545
Ravi Kumar Alamanda76315572015-04-23 13:13:56 -07001546 audio_extn_hwdep_cal_send(adev->snd_card, my_data->acdb_handle);
1547
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001548 /* load csd client */
1549 platform_csd_init(my_data);
1550
David Linee3fe402017-03-13 10:00:42 -07001551 platform_backend_config_init(my_data);
1552
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001553 init_be_dai_name_table(adev);
1554
1555 if (platform_supports_app_type_cfg())
1556 platform_backend_app_type_cfg_init(my_data, adev->mixer);
1557
Eric Laurentb23d5282013-05-14 15:27:20 -07001558 return my_data;
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001559
1560init_failed:
1561 if (my_data)
1562 free(my_data);
1563 return NULL;
Eric Laurentb23d5282013-05-14 15:27:20 -07001564}
1565
1566void platform_deinit(void *platform)
1567{
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001568 int32_t dev;
keunhui.park2f7306a2015-07-16 16:48:06 +09001569 struct operator_info *info_item;
1570 struct operator_specific_device *device_item;
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001571 struct app_type_entry *ap;
keunhui.park2f7306a2015-07-16 16:48:06 +09001572 struct listnode *node;
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001573
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001574 struct platform_data *my_data = (struct platform_data *)platform;
1575 close_csd_client(my_data->csd);
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001576
vivek mehtade4849c2016-03-03 17:23:38 -08001577 hw_info_deinit(my_data->hw_info);
1578
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001579 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
1580 if (backend_tag_table[dev])
1581 free(backend_tag_table[dev]);
1582 if (hw_interface_table[dev])
1583 free(hw_interface_table[dev]);
keunhui.park2f7306a2015-07-16 16:48:06 +09001584 if (operator_specific_device_table[dev]) {
1585 while (!list_empty(operator_specific_device_table[dev])) {
1586 node = list_head(operator_specific_device_table[dev]);
1587 list_remove(node);
1588 device_item = node_to_item(node, struct operator_specific_device, list);
1589 free(device_item->operator);
1590 free(device_item->mixer_path);
1591 free(device_item);
1592 }
1593 free(operator_specific_device_table[dev]);
1594 }
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07001595 }
1596
1597 if (my_data->snd_card_name)
1598 free(my_data->snd_card_name);
1599
keunhui.park2f7306a2015-07-16 16:48:06 +09001600 while (!list_empty(&operator_info_list)) {
1601 node = list_head(&operator_info_list);
1602 list_remove(node);
1603 info_item = node_to_item(node, struct operator_info, list);
1604 free(info_item->name);
1605 free(info_item->mccmnc);
1606 free(info_item);
1607 }
1608
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001609 while (!list_empty(&app_type_entry_list)) {
1610 node = list_head(&app_type_entry_list);
1611 list_remove(node);
1612 ap = node_to_item(node, struct app_type_entry, node);
1613 free(ap);
1614 }
1615
Kevin Rocarde35d4af2017-05-02 16:55:28 -07001616 mixer_close(my_data->adev->mixer);
Eric Laurentb23d5282013-05-14 15:27:20 -07001617 free(platform);
David Linee3fe402017-03-13 10:00:42 -07001618
1619 /* deinit usb */
1620 audio_extn_usb_deinit();
Eric Laurentb23d5282013-05-14 15:27:20 -07001621}
1622
1623const char *platform_get_snd_device_name(snd_device_t snd_device)
1624{
keunhui.park2f7306a2015-07-16 16:48:06 +09001625 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
1626 if (operator_specific_device_table[snd_device] != NULL) {
1627 return get_operator_specific_device_mixer_path(snd_device);
1628 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001629 return device_table[snd_device];
keunhui.park2f7306a2015-07-16 16:48:06 +09001630 } else
Ravi Kumar Alamanda64026462014-09-15 00:08:58 -07001631 return "none";
Eric Laurentb23d5282013-05-14 15:27:20 -07001632}
1633
vivek mehtade4849c2016-03-03 17:23:38 -08001634int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
1635 char *device_name)
1636{
1637 struct platform_data *my_data = (struct platform_data *)platform;
1638
David Benjamin1565f992016-09-21 12:10:34 -04001639 if (platform == NULL) {
vivek mehtade4849c2016-03-03 17:23:38 -08001640 ALOGW("%s: something wrong, use legacy get_snd_device name", __func__);
David Benjamin1565f992016-09-21 12:10:34 -04001641 strlcpy(device_name, platform_get_snd_device_name(snd_device),
1642 DEVICE_NAME_MAX_SIZE);
vivek mehtade4849c2016-03-03 17:23:38 -08001643 } else if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
1644 if (operator_specific_device_table[snd_device] != NULL) {
1645 strlcpy(device_name, get_operator_specific_device_mixer_path(snd_device),
1646 DEVICE_NAME_MAX_SIZE);
1647 } else {
1648 strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
1649 }
1650 hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
1651 } else {
1652 strlcpy(device_name, "none", DEVICE_NAME_MAX_SIZE);
1653 }
1654
1655 return 0;
1656}
1657
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -05001658void platform_add_backend_name(void *platform, char *mixer_path,
1659 snd_device_t snd_device)
Eric Laurentb23d5282013-05-14 15:27:20 -07001660{
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -05001661 struct platform_data *my_data = (struct platform_data *)platform;
1662
Haynes Mathew George98c95622014-06-20 19:14:25 -07001663 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1664 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1665 return;
Ravi Kumar Alamanda1de6e5a2014-06-19 21:55:39 -05001666 }
Haynes Mathew George98c95622014-06-20 19:14:25 -07001667
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001668 const char * suffix = backend_tag_table[snd_device];
Haynes Mathew George98c95622014-06-20 19:14:25 -07001669
1670 if (suffix != NULL) {
1671 strcat(mixer_path, " ");
1672 strcat(mixer_path, suffix);
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -05001673 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001674}
1675
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001676bool platform_check_backends_match(snd_device_t snd_device1, snd_device_t snd_device2)
1677{
1678 bool result = true;
1679
1680 ALOGV("%s: snd_device1 = %s, snd_device2 = %s", __func__,
1681 platform_get_snd_device_name(snd_device1),
1682 platform_get_snd_device_name(snd_device2));
1683
1684 if ((snd_device1 < SND_DEVICE_MIN) || (snd_device1 >= SND_DEVICE_MAX)) {
1685 ALOGE("%s: Invalid snd_device = %s", __func__,
1686 platform_get_snd_device_name(snd_device1));
1687 return false;
1688 }
1689 if ((snd_device2 < SND_DEVICE_MIN) || (snd_device2 >= SND_DEVICE_MAX)) {
1690 ALOGE("%s: Invalid snd_device = %s", __func__,
1691 platform_get_snd_device_name(snd_device2));
1692 return false;
1693 }
1694 const char * be_itf1 = hw_interface_table[snd_device1];
1695 const char * be_itf2 = hw_interface_table[snd_device2];
1696
1697 if (NULL != be_itf1 && NULL != be_itf2) {
Eric Laurente63e61d2015-09-10 12:19:33 -07001698 if ((NULL == strstr(be_itf2, be_itf1)) && (NULL == strstr(be_itf1, be_itf2)))
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001699 result = false;
1700 }
1701
1702 ALOGV("%s: be_itf1 = %s, be_itf2 = %s, match %d", __func__, be_itf1, be_itf2, result);
1703 return result;
1704}
1705
Eric Laurentb23d5282013-05-14 15:27:20 -07001706int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
1707{
1708 int device_id;
1709 if (device_type == PCM_PLAYBACK)
1710 device_id = pcm_device_table[usecase][0];
1711 else
1712 device_id = pcm_device_table[usecase][1];
1713 return device_id;
1714}
1715
Haynes Mathew George98c95622014-06-20 19:14:25 -07001716static int find_index(const struct name_to_index * table, int32_t len,
1717 const char * name)
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001718{
1719 int ret = 0;
Haynes Mathew George98c95622014-06-20 19:14:25 -07001720 int32_t i;
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001721
Haynes Mathew George98c95622014-06-20 19:14:25 -07001722 if (table == NULL) {
1723 ALOGE("%s: table is NULL", __func__);
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001724 ret = -ENODEV;
1725 goto done;
1726 }
1727
Haynes Mathew George98c95622014-06-20 19:14:25 -07001728 if (name == NULL) {
1729 ALOGE("null key");
1730 ret = -ENODEV;
1731 goto done;
1732 }
1733
1734 for (i=0; i < len; i++) {
1735 if (!strcmp(table[i].name, name)) {
1736 ret = table[i].index;
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001737 goto done;
1738 }
1739 }
Haynes Mathew George98c95622014-06-20 19:14:25 -07001740 ALOGE("%s: Could not find index for name = %s",
1741 __func__, name);
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001742 ret = -ENODEV;
1743done:
1744 return ret;
1745}
1746
Haynes Mathew George98c95622014-06-20 19:14:25 -07001747int platform_get_snd_device_index(char *device_name)
1748{
1749 return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
1750}
1751
1752int platform_get_usecase_index(const char *usecase_name)
1753{
1754 return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
1755}
1756
keunhui.park2f7306a2015-07-16 16:48:06 +09001757void platform_add_operator_specific_device(snd_device_t snd_device,
1758 const char *operator,
1759 const char *mixer_path,
1760 unsigned int acdb_id)
1761{
1762 struct operator_specific_device *device;
1763
1764 if (operator_specific_device_table[snd_device] == NULL) {
1765 operator_specific_device_table[snd_device] =
1766 (struct listnode *)calloc(1, sizeof(struct listnode));
1767 list_init(operator_specific_device_table[snd_device]);
1768 }
1769
1770 device = (struct operator_specific_device *)calloc(1, sizeof(struct operator_specific_device));
1771
1772 device->operator = strdup(operator);
1773 device->mixer_path = strdup(mixer_path);
1774 device->acdb_id = acdb_id;
1775
1776 list_add_tail(operator_specific_device_table[snd_device], &device->list);
1777
Eric Laurent2bafff12016-03-17 12:17:23 -07001778 ALOGD("%s: device[%s] -> operator[%s] mixer_path[%s] acdb_id[%d]", __func__,
keunhui.park2f7306a2015-07-16 16:48:06 +09001779 platform_get_snd_device_name(snd_device), operator, mixer_path, acdb_id);
1780
1781}
1782
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001783int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
1784{
1785 int ret = 0;
1786
1787 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1788 ALOGE("%s: Invalid snd_device = %d",
1789 __func__, snd_device);
1790 ret = -EINVAL;
1791 goto done;
1792 }
1793
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001794 ALOGV("%s: acdb_device_table[%s]: old = %d new = %d", __func__,
1795 platform_get_snd_device_name(snd_device), acdb_device_table[snd_device], acdb_id);
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001796 acdb_device_table[snd_device] = acdb_id;
1797done:
1798 return ret;
1799}
1800
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001801int platform_get_snd_device_acdb_id(snd_device_t snd_device)
1802{
1803 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1804 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1805 return -EINVAL;
1806 }
keunhui.park2f7306a2015-07-16 16:48:06 +09001807
1808 if (operator_specific_device_table[snd_device] != NULL)
1809 return get_operator_specific_device_acdb_id(snd_device);
1810 else
1811 return acdb_device_table[snd_device];
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001812}
1813
David Linee3fe402017-03-13 10:00:42 -07001814static int platform_get_backend_index(snd_device_t snd_device)
1815{
1816 int32_t port = DEFAULT_CODEC_BACKEND;
1817
1818 if (snd_device >= SND_DEVICE_OUT_BEGIN && snd_device < SND_DEVICE_OUT_END) {
1819 if (backend_tag_table[snd_device] != NULL) {
1820 if (strncmp(backend_tag_table[snd_device], "headphones",
1821 sizeof("headphones")) == 0)
1822 port = HEADPHONE_BACKEND;
1823 else if (strcmp(backend_tag_table[snd_device], "hdmi") == 0)
1824 port = HDMI_RX_BACKEND;
1825 else if ((strcmp(backend_tag_table[snd_device], "usb-headphones") == 0) ||
1826 (strcmp(backend_tag_table[snd_device], "usb-headset") == 0))
1827 port = USB_AUDIO_RX_BACKEND;
1828 }
1829 } else if (snd_device >= SND_DEVICE_IN_BEGIN && snd_device < SND_DEVICE_IN_END) {
1830 port = DEFAULT_CODEC_TX_BACKEND;
1831 if (backend_tag_table[snd_device] != NULL) {
1832 if (strcmp(backend_tag_table[snd_device], "usb-headset-mic") == 0)
1833 port = USB_AUDIO_TX_BACKEND;
1834 else if (strstr(backend_tag_table[snd_device], "bt-sco") != NULL)
1835 port = BT_SCO_TX_BACKEND;
1836 }
1837 } else {
1838 ALOGW("%s:napb: Invalid device - %d ", __func__, snd_device);
1839 }
1840
1841 ALOGV("%s:napb: backend port - %d device - %d ", __func__, port, snd_device);
1842
1843 return port;
1844}
1845
Eric Laurentb23d5282013-05-14 15:27:20 -07001846int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
1847{
1848 struct platform_data *my_data = (struct platform_data *)platform;
1849 int acdb_dev_id, acdb_dev_type;
1850
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001851 if (platform_supports_app_type_cfg()) // use v2 instead
1852 return -ENOSYS;
1853
Ravi Kumar Alamandaadf0f3b2015-06-04 02:34:02 -07001854 acdb_dev_id = acdb_device_table[audio_extn_get_spkr_prot_snd_device(snd_device)];
Eric Laurentb23d5282013-05-14 15:27:20 -07001855 if (acdb_dev_id < 0) {
1856 ALOGE("%s: Could not find acdb id for device(%d)",
1857 __func__, snd_device);
1858 return -EINVAL;
1859 }
1860 if (my_data->acdb_send_audio_cal) {
Joe Onorato188b6222016-03-01 11:02:27 -08001861 ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
Eric Laurentb23d5282013-05-14 15:27:20 -07001862 __func__, snd_device, acdb_dev_id);
1863 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
1864 snd_device < SND_DEVICE_OUT_END)
1865 acdb_dev_type = ACDB_DEV_TYPE_OUT;
1866 else
1867 acdb_dev_type = ACDB_DEV_TYPE_IN;
1868 my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
1869 }
1870 return 0;
1871}
1872
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001873int platform_send_audio_calibration_v2(void *platform, struct audio_usecase *usecase,
1874 int app_type, int sample_rate)
1875{
1876 struct platform_data *my_data = (struct platform_data *)platform;
1877 int acdb_dev_id, acdb_dev_type;
1878 int snd_device = SND_DEVICE_OUT_SPEAKER;
1879 int new_snd_device[SND_DEVICE_OUT_END] = {0};
1880 int i, num_devices = 1;
1881
1882 if (!platform_supports_app_type_cfg()) // use v1 instead
1883 return -ENOSYS;
1884
1885 if (usecase->type == PCM_PLAYBACK)
1886 snd_device = usecase->out_snd_device;
1887 else if (usecase->type == PCM_CAPTURE)
1888 snd_device = usecase->in_snd_device;
1889
1890 // skipped over get_spkr_prot_device
1891 acdb_dev_id = acdb_device_table[snd_device];
1892 if (acdb_dev_id < 0) {
1893 ALOGE("%s: Could not find acdb id for device(%d)",
1894 __func__, snd_device);
1895 return -EINVAL;
1896 }
1897
1898 if (platform_can_split_snd_device(snd_device,
1899 &num_devices, new_snd_device) < 0) {
1900 new_snd_device[0] = snd_device;
1901 }
1902
1903 for (i = 0; i < num_devices; i++) {
1904 acdb_dev_id = acdb_device_table[new_snd_device[i]];
1905 if (acdb_dev_id < 0) {
1906 ALOGE("%s: Could not find acdb id for device(%d)",
1907 __func__, new_snd_device[i]);
1908 return -EINVAL;
1909 }
1910 ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
1911 __func__, new_snd_device[i], acdb_dev_id);
1912 if (new_snd_device[i] >= SND_DEVICE_OUT_BEGIN &&
1913 new_snd_device[i] < SND_DEVICE_OUT_END)
1914 acdb_dev_type = ACDB_DEV_TYPE_OUT;
1915 else
1916 acdb_dev_type = ACDB_DEV_TYPE_IN;
1917
1918 if (my_data->acdb_send_audio_cal_v3) {
1919 my_data->acdb_send_audio_cal_v3(acdb_dev_id, acdb_dev_type,
1920 app_type, sample_rate, i);
1921 } else if (my_data->acdb_send_audio_cal) {
1922 my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type); // this version differs from internal
1923 }
1924 }
1925
1926 return 0;
1927}
1928
1929
Eric Laurentb23d5282013-05-14 15:27:20 -07001930int platform_switch_voice_call_device_pre(void *platform)
1931{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001932 struct platform_data *my_data = (struct platform_data *)platform;
1933 int ret = 0;
1934
1935 if (my_data->csd != NULL &&
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001936 voice_is_in_call(my_data->adev)) {
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001937 /* This must be called before disabling mixer controls on APQ side */
1938 ret = my_data->csd->disable_device();
1939 if (ret < 0) {
1940 ALOGE("%s: csd_client_disable_device, failed, error %d",
1941 __func__, ret);
1942 }
1943 }
1944 return ret;
1945}
1946
1947int platform_switch_voice_call_enable_device_config(void *platform,
1948 snd_device_t out_snd_device,
1949 snd_device_t in_snd_device)
1950{
1951 struct platform_data *my_data = (struct platform_data *)platform;
1952 int acdb_rx_id, acdb_tx_id;
1953 int ret = 0;
1954
1955 if (my_data->csd == NULL)
1956 return ret;
1957
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001958 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1959 audio_extn_spkr_prot_is_enabled())
keunhui.park2f7306a2015-07-16 16:48:06 +09001960 acdb_rx_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_SPEAKER_PROTECTED);
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001961 else
keunhui.park2f7306a2015-07-16 16:48:06 +09001962 acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001963
keunhui.park2f7306a2015-07-16 16:48:06 +09001964 acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001965
1966 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1967 ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
1968 if (ret < 0) {
1969 ALOGE("%s: csd_enable_device_config, failed, error %d",
1970 __func__, ret);
1971 }
1972 } else {
1973 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1974 acdb_rx_id, acdb_tx_id);
1975 }
1976
1977 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001978}
1979
1980int platform_switch_voice_call_device_post(void *platform,
1981 snd_device_t out_snd_device,
1982 snd_device_t in_snd_device)
1983{
1984 struct platform_data *my_data = (struct platform_data *)platform;
1985 int acdb_rx_id, acdb_tx_id;
1986
1987 if (my_data->acdb_send_voice_cal == NULL) {
1988 ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
1989 } else {
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001990 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1991 audio_extn_spkr_prot_is_enabled())
1992 out_snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
1993
keunhui.park2f7306a2015-07-16 16:48:06 +09001994 acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
1995 acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
Eric Laurentb23d5282013-05-14 15:27:20 -07001996
1997 if (acdb_rx_id > 0 && acdb_tx_id > 0)
1998 my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
1999 else
2000 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
2001 acdb_rx_id, acdb_tx_id);
2002 }
2003
2004 return 0;
2005}
2006
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07002007int platform_switch_voice_call_usecase_route_post(void *platform,
2008 snd_device_t out_snd_device,
2009 snd_device_t in_snd_device)
2010{
2011 struct platform_data *my_data = (struct platform_data *)platform;
2012 int acdb_rx_id, acdb_tx_id;
2013 int ret = 0;
2014
2015 if (my_data->csd == NULL)
2016 return ret;
2017
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07002018 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
2019 audio_extn_spkr_prot_is_enabled())
keunhui.park2f7306a2015-07-16 16:48:06 +09002020 acdb_rx_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED);
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07002021 else
keunhui.park2f7306a2015-07-16 16:48:06 +09002022 acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07002023
keunhui.park2f7306a2015-07-16 16:48:06 +09002024 acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07002025
2026 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
2027 ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
2028 my_data->adev->acdb_settings);
2029 if (ret < 0) {
2030 ALOGE("%s: csd_enable_device, failed, error %d", __func__, ret);
2031 }
2032 } else {
2033 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
2034 acdb_rx_id, acdb_tx_id);
2035 }
2036
2037 return ret;
2038}
2039
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002040int platform_start_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07002041{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07002042 struct platform_data *my_data = (struct platform_data *)platform;
2043 int ret = 0;
2044
2045 if (my_data->csd != NULL) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002046 ret = my_data->csd->start_voice(vsid);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07002047 if (ret < 0) {
2048 ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
2049 }
2050 }
2051 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07002052}
2053
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002054int platform_stop_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07002055{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07002056 struct platform_data *my_data = (struct platform_data *)platform;
2057 int ret = 0;
2058
2059 if (my_data->csd != NULL) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002060 ret = my_data->csd->stop_voice(vsid);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07002061 if (ret < 0) {
2062 ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
2063 }
2064 }
2065 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07002066}
2067
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002068int platform_get_sample_rate(void *platform, uint32_t *rate)
2069{
2070 struct platform_data *my_data = (struct platform_data *)platform;
2071 int ret = 0;
2072
2073 if (my_data->csd != NULL) {
2074 ret = my_data->csd->get_sample_rate(rate);
2075 if (ret < 0) {
2076 ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret);
2077 }
2078 }
2079 return ret;
2080}
2081
vivek mehtab6506412015-08-07 16:55:17 -07002082void platform_set_speaker_gain_in_combo(struct audio_device *adev,
2083 snd_device_t snd_device,
2084 bool enable)
2085{
2086 const char* name;
2087 switch (snd_device) {
2088 case SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES:
2089 if (enable)
2090 name = "spkr-gain-in-headphone-combo";
2091 else
2092 name = "speaker-gain-default";
2093 break;
2094 case SND_DEVICE_OUT_SPEAKER_AND_LINE:
2095 if (enable)
2096 name = "spkr-gain-in-line-combo";
2097 else
2098 name = "speaker-gain-default";
2099 break;
2100 case SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES:
2101 if (enable)
2102 name = "spkr-safe-gain-in-headphone-combo";
2103 else
2104 name = "speaker-safe-gain-default";
2105 break;
2106 case SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE:
2107 if (enable)
2108 name = "spkr-safe-gain-in-line-combo";
2109 else
2110 name = "speaker-safe-gain-default";
2111 break;
2112 default:
2113 return;
2114 }
2115
2116 audio_route_apply_and_update_path(adev->audio_route, name);
2117}
2118
Eric Laurentb23d5282013-05-14 15:27:20 -07002119int platform_set_voice_volume(void *platform, int volume)
2120{
2121 struct platform_data *my_data = (struct platform_data *)platform;
2122 struct audio_device *adev = my_data->adev;
2123 struct mixer_ctl *ctl;
sangwoo53b2cf02013-07-25 19:18:44 -07002124 const char *mixer_ctl_name = "Voice Rx Gain";
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002125 int vol_index = 0, ret = 0;
2126 uint32_t set_values[ ] = {0,
2127 ALL_SESSION_VSID,
2128 DEFAULT_VOLUME_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07002129
2130 // Voice volume levels are mapped to adsp volume levels as follows.
2131 // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0
2132 // But this values don't changed in kernel. So, below change is need.
keunhui.parkc5aaa0e2015-07-13 10:57:37 +09002133 vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, my_data->max_vol_index);
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002134 set_values[0] = vol_index;
Eric Laurentb23d5282013-05-14 15:27:20 -07002135
2136 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2137 if (!ctl) {
2138 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2139 __func__, mixer_ctl_name);
2140 return -EINVAL;
2141 }
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002142 ALOGV("Setting voice volume index: %d", set_values[0]);
2143 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
2144
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07002145 if (my_data->csd != NULL) {
2146 ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
2147 DEFAULT_VOLUME_RAMP_DURATION_MS);
2148 if (ret < 0) {
2149 ALOGE("%s: csd_volume error %d", __func__, ret);
2150 }
2151 }
2152 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07002153}
2154
2155int platform_set_mic_mute(void *platform, bool state)
2156{
2157 struct platform_data *my_data = (struct platform_data *)platform;
2158 struct audio_device *adev = my_data->adev;
2159 struct mixer_ctl *ctl;
2160 const char *mixer_ctl_name = "Voice Tx Mute";
sangwoo53b2cf02013-07-25 19:18:44 -07002161 int ret = 0;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002162 uint32_t set_values[ ] = {0,
2163 ALL_SESSION_VSID,
2164 DEFAULT_MUTE_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07002165
Uday Kishore Pasupuletia1f48052015-09-08 22:49:18 +09002166 if (adev->mode != AUDIO_MODE_IN_CALL &&
2167 adev->mode != AUDIO_MODE_IN_COMMUNICATION)
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002168 return 0;
2169
Uday Kishore Pasupuletia1f48052015-09-08 22:49:18 +09002170 if (adev->enable_hfp)
2171 mixer_ctl_name = "HFP Tx Mute";
2172
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002173 set_values[0] = state;
2174 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2175 if (!ctl) {
2176 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2177 __func__, mixer_ctl_name);
2178 return -EINVAL;
2179 }
2180 ALOGV("Setting voice mute state: %d", state);
2181 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
2182
2183 if (my_data->csd != NULL) {
2184 ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state,
2185 DEFAULT_MUTE_RAMP_DURATION_MS);
sangwoo53b2cf02013-07-25 19:18:44 -07002186 if (ret < 0) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002187 ALOGE("%s: csd_mic_mute error %d", __func__, ret);
sangwoo53b2cf02013-07-25 19:18:44 -07002188 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002189 }
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002190 return ret;
2191}
Eric Laurentb23d5282013-05-14 15:27:20 -07002192
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002193int platform_set_device_mute(void *platform, bool state, char *dir)
2194{
2195 struct platform_data *my_data = (struct platform_data *)platform;
2196 struct audio_device *adev = my_data->adev;
2197 struct mixer_ctl *ctl;
2198 char *mixer_ctl_name = NULL;
2199 int ret = 0;
2200 uint32_t set_values[ ] = {0,
2201 ALL_SESSION_VSID,
2202 0};
2203 if(dir == NULL) {
2204 ALOGE("%s: Invalid direction:%s", __func__, dir);
2205 return -EINVAL;
2206 }
2207
2208 if (!strncmp("rx", dir, sizeof("rx"))) {
2209 mixer_ctl_name = "Voice Rx Device Mute";
2210 } else if (!strncmp("tx", dir, sizeof("tx"))) {
2211 mixer_ctl_name = "Voice Tx Device Mute";
2212 } else {
2213 return -EINVAL;
2214 }
2215
2216 set_values[0] = state;
2217 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2218 if (!ctl) {
2219 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2220 __func__, mixer_ctl_name);
2221 return -EINVAL;
2222 }
2223
2224 ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
2225 __func__,state, mixer_ctl_name);
2226 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
2227
2228 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07002229}
2230
Haynes Mathew George2d809e02016-09-22 17:38:16 -07002231int platform_can_split_snd_device(snd_device_t snd_device,
2232 int *num_devices,
2233 snd_device_t *new_snd_devices)
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07002234{
Haynes Mathew George2d809e02016-09-22 17:38:16 -07002235 int ret = -EINVAL;
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07002236 if (NULL == num_devices || NULL == new_snd_devices) {
2237 ALOGE("%s: NULL pointer ..", __func__);
Haynes Mathew George2d809e02016-09-22 17:38:16 -07002238 return -EINVAL;
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07002239 }
2240
2241 /*
2242 * If wired headset/headphones/line devices share the same backend
Haynes Mathew George2d809e02016-09-22 17:38:16 -07002243 * with speaker/earpiece this routine returns -EINVAL.
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07002244 */
2245 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES &&
2246 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HEADPHONES)) {
2247 *num_devices = 2;
2248 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
2249 new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
Haynes Mathew George2d809e02016-09-22 17:38:16 -07002250 ret = 0;
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07002251 } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_LINE &&
2252 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_LINE)) {
2253 *num_devices = 2;
2254 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
2255 new_snd_devices[1] = SND_DEVICE_OUT_LINE;
Haynes Mathew George2d809e02016-09-22 17:38:16 -07002256 ret = 0;
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -07002257 } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES &&
2258 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_HEADPHONES)) {
2259 *num_devices = 2;
2260 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
2261 new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
Haynes Mathew George2d809e02016-09-22 17:38:16 -07002262 ret = 0;
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -07002263 } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE &&
2264 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_LINE)) {
2265 *num_devices = 2;
2266 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
2267 new_snd_devices[1] = SND_DEVICE_OUT_LINE;
Haynes Mathew George2d809e02016-09-22 17:38:16 -07002268 ret = 0;
Haynes Mathew George6dcb1a82016-12-21 12:38:55 -08002269 } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_BT_SCO &&
2270 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER,
2271 SND_DEVICE_OUT_BT_SCO)) {
2272 *num_devices = 2;
2273 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
2274 new_snd_devices[1] = SND_DEVICE_OUT_BT_SCO;
2275 ret = 0;
2276 } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB &&
2277 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER,
2278 SND_DEVICE_OUT_BT_SCO_WB)) {
2279 *num_devices = 2;
2280 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
2281 new_snd_devices[1] = SND_DEVICE_OUT_BT_SCO_WB;
2282 ret = 0;
David Linee3fe402017-03-13 10:00:42 -07002283 } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET &&
2284 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_USB_HEADSET)) {
2285 *num_devices = 2;
2286 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
2287 new_snd_devices[1] = SND_DEVICE_OUT_USB_HEADSET;
2288 ret = 0;
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07002289 }
Haynes Mathew George2d809e02016-09-22 17:38:16 -07002290 return ret;
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07002291}
2292
Eric Laurentb23d5282013-05-14 15:27:20 -07002293snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
2294{
2295 struct platform_data *my_data = (struct platform_data *)platform;
2296 struct audio_device *adev = my_data->adev;
2297 audio_mode_t mode = adev->mode;
2298 snd_device_t snd_device = SND_DEVICE_NONE;
2299
2300 ALOGV("%s: enter: output devices(%#x)", __func__, devices);
2301 if (devices == AUDIO_DEVICE_NONE ||
2302 devices & AUDIO_DEVICE_BIT_IN) {
2303 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
2304 goto exit;
2305 }
2306
Eric Laurent1b491552015-09-15 17:52:41 -07002307 if (popcount(devices) == 2) {
2308 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
2309 AUDIO_DEVICE_OUT_SPEAKER) ||
2310 devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
2311 AUDIO_DEVICE_OUT_SPEAKER)) {
2312 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
2313 } else if (devices == (AUDIO_DEVICE_OUT_LINE |
2314 AUDIO_DEVICE_OUT_SPEAKER)) {
2315 snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
2316 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
2317 AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
2318 devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
2319 AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
2320 snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES;
2321 } else if (devices == (AUDIO_DEVICE_OUT_LINE |
2322 AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
2323 snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE;
2324 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
2325 AUDIO_DEVICE_OUT_SPEAKER)) {
2326 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
Haynes Mathew George6dcb1a82016-12-21 12:38:55 -08002327 } else if ((devices & AUDIO_DEVICE_OUT_ALL_SCO) &&
2328 ((devices & ~AUDIO_DEVICE_OUT_ALL_SCO) == AUDIO_DEVICE_OUT_SPEAKER)) {
2329 snd_device = adev->bt_wb_speech_enabled ?
2330 SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB :
2331 SND_DEVICE_OUT_SPEAKER_AND_BT_SCO;
David Linee3fe402017-03-13 10:00:42 -07002332 } else if (devices == (AUDIO_DEVICE_OUT_USB_DEVICE |
2333 AUDIO_DEVICE_OUT_SPEAKER)) {
2334 snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
Eric Laurent1b491552015-09-15 17:52:41 -07002335 } else {
2336 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
2337 goto exit;
2338 }
2339 if (snd_device != SND_DEVICE_NONE) {
2340 goto exit;
2341 }
2342 }
2343
2344 if (popcount(devices) != 1) {
2345 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
2346 goto exit;
2347 }
2348
Madhuri Athota3f6051b2016-10-13 23:25:38 +05302349 if (voice_is_in_call(adev) || adev->enable_voicerx || audio_extn_hfp_is_active(adev)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07002350 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05002351 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
2352 devices & AUDIO_DEVICE_OUT_LINE) {
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07002353 if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05002354 (adev->voice.tty_mode == TTY_MODE_FULL))
Eric Laurentb23d5282013-05-14 15:27:20 -07002355 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07002356 else if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05002357 (adev->voice.tty_mode == TTY_MODE_VCO))
Eric Laurentb23d5282013-05-14 15:27:20 -07002358 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07002359 else if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05002360 (adev->voice.tty_mode == TTY_MODE_HCO))
Eric Laurentb23d5282013-05-14 15:27:20 -07002361 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
Eric Laurent09f2e0e2014-07-29 16:02:32 -05002362 else {
2363 if (devices & AUDIO_DEVICE_OUT_LINE)
2364 snd_device = SND_DEVICE_OUT_VOICE_LINE;
2365 else
2366 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
2367 }
vivek mehtaa6b79742017-03-09 15:40:43 -08002368 } else if (devices & AUDIO_DEVICE_OUT_USB_DEVICE) {
2369 if (voice_is_in_call(adev)) {
2370 switch (adev->voice.tty_mode) {
2371 case TTY_MODE_FULL:
2372 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_USB;
2373 break;
2374 case TTY_MODE_VCO:
2375 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_USB;
2376 break;
2377 case TTY_MODE_HCO:
2378 // since Hearing will be on handset\speaker, use existing device
2379 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
2380 break;
Haynes Mathew George9a29f372017-04-11 19:19:07 -07002381 case TTY_MODE_OFF:
2382 break;
vivek mehtaa6b79742017-03-09 15:40:43 -08002383 default:
2384 ALOGE("%s: Invalid TTY mode (%#x)",
2385 __func__, adev->voice.tty_mode);
2386 }
2387 }
Haynes Mathew George9a29f372017-04-11 19:19:07 -07002388 if (snd_device == SND_DEVICE_NONE) {
2389 snd_device = audio_extn_usb_is_capture_supported() ?
2390 SND_DEVICE_OUT_VOICE_USB_HEADSET :
2391 SND_DEVICE_OUT_VOICE_USB_HEADPHONES;
2392 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002393 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07002394 if (adev->bt_wb_speech_enabled) {
2395 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
2396 } else {
2397 snd_device = SND_DEVICE_OUT_BT_SCO;
2398 }
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07002399 } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Uday Kishore Pasupuleti76297192015-09-18 08:39:43 -07002400 if (!adev->enable_hfp) {
2401 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
2402 } else {
2403 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_HFP;
2404 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002405 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurent9d0d3f12014-07-25 12:40:29 -05002406 if(adev->voice.hac)
2407 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
2408 else if (is_operator_tmus())
Eric Laurentb23d5282013-05-14 15:27:20 -07002409 snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
2410 else
Eric Laurentb4d368e2014-06-25 10:21:54 -05002411 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -07002412 } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
2413 snd_device = SND_DEVICE_OUT_VOICE_TX;
2414
Eric Laurentb23d5282013-05-14 15:27:20 -07002415 if (snd_device != SND_DEVICE_NONE) {
2416 goto exit;
2417 }
2418 }
2419
Eric Laurentb23d5282013-05-14 15:27:20 -07002420 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
2421 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
2422 snd_device = SND_DEVICE_OUT_HEADPHONES;
Eric Laurent09f2e0e2014-07-29 16:02:32 -05002423 } else if (devices & AUDIO_DEVICE_OUT_LINE) {
2424 snd_device = SND_DEVICE_OUT_LINE;
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07002425 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
2426 snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
Eric Laurentb23d5282013-05-14 15:27:20 -07002427 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07002428 if (my_data->speaker_lr_swap)
Eric Laurentb23d5282013-05-14 15:27:20 -07002429 snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
2430 else
2431 snd_device = SND_DEVICE_OUT_SPEAKER;
2432 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07002433 if (adev->bt_wb_speech_enabled) {
2434 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
2435 } else {
2436 snd_device = SND_DEVICE_OUT_BT_SCO;
2437 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002438 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
2439 snd_device = SND_DEVICE_OUT_HDMI ;
David Linee3fe402017-03-13 10:00:42 -07002440 } else if (devices & AUDIO_DEVICE_OUT_USB_DEVICE) {
2441 if (audio_extn_usb_is_capture_supported())
2442 snd_device = SND_DEVICE_OUT_USB_HEADSET;
2443 else
2444 snd_device = SND_DEVICE_OUT_USB_HEADPHONES;
2445 }else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurent9d0d3f12014-07-25 12:40:29 -05002446 /*HAC support for voice-ish audio (eg visual voicemail)*/
2447 if(adev->voice.hac)
2448 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
2449 else
2450 snd_device = SND_DEVICE_OUT_HANDSET;
Eric Laurentb23d5282013-05-14 15:27:20 -07002451 } else {
2452 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
2453 }
2454exit:
2455 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
2456 return snd_device;
2457}
2458
2459snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
2460{
2461 struct platform_data *my_data = (struct platform_data *)platform;
2462 struct audio_device *adev = my_data->adev;
2463 audio_source_t source = (adev->active_input == NULL) ?
2464 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
2465
2466 audio_mode_t mode = adev->mode;
2467 audio_devices_t in_device = ((adev->active_input == NULL) ?
2468 AUDIO_DEVICE_NONE : adev->active_input->device)
2469 & ~AUDIO_DEVICE_BIT_IN;
2470 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
2471 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
2472 snd_device_t snd_device = SND_DEVICE_NONE;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002473 int channel_count = popcount(channel_mask);
Eric Laurentb23d5282013-05-14 15:27:20 -07002474
Prashant Malanic92c5962015-08-11 15:10:18 -07002475 ALOGV("%s: enter: out_device(%#x) in_device(%#x) channel_count (%d) channel_mask (0x%x)",
2476 __func__, out_device, in_device, channel_count, channel_mask);
Devin Kimd789e432016-10-26 15:07:27 -07002477 if ((out_device != AUDIO_DEVICE_NONE) && (voice_is_in_call(adev) ||
2478 audio_extn_hfp_is_active(adev))) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002479 if (adev->voice.tty_mode != TTY_MODE_OFF) {
Eric Laurentb23d5282013-05-14 15:27:20 -07002480 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05002481 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
2482 out_device & AUDIO_DEVICE_OUT_LINE) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002483 switch (adev->voice.tty_mode) {
vivek mehtaa6b79742017-03-09 15:40:43 -08002484 case TTY_MODE_FULL:
2485 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
2486 break;
2487 case TTY_MODE_VCO:
2488 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
2489 break;
2490 case TTY_MODE_HCO:
2491 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
2492 break;
2493 default:
2494 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
2495 }
2496 goto exit;
2497 } else if (out_device & AUDIO_DEVICE_OUT_USB_DEVICE) {
2498 switch (adev->voice.tty_mode) {
2499 case TTY_MODE_FULL:
2500 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC;
2501 break;
2502 case TTY_MODE_VCO:
2503 // since voice will be captured from handset mic, use existing device
2504 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
2505 break;
2506 case TTY_MODE_HCO:
2507 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC;
2508 break;
2509 default:
2510 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
Eric Laurentb23d5282013-05-14 15:27:20 -07002511 }
2512 goto exit;
2513 }
2514 }
Eric Laurentb991fb02014-08-29 15:23:17 -05002515 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07002516 if (my_data->fluence_in_voice_call == false) {
2517 snd_device = SND_DEVICE_IN_HANDSET_MIC;
2518 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002519 if (is_operator_tmus())
2520 snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS;
Eric Laurentb23d5282013-05-14 15:27:20 -07002521 else
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002522 snd_device = SND_DEVICE_IN_VOICE_DMIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07002523 }
2524 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
2525 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
2526 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07002527 if (adev->bt_wb_speech_enabled) {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07002528 if (adev->bluetooth_nrec)
2529 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2530 else
2531 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07002532 } else {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07002533 if (adev->bluetooth_nrec)
2534 snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2535 else
2536 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07002537 }
Eric Laurentb991fb02014-08-29 15:23:17 -05002538 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
Prashant Malanic92c5962015-08-11 15:10:18 -07002539 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
2540 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
2541 out_device & AUDIO_DEVICE_OUT_LINE) {
2542 if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode) {
2543 if (my_data->source_mic_type & SOURCE_DUAL_MIC) {
2544 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
2545 } else {
2546 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
2547 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002548 }
vivek mehtafe121d52015-08-10 23:39:23 -07002549
2550 //select default
2551 if (snd_device == SND_DEVICE_NONE) {
Uday Kishore Pasupuleti76297192015-09-18 08:39:43 -07002552 if (!adev->enable_hfp) {
2553 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
2554 } else {
2555 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP;
2556 platform_set_echo_reference(adev, true, out_device);
2557 }
vivek mehtafe121d52015-08-10 23:39:23 -07002558 }
Prashant Malanic92c5962015-08-11 15:10:18 -07002559 } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX) {
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -07002560 snd_device = SND_DEVICE_IN_VOICE_RX;
Haynes Mathew George9a29f372017-04-11 19:19:07 -07002561 } else if (out_device & AUDIO_DEVICE_OUT_USB_DEVICE) {
2562 if (audio_extn_usb_is_capture_supported()) {
2563 snd_device = SND_DEVICE_IN_VOICE_USB_HEADSET_MIC;
2564 }
Prashant Malanic92c5962015-08-11 15:10:18 -07002565 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002566 } else if (source == AUDIO_SOURCE_CAMCORDER) {
2567 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
2568 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2569 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
2570 }
2571 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
2572 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Prashant Malanic92c5962015-08-11 15:10:18 -07002573 if (my_data->fluence_in_voice_rec && channel_count == 1) {
2574 if ((my_data->fluence_type == FLUENCE_PRO_ENABLE) &&
2575 (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
vivek mehta733c1df2016-04-04 15:09:24 -07002576 if (adev->active_input->enable_aec)
2577 snd_device = SND_DEVICE_IN_HANDSET_QMIC_AEC;
2578 else
2579 snd_device = SND_DEVICE_IN_HANDSET_QMIC;
Prashant Malanic92c5962015-08-11 15:10:18 -07002580 } else if ((my_data->fluence_type == FLUENCE_PRO_ENABLE) &&
2581 (my_data->source_mic_type & SOURCE_THREE_MIC)) {
vivek mehta733c1df2016-04-04 15:09:24 -07002582 if (adev->active_input->enable_aec)
2583 snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC;
2584 else
2585 snd_device = SND_DEVICE_IN_HANDSET_TMIC;
Prashant Malanic92c5962015-08-11 15:10:18 -07002586 } else if (((my_data->fluence_type == FLUENCE_PRO_ENABLE) ||
2587 (my_data->fluence_type == FLUENCE_ENABLE)) &&
2588 (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
vivek mehta733c1df2016-04-04 15:09:24 -07002589 if (adev->active_input->enable_aec)
2590 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
2591 else
2592 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
Prashant Malanic92c5962015-08-11 15:10:18 -07002593 }
2594 platform_set_echo_reference(adev, true, out_device);
2595 } else if ((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) &&
2596 (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
2597 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
Glenn Kastencbe06ca2016-11-09 10:49:26 -08002598 } else if ((channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) &&
Prashant Malanic92c5962015-08-11 15:10:18 -07002599 (my_data->source_mic_type & SOURCE_THREE_MIC)) {
2600 snd_device = SND_DEVICE_IN_THREE_MIC;
Glenn Kastencbe06ca2016-11-09 10:49:26 -08002601 } else if ((channel_mask == AUDIO_CHANNEL_INDEX_MASK_4) &&
Prashant Malanic92c5962015-08-11 15:10:18 -07002602 (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
2603 snd_device = SND_DEVICE_IN_QUAD_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07002604 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002605 if (snd_device == SND_DEVICE_NONE) {
vivek mehtaf3440682016-05-11 14:24:37 -07002606 if (adev->active_input->enable_aec) {
2607 if (adev->active_input->enable_ns) {
2608 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS;
2609 } else {
2610 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_AEC;
2611 }
vivek mehta733c1df2016-04-04 15:09:24 -07002612 platform_set_echo_reference(adev, true, out_device);
vivek mehtaf3440682016-05-11 14:24:37 -07002613 } else if (adev->active_input->enable_ns) {
2614 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
2615 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002616 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
vivek mehtaf3440682016-05-11 14:24:37 -07002617 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002618 }
Jean-Michel Trivi8c83fe82015-09-25 15:06:53 -07002619 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2620 snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
Haynes Mathew George9a29f372017-04-11 19:19:07 -07002621 } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
2622 snd_device = SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07002623 }
rago90fb9612015-12-02 11:37:53 -08002624 } else if (source == AUDIO_SOURCE_UNPROCESSED) {
2625 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
vivek mehta4ed66e62016-04-15 23:33:34 -07002626 if (((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) ||
2627 (channel_mask == AUDIO_CHANNEL_IN_STEREO)) &&
2628 (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
2629 snd_device = SND_DEVICE_IN_UNPROCESSED_STEREO_MIC;
Glenn Kastencbe06ca2016-11-09 10:49:26 -08002630 } else if ((channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) &&
vivek mehta4ed66e62016-04-15 23:33:34 -07002631 (my_data->source_mic_type & SOURCE_THREE_MIC)) {
2632 snd_device = SND_DEVICE_IN_UNPROCESSED_THREE_MIC;
Glenn Kastencbe06ca2016-11-09 10:49:26 -08002633 } else if ((channel_mask == AUDIO_CHANNEL_INDEX_MASK_4) &&
vivek mehta4ed66e62016-04-15 23:33:34 -07002634 (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
2635 snd_device = SND_DEVICE_IN_UNPROCESSED_QUAD_MIC;
2636 } else {
2637 snd_device = SND_DEVICE_IN_UNPROCESSED_MIC;
2638 }
rago90fb9612015-12-02 11:37:53 -08002639 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2640 snd_device = SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC;
Haynes Mathew George9a29f372017-04-11 19:19:07 -07002641 } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
2642 snd_device = SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC;
rago90fb9612015-12-02 11:37:53 -08002643 }
Eric Laurent50a38ed2015-10-14 18:48:06 -07002644 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
rago90fb9612015-12-02 11:37:53 -08002645 mode == AUDIO_MODE_IN_COMMUNICATION) {
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07002646 if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE))
Eric Laurentb23d5282013-05-14 15:27:20 -07002647 in_device = AUDIO_DEVICE_IN_BACK_MIC;
2648 if (adev->active_input) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002649 if (adev->active_input->enable_aec &&
2650 adev->active_input->enable_ns) {
Eric Laurentb23d5282013-05-14 15:27:20 -07002651 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002652 if (my_data->fluence_in_spkr_mode &&
2653 my_data->fluence_in_voice_comm &&
Prashant Malanic92c5962015-08-11 15:10:18 -07002654 (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002655 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
Prashant Malanic92c5962015-08-11 15:10:18 -07002656 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002657 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
Prashant Malanic92c5962015-08-11 15:10:18 -07002658 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002659 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002660 if (my_data->fluence_in_voice_comm &&
Prashant Malanic92c5962015-08-11 15:10:18 -07002661 (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002662 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
Prashant Malanic92c5962015-08-11 15:10:18 -07002663 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002664 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
Prashant Malanic92c5962015-08-11 15:10:18 -07002665 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05002666 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2667 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
Haynes Mathew George9a29f372017-04-11 19:19:07 -07002668 } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
2669 snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
Eric Laurentb23d5282013-05-14 15:27:20 -07002670 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05002671 platform_set_echo_reference(adev, true, out_device);
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002672 } else if (adev->active_input->enable_aec) {
2673 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2674 if (my_data->fluence_in_spkr_mode &&
2675 my_data->fluence_in_voice_comm &&
Prashant Malanic92c5962015-08-11 15:10:18 -07002676 (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002677 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
Prashant Malanic92c5962015-08-11 15:10:18 -07002678 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002679 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
Prashant Malanic92c5962015-08-11 15:10:18 -07002680 }
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002681 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2682 if (my_data->fluence_in_voice_comm &&
Prashant Malanic92c5962015-08-11 15:10:18 -07002683 (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002684 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
Prashant Malanic92c5962015-08-11 15:10:18 -07002685 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002686 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
Prashant Malanic92c5962015-08-11 15:10:18 -07002687 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05002688 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2689 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
Haynes Mathew George9a29f372017-04-11 19:19:07 -07002690 } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE) {
2691 snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
Eric Laurentcefbbac2014-09-04 13:54:10 -05002692 }
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -08002693 platform_set_echo_reference(adev, true, out_device);
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002694 } else if (adev->active_input->enable_ns) {
2695 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2696 if (my_data->fluence_in_spkr_mode &&
2697 my_data->fluence_in_voice_comm &&
Prashant Malanic92c5962015-08-11 15:10:18 -07002698 (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002699 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
Prashant Malanic92c5962015-08-11 15:10:18 -07002700 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002701 snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
Prashant Malanic92c5962015-08-11 15:10:18 -07002702 }
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002703 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2704 if (my_data->fluence_in_voice_comm &&
Prashant Malanic92c5962015-08-11 15:10:18 -07002705 (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002706 snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
Prashant Malanic92c5962015-08-11 15:10:18 -07002707 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002708 snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
Prashant Malanic92c5962015-08-11 15:10:18 -07002709 }
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002710 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05002711 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002712 }
2713 } else if (source == AUDIO_SOURCE_DEFAULT) {
2714 goto exit;
2715 }
2716
2717
2718 if (snd_device != SND_DEVICE_NONE) {
2719 goto exit;
2720 }
2721
2722 if (in_device != AUDIO_DEVICE_NONE &&
2723 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
2724 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
2725 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Prashant Malanic92c5962015-08-11 15:10:18 -07002726 if ((my_data->source_mic_type & SOURCE_QUAD_MIC) &&
Glenn Kastencbe06ca2016-11-09 10:49:26 -08002727 channel_mask == AUDIO_CHANNEL_INDEX_MASK_4) {
Prashant Malanic92c5962015-08-11 15:10:18 -07002728 snd_device = SND_DEVICE_IN_QUAD_MIC;
2729 } else if ((my_data->source_mic_type & SOURCE_THREE_MIC) &&
Glenn Kastencbe06ca2016-11-09 10:49:26 -08002730 channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) {
Prashant Malanic92c5962015-08-11 15:10:18 -07002731 snd_device = SND_DEVICE_IN_THREE_MIC;
2732 } else if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
2733 channel_count == 2) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002734 snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
Prashant Malanic92c5962015-08-11 15:10:18 -07002735 } else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
2736 channel_count == 1) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002737 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Prashant Malanic92c5962015-08-11 15:10:18 -07002738 } else {
2739 ALOGE("%s: something wrong (1): source type (%d) channel_count (%d) .."
2740 " channel mask (0x%x) no combination found .. setting to mono", __func__,
2741 my_data->source_mic_type, channel_count, channel_mask);
2742 snd_device = SND_DEVICE_IN_HANDSET_MIC;
2743 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002744 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Prashant Malanic92c5962015-08-11 15:10:18 -07002745 if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
2746 channel_count == 2) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002747 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
Prashant Malanic92c5962015-08-11 15:10:18 -07002748 } else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
2749 channel_count == 1) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002750 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Prashant Malanic92c5962015-08-11 15:10:18 -07002751 } else {
2752 ALOGE("%s: something wrong (2): source type (%d) channel_count (%d) .."
2753 " no combination found .. setting to mono", __func__,
2754 my_data->source_mic_type, channel_count);
2755 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
2756 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002757 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2758 snd_device = SND_DEVICE_IN_HEADSET_MIC;
2759 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07002760 if (adev->bt_wb_speech_enabled) {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07002761 if (adev->bluetooth_nrec)
2762 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2763 else
2764 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07002765 } else {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07002766 if (adev->bluetooth_nrec)
2767 snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2768 else
2769 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07002770 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002771 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
2772 snd_device = SND_DEVICE_IN_HDMI_MIC;
David Linee3fe402017-03-13 10:00:42 -07002773 } else if (in_device & AUDIO_DEVICE_IN_USB_DEVICE ) {
2774 snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07002775 } else {
2776 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
2777 ALOGW("%s: Using default handset-mic", __func__);
2778 snd_device = SND_DEVICE_IN_HANDSET_MIC;
2779 }
2780 } else {
2781 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
2782 snd_device = SND_DEVICE_IN_HANDSET_MIC;
2783 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
2784 snd_device = SND_DEVICE_IN_HEADSET_MIC;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002785 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07002786 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002787 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05002788 out_device & AUDIO_DEVICE_OUT_LINE) {
Prashant Malanic92c5962015-08-11 15:10:18 -07002789 if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
2790 channel_count == 2) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002791 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
Prashant Malanic92c5962015-08-11 15:10:18 -07002792 } else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
2793 channel_count == 1) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07002794 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Prashant Malanic92c5962015-08-11 15:10:18 -07002795 } else {
2796 ALOGE("%s: something wrong (3): source type (%d) channel_count (%d) .."
2797 " no combination found .. setting to mono", __func__,
2798 my_data->source_mic_type, channel_count);
2799 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
2800 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002801 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07002802 if (adev->bt_wb_speech_enabled) {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07002803 if (adev->bluetooth_nrec)
2804 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2805 else
2806 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07002807 } else {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07002808 if (adev->bluetooth_nrec)
2809 snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2810 else
2811 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07002812 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002813 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
2814 snd_device = SND_DEVICE_IN_HDMI_MIC;
David Linee3fe402017-03-13 10:00:42 -07002815 } else if (out_device & AUDIO_DEVICE_OUT_USB_DEVICE) {
2816 if (audio_extn_usb_is_capture_supported())
2817 snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
2818 else
2819 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07002820 } else {
2821 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
2822 ALOGW("%s: Using default handset-mic", __func__);
2823 snd_device = SND_DEVICE_IN_HANDSET_MIC;
2824 }
2825 }
2826exit:
2827 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
2828 return snd_device;
2829}
2830
2831int platform_set_hdmi_channels(void *platform, int channel_count)
2832{
2833 struct platform_data *my_data = (struct platform_data *)platform;
2834 struct audio_device *adev = my_data->adev;
2835 struct mixer_ctl *ctl;
2836 const char *channel_cnt_str = NULL;
2837 const char *mixer_ctl_name = "HDMI_RX Channels";
2838 switch (channel_count) {
2839 case 8:
2840 channel_cnt_str = "Eight"; break;
2841 case 7:
2842 channel_cnt_str = "Seven"; break;
2843 case 6:
2844 channel_cnt_str = "Six"; break;
2845 case 5:
2846 channel_cnt_str = "Five"; break;
2847 case 4:
2848 channel_cnt_str = "Four"; break;
2849 case 3:
2850 channel_cnt_str = "Three"; break;
2851 default:
2852 channel_cnt_str = "Two"; break;
2853 }
2854 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2855 if (!ctl) {
2856 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2857 __func__, mixer_ctl_name);
2858 return -EINVAL;
2859 }
2860 ALOGV("HDMI channel count: %s", channel_cnt_str);
2861 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
2862 return 0;
2863}
2864
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002865int platform_edid_get_max_channels(void *platform)
Eric Laurentb23d5282013-05-14 15:27:20 -07002866{
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002867 struct platform_data *my_data = (struct platform_data *)platform;
2868 struct audio_device *adev = my_data->adev;
Eric Laurentb23d5282013-05-14 15:27:20 -07002869 char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
2870 char *sad = block;
2871 int num_audio_blocks;
2872 int channel_count;
2873 int max_channels = 0;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002874 int i, ret, count;
Eric Laurentb23d5282013-05-14 15:27:20 -07002875
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002876 struct mixer_ctl *ctl;
2877
2878 ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
2879 if (!ctl) {
2880 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2881 __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
Eric Laurentb23d5282013-05-14 15:27:20 -07002882 return 0;
2883 }
2884
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002885 mixer_ctl_update(ctl);
2886
2887 count = mixer_ctl_get_num_values(ctl);
Eric Laurentb23d5282013-05-14 15:27:20 -07002888
2889 /* Read SAD blocks, clamping the maximum size for safety */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002890 if (count > (int)sizeof(block))
2891 count = (int)sizeof(block);
Eric Laurentb23d5282013-05-14 15:27:20 -07002892
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002893 ret = mixer_ctl_get_array(ctl, block, count);
2894 if (ret != 0) {
2895 ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
2896 return 0;
2897 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002898
2899 /* Calculate the number of SAD blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002900 num_audio_blocks = count / SAD_BLOCK_SIZE;
Eric Laurentb23d5282013-05-14 15:27:20 -07002901
2902 for (i = 0; i < num_audio_blocks; i++) {
2903 /* Only consider LPCM blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002904 if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
2905 sad += 3;
Eric Laurentb23d5282013-05-14 15:27:20 -07002906 continue;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002907 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002908
2909 channel_count = (sad[0] & 0x7) + 1;
2910 if (channel_count > max_channels)
2911 max_channels = channel_count;
2912
2913 /* Advance to next block */
2914 sad += 3;
2915 }
2916
2917 return max_channels;
2918}
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07002919
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002920int platform_set_incall_recording_session_id(void *platform,
2921 uint32_t session_id, int rec_mode)
2922{
2923 int ret = 0;
2924 struct platform_data *my_data = (struct platform_data *)platform;
2925 struct audio_device *adev = my_data->adev;
2926 struct mixer_ctl *ctl;
2927 const char *mixer_ctl_name = "Voc VSID";
2928 int num_ctl_values;
2929 int i;
2930
2931 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2932 if (!ctl) {
2933 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2934 __func__, mixer_ctl_name);
2935 ret = -EINVAL;
2936 } else {
2937 num_ctl_values = mixer_ctl_get_num_values(ctl);
2938 for (i = 0; i < num_ctl_values; i++) {
2939 if (mixer_ctl_set_value(ctl, i, session_id)) {
2940 ALOGV("Error: invalid session_id: %x", session_id);
2941 ret = -EINVAL;
2942 break;
2943 }
2944 }
2945 }
2946
2947 if (my_data->csd != NULL) {
2948 ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
2949 if (ret < 0) {
2950 ALOGE("%s: csd_client_start_record failed, error %d",
2951 __func__, ret);
2952 }
2953 }
2954
2955 return ret;
2956}
2957
2958int platform_stop_incall_recording_usecase(void *platform)
2959{
2960 int ret = 0;
2961 struct platform_data *my_data = (struct platform_data *)platform;
2962
2963 if (my_data->csd != NULL) {
2964 ret = my_data->csd->stop_record(ALL_SESSION_VSID);
2965 if (ret < 0) {
2966 ALOGE("%s: csd_client_stop_record failed, error %d",
2967 __func__, ret);
2968 }
2969 }
2970
2971 return ret;
2972}
2973
2974int platform_start_incall_music_usecase(void *platform)
2975{
2976 int ret = 0;
2977 struct platform_data *my_data = (struct platform_data *)platform;
2978
2979 if (my_data->csd != NULL) {
2980 ret = my_data->csd->start_playback(ALL_SESSION_VSID);
2981 if (ret < 0) {
2982 ALOGE("%s: csd_client_start_playback failed, error %d",
2983 __func__, ret);
2984 }
2985 }
2986
2987 return ret;
2988}
2989
2990int platform_stop_incall_music_usecase(void *platform)
2991{
2992 int ret = 0;
2993 struct platform_data *my_data = (struct platform_data *)platform;
2994
2995 if (my_data->csd != NULL) {
2996 ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
2997 if (ret < 0) {
2998 ALOGE("%s: csd_client_stop_playback failed, error %d",
2999 __func__, ret);
3000 }
3001 }
3002
3003 return ret;
3004}
3005
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07003006int platform_set_parameters(void *platform, struct str_parms *parms)
3007{
3008 struct platform_data *my_data = (struct platform_data *)platform;
keunhui.park2f7306a2015-07-16 16:48:06 +09003009 char value[128];
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07003010 char *kv_pairs = str_parms_to_str(parms);
3011 int ret = 0, err;
3012
3013 if (kv_pairs == NULL) {
3014 ret = -EINVAL;
3015 ALOGE("%s: key-value pair is NULL",__func__);
3016 goto done;
3017 }
3018
3019 ALOGV("%s: enter: %s", __func__, kv_pairs);
3020
3021 err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_SOUNDCARD_NAME,
3022 value, sizeof(value));
3023 if (err >= 0) {
3024 str_parms_del(parms, PLATFORM_CONFIG_KEY_SOUNDCARD_NAME);
3025 my_data->snd_card_name = strdup(value);
3026 ALOGV("%s: sound card name %s", __func__, my_data->snd_card_name);
3027 }
3028
keunhui.park2f7306a2015-07-16 16:48:06 +09003029 err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO,
3030 value, sizeof(value));
3031 if (err >= 0) {
3032 struct operator_info *info;
3033 char *str = value;
3034 char *name;
3035
3036 str_parms_del(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO);
3037 info = (struct operator_info *)calloc(1, sizeof(struct operator_info));
3038 name = strtok(str, ";");
3039 info->name = strdup(name);
3040 info->mccmnc = strdup(str + strlen(name) + 1);
3041
3042 list_add_tail(&operator_info_list, &info->list);
Joe Onorato188b6222016-03-01 11:02:27 -08003043 ALOGV("%s: add operator[%s] mccmnc[%s]", __func__, info->name, info->mccmnc);
keunhui.park2f7306a2015-07-16 16:48:06 +09003044 }
Prashant Malanic92c5962015-08-11 15:10:18 -07003045
3046 memset(value, 0, sizeof(value));
Eric Laurentc6333382015-09-14 12:43:44 -07003047 err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_MAX_MIC_COUNT,
Prashant Malanic92c5962015-08-11 15:10:18 -07003048 value, sizeof(value));
3049 if (err >= 0) {
Eric Laurentc6333382015-09-14 12:43:44 -07003050 str_parms_del(parms, PLATFORM_CONFIG_KEY_MAX_MIC_COUNT);
Prashant Malanic92c5962015-08-11 15:10:18 -07003051 my_data->max_mic_count = atoi(value);
3052 ALOGV("%s: max_mic_count %s/%d", __func__, value, my_data->max_mic_count);
Prashant Malanic92c5962015-08-11 15:10:18 -07003053 }
3054
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07003055done:
3056 ALOGV("%s: exit with code(%d)", __func__, ret);
3057 if (kv_pairs != NULL)
3058 free(kv_pairs);
3059
3060 return ret;
3061}
3062
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07003063/* Delay in Us */
3064int64_t platform_render_latency(audio_usecase_t usecase)
3065{
3066 switch (usecase) {
3067 case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
3068 return DEEP_BUFFER_PLATFORM_DELAY;
3069 case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
3070 return LOW_LATENCY_PLATFORM_DELAY;
Haynes Mathew George03c40102016-01-29 17:57:48 -08003071 case USECASE_AUDIO_PLAYBACK_ULL:
3072 return ULL_PLATFORM_DELAY;
Eric Laurent0e46adf2016-12-16 12:49:24 -08003073 case USECASE_AUDIO_PLAYBACK_MMAP:
3074 return MMAP_PLATFORM_DELAY;
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07003075 default:
3076 return 0;
3077 }
3078}
Haynes Mathew George98c95622014-06-20 19:14:25 -07003079
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07003080int platform_set_snd_device_backend(snd_device_t device, const char *backend_tag,
3081 const char * hw_interface)
Haynes Mathew George98c95622014-06-20 19:14:25 -07003082{
3083 int ret = 0;
3084
3085 if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
3086 ALOGE("%s: Invalid snd_device = %d",
3087 __func__, device);
3088 ret = -EINVAL;
3089 goto done;
3090 }
3091
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07003092 ALOGV("%s: backend_tag_table[%s]: old = %s new = %s", __func__,
3093 platform_get_snd_device_name(device),
3094 backend_tag_table[device] != NULL ? backend_tag_table[device]: "null", backend_tag);
3095 if (backend_tag_table[device]) {
3096 free(backend_tag_table[device]);
Haynes Mathew George98c95622014-06-20 19:14:25 -07003097 }
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07003098 backend_tag_table[device] = strdup(backend_tag);
3099
3100 if (hw_interface != NULL) {
3101 if (hw_interface_table[device])
3102 free(hw_interface_table[device]);
3103 ALOGV("%s: hw_interface_table[%d] = %s", __func__, device, hw_interface);
3104 hw_interface_table[device] = strdup(hw_interface);
3105 }
Haynes Mathew George98c95622014-06-20 19:14:25 -07003106done:
3107 return ret;
3108}
3109
3110int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
3111{
3112 int ret = 0;
3113 if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
3114 ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
3115 ret = -EINVAL;
3116 goto done;
3117 }
3118
3119 if ((type != 0) && (type != 1)) {
3120 ALOGE("%s: invalid usecase type", __func__);
3121 ret = -EINVAL;
3122 }
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07003123 ALOGV("%s: pcm_device_table[%d][%d] = %d", __func__, usecase, type, pcm_id);
Haynes Mathew George98c95622014-06-20 19:14:25 -07003124 pcm_device_table[usecase][type] = pcm_id;
3125done:
3126 return ret;
3127}
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07003128
Jean-Michel Trivi88cbad32015-09-23 14:51:02 -07003129#define DEFAULT_NOMINAL_SPEAKER_GAIN 20
3130int ramp_speaker_gain(struct audio_device *adev, bool ramp_up, int target_ramp_up_gain) {
3131 // backup_gain: gain to try to set in case of an error during ramp
3132 int start_gain, end_gain, step, backup_gain, i;
3133 bool error = false;
3134 const struct mixer_ctl *ctl;
3135 const char *mixer_ctl_name_gain_left = "Left Speaker Gain";
3136 const char *mixer_ctl_name_gain_right = "Right Speaker Gain";
3137 struct mixer_ctl *ctl_left = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_left);
3138 struct mixer_ctl *ctl_right = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_right);
3139 if (!ctl_left || !ctl_right) {
3140 ALOGE("%s: Could not get ctl for mixer cmd - %s or %s, not applying speaker gain ramp",
3141 __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
3142 return -EINVAL;
3143 } else if ((mixer_ctl_get_num_values(ctl_left) != 1)
3144 || (mixer_ctl_get_num_values(ctl_right) != 1)) {
3145 ALOGE("%s: Unexpected num values for mixer cmd - %s or %s, not applying speaker gain ramp",
3146 __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
3147 return -EINVAL;
3148 }
3149 if (ramp_up) {
3150 start_gain = 0;
3151 end_gain = target_ramp_up_gain > 0 ? target_ramp_up_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
3152 step = +1;
3153 backup_gain = end_gain;
3154 } else {
3155 // using same gain on left and right
3156 const int left_gain = mixer_ctl_get_value(ctl_left, 0);
3157 start_gain = left_gain > 0 ? left_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
3158 end_gain = 0;
3159 step = -1;
3160 backup_gain = start_gain;
3161 }
3162 for (i = start_gain ; i != (end_gain + step) ; i += step) {
3163 //ALOGV("setting speaker gain to %d", i);
3164 if (mixer_ctl_set_value(ctl_left, 0, i)) {
3165 ALOGE("%s: error setting %s to %d during gain ramp",
3166 __func__, mixer_ctl_name_gain_left, i);
3167 error = true;
3168 break;
3169 }
3170 if (mixer_ctl_set_value(ctl_right, 0, i)) {
3171 ALOGE("%s: error setting %s to %d during gain ramp",
3172 __func__, mixer_ctl_name_gain_right, i);
3173 error = true;
3174 break;
3175 }
3176 usleep(1000);
3177 }
3178 if (error) {
3179 // an error occured during the ramp, let's still try to go back to a safe volume
3180 if (mixer_ctl_set_value(ctl_left, 0, backup_gain)) {
3181 ALOGE("%s: error restoring left gain to %d", __func__, backup_gain);
3182 }
3183 if (mixer_ctl_set_value(ctl_right, 0, backup_gain)) {
3184 ALOGE("%s: error restoring right gain to %d", __func__, backup_gain);
3185 }
3186 }
3187 return start_gain;
3188}
3189
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07003190int platform_swap_lr_channels(struct audio_device *adev, bool swap_channels)
3191{
3192 // only update if there is active pcm playback on speaker
3193 struct audio_usecase *usecase;
3194 struct listnode *node;
3195 struct platform_data *my_data = (struct platform_data *)adev->platform;
3196
3197 if (my_data->speaker_lr_swap != swap_channels) {
Jean-Michel Trivif7148702016-09-16 18:23:05 -07003198
3199 // do not swap channels in audio modes with concurrent capture and playback
3200 // as this may break the echo reference
3201 if ((adev->mode == AUDIO_MODE_IN_COMMUNICATION) || (adev->mode == AUDIO_MODE_IN_CALL)) {
3202 ALOGV("%s: will not swap due to audio mode %d", __func__, adev->mode);
3203 return 0;
3204 }
3205
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07003206 my_data->speaker_lr_swap = swap_channels;
3207
3208 list_for_each(node, &adev->usecase_list) {
3209 usecase = node_to_item(node, struct audio_usecase, list);
3210 if (usecase->type == PCM_PLAYBACK &&
Ravi Kumar Alamanda425e1542015-09-22 09:11:18 -07003211 usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
3212 /*
3213 * If acdb tuning is different for SPEAKER_REVERSE, it is must
3214 * to perform device switch to disable the current backend to
3215 * enable it with new acdb data.
3216 */
3217 if (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
3218 acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE]) {
Jean-Michel Trivi88cbad32015-09-23 14:51:02 -07003219 const int initial_skpr_gain = ramp_speaker_gain(adev, false /*ramp_up*/, -1);
Ravi Kumar Alamanda425e1542015-09-22 09:11:18 -07003220 select_devices(adev, usecase->id);
Jean-Michel Trivi88cbad32015-09-23 14:51:02 -07003221 if (initial_skpr_gain != -EINVAL) {
3222 ramp_speaker_gain(adev, true /*ramp_up*/, initial_skpr_gain);
3223 }
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07003224 } else {
Ravi Kumar Alamanda425e1542015-09-22 09:11:18 -07003225 const char *mixer_path;
3226 if (swap_channels) {
3227 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
3228 audio_route_apply_and_update_path(adev->audio_route, mixer_path);
3229 } else {
3230 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
3231 audio_route_apply_and_update_path(adev->audio_route, mixer_path);
3232 }
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07003233 }
3234 break;
3235 }
3236 }
3237 }
3238 return 0;
3239}
vivek mehtaa8d7c922016-05-25 14:40:44 -07003240
3241static struct amp_db_and_gain_table tbl_mapping[MAX_VOLUME_CAL_STEPS];
3242static int num_gain_tbl_entry = 0;
3243
3244bool platform_add_gain_level_mapping(struct amp_db_and_gain_table *tbl_entry) {
3245
3246 ALOGV("%s: enter .. add %f %f %d", __func__, tbl_entry->amp, tbl_entry->db, tbl_entry->level);
3247 if (num_gain_tbl_entry == -1) {
3248 ALOGE("%s: num entry beyond valid step levels or corrupted..rejecting custom mapping",
3249 __func__);
3250 return false;
3251 }
3252
3253 if (num_gain_tbl_entry >= MAX_VOLUME_CAL_STEPS) {
3254 ALOGE("%s: max entry reached max[%d] current index[%d] .. rejecting", __func__,
3255 MAX_VOLUME_CAL_STEPS, num_gain_tbl_entry);
3256 num_gain_tbl_entry = -1; // indicates error and no more info will be cached
3257 return false;
3258 }
3259
3260 if (num_gain_tbl_entry > 0 && tbl_mapping[num_gain_tbl_entry - 1].amp >= tbl_entry->amp) {
3261 ALOGE("%s: value not in ascending order .. rejecting custom mapping", __func__);
3262 num_gain_tbl_entry = -1; // indicates error and no more info will be cached
3263 return false;
3264 }
3265
3266 tbl_mapping[num_gain_tbl_entry] = *tbl_entry;
3267 ++num_gain_tbl_entry;
3268
3269 return true;
3270}
3271
3272int platform_get_gain_level_mapping(struct amp_db_and_gain_table *mapping_tbl,
3273 int table_size) {
3274 int itt = 0;
3275 ALOGV("platform_get_gain_level_mapping called ");
3276
3277 if (num_gain_tbl_entry <= 0 || num_gain_tbl_entry > MAX_VOLUME_CAL_STEPS) {
3278 ALOGD("%s: empty or currupted gain_mapping_table", __func__);
3279 return 0;
3280 }
3281
3282 for (; itt < num_gain_tbl_entry && itt <= table_size; itt++) {
3283 mapping_tbl[itt] = tbl_mapping[itt];
3284 ALOGV("%s: added amp[%f] db[%f] level[%d]", __func__,
3285 mapping_tbl[itt].amp, mapping_tbl[itt].db, mapping_tbl[itt].level);
3286 }
3287
3288 return num_gain_tbl_entry;
3289}
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -07003290
3291int platform_snd_card_update(void *platform, card_status_t status)
3292{
3293 struct platform_data *my_data = (struct platform_data *)platform;
3294 struct audio_device *adev = my_data->adev;
3295
3296 if (status == CARD_STATUS_ONLINE) {
3297 if (my_data->acdb_send_custom_top)
3298 my_data->acdb_send_custom_top();
3299 }
3300 return 0;
3301}
David Linee3fe402017-03-13 10:00:42 -07003302
3303/*
3304 * configures afe with bit width and Sample Rate
3305 */
3306static int platform_set_backend_cfg(const struct audio_device* adev,
3307 snd_device_t snd_device,
3308 const struct audio_backend_cfg *backend_cfg)
3309{
3310
3311 int ret = 0;
3312 const int backend_idx = platform_get_backend_index(snd_device);
3313 struct platform_data *my_data = (struct platform_data *)adev->platform;
3314 const unsigned int bit_width = backend_cfg->bit_width;
3315 const unsigned int sample_rate = backend_cfg->sample_rate;
3316 const unsigned int channels = backend_cfg->channels;
3317 const audio_format_t format = backend_cfg->format;
3318 const bool passthrough_enabled = backend_cfg->passthrough_enabled;
3319
3320
3321 ALOGV("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
3322 ", backend_idx %d device (%s)", __func__, bit_width,
3323 sample_rate, channels, backend_idx,
3324 platform_get_snd_device_name(snd_device));
3325
3326 if ((my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl) &&
3327 (bit_width != my_data->current_backend_cfg[backend_idx].bit_width)) {
3328
3329 struct mixer_ctl *ctl = NULL;
3330 ctl = mixer_get_ctl_by_name(adev->mixer,
3331 my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl);
3332 if (!ctl) {
3333 ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
3334 __func__,
3335 my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl);
3336 return -EINVAL;
3337 }
3338
3339 if (bit_width == 24) {
3340 if (format == AUDIO_FORMAT_PCM_24_BIT_PACKED)
3341 ret = mixer_ctl_set_enum_by_string(ctl, "S24_3LE");
3342 else
3343 ret = mixer_ctl_set_enum_by_string(ctl, "S24_LE");
3344 } else if (bit_width == 32) {
3345 ret = mixer_ctl_set_enum_by_string(ctl, "S32_LE");
3346 } else {
3347 ret = mixer_ctl_set_enum_by_string(ctl, "S16_LE");
3348 }
3349 if ( ret < 0) {
3350 ALOGE("%s:becf: afe: fail for %s mixer set to %d bit for %x format", __func__,
3351 my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl, bit_width, format);
3352 } else {
3353 my_data->current_backend_cfg[backend_idx].bit_width = bit_width;
3354 ALOGD("%s:becf: afe: %s mixer set to %d bit for %x format", __func__,
3355 my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl, bit_width, format);
3356 }
3357 /* set the ret as 0 and not pass back to upper layer */
3358 ret = 0;
3359 }
3360
3361 if (passthrough_enabled || ((my_data->current_backend_cfg[backend_idx].samplerate_mixer_ctl) &&
3362 (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate))) {
3363 char *rate_str = NULL;
3364 struct mixer_ctl *ctl = NULL;
3365
3366 switch (sample_rate) {
3367 case 32000:
3368 if (passthrough_enabled) {
3369 rate_str = "KHZ_32";
3370 break;
3371 }
3372 case 8000:
3373 case 11025:
3374 case 16000:
3375 case 22050:
3376 case 48000:
3377 rate_str = "KHZ_48";
3378 break;
3379 case 44100:
3380 rate_str = "KHZ_44P1";
3381 break;
3382 case 64000:
3383 case 96000:
3384 rate_str = "KHZ_96";
3385 break;
3386 case 88200:
3387 rate_str = "KHZ_88P2";
3388 break;
3389 case 176400:
3390 rate_str = "KHZ_176P4";
3391 break;
3392 case 192000:
3393 rate_str = "KHZ_192";
3394 break;
3395 case 352800:
3396 rate_str = "KHZ_352P8";
3397 break;
3398 case 384000:
3399 rate_str = "KHZ_384";
3400 break;
3401 case 144000:
3402 if (passthrough_enabled) {
3403 rate_str = "KHZ_144";
3404 break;
3405 }
3406 default:
3407 rate_str = "KHZ_48";
3408 break;
3409 }
3410
3411 ctl = mixer_get_ctl_by_name(adev->mixer,
3412 my_data->current_backend_cfg[backend_idx].samplerate_mixer_ctl);
3413 if(!ctl) {
3414 ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
3415 __func__,
3416 my_data->current_backend_cfg[backend_idx].samplerate_mixer_ctl);
3417 return -EINVAL;
3418 }
3419
3420 ALOGD("%s:becf: afe: %s set to %s", __func__,
3421 my_data->current_backend_cfg[backend_idx].samplerate_mixer_ctl, rate_str);
3422 mixer_ctl_set_enum_by_string(ctl, rate_str);
3423 my_data->current_backend_cfg[backend_idx].sample_rate = sample_rate;
3424 }
3425 if ((my_data->current_backend_cfg[backend_idx].channels_mixer_ctl) &&
3426 (channels != my_data->current_backend_cfg[backend_idx].channels)) {
3427 struct mixer_ctl *ctl = NULL;
3428 char *channel_cnt_str = NULL;
3429
3430 switch (channels) {
3431 case 8:
3432 channel_cnt_str = "Eight"; break;
3433 case 7:
3434 channel_cnt_str = "Seven"; break;
3435 case 6:
3436 channel_cnt_str = "Six"; break;
3437 case 5:
3438 channel_cnt_str = "Five"; break;
3439 case 4:
3440 channel_cnt_str = "Four"; break;
3441 case 3:
3442 channel_cnt_str = "Three"; break;
3443 case 1:
3444 channel_cnt_str = "One"; break;
3445 case 2:
3446 default:
3447 channel_cnt_str = "Two"; break;
3448 }
3449
3450 ctl = mixer_get_ctl_by_name(adev->mixer,
3451 my_data->current_backend_cfg[backend_idx].channels_mixer_ctl);
3452 if (!ctl) {
3453 ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
3454 __func__,
3455 my_data->current_backend_cfg[backend_idx].channels_mixer_ctl);
3456 return -EINVAL;
3457 }
3458 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
3459 my_data->current_backend_cfg[backend_idx].channels = channels;
3460
3461 // skip EDID configuration for HDMI backend
3462
3463 ALOGD("%s:becf: afe: %s set to %s", __func__,
3464 my_data->current_backend_cfg[backend_idx].channels_mixer_ctl,
3465 channel_cnt_str);
3466 }
3467
3468 // skip set ext_display format mixer control
3469 return ret;
3470}
3471
3472static int platform_get_snd_device_bit_width(snd_device_t snd_device)
3473{
3474 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
3475 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
3476 return CODEC_BACKEND_DEFAULT_BIT_WIDTH;
3477 }
3478
3479 return backend_bit_width_table[snd_device];
3480}
3481
3482/*
3483 * return backend_idx on which voice call is active
3484 */
3485static int platform_get_voice_call_backend(struct audio_device* adev)
3486{
3487 struct audio_usecase *uc = NULL;
3488 struct listnode *node;
3489 snd_device_t out_snd_device = SND_DEVICE_NONE;
3490
3491 int backend_idx = -1;
3492
3493 if (voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
3494 list_for_each(node, &adev->usecase_list) {
3495 uc = node_to_item(node, struct audio_usecase, list);
3496 if (uc && uc->type == VOICE_CALL && uc->stream.out) {
3497 out_snd_device = platform_get_output_snd_device(adev->platform,
3498 uc->stream.out->devices);
3499 backend_idx = platform_get_backend_index(out_snd_device);
3500 break;
3501 }
3502 }
3503 }
3504 return backend_idx;
3505}
3506
3507/*
3508 * goes through all the current usecases and picks the highest
3509 * bitwidth & samplerate
3510 */
3511static bool platform_check_capture_backend_cfg(struct audio_device* adev,
3512 int backend_idx,
3513 struct audio_backend_cfg *backend_cfg)
3514{
3515 bool backend_change = false;
3516 unsigned int bit_width;
3517 unsigned int sample_rate;
3518 unsigned int channels;
3519 struct platform_data *my_data = (struct platform_data *)adev->platform;
3520
3521 bit_width = backend_cfg->bit_width;
3522 sample_rate = backend_cfg->sample_rate;
3523 channels = backend_cfg->channels;
3524
3525 ALOGV("%s:txbecf: afe: Codec selected backend: %d current bit width: %d and "
3526 "sample rate: %d, channels %d",__func__,backend_idx, bit_width,
3527 sample_rate, channels);
3528
3529 // For voice calls use default configuration i.e. 16b/48K, only applicable to
3530 // default backend
3531 // force routing is not required here, caller will do it anyway
3532 if (voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
3533 ALOGW("%s:txbecf: afe: Use default bw and sr for voice/voip calls and "
3534 "for unprocessed/camera source", __func__);
3535 bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
3536 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
3537 }
3538
3539 if (backend_idx == USB_AUDIO_TX_BACKEND) {
3540 audio_extn_usb_is_config_supported(&bit_width, &sample_rate, &channels, false);
3541 ALOGV("%s:txbecf: afe: USB BE configured as bit_width(%d)sample_rate(%d)channels(%d)",
3542 __func__, bit_width, sample_rate, channels);
3543 }
3544
3545 ALOGV("%s:txbecf: afe: Codec selected backend: %d updated bit width: %d and "
3546 "sample rate: %d", __func__, backend_idx, bit_width, sample_rate);
3547
3548 // Force routing if the expected bitwdith or samplerate
3549 // is not same as current backend comfiguration
3550 if ((bit_width != my_data->current_backend_cfg[backend_idx].bit_width) ||
3551 (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate) ||
3552 (channels != my_data->current_backend_cfg[backend_idx].channels)) {
3553 backend_cfg->bit_width = bit_width;
3554 backend_cfg->sample_rate= sample_rate;
3555 backend_cfg->channels = channels;
3556 backend_change = true;
3557 ALOGI("%s:txbecf: afe: Codec backend needs to be updated. new bit width: %d "
3558 "new sample rate: %d new channel: %d",
3559 __func__, backend_cfg->bit_width,
3560 backend_cfg->sample_rate, backend_cfg->channels);
3561 }
3562
3563 return backend_change;
3564}
3565
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08003566static void pick_playback_cfg_for_uc(struct audio_device *adev,
3567 struct audio_usecase *usecase,
3568 snd_device_t snd_device,
3569 unsigned int *bit_width,
3570 unsigned int *sample_rate,
3571 unsigned int *channels)
Haynes Mathew George4bd47992017-03-09 17:59:38 -08003572{
3573 int i =0;
3574 struct listnode *node;
3575 list_for_each(node, &adev->usecase_list) {
3576 struct audio_usecase *uc;
3577 uc = node_to_item(node, struct audio_usecase, list);
3578 struct stream_out *out = (struct stream_out*) uc->stream.out;
3579 if (uc->type == PCM_PLAYBACK && out && usecase != uc) {
3580 unsigned int out_channels = audio_channel_count_from_out_mask(out->channel_mask);
3581 ALOGV("%s:napb: (%d) - (%s)id (%d) sr %d bw "
3582 "(%d) ch (%d) device %s", __func__, i++, use_case_table[uc->id],
3583 uc->id, out->sample_rate,
3584 pcm_format_to_bits(out->config.format), out_channels,
3585 platform_get_snd_device_name(uc->out_snd_device));
3586
3587 if (platform_check_backends_match(snd_device, uc->out_snd_device)) {
3588 if (*bit_width < pcm_format_to_bits(out->config.format))
3589 *bit_width = pcm_format_to_bits(out->config.format);
3590 if (*sample_rate < out->sample_rate)
3591 *sample_rate = out->sample_rate;
3592 if (out->sample_rate < OUTPUT_SAMPLING_RATE_44100)
3593 *sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
3594 if (*channels < out_channels)
3595 *channels = out_channels;
3596 }
3597 }
3598 }
3599 return;
3600}
3601
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08003602static void headset_is_config_supported(unsigned int *bit_width,
3603 unsigned int *sample_rate,
3604 unsigned int *channels) {
3605 switch (*bit_width) {
3606 case 16:
3607 case 24:
3608 break;
3609 default:
3610 *bit_width = 16;
3611 break;
3612 }
3613
3614 if (*sample_rate > 192000) {
3615 *sample_rate = 192000;
3616 }
3617
3618 if (*channels > 2) {
3619 *channels = 2;
3620 }
3621}
3622
David Linee3fe402017-03-13 10:00:42 -07003623static bool platform_check_playback_backend_cfg(struct audio_device* adev,
3624 struct audio_usecase* usecase,
3625 snd_device_t snd_device,
3626 struct audio_backend_cfg *backend_cfg)
3627{
3628 bool backend_change = false;
David Linee3fe402017-03-13 10:00:42 -07003629 unsigned int bit_width;
3630 unsigned int sample_rate;
3631 unsigned int channels;
David Linee3fe402017-03-13 10:00:42 -07003632 int backend_idx = DEFAULT_CODEC_BACKEND;
3633 struct platform_data *my_data = (struct platform_data *)adev->platform;
David Linee3fe402017-03-13 10:00:42 -07003634
3635 if (snd_device == SND_DEVICE_OUT_BT_SCO ||
3636 snd_device == SND_DEVICE_OUT_BT_SCO_WB) {
3637 backend_change = false;
3638 return backend_change;
3639 }
3640
3641 backend_idx = platform_get_backend_index(snd_device);
3642 bit_width = backend_cfg->bit_width;
3643 sample_rate = backend_cfg->sample_rate;
3644 channels = backend_cfg->channels;
3645
3646 ALOGV("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
3647 ", backend_idx %d usecase = %d device (%s)", __func__, bit_width,
3648 sample_rate, channels, backend_idx, usecase->id,
3649 platform_get_snd_device_name(snd_device));
3650
3651 if (backend_idx == platform_get_voice_call_backend(adev)) {
3652 ALOGW("%s:becf: afe:Use default bw and sr for voice/voip calls ",
3653 __func__);
3654 bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
3655 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
3656 channels = CODEC_BACKEND_DEFAULT_CHANNELS;
3657 } else {
3658 /*
3659 * The backend should be configured at highest bit width and/or
3660 * sample rate amongst all playback usecases.
3661 * If the selected sample rate and/or bit width differ with
3662 * current backend sample rate and/or bit width, then, we set the
3663 * backend re-configuration flag.
3664 *
3665 * Exception: 16 bit playbacks is allowed through 16 bit/48/44.1 khz backend only
3666 */
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08003667 pick_playback_cfg_for_uc(adev, usecase, snd_device,
3668 &bit_width,
3669 &sample_rate,
3670 &channels);
David Linee3fe402017-03-13 10:00:42 -07003671 }
3672
Haynes Mathew George4bd47992017-03-09 17:59:38 -08003673 switch (backend_idx) {
3674 case USB_AUDIO_RX_BACKEND:
3675 audio_extn_usb_is_config_supported(&bit_width,
3676 &sample_rate, &channels, true);
3677 ALOGV("%s: USB BE configured as bit_width(%d)sample_rate(%d)channels(%d)",
3678 __func__, bit_width, sample_rate, channels);
3679 break;
Haynes Mathew George4bd47992017-03-09 17:59:38 -08003680 case HEADPHONE_BACKEND:
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08003681 headset_is_config_supported(&bit_width, &sample_rate, &channels);
3682 break;
3683 case DEFAULT_CODEC_BACKEND:
Haynes Mathew George4bd47992017-03-09 17:59:38 -08003684 default:
3685 bit_width = platform_get_snd_device_bit_width(snd_device);
3686 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
3687 channels = CODEC_BACKEND_DEFAULT_CHANNELS;
3688 break;
David Linee3fe402017-03-13 10:00:42 -07003689 }
3690
Haynes Mathew George4bd47992017-03-09 17:59:38 -08003691 ALOGV("%s:becf: afe: Codec selected backend: %d updated bit width: %d and"
3692 "sample rate: %d",
David Linee3fe402017-03-13 10:00:42 -07003693 __func__, backend_idx , bit_width, sample_rate);
3694
3695 // Force routing if the expected bitwdith or samplerate
3696 // is not same as current backend comfiguration
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08003697 if (bit_width != my_data->current_backend_cfg[backend_idx].bit_width ||
3698 sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate ||
3699 channels != my_data->current_backend_cfg[backend_idx].channels) {
David Linee3fe402017-03-13 10:00:42 -07003700 backend_cfg->bit_width = bit_width;
3701 backend_cfg->sample_rate = sample_rate;
3702 backend_cfg->channels = channels;
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08003703 backend_cfg->passthrough_enabled = false;
David Linee3fe402017-03-13 10:00:42 -07003704 backend_change = true;
3705 ALOGV("%s:becf: afe: Codec backend needs to be updated. new bit width: %d"
3706 "new sample rate: %d new channels: %d",
3707 __func__, backend_cfg->bit_width, backend_cfg->sample_rate, backend_cfg->channels);
3708 }
3709
3710 return backend_change;
3711}
3712
3713bool platform_check_and_set_playback_backend_cfg(struct audio_device* adev,
3714 struct audio_usecase *usecase, snd_device_t snd_device)
3715{
3716 int backend_idx = DEFAULT_CODEC_BACKEND;
3717 int new_snd_devices[SND_DEVICE_OUT_END];
3718 int i, num_devices = 1;
3719 bool ret = false;
3720 struct platform_data *my_data = (struct platform_data *)adev->platform;
3721 struct audio_backend_cfg backend_cfg;
3722
3723 backend_idx = platform_get_backend_index(snd_device);
3724
3725 backend_cfg.bit_width = pcm_format_to_bits(usecase->stream.out->config.format);
3726 backend_cfg.sample_rate = usecase->stream.out->sample_rate;
3727 backend_cfg.format = usecase->stream.out->format;
3728 backend_cfg.channels = audio_channel_count_from_out_mask(usecase->stream.out->channel_mask);
3729 /*this is populated by check_codec_backend_cfg hence set default value to false*/
3730 backend_cfg.passthrough_enabled = false;
3731
3732 ALOGV("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
3733 ", backend_idx %d usecase = %d device (%s)", __func__, backend_cfg.bit_width,
3734 backend_cfg.sample_rate, backend_cfg.channels, backend_idx, usecase->id,
3735 platform_get_snd_device_name(snd_device));
3736
3737 if (platform_can_split_snd_device(snd_device, &num_devices, new_snd_devices) < 0)
3738 new_snd_devices[0] = snd_device;
3739
3740 for (i = 0; i < num_devices; i++) {
3741 ALOGV("%s: new_snd_devices[%d] is %d", __func__, i, new_snd_devices[i]);
3742 if ((platform_check_playback_backend_cfg(adev, usecase, new_snd_devices[i],
3743 &backend_cfg))) {
3744 platform_set_backend_cfg(adev, new_snd_devices[i],
3745 &backend_cfg);
3746 ret = true;
3747 }
3748 }
3749 return ret;
3750}
3751
3752bool platform_check_and_set_capture_backend_cfg(struct audio_device* adev,
3753 struct audio_usecase *usecase, snd_device_t snd_device)
3754{
3755 int backend_idx = platform_get_backend_index(snd_device);
3756 int ret = 0;
3757 struct audio_backend_cfg backend_cfg;
Haynes Mathew George4bd47992017-03-09 17:59:38 -08003758 memset(&backend_cfg, 0, sizeof(struct audio_backend_cfg));
David Linee3fe402017-03-13 10:00:42 -07003759
Haynes Mathew George4bd47992017-03-09 17:59:38 -08003760 if (usecase->type == PCM_CAPTURE) {
3761 backend_cfg.format = usecase->stream.in->format;
David Linee3fe402017-03-13 10:00:42 -07003762 backend_cfg.channels = audio_channel_count_from_in_mask(usecase->stream.in->channel_mask);
3763 } else {
3764 backend_cfg.bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
3765 backend_cfg.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
3766 backend_cfg.format = AUDIO_FORMAT_PCM_16_BIT;
3767 backend_cfg.channels = 1;
3768 }
3769
3770 ALOGV("%s:txbecf: afe: bitwidth %d, samplerate %d, channel %d"
3771 ", backend_idx %d usecase = %d device (%s)", __func__,
3772 backend_cfg.bit_width,
3773 backend_cfg.sample_rate,
3774 backend_cfg.channels,
3775 backend_idx, usecase->id,
3776 platform_get_snd_device_name(snd_device));
3777
3778 if (platform_check_capture_backend_cfg(adev, backend_idx, &backend_cfg)) {
3779 ret = platform_set_backend_cfg(adev, snd_device,
3780 &backend_cfg);
3781 if(!ret)
3782 return true;
3783 }
3784
3785 return false;
3786}
3787
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08003788static int max_be_dai_names = 0;
3789static const struct be_dai_name_struct *be_dai_name_table;
3790
3791/*
3792 * Retrieves the be_dai_name_table from kernel to enable a mapping
3793 * between sound device hw interfaces and backend IDs. This allows HAL to
3794 * specify the backend a specific calibration is needed for.
3795 */
3796static int init_be_dai_name_table(struct audio_device *adev)
3797{
3798 const char *mixer_ctl_name = "Backend DAI Name Table";
3799 struct mixer_ctl *ctl;
3800 int i, j, ret, size;
3801 bool valid_hw_interface;
3802
3803 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
3804 if (!ctl) {
3805 ALOGE("%s: Could not get ctl for mixer name %s\n",
3806 __func__, mixer_ctl_name);
3807 ret = -EINVAL;
3808 goto done;
3809 }
3810
3811 mixer_ctl_update(ctl);
3812
3813 size = mixer_ctl_get_num_values(ctl);
3814 if (size <= 0){
3815 ALOGE("%s: Failed to get %s size %d\n",
3816 __func__, mixer_ctl_name, size);
3817 ret = -EFAULT;
3818 goto done;
3819 }
3820
3821 posix_memalign((void **)&be_dai_name_table, 32, size);
3822 if (be_dai_name_table == NULL) {
3823 ALOGE("%s: Failed to allocate memory for %s\n",
3824 __func__, mixer_ctl_name);
3825 ret = -ENOMEM;
3826 goto freeMem;
3827 }
3828
3829 ret = mixer_ctl_get_array(ctl, (void *)be_dai_name_table, size);
3830 if (ret) {
3831 ALOGE("%s: Failed to get %s, ret %d\n",
3832 __func__, mixer_ctl_name, ret);
3833 ret = -EFAULT;
3834 goto freeMem;
3835 }
3836
3837 if (be_dai_name_table != NULL) {
3838 max_be_dai_names = size / sizeof(struct be_dai_name_struct);
3839 ALOGV("%s: Successfully got %s, number of be dais is %d\n",
3840 __func__, mixer_ctl_name, max_be_dai_names);
3841 ret = 0;
3842 } else {
3843 ALOGE("%s: Failed to get %s\n", __func__, mixer_ctl_name);
3844 ret = -EFAULT;
3845 goto freeMem;
3846 }
3847
3848 /*
3849 * Validate all sound devices have a valid backend set to catch
3850 * errors for uncommon sound devices
3851 */
3852 for (i = 0; i < SND_DEVICE_MAX; i++) {
3853 valid_hw_interface = false;
3854
3855 if (hw_interface_table[i] == NULL) {
3856 ALOGW("%s: sound device %s has no hw interface set\n",
3857 __func__, platform_get_snd_device_name(i));
3858 continue;
3859 }
3860
3861 for (j = 0; j < max_be_dai_names; j++) {
3862 if (strcmp(hw_interface_table[i], be_dai_name_table[j].be_name)
3863 == 0) {
3864 valid_hw_interface = true;
3865 break;
3866 }
3867 }
3868 if (!valid_hw_interface)
3869 ALOGD("%s: sound device %s does not have a valid hw interface set "
3870 "(disregard for combo devices) %s\n",
3871 __func__, platform_get_snd_device_name(i),
3872 hw_interface_table[i]);
3873 }
3874
3875 goto done;
3876
3877freeMem:
3878 if (be_dai_name_table) {
3879 free((void *)be_dai_name_table);
3880 be_dai_name_table = NULL;
3881 }
3882
3883done:
3884 return ret;
3885}
3886
3887int platform_get_snd_device_backend_index(snd_device_t device)
3888{
3889 int i, be_dai_id;
3890 const char * hw_interface_name = NULL;
3891
3892 ALOGV("%s: enter with device %d\n", __func__, device);
3893
3894 if ((device <= SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
3895 ALOGE("%s: Invalid snd_device = %d",
3896 __func__, device);
3897 be_dai_id = -EINVAL;
3898 goto done;
3899 }
3900
3901 /* Get string value of necessary backend for device */
3902 hw_interface_name = hw_interface_table[device];
3903 if (hw_interface_name == NULL) {
3904 ALOGE("%s: no hw_interface set for device %d\n", __func__, device);
3905 be_dai_id = -EINVAL;
3906 goto done;
3907 }
3908
3909 /* Check if be dai name table was retrieved successfully */
3910 if (be_dai_name_table == NULL) {
3911 ALOGE("%s: BE DAI Name Table is not present\n", __func__);
3912 be_dai_id = -EFAULT;
3913 goto done;
3914 }
3915
3916 /* Get backend ID for device specified */
3917 for (i = 0; i < max_be_dai_names; i++) {
3918 if (strcmp(hw_interface_name, be_dai_name_table[i].be_name) == 0) {
3919 be_dai_id = be_dai_name_table[i].be_id;
3920 goto done;
3921 }
3922 }
3923 ALOGE("%s: no interface matching name %s\n", __func__, hw_interface_name);
3924 be_dai_id = -EINVAL;
3925 goto done;
3926
3927done:
3928 return be_dai_id;
3929}
3930
3931void platform_check_and_update_copp_sample_rate(void* platform, snd_device_t snd_device,
3932 unsigned int stream_sr, int* sample_rate)
3933{
3934 struct platform_data* my_data = (struct platform_data *)platform;
3935 int backend_idx = platform_get_backend_index(snd_device);
3936 int device_sr = my_data->current_backend_cfg[backend_idx].sample_rate;
3937 /*
3938 *Check if device SR is multiple of 8K or 11.025 Khz
3939 *check if the stream SR is multiple of same base, if yes
3940 *then have copp SR equal to stream SR, this ensures that
3941 *post processing happens at stream SR, else have
3942 *copp SR equal to device SR.
3943 */
3944 if (!(((sample_rate_multiple(device_sr, SAMPLE_RATE_8000)) &&
3945 (sample_rate_multiple(stream_sr, SAMPLE_RATE_8000))) ||
3946 ((sample_rate_multiple(device_sr, SAMPLE_RATE_11025)) &&
3947 (sample_rate_multiple(stream_sr, SAMPLE_RATE_11025))))) {
3948 *sample_rate = device_sr;
3949 } else
3950 *sample_rate = stream_sr;
3951
3952 ALOGI("sn_device %d device sr %d stream sr %d copp sr %d", snd_device, device_sr, stream_sr
3953 , *sample_rate);
3954
3955}
3956
3957// called from info parser
3958void platform_add_app_type(int bw, const char *uc_type,
3959 int app_type, int max_rate) {
3960 struct app_type_entry *ap =
3961 (struct app_type_entry *)calloc(1, sizeof(struct app_type_entry));
3962
3963 if (!ap) {
3964 ALOGE("%s failed to allocate mem for app type", __func__);
3965 return;
3966 }
3967
3968 ap->uc_type = -1;
3969 for (int i=0; i<USECASE_TYPE_MAX; i++) {
3970 if (!strcmp(uc_type, usecase_type_index[i].name)) {
3971 ap->uc_type = usecase_type_index[i].index;
3972 break;
3973 }
3974 }
3975
3976 if (ap->uc_type == -1) {
3977 free(ap);
3978 return;
3979 }
3980
3981 ALOGI("%s bw %d uc %s app_type %d max_rate %d",
3982 __func__, bw, uc_type, app_type, max_rate);
3983 ap->bit_width = bw;
3984 ap->app_type = app_type;
3985 ap->max_rate = max_rate;
3986 list_add_tail(&app_type_entry_list, &ap->node);
3987}
3988
3989
3990int platform_get_default_app_type_v2(void *platform __unused,
3991 usecase_type_t type,
3992 int *app_type )
3993{
3994 if (type == PCM_PLAYBACK)
3995 *app_type = DEFAULT_APP_TYPE_RX_PATH;
3996 else
3997 *app_type = DEFAULT_APP_TYPE_TX_PATH;
3998 return 0;
3999}
4000
4001int platform_get_app_type_v2(void *platform, usecase_type_t uc_type,
4002 int bw, int sr __unused,
4003 int *app_type)
4004{
4005 struct listnode *node;
4006 struct app_type_entry *entry;
4007 *app_type = -1;
4008 list_for_each(node, &app_type_entry_list) {
4009 entry = node_to_item(node, struct app_type_entry, node);
4010 if (entry->bit_width == bw &&
4011 entry->uc_type == uc_type) {
4012 *app_type = entry->app_type;
4013 break;
4014 }
4015 }
4016
4017 if (*app_type == -1) {
4018 return platform_get_default_app_type_v2(platform, uc_type, app_type);
4019 }
4020 return 0;
4021}