blob: 23a122aad89818f0e86436ab9d9875894bd84b92 [file] [log] [blame]
Eric Laurentb23d5282013-05-14 15:27:20 -07001/*
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002 * Copyright (C) 2013-2014 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 */
16
17#define LOG_TAG "msm8974_platform"
18/*#define LOG_NDEBUG 0*/
19#define LOG_NDDEBUG 0
20
21#include <stdlib.h>
22#include <dlfcn.h>
23#include <cutils/log.h>
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -070024#include <cutils/str_parms.h>
Eric Laurentb23d5282013-05-14 15:27:20 -070025#include <cutils/properties.h>
26#include <audio_hw.h>
27#include <platform_api.h>
28#include "platform.h"
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -070029#include "audio_extn.h"
vivek mehta1a9b7c02015-06-25 11:49:38 -070030#include <linux/msm_audio.h>
Eric Laurentb23d5282013-05-14 15:27:20 -070031
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070032#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
Eric Laurentb23d5282013-05-14 15:27:20 -070033#define LIB_ACDB_LOADER "libacdbloader.so"
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070034#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +090035#define CVD_VERSION_MIXER_CTL "CVD Version"
Eric Laurentb23d5282013-05-14 15:27:20 -070036
37#define DUALMIC_CONFIG_NONE 0 /* Target does not contain 2 mics */
38#define DUALMIC_CONFIG_ENDFIRE 1
39#define DUALMIC_CONFIG_BROADSIDE 2
40
41/*
Eric Laurentb23d5282013-05-14 15:27:20 -070042 * This file will have a maximum of 38 bytes:
43 *
44 * 4 bytes: number of audio blocks
45 * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
46 * Maximum 10 * 3 bytes: SAD blocks
47 */
48#define MAX_SAD_BLOCKS 10
49#define SAD_BLOCK_SIZE 3
50
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +090051#define MAX_CVD_VERSION_STRING_SIZE 100
52
Eric Laurentb23d5282013-05-14 15:27:20 -070053/* EDID format ID for LPCM audio */
54#define EDID_FORMAT_LPCM 1
55
sangwoo1b9f4b32013-06-21 18:22:55 -070056/* Retry for delay in FW loading*/
57#define RETRY_NUMBER 10
58#define RETRY_US 500000
Vineeta Srivastava4b89e372014-06-19 14:21:42 -070059#define MAX_SND_CARD 8
sangwoo53b2cf02013-07-25 19:18:44 -070060
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -070061#define MAX_SND_CARD_NAME_LEN 31
62
vivek mehta1a9b7c02015-06-25 11:49:38 -070063#define DEFAULT_APP_TYPE_RX_PATH 0x11130
64
keunhui.parkc5aaa0e2015-07-13 10:57:37 +090065#define TOSTRING_(x) #x
66#define TOSTRING(x) TOSTRING_(x)
67
Eric Laurentb23d5282013-05-14 15:27:20 -070068struct audio_block_header
69{
70 int reserved;
71 int length;
72};
73
vivek mehta1a9b7c02015-06-25 11:49:38 -070074enum {
75 CAL_MODE_SEND = 0x1,
76 CAL_MODE_PERSIST = 0x2,
77 CAL_MODE_RTAC = 0x4
78};
79
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -070080/* Audio calibration related functions */
Eric Laurentb23d5282013-05-14 15:27:20 -070081typedef void (*acdb_deallocate_t)();
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +090082typedef int (*acdb_init_v2_cvd_t)(char *, char *);
83typedef int (*acdb_init_v2_t)(char *);
Eric Laurentb23d5282013-05-14 15:27:20 -070084typedef int (*acdb_init_t)();
85typedef void (*acdb_send_audio_cal_t)(int, int);
86typedef void (*acdb_send_voice_cal_t)(int, int);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -070087typedef int (*acdb_reload_vocvoltable_t)(int);
vivek mehta1a9b7c02015-06-25 11:49:38 -070088typedef int (*acdb_send_gain_dep_cal_t)(int, int, int, int, int);
Eric Laurentb23d5282013-05-14 15:27:20 -070089
90/* Audio calibration related functions */
91struct platform_data {
92 struct audio_device *adev;
93 bool fluence_in_spkr_mode;
94 bool fluence_in_voice_call;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -070095 bool fluence_in_voice_comm;
Eric Laurentb23d5282013-05-14 15:27:20 -070096 bool fluence_in_voice_rec;
97 int dualmic_config;
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -070098 bool speaker_lr_swap;
99
Eric Laurentb23d5282013-05-14 15:27:20 -0700100 void *acdb_handle;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700101 acdb_deallocate_t acdb_deallocate;
102 acdb_send_audio_cal_t acdb_send_audio_cal;
103 acdb_send_voice_cal_t acdb_send_voice_cal;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700104 acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
vivek mehta1a9b7c02015-06-25 11:49:38 -0700105 acdb_send_gain_dep_cal_t acdb_send_gain_dep_cal;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700106 struct csd_data *csd;
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800107 char ec_ref_mixer_path[64];
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -0700108
109 char *snd_card_name;
keunhui.parkc5aaa0e2015-07-13 10:57:37 +0900110 int max_vol_index;
Eric Laurentb23d5282013-05-14 15:27:20 -0700111};
112
Haynes Mathew George98c95622014-06-20 19:14:25 -0700113static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700114 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
115 DEEP_BUFFER_PCM_DEVICE},
116 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
117 LOWLATENCY_PCM_DEVICE},
118 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
119 MULTIMEDIA2_PCM_DEVICE},
120 [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {PLAYBACK_OFFLOAD_DEVICE,
121 PLAYBACK_OFFLOAD_DEVICE},
Ravi Kumar Alamandaf78a4d92015-04-24 15:18:23 -0700122 [USECASE_AUDIO_PLAYBACK_TTS] = {MULTIMEDIA3_PCM_DEVICE,
123 MULTIMEDIA3_PCM_DEVICE},
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700124 [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE,
125 AUDIO_RECORD_PCM_DEVICE},
126 [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
127 LOWLATENCY_PCM_DEVICE},
128 [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE,
129 VOICE_CALL_PCM_DEVICE},
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700130 [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
131 [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
132 [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
133 [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
134 [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
135 AUDIO_RECORD_PCM_DEVICE},
136 [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
137 AUDIO_RECORD_PCM_DEVICE},
138 [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
139 AUDIO_RECORD_PCM_DEVICE},
Ravi Kumar Alamanda8e6e98f2013-11-05 15:57:39 -0800140 [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700141
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700142 [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
143 [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
144
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700145 [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
146 AFE_PROXY_RECORD_PCM_DEVICE},
147 [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
148 AFE_PROXY_RECORD_PCM_DEVICE},
zhaoyang yin4211fad2015-06-04 21:13:25 +0800149 [USECASE_AUDIO_DSM_FEEDBACK] = {QUAT_MI2S_PCM_DEVICE, QUAT_MI2S_PCM_DEVICE},
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700150
Eric Laurentb23d5282013-05-14 15:27:20 -0700151};
152
153/* Array to store sound devices */
154static const char * const device_table[SND_DEVICE_MAX] = {
155 [SND_DEVICE_NONE] = "none",
156 /* Playback sound devices */
157 [SND_DEVICE_OUT_HANDSET] = "handset",
158 [SND_DEVICE_OUT_SPEAKER] = "speaker",
159 [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700160 [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
Eric Laurentb23d5282013-05-14 15:27:20 -0700161 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500162 [SND_DEVICE_OUT_LINE] = "line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700163 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700164 [SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = "speaker-safe-and-headphones",
Eric Laurent744996b2014-10-01 11:40:40 -0500165 [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700166 [SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = "speaker-safe-and-line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700167 [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500168 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
Eric Laurentb23d5282013-05-14 15:27:20 -0700169 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
170 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500171 [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700172 [SND_DEVICE_OUT_HDMI] = "hdmi",
173 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
174 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700175 [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700176 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
177 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
178 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
179 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700180 [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700181 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
182 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
Eric Laurentb23d5282013-05-14 15:27:20 -0700183
184 /* Capture sound devices */
185 [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700186 [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700187 [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
188 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
189 [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
190 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
191 [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
192 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
193 [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = "dmic-endfire",
194
195 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
196 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
197 [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
198 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
199 [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
200 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
201 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
202 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
203 [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = "speaker-dmic-endfire",
204
205 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
Eric Laurentcefbbac2014-09-04 13:54:10 -0500206 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700207
Eric Laurentb23d5282013-05-14 15:27:20 -0700208 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
209 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700210 [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700211 [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700212 [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700213 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700214
215 [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
216 [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
217 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
218 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
219 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700220 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
221 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
222 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700223
Eric Laurentb23d5282013-05-14 15:27:20 -0700224 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700225 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
226 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
227 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700228
229 [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700230
231 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
Eric Laurentb23d5282013-05-14 15:27:20 -0700232};
233
234/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700235static int acdb_device_table[SND_DEVICE_MAX] = {
Eric Laurentb23d5282013-05-14 15:27:20 -0700236 [SND_DEVICE_NONE] = -1,
237 [SND_DEVICE_OUT_HANDSET] = 7,
238 [SND_DEVICE_OUT_SPEAKER] = 15,
239 [SND_DEVICE_OUT_SPEAKER_REVERSE] = 15,
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700240 [SND_DEVICE_OUT_SPEAKER_SAFE] = 15,
Eric Laurentb23d5282013-05-14 15:27:20 -0700241 [SND_DEVICE_OUT_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500242 [SND_DEVICE_OUT_LINE] = 77,
Eric Laurentb23d5282013-05-14 15:27:20 -0700243 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700244 [SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500245 [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 77,
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700246 [SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = 77,
Ravi Kumar Alamanda235c3482014-08-21 17:32:44 -0700247 [SND_DEVICE_OUT_VOICE_HANDSET] = ACDB_ID_VOICE_HANDSET,
248 [SND_DEVICE_OUT_VOICE_SPEAKER] = ACDB_ID_VOICE_SPEAKER,
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500249 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
Eric Laurentb23d5282013-05-14 15:27:20 -0700250 [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500251 [SND_DEVICE_OUT_VOICE_LINE] = 77,
Eric Laurentb23d5282013-05-14 15:27:20 -0700252 [SND_DEVICE_OUT_HDMI] = 18,
253 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 15,
254 [SND_DEVICE_OUT_BT_SCO] = 22,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700255 [SND_DEVICE_OUT_BT_SCO_WB] = 39,
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700256 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = ACDB_ID_VOICE_HANDSET_TMUS,
Eric Laurentb23d5282013-05-14 15:27:20 -0700257 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
258 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
259 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700260 [SND_DEVICE_OUT_VOICE_TX] = 45,
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700261 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
262 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
Eric Laurentb23d5282013-05-14 15:27:20 -0700263
264 [SND_DEVICE_IN_HANDSET_MIC] = 4,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700265 [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
266 [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
267 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
268 [SND_DEVICE_IN_HANDSET_DMIC] = 41,
269 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
270 [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
271 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
272 [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = 34,
273
274 [SND_DEVICE_IN_SPEAKER_MIC] = 11,
275 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
276 [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
277 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
278 [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
279 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
280 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
281 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
282 [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = 35,
283
Eric Laurentb23d5282013-05-14 15:27:20 -0700284 [SND_DEVICE_IN_HEADSET_MIC] = 8,
Eric Laurentcefbbac2014-09-04 13:54:10 -0500285 [SND_DEVICE_IN_HEADSET_MIC_AEC] = ACDB_ID_HEADSET_MIC_AEC,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700286
Eric Laurentb23d5282013-05-14 15:27:20 -0700287 [SND_DEVICE_IN_HDMI_MIC] = 4,
288 [SND_DEVICE_IN_BT_SCO_MIC] = 21,
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700289 [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 21,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700290 [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700291 [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 38,
Eric Laurentb23d5282013-05-14 15:27:20 -0700292 [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700293
294 [SND_DEVICE_IN_VOICE_DMIC] = 41,
295 [SND_DEVICE_IN_VOICE_DMIC_TMUS] = ACDB_ID_VOICE_DMIC_EF_TMUS,
296 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
297 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
298 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
Eric Laurentb23d5282013-05-14 15:27:20 -0700299 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
300 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
301 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700302
Eric Laurentb23d5282013-05-14 15:27:20 -0700303 [SND_DEVICE_IN_VOICE_REC_MIC] = 62,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700304 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 113,
305 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 35,
306 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 43,
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700307
308 [SND_DEVICE_IN_VOICE_RX] = 44,
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700309
310 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
Eric Laurentb23d5282013-05-14 15:27:20 -0700311};
312
Haynes Mathew George98c95622014-06-20 19:14:25 -0700313struct name_to_index {
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700314 char name[100];
315 unsigned int index;
316};
317
318#define TO_NAME_INDEX(X) #X, X
319
Haynes Mathew George98c95622014-06-20 19:14:25 -0700320/* Used to get index from parsed string */
321static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
322 /* out */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700323 {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
324 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
325 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700326 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700327 {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500328 {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700329 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700330 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES)},
Eric Laurent744996b2014-10-01 11:40:40 -0500331 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700332 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700333 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
334 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
335 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500336 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700337 {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
338 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
339 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
340 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700341 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET_TMUS)},
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500342 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700343 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
344 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
345 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700346
347 /* in */
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700348 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
349 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700350 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700351 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700352 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
353 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
354 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
355 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
356 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
357 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
358 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_STEREO)},
359
360 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700361 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700362 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
363 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
364 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
365 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
366 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
367 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
368 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
369
370 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700371 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700372
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700373 {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
374 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700375 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700376 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700377 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700378 {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700379
380 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
381 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
382 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
383 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
384 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700385 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
386 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
387 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700388
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700389 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700390 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
391 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
392 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700393
394 {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700395};
396
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700397static char * backend_tag_table[SND_DEVICE_MAX] = {0};
398static char * hw_interface_table[SND_DEVICE_MAX] = {0};
Haynes Mathew George98c95622014-06-20 19:14:25 -0700399
400static const struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
401 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
402 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
403 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
404 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
405 {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
406 {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
407 {TO_NAME_INDEX(USECASE_VOICE_CALL)},
408 {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
409 {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
410 {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
411 {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
412 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK)},
413 {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
414 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
415 {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700416};
417
Haynes Mathew George7ff216f2013-09-11 19:51:41 -0700418#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
419#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
420
Eric Laurentb23d5282013-05-14 15:27:20 -0700421static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
422static bool is_tmus = false;
423
424static void check_operator()
425{
426 char value[PROPERTY_VALUE_MAX];
427 int mccmnc;
428 property_get("gsm.sim.operator.numeric",value,"0");
429 mccmnc = atoi(value);
430 ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
431 switch(mccmnc) {
432 /* TMUS MCC(310), MNC(490, 260, 026) */
433 case 310490:
434 case 310260:
435 case 310026:
sangwon.jeonb891db52013-09-14 17:39:15 +0900436 /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
437 case 310800:
438 case 310660:
439 case 310580:
440 case 310310:
441 case 310270:
442 case 310250:
443 case 310240:
444 case 310230:
445 case 310220:
446 case 310210:
447 case 310200:
448 case 310160:
Eric Laurentb23d5282013-05-14 15:27:20 -0700449 is_tmus = true;
450 break;
451 }
452}
453
454bool is_operator_tmus()
455{
456 pthread_once(&check_op_once_ctl, check_operator);
457 return is_tmus;
458}
459
vivek mehta1a9b7c02015-06-25 11:49:38 -0700460bool platform_send_gain_dep_cal(void *platform, int level)
461{
462 bool ret_val = false;
463 struct platform_data *my_data = (struct platform_data *)platform;
464 struct audio_device *adev = my_data->adev;
465 int acdb_dev_id, app_type;
466 int acdb_dev_type = MSM_SNDDEV_CAP_RX;
467 int mode = CAL_MODE_RTAC;
468 struct listnode *node;
469 struct audio_usecase *usecase;
vivek mehta1a9b7c02015-06-25 11:49:38 -0700470
471 if (my_data->acdb_send_gain_dep_cal == NULL) {
472 ALOGE("%s: dlsym error for acdb_send_gain_dep_cal", __func__);
473 return ret_val;
474 }
475
476 if (!voice_is_in_call(adev)) {
477 ALOGV("%s: Not Voice call usecase, apply new cal for level %d",
478 __func__, level);
479 app_type = DEFAULT_APP_TYPE_RX_PATH;
480
481 // find the current active sound device
482 list_for_each(node, &adev->usecase_list) {
483 usecase = node_to_item(node, struct audio_usecase, list);
484
485 if (usecase != NULL &&
486 usecase->type == PCM_PLAYBACK &&
487 (usecase->stream.out->devices == AUDIO_DEVICE_OUT_SPEAKER)) {
488
489 ALOGV("%s: out device is %d", __func__, usecase->out_snd_device);
vivek mehta4cb82982015-07-13 12:05:49 -0700490 if (audio_extn_spkr_prot_is_enabled()) {
491 acdb_dev_id = audio_extn_spkr_prot_get_acdb_id(usecase->out_snd_device);
492 } else {
493 acdb_dev_id = acdb_device_table[usecase->out_snd_device];
494 }
495
vivek mehta1a9b7c02015-06-25 11:49:38 -0700496 if (!my_data->acdb_send_gain_dep_cal(acdb_dev_id, app_type,
497 acdb_dev_type, mode, level)) {
498 // set ret_val true if at least one calibration is set successfully
499 ret_val = true;
500 } else {
501 ALOGE("%s: my_data->acdb_send_gain_dep_cal failed ", __func__);
502 }
503 } else {
504 ALOGW("%s: Usecase list is empty", __func__);
505 }
506 }
507 } else {
508 ALOGW("%s: Voice call in progress .. ignore setting new cal",
509 __func__);
510 }
511 return ret_val;
512}
513
Eric Laurentcefbbac2014-09-04 13:54:10 -0500514void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
Eric Laurentb23d5282013-05-14 15:27:20 -0700515{
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800516 struct platform_data *my_data = (struct platform_data *)adev->platform;
Eric Laurentcefbbac2014-09-04 13:54:10 -0500517 snd_device_t snd_device = SND_DEVICE_NONE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700518
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800519 if (strcmp(my_data->ec_ref_mixer_path, "")) {
520 ALOGV("%s: diabling %s", __func__, my_data->ec_ref_mixer_path);
521 audio_route_reset_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
Eric Laurentcefbbac2014-09-04 13:54:10 -0500522 }
523
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800524 if (enable) {
525 strcpy(my_data->ec_ref_mixer_path, "echo-reference");
526 if (out_device != AUDIO_DEVICE_NONE) {
527 snd_device = platform_get_output_snd_device(adev->platform, out_device);
528 platform_add_backend_name(adev->platform, my_data->ec_ref_mixer_path, snd_device);
529 }
Eric Laurentcefbbac2014-09-04 13:54:10 -0500530
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800531 ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
532 audio_route_apply_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
533 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700534}
535
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700536static struct csd_data *open_csd_client(bool i2s_ext_modem)
537{
538 struct csd_data *csd = calloc(1, sizeof(struct csd_data));
539
540 csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
541 if (csd->csd_client == NULL) {
542 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
543 goto error;
544 } else {
545 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
546
547 csd->deinit = (deinit_t)dlsym(csd->csd_client,
548 "csd_client_deinit");
549 if (csd->deinit == NULL) {
550 ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
551 dlerror());
552 goto error;
553 }
554 csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
555 "csd_client_disable_device");
556 if (csd->disable_device == NULL) {
557 ALOGE("%s: dlsym error %s for csd_client_disable_device",
558 __func__, dlerror());
559 goto error;
560 }
561 csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
562 "csd_client_enable_device_config");
563 if (csd->enable_device_config == NULL) {
564 ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
565 __func__, dlerror());
566 goto error;
567 }
568 csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
569 "csd_client_enable_device");
570 if (csd->enable_device == NULL) {
571 ALOGE("%s: dlsym error %s for csd_client_enable_device",
572 __func__, dlerror());
573 goto error;
574 }
575 csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
576 "csd_client_start_voice");
577 if (csd->start_voice == NULL) {
578 ALOGE("%s: dlsym error %s for csd_client_start_voice",
579 __func__, dlerror());
580 goto error;
581 }
582 csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
583 "csd_client_stop_voice");
584 if (csd->stop_voice == NULL) {
585 ALOGE("%s: dlsym error %s for csd_client_stop_voice",
586 __func__, dlerror());
587 goto error;
588 }
589 csd->volume = (volume_t)dlsym(csd->csd_client,
590 "csd_client_volume");
591 if (csd->volume == NULL) {
592 ALOGE("%s: dlsym error %s for csd_client_volume",
593 __func__, dlerror());
594 goto error;
595 }
596 csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
597 "csd_client_mic_mute");
598 if (csd->mic_mute == NULL) {
599 ALOGE("%s: dlsym error %s for csd_client_mic_mute",
600 __func__, dlerror());
601 goto error;
602 }
603 csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
604 "csd_client_slow_talk");
605 if (csd->slow_talk == NULL) {
606 ALOGE("%s: dlsym error %s for csd_client_slow_talk",
607 __func__, dlerror());
608 goto error;
609 }
610 csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
611 "csd_client_start_playback");
612 if (csd->start_playback == NULL) {
613 ALOGE("%s: dlsym error %s for csd_client_start_playback",
614 __func__, dlerror());
615 goto error;
616 }
617 csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
618 "csd_client_stop_playback");
619 if (csd->stop_playback == NULL) {
620 ALOGE("%s: dlsym error %s for csd_client_stop_playback",
621 __func__, dlerror());
622 goto error;
623 }
624 csd->start_record = (start_record_t)dlsym(csd->csd_client,
625 "csd_client_start_record");
626 if (csd->start_record == NULL) {
627 ALOGE("%s: dlsym error %s for csd_client_start_record",
628 __func__, dlerror());
629 goto error;
630 }
631 csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
632 "csd_client_stop_record");
633 if (csd->stop_record == NULL) {
634 ALOGE("%s: dlsym error %s for csd_client_stop_record",
635 __func__, dlerror());
636 goto error;
637 }
638
639 csd->get_sample_rate = (get_sample_rate_t)dlsym(csd->csd_client,
640 "csd_client_get_sample_rate");
641 if (csd->get_sample_rate == NULL) {
642 ALOGE("%s: dlsym error %s for csd_client_get_sample_rate",
643 __func__, dlerror());
644
645 goto error;
646 }
647
648 csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
649
650 if (csd->init == NULL) {
651 ALOGE("%s: dlsym error %s for csd_client_init",
652 __func__, dlerror());
653 goto error;
654 } else {
655 csd->init(i2s_ext_modem);
656 }
657 }
658 return csd;
659
660error:
661 free(csd);
662 csd = NULL;
663 return csd;
664}
665
666void close_csd_client(struct csd_data *csd)
667{
668 if (csd != NULL) {
669 csd->deinit();
670 dlclose(csd->csd_client);
671 free(csd);
672 csd = NULL;
673 }
674}
675
676static void platform_csd_init(struct platform_data *my_data)
677{
678#ifdef PLATFORM_MSM8084
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700679 int32_t modems, (*count_modems)(void);
680 const char *name = "libdetectmodem.so";
681 const char *func = "count_modems";
682 const char *error;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700683
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700684 my_data->csd = NULL;
685
686 void *lib = dlopen(name, RTLD_NOW);
687 error = dlerror();
688 if (!lib) {
689 ALOGE("%s: could not find %s: %s", __func__, name, error);
690 return;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700691 }
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700692
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700693 count_modems = NULL;
694 *(void **)(&count_modems) = dlsym(lib, func);
695 error = dlerror();
696 if (!count_modems) {
697 ALOGE("%s: could not find symbol %s in %s: %s",
698 __func__, func, name, error);
699 goto done;
700 }
701
702 modems = count_modems();
703 if (modems < 0) {
704 ALOGE("%s: count_modems failed\n", __func__);
705 goto done;
706 }
707
708 ALOGD("%s: num_modems %d\n", __func__, modems);
709 if (modems > 0)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700710 my_data->csd = open_csd_client(false /*is_i2s_ext_modem*/);
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700711
712done:
713 dlclose(lib);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700714#else
715 my_data->csd = NULL;
716#endif
717}
718
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700719static void set_platform_defaults(struct platform_data * my_data __unused)
Haynes Mathew George98c95622014-06-20 19:14:25 -0700720{
721 int32_t dev;
722 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700723 backend_tag_table[dev] = NULL;
724 hw_interface_table[dev] = NULL;
Haynes Mathew George98c95622014-06-20 19:14:25 -0700725 }
726
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700727 // To overwrite these go to the audio_platform_info.xml file.
728 backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700729 backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_NREC] = strdup("bt-sco");
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700730 backend_tag_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
731 backend_tag_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
732 backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
733 backend_tag_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
734 backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -0700735 backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = strdup("bt-sco-wb");
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700736 backend_tag_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
737 backend_tag_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700738
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700739 hw_interface_table[SND_DEVICE_OUT_HANDSET] = strdup("SLIMBUS_0_RX");
740 hw_interface_table[SND_DEVICE_OUT_SPEAKER] = strdup("SLIMBUS_0_RX");
741 hw_interface_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = strdup("SLIMBUS_0_RX");
742 hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE] = strdup("SLIMBUS_0_RX");
743 hw_interface_table[SND_DEVICE_OUT_HEADPHONES] = strdup("SLIMBUS_0_RX");
744 hw_interface_table[SND_DEVICE_OUT_LINE] = strdup("SLIMBUS_0_RX");
745 hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = strdup("SLIMBUS_0_RX");
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700746 hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = strdup("SLIMBUS_0_RX");
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700747 hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_LINE] = strdup("SLIMBUS_0_RX");
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -0700748 hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = strdup("SLIMBUS_0_RX");
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700749 hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET] = strdup("SLIMBUS_0_RX");
750 hw_interface_table[SND_DEVICE_OUT_VOICE_HAC_HANDSET] = strdup("SLIMBUS_0_RX");
751 hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER] = strdup("SLIMBUS_0_RX");
752 hw_interface_table[SND_DEVICE_OUT_VOICE_HEADPHONES] = strdup("SLIMBUS_0_RX");
753 hw_interface_table[SND_DEVICE_OUT_VOICE_LINE] = strdup("SLIMBUS_0_RX");
754 hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI_RX");
755 hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
756 hw_interface_table[SND_DEVICE_OUT_BT_SCO] = strdup("SEC_AUX_PCM_RX");
757 hw_interface_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("SEC_AUX_PCM_RX");
758 hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = strdup("SLIMBUS_0_RX");
759 hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = strdup("SLIMBUS_0_RX");
760 hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = strdup("SLIMBUS_0_RX");
761 hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("SLIMBUS_0_RX");
762 hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
763 hw_interface_table[SND_DEVICE_OUT_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
764 hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700765}
766
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +0900767void get_cvd_version(char *cvd_version, struct audio_device *adev)
768{
769 struct mixer_ctl *ctl;
770 int count;
771 int ret = 0;
772
773 ctl = mixer_get_ctl_by_name(adev->mixer, CVD_VERSION_MIXER_CTL);
774 if (!ctl) {
775 ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, CVD_VERSION_MIXER_CTL);
776 goto done;
777 }
778 mixer_ctl_update(ctl);
779
780 count = mixer_ctl_get_num_values(ctl);
781 if (count > MAX_CVD_VERSION_STRING_SIZE)
782 count = MAX_CVD_VERSION_STRING_SIZE - 1;
783
784 ret = mixer_ctl_get_array(ctl, cvd_version, count);
785 if (ret != 0) {
786 ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
787 goto done;
788 }
789
790done:
791 return;
792}
793
Eric Laurentb23d5282013-05-14 15:27:20 -0700794void *platform_init(struct audio_device *adev)
795{
796 char value[PROPERTY_VALUE_MAX];
797 struct platform_data *my_data;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700798 int retry_num = 0, snd_card_num = 0;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700799 const char *snd_card_name;
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +0900800 char *cvd_version = NULL;
sangwoo1b9f4b32013-06-21 18:22:55 -0700801
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -0700802 my_data = calloc(1, sizeof(struct platform_data));
803
804 my_data->adev = adev;
805
806 set_platform_defaults(my_data);
807
808 /* Initialize platform specific ids and/or backends*/
809 platform_info_init(my_data);
810
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700811 while (snd_card_num < MAX_SND_CARD) {
812 adev->mixer = mixer_open(snd_card_num);
sangwoo1b9f4b32013-06-21 18:22:55 -0700813
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700814 while (!adev->mixer && retry_num < RETRY_NUMBER) {
815 usleep(RETRY_US);
816 adev->mixer = mixer_open(snd_card_num);
817 retry_num++;
818 }
819
820 if (!adev->mixer) {
821 ALOGE("%s: Unable to open the mixer card: %d", __func__,
822 snd_card_num);
823 retry_num = 0;
824 snd_card_num++;
825 continue;
826 }
827
828 snd_card_name = mixer_get_name(adev->mixer);
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -0700829
830 /* validate the sound card name */
831 if (my_data->snd_card_name != NULL &&
832 strncmp(snd_card_name, my_data->snd_card_name, MAX_SND_CARD_NAME_LEN) != 0) {
833 ALOGI("%s: found valid sound card %s, but not primary sound card %s",
834 __func__, snd_card_name, my_data->snd_card_name);
835 retry_num = 0;
836 snd_card_num++;
837 continue;
838 }
839
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700840 ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
841
842 adev->audio_route = audio_route_init(snd_card_num, MIXER_XML_PATH);
843 if (!adev->audio_route) {
844 ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -0700845 goto init_failed;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700846 }
847 adev->snd_card = snd_card_num;
848 ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
849 break;
sangwoo1b9f4b32013-06-21 18:22:55 -0700850 }
851
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700852 if (snd_card_num >= MAX_SND_CARD) {
853 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -0700854 goto init_failed;
sangwoo1b9f4b32013-06-21 18:22:55 -0700855 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700856
keunhui.parkc5aaa0e2015-07-13 10:57:37 +0900857 //set max volume step for voice call
858 property_get("ro.config.vc_call_vol_steps", value, TOSTRING(MAX_VOL_INDEX));
859 my_data->max_vol_index = atoi(value);
860
Eric Laurentb23d5282013-05-14 15:27:20 -0700861 my_data->dualmic_config = DUALMIC_CONFIG_NONE;
862 my_data->fluence_in_spkr_mode = false;
863 my_data->fluence_in_voice_call = false;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700864 my_data->fluence_in_voice_comm = false;
Eric Laurentb23d5282013-05-14 15:27:20 -0700865 my_data->fluence_in_voice_rec = false;
866
867 property_get("persist.audio.dualmic.config",value,"");
868 if (!strcmp("broadside", value)) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700869 ALOGE("%s: Unsupported dualmic configuration", __func__);
Eric Laurentb23d5282013-05-14 15:27:20 -0700870 } else if (!strcmp("endfire", value)) {
871 my_data->dualmic_config = DUALMIC_CONFIG_ENDFIRE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700872 }
873
874 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
875 property_get("persist.audio.fluence.voicecall",value,"");
876 if (!strcmp("true", value)) {
877 my_data->fluence_in_voice_call = true;
878 }
879
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700880 property_get("persist.audio.fluence.voicecomm",value,"");
881 if (!strcmp("true", value)) {
882 my_data->fluence_in_voice_comm = true;
883 }
884
Eric Laurentb23d5282013-05-14 15:27:20 -0700885 property_get("persist.audio.fluence.voicerec",value,"");
886 if (!strcmp("true", value)) {
887 my_data->fluence_in_voice_rec = true;
888 }
889
890 property_get("persist.audio.fluence.speaker",value,"");
891 if (!strcmp("true", value)) {
892 my_data->fluence_in_spkr_mode = true;
893 }
894 }
895
896 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
897 if (my_data->acdb_handle == NULL) {
898 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
899 } else {
900 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
901 my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
902 "acdb_loader_deallocate_ACDB");
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700903 if (!my_data->acdb_deallocate)
904 ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
905 __func__, LIB_ACDB_LOADER);
906
Eric Laurentb23d5282013-05-14 15:27:20 -0700907 my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
908 "acdb_loader_send_audio_cal");
909 if (!my_data->acdb_send_audio_cal)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700910 ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
Eric Laurentb23d5282013-05-14 15:27:20 -0700911 __func__, LIB_ACDB_LOADER);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700912
Eric Laurentb23d5282013-05-14 15:27:20 -0700913 my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
914 "acdb_loader_send_voice_cal");
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700915 if (!my_data->acdb_send_voice_cal)
916 ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
917 __func__, LIB_ACDB_LOADER);
918
919 my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
920 "acdb_loader_reload_vocvoltable");
921 if (!my_data->acdb_reload_vocvoltable)
922 ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
923 __func__, LIB_ACDB_LOADER);
vivek mehta1a9b7c02015-06-25 11:49:38 -0700924
925 my_data->acdb_send_gain_dep_cal = (acdb_send_gain_dep_cal_t)dlsym(my_data->acdb_handle,
926 "acdb_loader_send_gain_dep_cal");
927 if (!my_data->acdb_send_gain_dep_cal)
928 ALOGV("%s: Could not find the symbol acdb_loader_send_gain_dep_cal from %s",
929 __func__, LIB_ACDB_LOADER);
930
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +0900931#if defined (PLATFORM_MSM8994)
932 acdb_init_v2_cvd_t acdb_init;
933 acdb_init = (acdb_init_v2_cvd_t)dlsym(my_data->acdb_handle,
934 "acdb_loader_init_v2");
935 if (acdb_init == NULL) {
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700936 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +0900937 goto acdb_init_fail;
938 }
939
940 cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
941 get_cvd_version(cvd_version, adev);
942 if (!cvd_version)
943 ALOGE("failed to allocate cvd_version");
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700944 else
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +0900945 acdb_init((char *)snd_card_name, cvd_version);
946 free(cvd_version);
947#elif defined (PLATFORM_MSM8084)
948 acdb_init_v2_t acdb_init;
949 acdb_init = (acdb_init_v2_t)dlsym(my_data->acdb_handle,
950 "acdb_loader_init_v2");
951 if (acdb_init == NULL) {
952 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
953 goto acdb_init_fail;
954 }
955 acdb_init((char *)snd_card_name);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700956#else
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +0900957 acdb_init_t acdb_init;
958 acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
Eric Laurentb23d5282013-05-14 15:27:20 -0700959 "acdb_loader_init_ACDB");
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +0900960 if (acdb_init == NULL)
Eric Laurentb23d5282013-05-14 15:27:20 -0700961 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
962 else
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +0900963 acdb_init();
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700964#endif
Eric Laurentb23d5282013-05-14 15:27:20 -0700965 }
966
Ravi Kumar Alamanda5c049df2015-07-01 16:23:03 +0900967acdb_init_fail:
968
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700969 audio_extn_spkr_prot_init(adev);
Haynes Mathew George98c95622014-06-20 19:14:25 -0700970
Ravi Kumar Alamanda76315572015-04-23 13:13:56 -0700971 audio_extn_hwdep_cal_send(adev->snd_card, my_data->acdb_handle);
972
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700973 /* load csd client */
974 platform_csd_init(my_data);
975
Eric Laurentb23d5282013-05-14 15:27:20 -0700976 return my_data;
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -0700977
978init_failed:
979 if (my_data)
980 free(my_data);
981 return NULL;
Eric Laurentb23d5282013-05-14 15:27:20 -0700982}
983
984void platform_deinit(void *platform)
985{
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -0700986 int32_t dev;
987
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700988 struct platform_data *my_data = (struct platform_data *)platform;
989 close_csd_client(my_data->csd);
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -0700990
991 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
992 if (backend_tag_table[dev])
993 free(backend_tag_table[dev]);
994 if (hw_interface_table[dev])
995 free(hw_interface_table[dev]);
996 }
997
998 if (my_data->snd_card_name)
999 free(my_data->snd_card_name);
1000
Eric Laurentb23d5282013-05-14 15:27:20 -07001001 free(platform);
1002}
1003
1004const char *platform_get_snd_device_name(snd_device_t snd_device)
1005{
1006 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
1007 return device_table[snd_device];
1008 else
Ravi Kumar Alamanda64026462014-09-15 00:08:58 -07001009 return "none";
Eric Laurentb23d5282013-05-14 15:27:20 -07001010}
1011
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -05001012void platform_add_backend_name(void *platform, char *mixer_path,
1013 snd_device_t snd_device)
Eric Laurentb23d5282013-05-14 15:27:20 -07001014{
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -05001015 struct platform_data *my_data = (struct platform_data *)platform;
1016
Haynes Mathew George98c95622014-06-20 19:14:25 -07001017 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1018 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1019 return;
Ravi Kumar Alamanda1de6e5a2014-06-19 21:55:39 -05001020 }
Haynes Mathew George98c95622014-06-20 19:14:25 -07001021
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001022 const char * suffix = backend_tag_table[snd_device];
Haynes Mathew George98c95622014-06-20 19:14:25 -07001023
1024 if (suffix != NULL) {
1025 strcat(mixer_path, " ");
1026 strcat(mixer_path, suffix);
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -05001027 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001028}
1029
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001030bool platform_check_backends_match(snd_device_t snd_device1, snd_device_t snd_device2)
1031{
1032 bool result = true;
1033
1034 ALOGV("%s: snd_device1 = %s, snd_device2 = %s", __func__,
1035 platform_get_snd_device_name(snd_device1),
1036 platform_get_snd_device_name(snd_device2));
1037
1038 if ((snd_device1 < SND_DEVICE_MIN) || (snd_device1 >= SND_DEVICE_MAX)) {
1039 ALOGE("%s: Invalid snd_device = %s", __func__,
1040 platform_get_snd_device_name(snd_device1));
1041 return false;
1042 }
1043 if ((snd_device2 < SND_DEVICE_MIN) || (snd_device2 >= SND_DEVICE_MAX)) {
1044 ALOGE("%s: Invalid snd_device = %s", __func__,
1045 platform_get_snd_device_name(snd_device2));
1046 return false;
1047 }
1048 const char * be_itf1 = hw_interface_table[snd_device1];
1049 const char * be_itf2 = hw_interface_table[snd_device2];
1050
1051 if (NULL != be_itf1 && NULL != be_itf2) {
1052 if (0 != strcmp(be_itf1, be_itf2))
1053 result = false;
1054 }
1055
1056 ALOGV("%s: be_itf1 = %s, be_itf2 = %s, match %d", __func__, be_itf1, be_itf2, result);
1057 return result;
1058}
1059
Eric Laurentb23d5282013-05-14 15:27:20 -07001060int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
1061{
1062 int device_id;
1063 if (device_type == PCM_PLAYBACK)
1064 device_id = pcm_device_table[usecase][0];
1065 else
1066 device_id = pcm_device_table[usecase][1];
1067 return device_id;
1068}
1069
Haynes Mathew George98c95622014-06-20 19:14:25 -07001070static int find_index(const struct name_to_index * table, int32_t len,
1071 const char * name)
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001072{
1073 int ret = 0;
Haynes Mathew George98c95622014-06-20 19:14:25 -07001074 int32_t i;
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001075
Haynes Mathew George98c95622014-06-20 19:14:25 -07001076 if (table == NULL) {
1077 ALOGE("%s: table is NULL", __func__);
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001078 ret = -ENODEV;
1079 goto done;
1080 }
1081
Haynes Mathew George98c95622014-06-20 19:14:25 -07001082 if (name == NULL) {
1083 ALOGE("null key");
1084 ret = -ENODEV;
1085 goto done;
1086 }
1087
1088 for (i=0; i < len; i++) {
1089 if (!strcmp(table[i].name, name)) {
1090 ret = table[i].index;
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001091 goto done;
1092 }
1093 }
Haynes Mathew George98c95622014-06-20 19:14:25 -07001094 ALOGE("%s: Could not find index for name = %s",
1095 __func__, name);
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001096 ret = -ENODEV;
1097done:
1098 return ret;
1099}
1100
Haynes Mathew George98c95622014-06-20 19:14:25 -07001101int platform_get_snd_device_index(char *device_name)
1102{
1103 return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
1104}
1105
1106int platform_get_usecase_index(const char *usecase_name)
1107{
1108 return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
1109}
1110
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001111int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
1112{
1113 int ret = 0;
1114
1115 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1116 ALOGE("%s: Invalid snd_device = %d",
1117 __func__, snd_device);
1118 ret = -EINVAL;
1119 goto done;
1120 }
1121
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001122 ALOGV("%s: acdb_device_table[%s]: old = %d new = %d", __func__,
1123 platform_get_snd_device_name(snd_device), acdb_device_table[snd_device], acdb_id);
Haynes Mathew George5bc18842014-06-16 16:36:20 -07001124 acdb_device_table[snd_device] = acdb_id;
1125done:
1126 return ret;
1127}
1128
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001129int platform_get_snd_device_acdb_id(snd_device_t snd_device)
1130{
1131 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1132 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1133 return -EINVAL;
1134 }
1135 return acdb_device_table[snd_device];
1136}
1137
Eric Laurentb23d5282013-05-14 15:27:20 -07001138int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
1139{
1140 struct platform_data *my_data = (struct platform_data *)platform;
1141 int acdb_dev_id, acdb_dev_type;
1142
Ravi Kumar Alamandaadf0f3b2015-06-04 02:34:02 -07001143 acdb_dev_id = acdb_device_table[audio_extn_get_spkr_prot_snd_device(snd_device)];
Eric Laurentb23d5282013-05-14 15:27:20 -07001144 if (acdb_dev_id < 0) {
1145 ALOGE("%s: Could not find acdb id for device(%d)",
1146 __func__, snd_device);
1147 return -EINVAL;
1148 }
1149 if (my_data->acdb_send_audio_cal) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001150 ALOGD("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
Eric Laurentb23d5282013-05-14 15:27:20 -07001151 __func__, snd_device, acdb_dev_id);
1152 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
1153 snd_device < SND_DEVICE_OUT_END)
1154 acdb_dev_type = ACDB_DEV_TYPE_OUT;
1155 else
1156 acdb_dev_type = ACDB_DEV_TYPE_IN;
1157 my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
1158 }
1159 return 0;
1160}
1161
1162int platform_switch_voice_call_device_pre(void *platform)
1163{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001164 struct platform_data *my_data = (struct platform_data *)platform;
1165 int ret = 0;
1166
1167 if (my_data->csd != NULL &&
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001168 voice_is_in_call(my_data->adev)) {
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001169 /* This must be called before disabling mixer controls on APQ side */
1170 ret = my_data->csd->disable_device();
1171 if (ret < 0) {
1172 ALOGE("%s: csd_client_disable_device, failed, error %d",
1173 __func__, ret);
1174 }
1175 }
1176 return ret;
1177}
1178
1179int platform_switch_voice_call_enable_device_config(void *platform,
1180 snd_device_t out_snd_device,
1181 snd_device_t in_snd_device)
1182{
1183 struct platform_data *my_data = (struct platform_data *)platform;
1184 int acdb_rx_id, acdb_tx_id;
1185 int ret = 0;
1186
1187 if (my_data->csd == NULL)
1188 return ret;
1189
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001190 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1191 audio_extn_spkr_prot_is_enabled())
1192 acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
1193 else
1194 acdb_rx_id = acdb_device_table[out_snd_device];
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001195
1196 acdb_tx_id = acdb_device_table[in_snd_device];
1197
1198 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1199 ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
1200 if (ret < 0) {
1201 ALOGE("%s: csd_enable_device_config, failed, error %d",
1202 __func__, ret);
1203 }
1204 } else {
1205 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1206 acdb_rx_id, acdb_tx_id);
1207 }
1208
1209 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001210}
1211
1212int platform_switch_voice_call_device_post(void *platform,
1213 snd_device_t out_snd_device,
1214 snd_device_t in_snd_device)
1215{
1216 struct platform_data *my_data = (struct platform_data *)platform;
1217 int acdb_rx_id, acdb_tx_id;
1218
1219 if (my_data->acdb_send_voice_cal == NULL) {
1220 ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
1221 } else {
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001222 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1223 audio_extn_spkr_prot_is_enabled())
1224 out_snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
1225
Eric Laurentb23d5282013-05-14 15:27:20 -07001226 acdb_rx_id = acdb_device_table[out_snd_device];
1227 acdb_tx_id = acdb_device_table[in_snd_device];
1228
1229 if (acdb_rx_id > 0 && acdb_tx_id > 0)
1230 my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
1231 else
1232 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1233 acdb_rx_id, acdb_tx_id);
1234 }
1235
1236 return 0;
1237}
1238
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001239int platform_switch_voice_call_usecase_route_post(void *platform,
1240 snd_device_t out_snd_device,
1241 snd_device_t in_snd_device)
1242{
1243 struct platform_data *my_data = (struct platform_data *)platform;
1244 int acdb_rx_id, acdb_tx_id;
1245 int ret = 0;
1246
1247 if (my_data->csd == NULL)
1248 return ret;
1249
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001250 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1251 audio_extn_spkr_prot_is_enabled())
1252 acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED];
1253 else
1254 acdb_rx_id = acdb_device_table[out_snd_device];
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001255
1256 acdb_tx_id = acdb_device_table[in_snd_device];
1257
1258 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1259 ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
1260 my_data->adev->acdb_settings);
1261 if (ret < 0) {
1262 ALOGE("%s: csd_enable_device, failed, error %d", __func__, ret);
1263 }
1264 } else {
1265 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1266 acdb_rx_id, acdb_tx_id);
1267 }
1268
1269 return ret;
1270}
1271
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001272int platform_start_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001273{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001274 struct platform_data *my_data = (struct platform_data *)platform;
1275 int ret = 0;
1276
1277 if (my_data->csd != NULL) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001278 ret = my_data->csd->start_voice(vsid);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001279 if (ret < 0) {
1280 ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
1281 }
1282 }
1283 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001284}
1285
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001286int platform_stop_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001287{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001288 struct platform_data *my_data = (struct platform_data *)platform;
1289 int ret = 0;
1290
1291 if (my_data->csd != NULL) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001292 ret = my_data->csd->stop_voice(vsid);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001293 if (ret < 0) {
1294 ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
1295 }
1296 }
1297 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001298}
1299
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001300int platform_get_sample_rate(void *platform, uint32_t *rate)
1301{
1302 struct platform_data *my_data = (struct platform_data *)platform;
1303 int ret = 0;
1304
1305 if (my_data->csd != NULL) {
1306 ret = my_data->csd->get_sample_rate(rate);
1307 if (ret < 0) {
1308 ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret);
1309 }
1310 }
1311 return ret;
1312}
1313
Eric Laurentb23d5282013-05-14 15:27:20 -07001314int platform_set_voice_volume(void *platform, int volume)
1315{
1316 struct platform_data *my_data = (struct platform_data *)platform;
1317 struct audio_device *adev = my_data->adev;
1318 struct mixer_ctl *ctl;
sangwoo53b2cf02013-07-25 19:18:44 -07001319 const char *mixer_ctl_name = "Voice Rx Gain";
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001320 int vol_index = 0, ret = 0;
1321 uint32_t set_values[ ] = {0,
1322 ALL_SESSION_VSID,
1323 DEFAULT_VOLUME_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001324
1325 // Voice volume levels are mapped to adsp volume levels as follows.
1326 // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0
1327 // But this values don't changed in kernel. So, below change is need.
keunhui.parkc5aaa0e2015-07-13 10:57:37 +09001328 vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, my_data->max_vol_index);
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001329 set_values[0] = vol_index;
Eric Laurentb23d5282013-05-14 15:27:20 -07001330
1331 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1332 if (!ctl) {
1333 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1334 __func__, mixer_ctl_name);
1335 return -EINVAL;
1336 }
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001337 ALOGV("Setting voice volume index: %d", set_values[0]);
1338 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1339
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001340 if (my_data->csd != NULL) {
1341 ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
1342 DEFAULT_VOLUME_RAMP_DURATION_MS);
1343 if (ret < 0) {
1344 ALOGE("%s: csd_volume error %d", __func__, ret);
1345 }
1346 }
1347 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001348}
1349
1350int platform_set_mic_mute(void *platform, bool state)
1351{
1352 struct platform_data *my_data = (struct platform_data *)platform;
1353 struct audio_device *adev = my_data->adev;
1354 struct mixer_ctl *ctl;
1355 const char *mixer_ctl_name = "Voice Tx Mute";
sangwoo53b2cf02013-07-25 19:18:44 -07001356 int ret = 0;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001357 uint32_t set_values[ ] = {0,
1358 ALL_SESSION_VSID,
1359 DEFAULT_MUTE_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001360
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001361 if (adev->mode != AUDIO_MODE_IN_CALL)
1362 return 0;
1363
1364 set_values[0] = state;
1365 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1366 if (!ctl) {
1367 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1368 __func__, mixer_ctl_name);
1369 return -EINVAL;
1370 }
1371 ALOGV("Setting voice mute state: %d", state);
1372 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1373
1374 if (my_data->csd != NULL) {
1375 ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state,
1376 DEFAULT_MUTE_RAMP_DURATION_MS);
sangwoo53b2cf02013-07-25 19:18:44 -07001377 if (ret < 0) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001378 ALOGE("%s: csd_mic_mute error %d", __func__, ret);
sangwoo53b2cf02013-07-25 19:18:44 -07001379 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001380 }
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001381 return ret;
1382}
Eric Laurentb23d5282013-05-14 15:27:20 -07001383
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001384int platform_set_device_mute(void *platform, bool state, char *dir)
1385{
1386 struct platform_data *my_data = (struct platform_data *)platform;
1387 struct audio_device *adev = my_data->adev;
1388 struct mixer_ctl *ctl;
1389 char *mixer_ctl_name = NULL;
1390 int ret = 0;
1391 uint32_t set_values[ ] = {0,
1392 ALL_SESSION_VSID,
1393 0};
1394 if(dir == NULL) {
1395 ALOGE("%s: Invalid direction:%s", __func__, dir);
1396 return -EINVAL;
1397 }
1398
1399 if (!strncmp("rx", dir, sizeof("rx"))) {
1400 mixer_ctl_name = "Voice Rx Device Mute";
1401 } else if (!strncmp("tx", dir, sizeof("tx"))) {
1402 mixer_ctl_name = "Voice Tx Device Mute";
1403 } else {
1404 return -EINVAL;
1405 }
1406
1407 set_values[0] = state;
1408 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1409 if (!ctl) {
1410 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1411 __func__, mixer_ctl_name);
1412 return -EINVAL;
1413 }
1414
1415 ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
1416 __func__,state, mixer_ctl_name);
1417 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1418
1419 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001420}
1421
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001422bool platform_can_split_snd_device(snd_device_t snd_device,
1423 int *num_devices,
1424 snd_device_t *new_snd_devices)
1425{
1426 bool status = false;
1427
1428 if (NULL == num_devices || NULL == new_snd_devices) {
1429 ALOGE("%s: NULL pointer ..", __func__);
1430 return false;
1431 }
1432
1433 /*
1434 * If wired headset/headphones/line devices share the same backend
1435 * with speaker/earpiece this routine returns false.
1436 */
1437 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES &&
1438 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HEADPHONES)) {
1439 *num_devices = 2;
1440 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
1441 new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
1442 status = true;
1443 } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_LINE &&
1444 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_LINE)) {
1445 *num_devices = 2;
1446 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
1447 new_snd_devices[1] = SND_DEVICE_OUT_LINE;
1448 status = true;
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -07001449 } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES &&
1450 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_HEADPHONES)) {
1451 *num_devices = 2;
1452 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
1453 new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
1454 status = true;
1455 } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE &&
1456 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_LINE)) {
1457 *num_devices = 2;
1458 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
1459 new_snd_devices[1] = SND_DEVICE_OUT_LINE;
1460 status = true;
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001461 }
1462 return status;
1463}
1464
Eric Laurentb23d5282013-05-14 15:27:20 -07001465snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
1466{
1467 struct platform_data *my_data = (struct platform_data *)platform;
1468 struct audio_device *adev = my_data->adev;
1469 audio_mode_t mode = adev->mode;
1470 snd_device_t snd_device = SND_DEVICE_NONE;
1471
1472 ALOGV("%s: enter: output devices(%#x)", __func__, devices);
1473 if (devices == AUDIO_DEVICE_NONE ||
1474 devices & AUDIO_DEVICE_BIT_IN) {
1475 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
1476 goto exit;
1477 }
1478
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001479 if (voice_is_in_call(adev) || adev->enable_voicerx) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001480 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001481 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1482 devices & AUDIO_DEVICE_OUT_LINE) {
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001483 if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001484 (adev->voice.tty_mode == TTY_MODE_FULL))
Eric Laurentb23d5282013-05-14 15:27:20 -07001485 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001486 else if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001487 (adev->voice.tty_mode == TTY_MODE_VCO))
Eric Laurentb23d5282013-05-14 15:27:20 -07001488 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001489 else if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001490 (adev->voice.tty_mode == TTY_MODE_HCO))
Eric Laurentb23d5282013-05-14 15:27:20 -07001491 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001492 else {
1493 if (devices & AUDIO_DEVICE_OUT_LINE)
1494 snd_device = SND_DEVICE_OUT_VOICE_LINE;
1495 else
1496 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
1497 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001498 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001499 if (adev->bt_wb_speech_enabled) {
1500 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1501 } else {
1502 snd_device = SND_DEVICE_OUT_BT_SCO;
1503 }
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001504 } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001505 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
1506 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurent9d0d3f12014-07-25 12:40:29 -05001507 if(adev->voice.hac)
1508 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1509 else if (is_operator_tmus())
Eric Laurentb23d5282013-05-14 15:27:20 -07001510 snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
1511 else
Eric Laurentb4d368e2014-06-25 10:21:54 -05001512 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -07001513 } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1514 snd_device = SND_DEVICE_OUT_VOICE_TX;
1515
Eric Laurentb23d5282013-05-14 15:27:20 -07001516 if (snd_device != SND_DEVICE_NONE) {
1517 goto exit;
1518 }
1519 }
1520
1521 if (popcount(devices) == 2) {
1522 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -07001523 AUDIO_DEVICE_OUT_SPEAKER) ||
1524 devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1525 AUDIO_DEVICE_OUT_SPEAKER)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001526 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
Eric Laurent744996b2014-10-01 11:40:40 -05001527 } else if (devices == (AUDIO_DEVICE_OUT_LINE |
1528 AUDIO_DEVICE_OUT_SPEAKER)) {
1529 snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
Ravi Kumar Alamanda3b86d472015-06-08 00:35:57 -07001530 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1531 AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
1532 devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1533 AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
1534 snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES;
1535 } else if (devices == (AUDIO_DEVICE_OUT_LINE |
1536 AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
1537 snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001538 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
1539 AUDIO_DEVICE_OUT_SPEAKER)) {
1540 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
1541 } else {
1542 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
1543 goto exit;
1544 }
1545 if (snd_device != SND_DEVICE_NONE) {
1546 goto exit;
1547 }
1548 }
1549
1550 if (popcount(devices) != 1) {
1551 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
1552 goto exit;
1553 }
1554
1555 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1556 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1557 snd_device = SND_DEVICE_OUT_HEADPHONES;
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001558 } else if (devices & AUDIO_DEVICE_OUT_LINE) {
1559 snd_device = SND_DEVICE_OUT_LINE;
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001560 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
1561 snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001562 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07001563 if (my_data->speaker_lr_swap)
Eric Laurentb23d5282013-05-14 15:27:20 -07001564 snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
1565 else
1566 snd_device = SND_DEVICE_OUT_SPEAKER;
1567 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001568 if (adev->bt_wb_speech_enabled) {
1569 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1570 } else {
1571 snd_device = SND_DEVICE_OUT_BT_SCO;
1572 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001573 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1574 snd_device = SND_DEVICE_OUT_HDMI ;
1575 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurent9d0d3f12014-07-25 12:40:29 -05001576 /*HAC support for voice-ish audio (eg visual voicemail)*/
1577 if(adev->voice.hac)
1578 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1579 else
1580 snd_device = SND_DEVICE_OUT_HANDSET;
Eric Laurentb23d5282013-05-14 15:27:20 -07001581 } else {
1582 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
1583 }
1584exit:
1585 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
1586 return snd_device;
1587}
1588
1589snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
1590{
1591 struct platform_data *my_data = (struct platform_data *)platform;
1592 struct audio_device *adev = my_data->adev;
1593 audio_source_t source = (adev->active_input == NULL) ?
1594 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
1595
1596 audio_mode_t mode = adev->mode;
1597 audio_devices_t in_device = ((adev->active_input == NULL) ?
1598 AUDIO_DEVICE_NONE : adev->active_input->device)
1599 & ~AUDIO_DEVICE_BIT_IN;
1600 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1601 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1602 snd_device_t snd_device = SND_DEVICE_NONE;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001603 int channel_count = popcount(channel_mask);
Eric Laurentb23d5282013-05-14 15:27:20 -07001604
1605 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
1606 __func__, out_device, in_device);
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001607 if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001608 if (adev->voice.tty_mode != TTY_MODE_OFF) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001609 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001610 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1611 out_device & AUDIO_DEVICE_OUT_LINE) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001612 switch (adev->voice.tty_mode) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001613 case TTY_MODE_FULL:
1614 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
1615 break;
1616 case TTY_MODE_VCO:
1617 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
1618 break;
1619 case TTY_MODE_HCO:
1620 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
1621 break;
1622 default:
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001623 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
Eric Laurentb23d5282013-05-14 15:27:20 -07001624 }
1625 goto exit;
1626 }
1627 }
Eric Laurentb991fb02014-08-29 15:23:17 -05001628 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001629 if (my_data->fluence_in_voice_call == false) {
1630 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1631 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001632 if (is_operator_tmus())
1633 snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001634 else
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001635 snd_device = SND_DEVICE_IN_VOICE_DMIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001636 }
1637 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1638 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
1639 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001640 if (adev->bt_wb_speech_enabled) {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07001641 if (adev->bluetooth_nrec)
1642 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
1643 else
1644 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001645 } else {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07001646 if (adev->bluetooth_nrec)
1647 snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
1648 else
1649 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001650 }
Eric Laurentb991fb02014-08-29 15:23:17 -05001651 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001652 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
Eric Laurentb991fb02014-08-29 15:23:17 -05001653 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1654 out_device & AUDIO_DEVICE_OUT_LINE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001655 if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001656 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1657 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001658 } else {
1659 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
1660 }
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -07001661 } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1662 snd_device = SND_DEVICE_IN_VOICE_RX;
Eric Laurentb23d5282013-05-14 15:27:20 -07001663 } else if (source == AUDIO_SOURCE_CAMCORDER) {
1664 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
1665 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1666 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
1667 }
1668 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1669 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001670 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001671 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001672 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
1673 else if (my_data->fluence_in_voice_rec &&
1674 adev->active_input->enable_ns)
1675 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001676 }
1677
1678 if (snd_device == SND_DEVICE_NONE) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001679 if (adev->active_input->enable_ns)
1680 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
1681 else
1682 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001683 }
1684 }
1685 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001686 if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE))
Eric Laurentb23d5282013-05-14 15:27:20 -07001687 in_device = AUDIO_DEVICE_IN_BACK_MIC;
1688 if (adev->active_input) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001689 if (adev->active_input->enable_aec &&
1690 adev->active_input->enable_ns) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001691 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001692 if (my_data->fluence_in_spkr_mode &&
1693 my_data->fluence_in_voice_comm &&
1694 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1695 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
1696 } else
1697 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001698 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001699 if (my_data->fluence_in_voice_comm &&
1700 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1701 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
1702 } else
1703 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
Eric Laurentcefbbac2014-09-04 13:54:10 -05001704 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1705 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001706 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05001707 platform_set_echo_reference(adev, true, out_device);
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001708 } else if (adev->active_input->enable_aec) {
1709 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1710 if (my_data->fluence_in_spkr_mode &&
1711 my_data->fluence_in_voice_comm &&
1712 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1713 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
1714 } else
1715 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
1716 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1717 if (my_data->fluence_in_voice_comm &&
1718 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1719 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
1720 } else
1721 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
Eric Laurentcefbbac2014-09-04 13:54:10 -05001722 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1723 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
1724 }
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -08001725 platform_set_echo_reference(adev, true, out_device);
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001726 } else if (adev->active_input->enable_ns) {
1727 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1728 if (my_data->fluence_in_spkr_mode &&
1729 my_data->fluence_in_voice_comm &&
1730 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1731 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
1732 } else
1733 snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
1734 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1735 if (my_data->fluence_in_voice_comm &&
1736 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1737 snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
1738 } else
1739 snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
1740 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05001741 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001742 }
1743 } else if (source == AUDIO_SOURCE_DEFAULT) {
1744 goto exit;
1745 }
1746
1747
1748 if (snd_device != SND_DEVICE_NONE) {
1749 goto exit;
1750 }
1751
1752 if (in_device != AUDIO_DEVICE_NONE &&
1753 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
1754 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
1755 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001756 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
1757 channel_count == 2)
1758 snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
1759 else
1760 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001761 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001762 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
1763 channel_count == 2)
1764 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
1765 else
1766 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001767 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1768 snd_device = SND_DEVICE_IN_HEADSET_MIC;
1769 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001770 if (adev->bt_wb_speech_enabled) {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07001771 if (adev->bluetooth_nrec)
1772 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
1773 else
1774 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001775 } else {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07001776 if (adev->bluetooth_nrec)
1777 snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
1778 else
1779 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001780 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001781 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
1782 snd_device = SND_DEVICE_IN_HDMI_MIC;
1783 } else {
1784 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
1785 ALOGW("%s: Using default handset-mic", __func__);
1786 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1787 }
1788 } else {
1789 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
1790 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1791 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1792 snd_device = SND_DEVICE_IN_HEADSET_MIC;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001793 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001794 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001795 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001796 out_device & AUDIO_DEVICE_OUT_LINE) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001797 if (channel_count == 2)
1798 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
1799 else
1800 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001801 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001802 if (adev->bt_wb_speech_enabled) {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07001803 if (adev->bluetooth_nrec)
1804 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
1805 else
1806 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001807 } else {
Ravi Kumar Alamandae258e682015-06-25 13:32:42 -07001808 if (adev->bluetooth_nrec)
1809 snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
1810 else
1811 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001812 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001813 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1814 snd_device = SND_DEVICE_IN_HDMI_MIC;
1815 } else {
1816 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
1817 ALOGW("%s: Using default handset-mic", __func__);
1818 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1819 }
1820 }
1821exit:
1822 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
1823 return snd_device;
1824}
1825
1826int platform_set_hdmi_channels(void *platform, int channel_count)
1827{
1828 struct platform_data *my_data = (struct platform_data *)platform;
1829 struct audio_device *adev = my_data->adev;
1830 struct mixer_ctl *ctl;
1831 const char *channel_cnt_str = NULL;
1832 const char *mixer_ctl_name = "HDMI_RX Channels";
1833 switch (channel_count) {
1834 case 8:
1835 channel_cnt_str = "Eight"; break;
1836 case 7:
1837 channel_cnt_str = "Seven"; break;
1838 case 6:
1839 channel_cnt_str = "Six"; break;
1840 case 5:
1841 channel_cnt_str = "Five"; break;
1842 case 4:
1843 channel_cnt_str = "Four"; break;
1844 case 3:
1845 channel_cnt_str = "Three"; break;
1846 default:
1847 channel_cnt_str = "Two"; break;
1848 }
1849 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1850 if (!ctl) {
1851 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1852 __func__, mixer_ctl_name);
1853 return -EINVAL;
1854 }
1855 ALOGV("HDMI channel count: %s", channel_cnt_str);
1856 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
1857 return 0;
1858}
1859
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001860int platform_edid_get_max_channels(void *platform)
Eric Laurentb23d5282013-05-14 15:27:20 -07001861{
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001862 struct platform_data *my_data = (struct platform_data *)platform;
1863 struct audio_device *adev = my_data->adev;
Eric Laurentb23d5282013-05-14 15:27:20 -07001864 char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
1865 char *sad = block;
1866 int num_audio_blocks;
1867 int channel_count;
1868 int max_channels = 0;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001869 int i, ret, count;
Eric Laurentb23d5282013-05-14 15:27:20 -07001870
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001871 struct mixer_ctl *ctl;
1872
1873 ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
1874 if (!ctl) {
1875 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1876 __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
Eric Laurentb23d5282013-05-14 15:27:20 -07001877 return 0;
1878 }
1879
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001880 mixer_ctl_update(ctl);
1881
1882 count = mixer_ctl_get_num_values(ctl);
Eric Laurentb23d5282013-05-14 15:27:20 -07001883
1884 /* Read SAD blocks, clamping the maximum size for safety */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001885 if (count > (int)sizeof(block))
1886 count = (int)sizeof(block);
Eric Laurentb23d5282013-05-14 15:27:20 -07001887
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001888 ret = mixer_ctl_get_array(ctl, block, count);
1889 if (ret != 0) {
1890 ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
1891 return 0;
1892 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001893
1894 /* Calculate the number of SAD blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001895 num_audio_blocks = count / SAD_BLOCK_SIZE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001896
1897 for (i = 0; i < num_audio_blocks; i++) {
1898 /* Only consider LPCM blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001899 if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
1900 sad += 3;
Eric Laurentb23d5282013-05-14 15:27:20 -07001901 continue;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001902 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001903
1904 channel_count = (sad[0] & 0x7) + 1;
1905 if (channel_count > max_channels)
1906 max_channels = channel_count;
1907
1908 /* Advance to next block */
1909 sad += 3;
1910 }
1911
1912 return max_channels;
1913}
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07001914
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001915int platform_set_incall_recording_session_id(void *platform,
1916 uint32_t session_id, int rec_mode)
1917{
1918 int ret = 0;
1919 struct platform_data *my_data = (struct platform_data *)platform;
1920 struct audio_device *adev = my_data->adev;
1921 struct mixer_ctl *ctl;
1922 const char *mixer_ctl_name = "Voc VSID";
1923 int num_ctl_values;
1924 int i;
1925
1926 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1927 if (!ctl) {
1928 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1929 __func__, mixer_ctl_name);
1930 ret = -EINVAL;
1931 } else {
1932 num_ctl_values = mixer_ctl_get_num_values(ctl);
1933 for (i = 0; i < num_ctl_values; i++) {
1934 if (mixer_ctl_set_value(ctl, i, session_id)) {
1935 ALOGV("Error: invalid session_id: %x", session_id);
1936 ret = -EINVAL;
1937 break;
1938 }
1939 }
1940 }
1941
1942 if (my_data->csd != NULL) {
1943 ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
1944 if (ret < 0) {
1945 ALOGE("%s: csd_client_start_record failed, error %d",
1946 __func__, ret);
1947 }
1948 }
1949
1950 return ret;
1951}
1952
1953int platform_stop_incall_recording_usecase(void *platform)
1954{
1955 int ret = 0;
1956 struct platform_data *my_data = (struct platform_data *)platform;
1957
1958 if (my_data->csd != NULL) {
1959 ret = my_data->csd->stop_record(ALL_SESSION_VSID);
1960 if (ret < 0) {
1961 ALOGE("%s: csd_client_stop_record failed, error %d",
1962 __func__, ret);
1963 }
1964 }
1965
1966 return ret;
1967}
1968
1969int platform_start_incall_music_usecase(void *platform)
1970{
1971 int ret = 0;
1972 struct platform_data *my_data = (struct platform_data *)platform;
1973
1974 if (my_data->csd != NULL) {
1975 ret = my_data->csd->start_playback(ALL_SESSION_VSID);
1976 if (ret < 0) {
1977 ALOGE("%s: csd_client_start_playback failed, error %d",
1978 __func__, ret);
1979 }
1980 }
1981
1982 return ret;
1983}
1984
1985int platform_stop_incall_music_usecase(void *platform)
1986{
1987 int ret = 0;
1988 struct platform_data *my_data = (struct platform_data *)platform;
1989
1990 if (my_data->csd != NULL) {
1991 ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
1992 if (ret < 0) {
1993 ALOGE("%s: csd_client_stop_playback failed, error %d",
1994 __func__, ret);
1995 }
1996 }
1997
1998 return ret;
1999}
2000
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -07002001int platform_set_parameters(void *platform, struct str_parms *parms)
2002{
2003 struct platform_data *my_data = (struct platform_data *)platform;
2004 char value[64];
2005 char *kv_pairs = str_parms_to_str(parms);
2006 int ret = 0, err;
2007
2008 if (kv_pairs == NULL) {
2009 ret = -EINVAL;
2010 ALOGE("%s: key-value pair is NULL",__func__);
2011 goto done;
2012 }
2013
2014 ALOGV("%s: enter: %s", __func__, kv_pairs);
2015
2016 err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_SOUNDCARD_NAME,
2017 value, sizeof(value));
2018 if (err >= 0) {
2019 str_parms_del(parms, PLATFORM_CONFIG_KEY_SOUNDCARD_NAME);
2020 my_data->snd_card_name = strdup(value);
2021 ALOGV("%s: sound card name %s", __func__, my_data->snd_card_name);
2022 }
2023
2024done:
2025 ALOGV("%s: exit with code(%d)", __func__, ret);
2026 if (kv_pairs != NULL)
2027 free(kv_pairs);
2028
2029 return ret;
2030}
2031
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07002032/* Delay in Us */
2033int64_t platform_render_latency(audio_usecase_t usecase)
2034{
2035 switch (usecase) {
2036 case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
2037 return DEEP_BUFFER_PLATFORM_DELAY;
2038 case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
2039 return LOW_LATENCY_PLATFORM_DELAY;
2040 default:
2041 return 0;
2042 }
2043}
Haynes Mathew George98c95622014-06-20 19:14:25 -07002044
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07002045int platform_set_snd_device_backend(snd_device_t device, const char *backend_tag,
2046 const char * hw_interface)
Haynes Mathew George98c95622014-06-20 19:14:25 -07002047{
2048 int ret = 0;
2049
2050 if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
2051 ALOGE("%s: Invalid snd_device = %d",
2052 __func__, device);
2053 ret = -EINVAL;
2054 goto done;
2055 }
2056
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07002057 ALOGV("%s: backend_tag_table[%s]: old = %s new = %s", __func__,
2058 platform_get_snd_device_name(device),
2059 backend_tag_table[device] != NULL ? backend_tag_table[device]: "null", backend_tag);
2060 if (backend_tag_table[device]) {
2061 free(backend_tag_table[device]);
Haynes Mathew George98c95622014-06-20 19:14:25 -07002062 }
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07002063 backend_tag_table[device] = strdup(backend_tag);
2064
2065 if (hw_interface != NULL) {
2066 if (hw_interface_table[device])
2067 free(hw_interface_table[device]);
2068 ALOGV("%s: hw_interface_table[%d] = %s", __func__, device, hw_interface);
2069 hw_interface_table[device] = strdup(hw_interface);
2070 }
Haynes Mathew George98c95622014-06-20 19:14:25 -07002071done:
2072 return ret;
2073}
2074
2075int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
2076{
2077 int ret = 0;
2078 if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
2079 ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
2080 ret = -EINVAL;
2081 goto done;
2082 }
2083
2084 if ((type != 0) && (type != 1)) {
2085 ALOGE("%s: invalid usecase type", __func__);
2086 ret = -EINVAL;
2087 }
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07002088 ALOGV("%s: pcm_device_table[%d][%d] = %d", __func__, usecase, type, pcm_id);
Haynes Mathew George98c95622014-06-20 19:14:25 -07002089 pcm_device_table[usecase][type] = pcm_id;
2090done:
2091 return ret;
2092}
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07002093
2094int platform_swap_lr_channels(struct audio_device *adev, bool swap_channels)
2095{
2096 // only update if there is active pcm playback on speaker
2097 struct audio_usecase *usecase;
2098 struct listnode *node;
2099 struct platform_data *my_data = (struct platform_data *)adev->platform;
2100
2101 if (my_data->speaker_lr_swap != swap_channels) {
2102 my_data->speaker_lr_swap = swap_channels;
2103
2104 list_for_each(node, &adev->usecase_list) {
2105 usecase = node_to_item(node, struct audio_usecase, list);
2106 if (usecase->type == PCM_PLAYBACK &&
2107 usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
2108 const char *mixer_path;
2109 if (swap_channels) {
2110 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
2111 audio_route_apply_and_update_path(adev->audio_route, mixer_path);
2112 } else {
2113 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
2114 audio_route_apply_and_update_path(adev->audio_route, mixer_path);
2115 }
2116 break;
2117 }
2118 }
2119 }
2120 return 0;
2121}