blob: e0ea8edc22871ca9b7cb2d28683e40f4ff052bc6 [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"
Eric Laurentb23d5282013-05-14 15:27:20 -070030
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070031#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
Eric Laurentb23d5282013-05-14 15:27:20 -070032#define LIB_ACDB_LOADER "libacdbloader.so"
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070033#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
Eric Laurentb23d5282013-05-14 15:27:20 -070034
35#define DUALMIC_CONFIG_NONE 0 /* Target does not contain 2 mics */
36#define DUALMIC_CONFIG_ENDFIRE 1
37#define DUALMIC_CONFIG_BROADSIDE 2
38
39/*
Eric Laurentb23d5282013-05-14 15:27:20 -070040 * This file will have a maximum of 38 bytes:
41 *
42 * 4 bytes: number of audio blocks
43 * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
44 * Maximum 10 * 3 bytes: SAD blocks
45 */
46#define MAX_SAD_BLOCKS 10
47#define SAD_BLOCK_SIZE 3
48
49/* EDID format ID for LPCM audio */
50#define EDID_FORMAT_LPCM 1
51
sangwoo1b9f4b32013-06-21 18:22:55 -070052/* Retry for delay in FW loading*/
53#define RETRY_NUMBER 10
54#define RETRY_US 500000
Vineeta Srivastava4b89e372014-06-19 14:21:42 -070055#define MAX_SND_CARD 8
sangwoo53b2cf02013-07-25 19:18:44 -070056
Eric Laurentb23d5282013-05-14 15:27:20 -070057struct audio_block_header
58{
59 int reserved;
60 int length;
61};
62
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -070063/* Audio calibration related functions */
Eric Laurentb23d5282013-05-14 15:27:20 -070064typedef void (*acdb_deallocate_t)();
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -070065#ifdef PLATFORM_MSM8084
66typedef int (*acdb_init_t)(char *);
67#else
Eric Laurentb23d5282013-05-14 15:27:20 -070068typedef int (*acdb_init_t)();
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -070069#endif
Eric Laurentb23d5282013-05-14 15:27:20 -070070typedef void (*acdb_send_audio_cal_t)(int, int);
71typedef void (*acdb_send_voice_cal_t)(int, int);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -070072typedef int (*acdb_reload_vocvoltable_t)(int);
Eric Laurentb23d5282013-05-14 15:27:20 -070073
74/* Audio calibration related functions */
75struct platform_data {
76 struct audio_device *adev;
77 bool fluence_in_spkr_mode;
78 bool fluence_in_voice_call;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -070079 bool fluence_in_voice_comm;
Eric Laurentb23d5282013-05-14 15:27:20 -070080 bool fluence_in_voice_rec;
81 int dualmic_config;
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -070082 bool speaker_lr_swap;
83
Eric Laurentb23d5282013-05-14 15:27:20 -070084 void *acdb_handle;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -070085 acdb_init_t acdb_init;
86 acdb_deallocate_t acdb_deallocate;
87 acdb_send_audio_cal_t acdb_send_audio_cal;
88 acdb_send_voice_cal_t acdb_send_voice_cal;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -070089 acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
90 struct csd_data *csd;
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -050091 bool ext_speaker;
92 bool ext_earpiece;
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -080093 char ec_ref_mixer_path[64];
Eric Laurentb23d5282013-05-14 15:27:20 -070094};
95
Haynes Mathew George98c95622014-06-20 19:14:25 -070096static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -070097 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
98 DEEP_BUFFER_PCM_DEVICE},
99 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
100 LOWLATENCY_PCM_DEVICE},
101 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
102 MULTIMEDIA2_PCM_DEVICE},
103 [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {PLAYBACK_OFFLOAD_DEVICE,
104 PLAYBACK_OFFLOAD_DEVICE},
105 [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE,
106 AUDIO_RECORD_PCM_DEVICE},
107 [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
108 LOWLATENCY_PCM_DEVICE},
109 [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE,
110 VOICE_CALL_PCM_DEVICE},
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700111 [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
112 [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
113 [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
114 [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
115 [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
116 AUDIO_RECORD_PCM_DEVICE},
117 [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
118 AUDIO_RECORD_PCM_DEVICE},
119 [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
120 AUDIO_RECORD_PCM_DEVICE},
Ravi Kumar Alamanda8e6e98f2013-11-05 15:57:39 -0800121 [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700122
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700123 [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
124 [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
125
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700126 [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
127 AFE_PROXY_RECORD_PCM_DEVICE},
128 [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
129 AFE_PROXY_RECORD_PCM_DEVICE},
130
Eric Laurentb23d5282013-05-14 15:27:20 -0700131};
132
133/* Array to store sound devices */
134static const char * const device_table[SND_DEVICE_MAX] = {
135 [SND_DEVICE_NONE] = "none",
136 /* Playback sound devices */
137 [SND_DEVICE_OUT_HANDSET] = "handset",
138 [SND_DEVICE_OUT_SPEAKER] = "speaker",
139 [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700140 [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
Eric Laurentb23d5282013-05-14 15:27:20 -0700141 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500142 [SND_DEVICE_OUT_LINE] = "line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700143 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Eric Laurent744996b2014-10-01 11:40:40 -0500144 [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700145 [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500146 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
Eric Laurentb23d5282013-05-14 15:27:20 -0700147 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
148 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500149 [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700150 [SND_DEVICE_OUT_HDMI] = "hdmi",
151 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
152 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700153 [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700154 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
155 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
156 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
157 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700158 [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700159 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
160 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
Eric Laurentb23d5282013-05-14 15:27:20 -0700161
162 /* Capture sound devices */
163 [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700164 [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700165 [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
166 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
167 [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
168 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
169 [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
170 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
171 [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = "dmic-endfire",
172
173 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
174 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
175 [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
176 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
177 [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
178 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
179 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
180 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
181 [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = "speaker-dmic-endfire",
182
183 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
Eric Laurentcefbbac2014-09-04 13:54:10 -0500184 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700185
Eric Laurentb23d5282013-05-14 15:27:20 -0700186 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
187 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700188 [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700189
Eric Laurentb23d5282013-05-14 15:27:20 -0700190 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700191
192 [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
193 [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
194 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
195 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
196 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700197 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
198 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
199 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700200
Eric Laurentb23d5282013-05-14 15:27:20 -0700201 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700202 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
203 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
204 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700205
206 [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700207
208 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
Eric Laurentb23d5282013-05-14 15:27:20 -0700209};
210
211/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700212static int acdb_device_table[SND_DEVICE_MAX] = {
Eric Laurentb23d5282013-05-14 15:27:20 -0700213 [SND_DEVICE_NONE] = -1,
214 [SND_DEVICE_OUT_HANDSET] = 7,
215 [SND_DEVICE_OUT_SPEAKER] = 15,
216 [SND_DEVICE_OUT_SPEAKER_REVERSE] = 15,
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700217 [SND_DEVICE_OUT_SPEAKER_SAFE] = 15,
Eric Laurentb23d5282013-05-14 15:27:20 -0700218 [SND_DEVICE_OUT_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500219 [SND_DEVICE_OUT_LINE] = 77,
Eric Laurentb23d5282013-05-14 15:27:20 -0700220 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500221 [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 77,
Ravi Kumar Alamanda235c3482014-08-21 17:32:44 -0700222 [SND_DEVICE_OUT_VOICE_HANDSET] = ACDB_ID_VOICE_HANDSET,
223 [SND_DEVICE_OUT_VOICE_SPEAKER] = ACDB_ID_VOICE_SPEAKER,
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500224 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
Eric Laurentb23d5282013-05-14 15:27:20 -0700225 [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500226 [SND_DEVICE_OUT_VOICE_LINE] = 77,
Eric Laurentb23d5282013-05-14 15:27:20 -0700227 [SND_DEVICE_OUT_HDMI] = 18,
228 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 15,
229 [SND_DEVICE_OUT_BT_SCO] = 22,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700230 [SND_DEVICE_OUT_BT_SCO_WB] = 39,
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700231 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = ACDB_ID_VOICE_HANDSET_TMUS,
Eric Laurentb23d5282013-05-14 15:27:20 -0700232 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
233 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
234 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700235 [SND_DEVICE_OUT_VOICE_TX] = 45,
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700236 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
237 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
Eric Laurentb23d5282013-05-14 15:27:20 -0700238
239 [SND_DEVICE_IN_HANDSET_MIC] = 4,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700240 [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
241 [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
242 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
243 [SND_DEVICE_IN_HANDSET_DMIC] = 41,
244 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
245 [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
246 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
247 [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = 34,
248
249 [SND_DEVICE_IN_SPEAKER_MIC] = 11,
250 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
251 [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
252 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
253 [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
254 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
255 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
256 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
257 [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = 35,
258
Eric Laurentb23d5282013-05-14 15:27:20 -0700259 [SND_DEVICE_IN_HEADSET_MIC] = 8,
Eric Laurentcefbbac2014-09-04 13:54:10 -0500260 [SND_DEVICE_IN_HEADSET_MIC_AEC] = ACDB_ID_HEADSET_MIC_AEC,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700261
Eric Laurentb23d5282013-05-14 15:27:20 -0700262 [SND_DEVICE_IN_HDMI_MIC] = 4,
263 [SND_DEVICE_IN_BT_SCO_MIC] = 21,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700264 [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700265
Eric Laurentb23d5282013-05-14 15:27:20 -0700266 [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700267
268 [SND_DEVICE_IN_VOICE_DMIC] = 41,
269 [SND_DEVICE_IN_VOICE_DMIC_TMUS] = ACDB_ID_VOICE_DMIC_EF_TMUS,
270 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
271 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
272 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
Eric Laurentb23d5282013-05-14 15:27:20 -0700273 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
274 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
275 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700276
Eric Laurentb23d5282013-05-14 15:27:20 -0700277 [SND_DEVICE_IN_VOICE_REC_MIC] = 62,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700278 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 113,
279 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 35,
280 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 43,
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700281
282 [SND_DEVICE_IN_VOICE_RX] = 44,
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700283
284 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
Eric Laurentb23d5282013-05-14 15:27:20 -0700285};
286
Haynes Mathew George98c95622014-06-20 19:14:25 -0700287struct name_to_index {
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700288 char name[100];
289 unsigned int index;
290};
291
292#define TO_NAME_INDEX(X) #X, X
293
Haynes Mathew George98c95622014-06-20 19:14:25 -0700294/* Used to get index from parsed string */
295static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
296 /* out */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700297 {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
298 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
299 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700300 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700301 {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500302 {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700303 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
Eric Laurent744996b2014-10-01 11:40:40 -0500304 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700305 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
306 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
307 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500308 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700309 {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
310 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
311 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
312 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700313 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET_TMUS)},
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500314 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700315 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
316 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
317 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700318
319 /* in */
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700320 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
321 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700322 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700323 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700324 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
325 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
326 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
327 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
328 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
329 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
330 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_STEREO)},
331
332 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700333 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700334 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
335 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
336 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
337 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
338 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
339 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
340 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
341
342 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
343
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700344 {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
345 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
346 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700347
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700348 {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700349
350 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
351 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
352 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
353 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
354 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700355 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
356 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
357 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700358
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700359 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700360 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
361 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
362 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700363
364 {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700365};
366
367static char * backend_table[SND_DEVICE_MAX] = {0};
368
369static const struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
370 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
371 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
372 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
373 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
374 {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
375 {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
376 {TO_NAME_INDEX(USECASE_VOICE_CALL)},
377 {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
378 {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
379 {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
380 {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
381 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK)},
382 {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
383 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
384 {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700385};
386
Haynes Mathew George7ff216f2013-09-11 19:51:41 -0700387#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
388#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
389
Eric Laurentb23d5282013-05-14 15:27:20 -0700390static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
391static bool is_tmus = false;
392
393static void check_operator()
394{
395 char value[PROPERTY_VALUE_MAX];
396 int mccmnc;
397 property_get("gsm.sim.operator.numeric",value,"0");
398 mccmnc = atoi(value);
399 ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
400 switch(mccmnc) {
401 /* TMUS MCC(310), MNC(490, 260, 026) */
402 case 310490:
403 case 310260:
404 case 310026:
sangwon.jeonb891db52013-09-14 17:39:15 +0900405 /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
406 case 310800:
407 case 310660:
408 case 310580:
409 case 310310:
410 case 310270:
411 case 310250:
412 case 310240:
413 case 310230:
414 case 310220:
415 case 310210:
416 case 310200:
417 case 310160:
Eric Laurentb23d5282013-05-14 15:27:20 -0700418 is_tmus = true;
419 break;
420 }
421}
422
423bool is_operator_tmus()
424{
425 pthread_once(&check_op_once_ctl, check_operator);
426 return is_tmus;
427}
428
Eric Laurentcefbbac2014-09-04 13:54:10 -0500429void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
Eric Laurentb23d5282013-05-14 15:27:20 -0700430{
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800431 struct platform_data *my_data = (struct platform_data *)adev->platform;
Eric Laurentcefbbac2014-09-04 13:54:10 -0500432 snd_device_t snd_device = SND_DEVICE_NONE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700433
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800434 if (strcmp(my_data->ec_ref_mixer_path, "")) {
435 ALOGV("%s: diabling %s", __func__, my_data->ec_ref_mixer_path);
436 audio_route_reset_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
Eric Laurentcefbbac2014-09-04 13:54:10 -0500437 }
438
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800439 if (enable) {
440 strcpy(my_data->ec_ref_mixer_path, "echo-reference");
441 if (out_device != AUDIO_DEVICE_NONE) {
442 snd_device = platform_get_output_snd_device(adev->platform, out_device);
443 platform_add_backend_name(adev->platform, my_data->ec_ref_mixer_path, snd_device);
444 }
Eric Laurentcefbbac2014-09-04 13:54:10 -0500445
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800446 ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
447 audio_route_apply_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
448 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700449}
450
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700451static struct csd_data *open_csd_client(bool i2s_ext_modem)
452{
453 struct csd_data *csd = calloc(1, sizeof(struct csd_data));
454
455 csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
456 if (csd->csd_client == NULL) {
457 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
458 goto error;
459 } else {
460 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
461
462 csd->deinit = (deinit_t)dlsym(csd->csd_client,
463 "csd_client_deinit");
464 if (csd->deinit == NULL) {
465 ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
466 dlerror());
467 goto error;
468 }
469 csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
470 "csd_client_disable_device");
471 if (csd->disable_device == NULL) {
472 ALOGE("%s: dlsym error %s for csd_client_disable_device",
473 __func__, dlerror());
474 goto error;
475 }
476 csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
477 "csd_client_enable_device_config");
478 if (csd->enable_device_config == NULL) {
479 ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
480 __func__, dlerror());
481 goto error;
482 }
483 csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
484 "csd_client_enable_device");
485 if (csd->enable_device == NULL) {
486 ALOGE("%s: dlsym error %s for csd_client_enable_device",
487 __func__, dlerror());
488 goto error;
489 }
490 csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
491 "csd_client_start_voice");
492 if (csd->start_voice == NULL) {
493 ALOGE("%s: dlsym error %s for csd_client_start_voice",
494 __func__, dlerror());
495 goto error;
496 }
497 csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
498 "csd_client_stop_voice");
499 if (csd->stop_voice == NULL) {
500 ALOGE("%s: dlsym error %s for csd_client_stop_voice",
501 __func__, dlerror());
502 goto error;
503 }
504 csd->volume = (volume_t)dlsym(csd->csd_client,
505 "csd_client_volume");
506 if (csd->volume == NULL) {
507 ALOGE("%s: dlsym error %s for csd_client_volume",
508 __func__, dlerror());
509 goto error;
510 }
511 csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
512 "csd_client_mic_mute");
513 if (csd->mic_mute == NULL) {
514 ALOGE("%s: dlsym error %s for csd_client_mic_mute",
515 __func__, dlerror());
516 goto error;
517 }
518 csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
519 "csd_client_slow_talk");
520 if (csd->slow_talk == NULL) {
521 ALOGE("%s: dlsym error %s for csd_client_slow_talk",
522 __func__, dlerror());
523 goto error;
524 }
525 csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
526 "csd_client_start_playback");
527 if (csd->start_playback == NULL) {
528 ALOGE("%s: dlsym error %s for csd_client_start_playback",
529 __func__, dlerror());
530 goto error;
531 }
532 csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
533 "csd_client_stop_playback");
534 if (csd->stop_playback == NULL) {
535 ALOGE("%s: dlsym error %s for csd_client_stop_playback",
536 __func__, dlerror());
537 goto error;
538 }
539 csd->start_record = (start_record_t)dlsym(csd->csd_client,
540 "csd_client_start_record");
541 if (csd->start_record == NULL) {
542 ALOGE("%s: dlsym error %s for csd_client_start_record",
543 __func__, dlerror());
544 goto error;
545 }
546 csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
547 "csd_client_stop_record");
548 if (csd->stop_record == NULL) {
549 ALOGE("%s: dlsym error %s for csd_client_stop_record",
550 __func__, dlerror());
551 goto error;
552 }
553
554 csd->get_sample_rate = (get_sample_rate_t)dlsym(csd->csd_client,
555 "csd_client_get_sample_rate");
556 if (csd->get_sample_rate == NULL) {
557 ALOGE("%s: dlsym error %s for csd_client_get_sample_rate",
558 __func__, dlerror());
559
560 goto error;
561 }
562
563 csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
564
565 if (csd->init == NULL) {
566 ALOGE("%s: dlsym error %s for csd_client_init",
567 __func__, dlerror());
568 goto error;
569 } else {
570 csd->init(i2s_ext_modem);
571 }
572 }
573 return csd;
574
575error:
576 free(csd);
577 csd = NULL;
578 return csd;
579}
580
581void close_csd_client(struct csd_data *csd)
582{
583 if (csd != NULL) {
584 csd->deinit();
585 dlclose(csd->csd_client);
586 free(csd);
587 csd = NULL;
588 }
589}
590
591static void platform_csd_init(struct platform_data *my_data)
592{
593#ifdef PLATFORM_MSM8084
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700594 int32_t modems, (*count_modems)(void);
595 const char *name = "libdetectmodem.so";
596 const char *func = "count_modems";
597 const char *error;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700598
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700599 my_data->csd = NULL;
600
601 void *lib = dlopen(name, RTLD_NOW);
602 error = dlerror();
603 if (!lib) {
604 ALOGE("%s: could not find %s: %s", __func__, name, error);
605 return;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700606 }
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700607
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700608 count_modems = NULL;
609 *(void **)(&count_modems) = dlsym(lib, func);
610 error = dlerror();
611 if (!count_modems) {
612 ALOGE("%s: could not find symbol %s in %s: %s",
613 __func__, func, name, error);
614 goto done;
615 }
616
617 modems = count_modems();
618 if (modems < 0) {
619 ALOGE("%s: count_modems failed\n", __func__);
620 goto done;
621 }
622
623 ALOGD("%s: num_modems %d\n", __func__, modems);
624 if (modems > 0)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700625 my_data->csd = open_csd_client(false /*is_i2s_ext_modem*/);
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700626
627done:
628 dlclose(lib);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700629#else
630 my_data->csd = NULL;
631#endif
632}
633
Haynes Mathew George98c95622014-06-20 19:14:25 -0700634static void set_platform_defaults(struct platform_data * my_data)
635{
636 int32_t dev;
637 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
638 backend_table[dev] = NULL;
639 }
640
641 // TBD - do these go to the platform-info.xml file.
642 // will help in avoiding strdups here
643 backend_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
644 backend_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
645 backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
646 backend_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
647 backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
648 backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700649 backend_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
650 backend_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700651
652 if (my_data->ext_speaker) {
653 backend_table[SND_DEVICE_OUT_SPEAKER] = strdup("speaker");
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700654 backend_table[SND_DEVICE_OUT_SPEAKER_SAFE] = strdup("speaker");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700655 backend_table[SND_DEVICE_OUT_VOICE_SPEAKER] = strdup("speaker");
656 backend_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = strdup("speaker");
657 backend_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] =
658 strdup("speaker-and-headphones");
Eric Laurent744996b2014-10-01 11:40:40 -0500659 backend_table[SND_DEVICE_OUT_SPEAKER_AND_LINE] =
660 strdup("speaker-and-line");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700661 }
662
663 if (my_data->ext_earpiece) {
664 backend_table[SND_DEVICE_OUT_VOICE_HANDSET] = strdup("handset");
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500665 backend_table[SND_DEVICE_OUT_VOICE_HAC_HANDSET] = strdup("handset");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700666 backend_table[SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = strdup("handset");
667 backend_table[SND_DEVICE_OUT_HANDSET] = strdup("handset");
668 backend_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("handset");
669 }
670}
671
Eric Laurentb23d5282013-05-14 15:27:20 -0700672void *platform_init(struct audio_device *adev)
673{
674 char value[PROPERTY_VALUE_MAX];
675 struct platform_data *my_data;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700676 int retry_num = 0, snd_card_num = 0;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700677 const char *snd_card_name;
sangwoo1b9f4b32013-06-21 18:22:55 -0700678
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700679 while (snd_card_num < MAX_SND_CARD) {
680 adev->mixer = mixer_open(snd_card_num);
sangwoo1b9f4b32013-06-21 18:22:55 -0700681
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700682 while (!adev->mixer && retry_num < RETRY_NUMBER) {
683 usleep(RETRY_US);
684 adev->mixer = mixer_open(snd_card_num);
685 retry_num++;
686 }
687
688 if (!adev->mixer) {
689 ALOGE("%s: Unable to open the mixer card: %d", __func__,
690 snd_card_num);
691 retry_num = 0;
692 snd_card_num++;
693 continue;
694 }
695
696 snd_card_name = mixer_get_name(adev->mixer);
697 ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
698
699 adev->audio_route = audio_route_init(snd_card_num, MIXER_XML_PATH);
700 if (!adev->audio_route) {
701 ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
702 return NULL;
703 }
704 adev->snd_card = snd_card_num;
705 ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
706 break;
sangwoo1b9f4b32013-06-21 18:22:55 -0700707 }
708
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700709 if (snd_card_num >= MAX_SND_CARD) {
710 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
sangwoo1b9f4b32013-06-21 18:22:55 -0700711 return NULL;
712 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700713
714 my_data = calloc(1, sizeof(struct platform_data));
715
716 my_data->adev = adev;
717 my_data->dualmic_config = DUALMIC_CONFIG_NONE;
718 my_data->fluence_in_spkr_mode = false;
719 my_data->fluence_in_voice_call = false;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700720 my_data->fluence_in_voice_comm = false;
Eric Laurentb23d5282013-05-14 15:27:20 -0700721 my_data->fluence_in_voice_rec = false;
722
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500723 /*
724 * The default assumption is that earpiece (handset), speaker and headphones
725 * devices are connected to internal HW codec and communicated through
726 * slimbus backend. If any platform communicates with speaker or earpiece
727 * or headphones through non-slimbus backend such as MI2S or AUXPCM etc.,
728 * the ext_xxxx flags must be set accordingly.
729 */
730 if (strstr(snd_card_name, "tfa9890_stereo")) {
731 my_data->ext_speaker = true;
732 my_data->ext_earpiece = true;
733 } else if (strstr(snd_card_name, "tfa9890")) {
734 my_data->ext_speaker = true;
735 }
736
Eric Laurentb23d5282013-05-14 15:27:20 -0700737 property_get("persist.audio.dualmic.config",value,"");
738 if (!strcmp("broadside", value)) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700739 ALOGE("%s: Unsupported dualmic configuration", __func__);
Eric Laurentb23d5282013-05-14 15:27:20 -0700740 } else if (!strcmp("endfire", value)) {
741 my_data->dualmic_config = DUALMIC_CONFIG_ENDFIRE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700742 }
743
744 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
745 property_get("persist.audio.fluence.voicecall",value,"");
746 if (!strcmp("true", value)) {
747 my_data->fluence_in_voice_call = true;
748 }
749
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700750 property_get("persist.audio.fluence.voicecomm",value,"");
751 if (!strcmp("true", value)) {
752 my_data->fluence_in_voice_comm = true;
753 }
754
Eric Laurentb23d5282013-05-14 15:27:20 -0700755 property_get("persist.audio.fluence.voicerec",value,"");
756 if (!strcmp("true", value)) {
757 my_data->fluence_in_voice_rec = true;
758 }
759
760 property_get("persist.audio.fluence.speaker",value,"");
761 if (!strcmp("true", value)) {
762 my_data->fluence_in_spkr_mode = true;
763 }
764 }
765
766 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
767 if (my_data->acdb_handle == NULL) {
768 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
769 } else {
770 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
771 my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
772 "acdb_loader_deallocate_ACDB");
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700773 if (!my_data->acdb_deallocate)
774 ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
775 __func__, LIB_ACDB_LOADER);
776
Eric Laurentb23d5282013-05-14 15:27:20 -0700777 my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
778 "acdb_loader_send_audio_cal");
779 if (!my_data->acdb_send_audio_cal)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700780 ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
Eric Laurentb23d5282013-05-14 15:27:20 -0700781 __func__, LIB_ACDB_LOADER);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700782
Eric Laurentb23d5282013-05-14 15:27:20 -0700783 my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
784 "acdb_loader_send_voice_cal");
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700785 if (!my_data->acdb_send_voice_cal)
786 ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
787 __func__, LIB_ACDB_LOADER);
788
789 my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
790 "acdb_loader_reload_vocvoltable");
791 if (!my_data->acdb_reload_vocvoltable)
792 ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
793 __func__, LIB_ACDB_LOADER);
794#ifdef PLATFORM_MSM8084
795 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
796 "acdb_loader_init_v2");
797 if (my_data->acdb_init == NULL)
798 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
799 else
Haynes Mathew George98c95622014-06-20 19:14:25 -0700800 my_data->acdb_init((char *)snd_card_name);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700801#else
Eric Laurentb23d5282013-05-14 15:27:20 -0700802 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
803 "acdb_loader_init_ACDB");
804 if (my_data->acdb_init == NULL)
805 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
806 else
807 my_data->acdb_init();
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700808#endif
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700809
Eric Laurentb23d5282013-05-14 15:27:20 -0700810 }
811
Haynes Mathew George98c95622014-06-20 19:14:25 -0700812 set_platform_defaults(my_data);
813
814 /* Initialize platform specific ids and/or backends*/
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700815 audio_extn_spkr_prot_init(adev);
Haynes Mathew George98c95622014-06-20 19:14:25 -0700816
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700817 /* load csd client */
818 platform_csd_init(my_data);
819
Eric Laurentb23d5282013-05-14 15:27:20 -0700820 return my_data;
821}
822
823void platform_deinit(void *platform)
824{
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700825 struct platform_data *my_data = (struct platform_data *)platform;
826 close_csd_client(my_data->csd);
Eric Laurentb23d5282013-05-14 15:27:20 -0700827 free(platform);
828}
829
830const char *platform_get_snd_device_name(snd_device_t snd_device)
831{
832 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
833 return device_table[snd_device];
834 else
Ravi Kumar Alamanda64026462014-09-15 00:08:58 -0700835 return "none";
Eric Laurentb23d5282013-05-14 15:27:20 -0700836}
837
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500838void platform_add_backend_name(void *platform, char *mixer_path,
839 snd_device_t snd_device)
Eric Laurentb23d5282013-05-14 15:27:20 -0700840{
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500841 struct platform_data *my_data = (struct platform_data *)platform;
842
Haynes Mathew George98c95622014-06-20 19:14:25 -0700843 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
844 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
845 return;
Ravi Kumar Alamanda1de6e5a2014-06-19 21:55:39 -0500846 }
Haynes Mathew George98c95622014-06-20 19:14:25 -0700847
848 const char * suffix = backend_table[snd_device];
849
850 if (suffix != NULL) {
851 strcat(mixer_path, " ");
852 strcat(mixer_path, suffix);
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500853 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700854}
855
856int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
857{
858 int device_id;
859 if (device_type == PCM_PLAYBACK)
860 device_id = pcm_device_table[usecase][0];
861 else
862 device_id = pcm_device_table[usecase][1];
863 return device_id;
864}
865
Haynes Mathew George98c95622014-06-20 19:14:25 -0700866static int find_index(const struct name_to_index * table, int32_t len,
867 const char * name)
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700868{
869 int ret = 0;
Haynes Mathew George98c95622014-06-20 19:14:25 -0700870 int32_t i;
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700871
Haynes Mathew George98c95622014-06-20 19:14:25 -0700872 if (table == NULL) {
873 ALOGE("%s: table is NULL", __func__);
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700874 ret = -ENODEV;
875 goto done;
876 }
877
Haynes Mathew George98c95622014-06-20 19:14:25 -0700878 if (name == NULL) {
879 ALOGE("null key");
880 ret = -ENODEV;
881 goto done;
882 }
883
884 for (i=0; i < len; i++) {
885 if (!strcmp(table[i].name, name)) {
886 ret = table[i].index;
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700887 goto done;
888 }
889 }
Haynes Mathew George98c95622014-06-20 19:14:25 -0700890 ALOGE("%s: Could not find index for name = %s",
891 __func__, name);
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700892 ret = -ENODEV;
893done:
894 return ret;
895}
896
Haynes Mathew George98c95622014-06-20 19:14:25 -0700897int platform_get_snd_device_index(char *device_name)
898{
899 return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
900}
901
902int platform_get_usecase_index(const char *usecase_name)
903{
904 return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
905}
906
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700907int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
908{
909 int ret = 0;
910
911 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
912 ALOGE("%s: Invalid snd_device = %d",
913 __func__, snd_device);
914 ret = -EINVAL;
915 goto done;
916 }
917
918 acdb_device_table[snd_device] = acdb_id;
919done:
920 return ret;
921}
922
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700923int platform_get_snd_device_acdb_id(snd_device_t snd_device)
924{
925 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
926 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
927 return -EINVAL;
928 }
929 return acdb_device_table[snd_device];
930}
931
Eric Laurentb23d5282013-05-14 15:27:20 -0700932int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
933{
934 struct platform_data *my_data = (struct platform_data *)platform;
935 int acdb_dev_id, acdb_dev_type;
936
937 acdb_dev_id = acdb_device_table[snd_device];
938 if (acdb_dev_id < 0) {
939 ALOGE("%s: Could not find acdb id for device(%d)",
940 __func__, snd_device);
941 return -EINVAL;
942 }
943 if (my_data->acdb_send_audio_cal) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700944 ALOGD("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
Eric Laurentb23d5282013-05-14 15:27:20 -0700945 __func__, snd_device, acdb_dev_id);
946 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
947 snd_device < SND_DEVICE_OUT_END)
948 acdb_dev_type = ACDB_DEV_TYPE_OUT;
949 else
950 acdb_dev_type = ACDB_DEV_TYPE_IN;
951 my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
952 }
953 return 0;
954}
955
956int platform_switch_voice_call_device_pre(void *platform)
957{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700958 struct platform_data *my_data = (struct platform_data *)platform;
959 int ret = 0;
960
961 if (my_data->csd != NULL &&
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -0700962 voice_is_in_call(my_data->adev)) {
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700963 /* This must be called before disabling mixer controls on APQ side */
964 ret = my_data->csd->disable_device();
965 if (ret < 0) {
966 ALOGE("%s: csd_client_disable_device, failed, error %d",
967 __func__, ret);
968 }
969 }
970 return ret;
971}
972
973int platform_switch_voice_call_enable_device_config(void *platform,
974 snd_device_t out_snd_device,
975 snd_device_t in_snd_device)
976{
977 struct platform_data *my_data = (struct platform_data *)platform;
978 int acdb_rx_id, acdb_tx_id;
979 int ret = 0;
980
981 if (my_data->csd == NULL)
982 return ret;
983
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700984 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
985 audio_extn_spkr_prot_is_enabled())
986 acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
987 else
988 acdb_rx_id = acdb_device_table[out_snd_device];
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700989
990 acdb_tx_id = acdb_device_table[in_snd_device];
991
992 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
993 ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
994 if (ret < 0) {
995 ALOGE("%s: csd_enable_device_config, failed, error %d",
996 __func__, ret);
997 }
998 } else {
999 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1000 acdb_rx_id, acdb_tx_id);
1001 }
1002
1003 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001004}
1005
1006int platform_switch_voice_call_device_post(void *platform,
1007 snd_device_t out_snd_device,
1008 snd_device_t in_snd_device)
1009{
1010 struct platform_data *my_data = (struct platform_data *)platform;
1011 int acdb_rx_id, acdb_tx_id;
1012
1013 if (my_data->acdb_send_voice_cal == NULL) {
1014 ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
1015 } else {
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001016 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1017 audio_extn_spkr_prot_is_enabled())
1018 out_snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
1019
Eric Laurentb23d5282013-05-14 15:27:20 -07001020 acdb_rx_id = acdb_device_table[out_snd_device];
1021 acdb_tx_id = acdb_device_table[in_snd_device];
1022
1023 if (acdb_rx_id > 0 && acdb_tx_id > 0)
1024 my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
1025 else
1026 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1027 acdb_rx_id, acdb_tx_id);
1028 }
1029
1030 return 0;
1031}
1032
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001033int platform_switch_voice_call_usecase_route_post(void *platform,
1034 snd_device_t out_snd_device,
1035 snd_device_t in_snd_device)
1036{
1037 struct platform_data *my_data = (struct platform_data *)platform;
1038 int acdb_rx_id, acdb_tx_id;
1039 int ret = 0;
1040
1041 if (my_data->csd == NULL)
1042 return ret;
1043
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001044 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1045 audio_extn_spkr_prot_is_enabled())
1046 acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED];
1047 else
1048 acdb_rx_id = acdb_device_table[out_snd_device];
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001049
1050 acdb_tx_id = acdb_device_table[in_snd_device];
1051
1052 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1053 ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
1054 my_data->adev->acdb_settings);
1055 if (ret < 0) {
1056 ALOGE("%s: csd_enable_device, failed, error %d", __func__, ret);
1057 }
1058 } else {
1059 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1060 acdb_rx_id, acdb_tx_id);
1061 }
1062
1063 return ret;
1064}
1065
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001066int platform_start_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001067{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001068 struct platform_data *my_data = (struct platform_data *)platform;
1069 int ret = 0;
1070
1071 if (my_data->csd != NULL) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001072 ret = my_data->csd->start_voice(vsid);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001073 if (ret < 0) {
1074 ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
1075 }
1076 }
1077 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001078}
1079
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001080int platform_stop_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001081{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001082 struct platform_data *my_data = (struct platform_data *)platform;
1083 int ret = 0;
1084
1085 if (my_data->csd != NULL) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001086 ret = my_data->csd->stop_voice(vsid);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001087 if (ret < 0) {
1088 ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
1089 }
1090 }
1091 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001092}
1093
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001094int platform_get_sample_rate(void *platform, uint32_t *rate)
1095{
1096 struct platform_data *my_data = (struct platform_data *)platform;
1097 int ret = 0;
1098
1099 if (my_data->csd != NULL) {
1100 ret = my_data->csd->get_sample_rate(rate);
1101 if (ret < 0) {
1102 ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret);
1103 }
1104 }
1105 return ret;
1106}
1107
Eric Laurentb23d5282013-05-14 15:27:20 -07001108int platform_set_voice_volume(void *platform, int volume)
1109{
1110 struct platform_data *my_data = (struct platform_data *)platform;
1111 struct audio_device *adev = my_data->adev;
1112 struct mixer_ctl *ctl;
sangwoo53b2cf02013-07-25 19:18:44 -07001113 const char *mixer_ctl_name = "Voice Rx Gain";
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001114 int vol_index = 0, ret = 0;
1115 uint32_t set_values[ ] = {0,
1116 ALL_SESSION_VSID,
1117 DEFAULT_VOLUME_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001118
1119 // Voice volume levels are mapped to adsp volume levels as follows.
1120 // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0
1121 // But this values don't changed in kernel. So, below change is need.
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001122 vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
1123 set_values[0] = vol_index;
Eric Laurentb23d5282013-05-14 15:27:20 -07001124
1125 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1126 if (!ctl) {
1127 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1128 __func__, mixer_ctl_name);
1129 return -EINVAL;
1130 }
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001131 ALOGV("Setting voice volume index: %d", set_values[0]);
1132 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1133
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001134 if (my_data->csd != NULL) {
1135 ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
1136 DEFAULT_VOLUME_RAMP_DURATION_MS);
1137 if (ret < 0) {
1138 ALOGE("%s: csd_volume error %d", __func__, ret);
1139 }
1140 }
1141 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001142}
1143
1144int platform_set_mic_mute(void *platform, bool state)
1145{
1146 struct platform_data *my_data = (struct platform_data *)platform;
1147 struct audio_device *adev = my_data->adev;
1148 struct mixer_ctl *ctl;
1149 const char *mixer_ctl_name = "Voice Tx Mute";
sangwoo53b2cf02013-07-25 19:18:44 -07001150 int ret = 0;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001151 uint32_t set_values[ ] = {0,
1152 ALL_SESSION_VSID,
1153 DEFAULT_MUTE_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001154
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001155 if (adev->mode != AUDIO_MODE_IN_CALL)
1156 return 0;
1157
1158 set_values[0] = state;
1159 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1160 if (!ctl) {
1161 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1162 __func__, mixer_ctl_name);
1163 return -EINVAL;
1164 }
1165 ALOGV("Setting voice mute state: %d", state);
1166 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1167
1168 if (my_data->csd != NULL) {
1169 ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state,
1170 DEFAULT_MUTE_RAMP_DURATION_MS);
sangwoo53b2cf02013-07-25 19:18:44 -07001171 if (ret < 0) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001172 ALOGE("%s: csd_mic_mute error %d", __func__, ret);
sangwoo53b2cf02013-07-25 19:18:44 -07001173 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001174 }
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001175 return ret;
1176}
Eric Laurentb23d5282013-05-14 15:27:20 -07001177
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001178int platform_set_device_mute(void *platform, bool state, char *dir)
1179{
1180 struct platform_data *my_data = (struct platform_data *)platform;
1181 struct audio_device *adev = my_data->adev;
1182 struct mixer_ctl *ctl;
1183 char *mixer_ctl_name = NULL;
1184 int ret = 0;
1185 uint32_t set_values[ ] = {0,
1186 ALL_SESSION_VSID,
1187 0};
1188 if(dir == NULL) {
1189 ALOGE("%s: Invalid direction:%s", __func__, dir);
1190 return -EINVAL;
1191 }
1192
1193 if (!strncmp("rx", dir, sizeof("rx"))) {
1194 mixer_ctl_name = "Voice Rx Device Mute";
1195 } else if (!strncmp("tx", dir, sizeof("tx"))) {
1196 mixer_ctl_name = "Voice Tx Device Mute";
1197 } else {
1198 return -EINVAL;
1199 }
1200
1201 set_values[0] = state;
1202 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1203 if (!ctl) {
1204 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1205 __func__, mixer_ctl_name);
1206 return -EINVAL;
1207 }
1208
1209 ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
1210 __func__,state, mixer_ctl_name);
1211 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1212
1213 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001214}
1215
1216snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
1217{
1218 struct platform_data *my_data = (struct platform_data *)platform;
1219 struct audio_device *adev = my_data->adev;
1220 audio_mode_t mode = adev->mode;
1221 snd_device_t snd_device = SND_DEVICE_NONE;
1222
1223 ALOGV("%s: enter: output devices(%#x)", __func__, devices);
1224 if (devices == AUDIO_DEVICE_NONE ||
1225 devices & AUDIO_DEVICE_BIT_IN) {
1226 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
1227 goto exit;
1228 }
1229
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001230 if (voice_is_in_call(adev) || adev->enable_voicerx) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001231 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001232 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1233 devices & AUDIO_DEVICE_OUT_LINE) {
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001234 if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001235 (adev->voice.tty_mode == TTY_MODE_FULL))
Eric Laurentb23d5282013-05-14 15:27:20 -07001236 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001237 else if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001238 (adev->voice.tty_mode == TTY_MODE_VCO))
Eric Laurentb23d5282013-05-14 15:27:20 -07001239 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001240 else if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001241 (adev->voice.tty_mode == TTY_MODE_HCO))
Eric Laurentb23d5282013-05-14 15:27:20 -07001242 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001243 else {
1244 if (devices & AUDIO_DEVICE_OUT_LINE)
1245 snd_device = SND_DEVICE_OUT_VOICE_LINE;
1246 else
1247 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
1248 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001249 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001250 if (adev->bt_wb_speech_enabled) {
1251 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1252 } else {
1253 snd_device = SND_DEVICE_OUT_BT_SCO;
1254 }
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001255 } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001256 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
1257 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurent9d0d3f12014-07-25 12:40:29 -05001258 if(adev->voice.hac)
1259 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1260 else if (is_operator_tmus())
Eric Laurentb23d5282013-05-14 15:27:20 -07001261 snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
1262 else
Eric Laurentb4d368e2014-06-25 10:21:54 -05001263 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -07001264 } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1265 snd_device = SND_DEVICE_OUT_VOICE_TX;
1266
Eric Laurentb23d5282013-05-14 15:27:20 -07001267 if (snd_device != SND_DEVICE_NONE) {
1268 goto exit;
1269 }
1270 }
1271
1272 if (popcount(devices) == 2) {
1273 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1274 AUDIO_DEVICE_OUT_SPEAKER)) {
1275 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1276 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1277 AUDIO_DEVICE_OUT_SPEAKER)) {
1278 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
Eric Laurent744996b2014-10-01 11:40:40 -05001279 } else if (devices == (AUDIO_DEVICE_OUT_LINE |
1280 AUDIO_DEVICE_OUT_SPEAKER)) {
1281 snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001282 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
1283 AUDIO_DEVICE_OUT_SPEAKER)) {
1284 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
1285 } else {
1286 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
1287 goto exit;
1288 }
1289 if (snd_device != SND_DEVICE_NONE) {
1290 goto exit;
1291 }
1292 }
1293
1294 if (popcount(devices) != 1) {
1295 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
1296 goto exit;
1297 }
1298
1299 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1300 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1301 snd_device = SND_DEVICE_OUT_HEADPHONES;
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001302 } else if (devices & AUDIO_DEVICE_OUT_LINE) {
1303 snd_device = SND_DEVICE_OUT_LINE;
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001304 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
1305 snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001306 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07001307 if (my_data->speaker_lr_swap)
Eric Laurentb23d5282013-05-14 15:27:20 -07001308 snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
1309 else
1310 snd_device = SND_DEVICE_OUT_SPEAKER;
1311 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001312 if (adev->bt_wb_speech_enabled) {
1313 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1314 } else {
1315 snd_device = SND_DEVICE_OUT_BT_SCO;
1316 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001317 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1318 snd_device = SND_DEVICE_OUT_HDMI ;
1319 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurent9d0d3f12014-07-25 12:40:29 -05001320 /*HAC support for voice-ish audio (eg visual voicemail)*/
1321 if(adev->voice.hac)
1322 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1323 else
1324 snd_device = SND_DEVICE_OUT_HANDSET;
Eric Laurentb23d5282013-05-14 15:27:20 -07001325 } else {
1326 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
1327 }
1328exit:
1329 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
1330 return snd_device;
1331}
1332
1333snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
1334{
1335 struct platform_data *my_data = (struct platform_data *)platform;
1336 struct audio_device *adev = my_data->adev;
1337 audio_source_t source = (adev->active_input == NULL) ?
1338 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
1339
1340 audio_mode_t mode = adev->mode;
1341 audio_devices_t in_device = ((adev->active_input == NULL) ?
1342 AUDIO_DEVICE_NONE : adev->active_input->device)
1343 & ~AUDIO_DEVICE_BIT_IN;
1344 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1345 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1346 snd_device_t snd_device = SND_DEVICE_NONE;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001347 int channel_count = popcount(channel_mask);
Eric Laurentb23d5282013-05-14 15:27:20 -07001348
1349 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
1350 __func__, out_device, in_device);
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001351 if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001352 if (adev->voice.tty_mode != TTY_MODE_OFF) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001353 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001354 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1355 out_device & AUDIO_DEVICE_OUT_LINE) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001356 switch (adev->voice.tty_mode) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001357 case TTY_MODE_FULL:
1358 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
1359 break;
1360 case TTY_MODE_VCO:
1361 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
1362 break;
1363 case TTY_MODE_HCO:
1364 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
1365 break;
1366 default:
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001367 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
Eric Laurentb23d5282013-05-14 15:27:20 -07001368 }
1369 goto exit;
1370 }
1371 }
Eric Laurentb991fb02014-08-29 15:23:17 -05001372 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001373 if (my_data->fluence_in_voice_call == false) {
1374 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1375 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001376 if (is_operator_tmus())
1377 snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001378 else
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001379 snd_device = SND_DEVICE_IN_VOICE_DMIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001380 }
1381 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1382 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
1383 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001384 if (adev->bt_wb_speech_enabled) {
1385 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1386 } else {
1387 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1388 }
Eric Laurentb991fb02014-08-29 15:23:17 -05001389 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001390 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
Eric Laurentb991fb02014-08-29 15:23:17 -05001391 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1392 out_device & AUDIO_DEVICE_OUT_LINE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001393 if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001394 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1395 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001396 } else {
1397 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
1398 }
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -07001399 } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1400 snd_device = SND_DEVICE_IN_VOICE_RX;
Eric Laurentb23d5282013-05-14 15:27:20 -07001401 } else if (source == AUDIO_SOURCE_CAMCORDER) {
1402 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
1403 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1404 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
1405 }
1406 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1407 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001408 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001409 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001410 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
1411 else if (my_data->fluence_in_voice_rec &&
1412 adev->active_input->enable_ns)
1413 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001414 }
1415
1416 if (snd_device == SND_DEVICE_NONE) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001417 if (adev->active_input->enable_ns)
1418 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
1419 else
1420 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001421 }
1422 }
1423 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001424 if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE))
Eric Laurentb23d5282013-05-14 15:27:20 -07001425 in_device = AUDIO_DEVICE_IN_BACK_MIC;
1426 if (adev->active_input) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001427 if (adev->active_input->enable_aec &&
1428 adev->active_input->enable_ns) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001429 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001430 if (my_data->fluence_in_spkr_mode &&
1431 my_data->fluence_in_voice_comm &&
1432 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1433 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
1434 } else
1435 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001436 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001437 if (my_data->fluence_in_voice_comm &&
1438 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1439 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
1440 } else
1441 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
Eric Laurentcefbbac2014-09-04 13:54:10 -05001442 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1443 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001444 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05001445 platform_set_echo_reference(adev, true, out_device);
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001446 } else if (adev->active_input->enable_aec) {
1447 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1448 if (my_data->fluence_in_spkr_mode &&
1449 my_data->fluence_in_voice_comm &&
1450 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1451 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
1452 } else
1453 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
1454 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1455 if (my_data->fluence_in_voice_comm &&
1456 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1457 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
1458 } else
1459 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
Eric Laurentcefbbac2014-09-04 13:54:10 -05001460 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1461 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
1462 }
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -08001463 platform_set_echo_reference(adev, true, out_device);
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001464 } else if (adev->active_input->enable_ns) {
1465 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1466 if (my_data->fluence_in_spkr_mode &&
1467 my_data->fluence_in_voice_comm &&
1468 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1469 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
1470 } else
1471 snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
1472 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1473 if (my_data->fluence_in_voice_comm &&
1474 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1475 snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
1476 } else
1477 snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
1478 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05001479 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001480 }
1481 } else if (source == AUDIO_SOURCE_DEFAULT) {
1482 goto exit;
1483 }
1484
1485
1486 if (snd_device != SND_DEVICE_NONE) {
1487 goto exit;
1488 }
1489
1490 if (in_device != AUDIO_DEVICE_NONE &&
1491 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
1492 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
1493 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001494 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
1495 channel_count == 2)
1496 snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
1497 else
1498 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001499 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001500 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
1501 channel_count == 2)
1502 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
1503 else
1504 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001505 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1506 snd_device = SND_DEVICE_IN_HEADSET_MIC;
1507 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001508 if (adev->bt_wb_speech_enabled) {
1509 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1510 } else {
1511 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1512 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001513 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
1514 snd_device = SND_DEVICE_IN_HDMI_MIC;
1515 } else {
1516 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
1517 ALOGW("%s: Using default handset-mic", __func__);
1518 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1519 }
1520 } else {
1521 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
1522 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1523 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1524 snd_device = SND_DEVICE_IN_HEADSET_MIC;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001525 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001526 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001527 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001528 out_device & AUDIO_DEVICE_OUT_LINE) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001529 if (channel_count == 2)
1530 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
1531 else
1532 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001533 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001534 if (adev->bt_wb_speech_enabled) {
1535 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1536 } else {
1537 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1538 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001539 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1540 snd_device = SND_DEVICE_IN_HDMI_MIC;
1541 } else {
1542 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
1543 ALOGW("%s: Using default handset-mic", __func__);
1544 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1545 }
1546 }
1547exit:
1548 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
1549 return snd_device;
1550}
1551
1552int platform_set_hdmi_channels(void *platform, int channel_count)
1553{
1554 struct platform_data *my_data = (struct platform_data *)platform;
1555 struct audio_device *adev = my_data->adev;
1556 struct mixer_ctl *ctl;
1557 const char *channel_cnt_str = NULL;
1558 const char *mixer_ctl_name = "HDMI_RX Channels";
1559 switch (channel_count) {
1560 case 8:
1561 channel_cnt_str = "Eight"; break;
1562 case 7:
1563 channel_cnt_str = "Seven"; break;
1564 case 6:
1565 channel_cnt_str = "Six"; break;
1566 case 5:
1567 channel_cnt_str = "Five"; break;
1568 case 4:
1569 channel_cnt_str = "Four"; break;
1570 case 3:
1571 channel_cnt_str = "Three"; break;
1572 default:
1573 channel_cnt_str = "Two"; break;
1574 }
1575 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1576 if (!ctl) {
1577 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1578 __func__, mixer_ctl_name);
1579 return -EINVAL;
1580 }
1581 ALOGV("HDMI channel count: %s", channel_cnt_str);
1582 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
1583 return 0;
1584}
1585
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001586int platform_edid_get_max_channels(void *platform)
Eric Laurentb23d5282013-05-14 15:27:20 -07001587{
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001588 struct platform_data *my_data = (struct platform_data *)platform;
1589 struct audio_device *adev = my_data->adev;
Eric Laurentb23d5282013-05-14 15:27:20 -07001590 char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
1591 char *sad = block;
1592 int num_audio_blocks;
1593 int channel_count;
1594 int max_channels = 0;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001595 int i, ret, count;
Eric Laurentb23d5282013-05-14 15:27:20 -07001596
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001597 struct mixer_ctl *ctl;
1598
1599 ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
1600 if (!ctl) {
1601 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1602 __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
Eric Laurentb23d5282013-05-14 15:27:20 -07001603 return 0;
1604 }
1605
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001606 mixer_ctl_update(ctl);
1607
1608 count = mixer_ctl_get_num_values(ctl);
Eric Laurentb23d5282013-05-14 15:27:20 -07001609
1610 /* Read SAD blocks, clamping the maximum size for safety */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001611 if (count > (int)sizeof(block))
1612 count = (int)sizeof(block);
Eric Laurentb23d5282013-05-14 15:27:20 -07001613
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001614 ret = mixer_ctl_get_array(ctl, block, count);
1615 if (ret != 0) {
1616 ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
1617 return 0;
1618 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001619
1620 /* Calculate the number of SAD blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001621 num_audio_blocks = count / SAD_BLOCK_SIZE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001622
1623 for (i = 0; i < num_audio_blocks; i++) {
1624 /* Only consider LPCM blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001625 if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
1626 sad += 3;
Eric Laurentb23d5282013-05-14 15:27:20 -07001627 continue;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001628 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001629
1630 channel_count = (sad[0] & 0x7) + 1;
1631 if (channel_count > max_channels)
1632 max_channels = channel_count;
1633
1634 /* Advance to next block */
1635 sad += 3;
1636 }
1637
1638 return max_channels;
1639}
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07001640
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001641int platform_set_incall_recording_session_id(void *platform,
1642 uint32_t session_id, int rec_mode)
1643{
1644 int ret = 0;
1645 struct platform_data *my_data = (struct platform_data *)platform;
1646 struct audio_device *adev = my_data->adev;
1647 struct mixer_ctl *ctl;
1648 const char *mixer_ctl_name = "Voc VSID";
1649 int num_ctl_values;
1650 int i;
1651
1652 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1653 if (!ctl) {
1654 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1655 __func__, mixer_ctl_name);
1656 ret = -EINVAL;
1657 } else {
1658 num_ctl_values = mixer_ctl_get_num_values(ctl);
1659 for (i = 0; i < num_ctl_values; i++) {
1660 if (mixer_ctl_set_value(ctl, i, session_id)) {
1661 ALOGV("Error: invalid session_id: %x", session_id);
1662 ret = -EINVAL;
1663 break;
1664 }
1665 }
1666 }
1667
1668 if (my_data->csd != NULL) {
1669 ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
1670 if (ret < 0) {
1671 ALOGE("%s: csd_client_start_record failed, error %d",
1672 __func__, ret);
1673 }
1674 }
1675
1676 return ret;
1677}
1678
1679int platform_stop_incall_recording_usecase(void *platform)
1680{
1681 int ret = 0;
1682 struct platform_data *my_data = (struct platform_data *)platform;
1683
1684 if (my_data->csd != NULL) {
1685 ret = my_data->csd->stop_record(ALL_SESSION_VSID);
1686 if (ret < 0) {
1687 ALOGE("%s: csd_client_stop_record failed, error %d",
1688 __func__, ret);
1689 }
1690 }
1691
1692 return ret;
1693}
1694
1695int platform_start_incall_music_usecase(void *platform)
1696{
1697 int ret = 0;
1698 struct platform_data *my_data = (struct platform_data *)platform;
1699
1700 if (my_data->csd != NULL) {
1701 ret = my_data->csd->start_playback(ALL_SESSION_VSID);
1702 if (ret < 0) {
1703 ALOGE("%s: csd_client_start_playback failed, error %d",
1704 __func__, ret);
1705 }
1706 }
1707
1708 return ret;
1709}
1710
1711int platform_stop_incall_music_usecase(void *platform)
1712{
1713 int ret = 0;
1714 struct platform_data *my_data = (struct platform_data *)platform;
1715
1716 if (my_data->csd != NULL) {
1717 ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
1718 if (ret < 0) {
1719 ALOGE("%s: csd_client_stop_playback failed, error %d",
1720 __func__, ret);
1721 }
1722 }
1723
1724 return ret;
1725}
1726
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07001727/* Delay in Us */
1728int64_t platform_render_latency(audio_usecase_t usecase)
1729{
1730 switch (usecase) {
1731 case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
1732 return DEEP_BUFFER_PLATFORM_DELAY;
1733 case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
1734 return LOW_LATENCY_PLATFORM_DELAY;
1735 default:
1736 return 0;
1737 }
1738}
Haynes Mathew George98c95622014-06-20 19:14:25 -07001739
1740int platform_set_snd_device_backend(snd_device_t device, const char *backend)
1741{
1742 int ret = 0;
1743
1744 if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
1745 ALOGE("%s: Invalid snd_device = %d",
1746 __func__, device);
1747 ret = -EINVAL;
1748 goto done;
1749 }
1750
1751 if (backend_table[device]) {
1752 free(backend_table[device]);
1753 }
1754 backend_table[device] = strdup(backend);
1755done:
1756 return ret;
1757}
1758
1759int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
1760{
1761 int ret = 0;
1762 if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
1763 ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
1764 ret = -EINVAL;
1765 goto done;
1766 }
1767
1768 if ((type != 0) && (type != 1)) {
1769 ALOGE("%s: invalid usecase type", __func__);
1770 ret = -EINVAL;
1771 }
1772 pcm_device_table[usecase][type] = pcm_id;
1773done:
1774 return ret;
1775}
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07001776
1777int platform_swap_lr_channels(struct audio_device *adev, bool swap_channels)
1778{
1779 // only update if there is active pcm playback on speaker
1780 struct audio_usecase *usecase;
1781 struct listnode *node;
1782 struct platform_data *my_data = (struct platform_data *)adev->platform;
1783
1784 if (my_data->speaker_lr_swap != swap_channels) {
1785 my_data->speaker_lr_swap = swap_channels;
1786
1787 list_for_each(node, &adev->usecase_list) {
1788 usecase = node_to_item(node, struct audio_usecase, list);
1789 if (usecase->type == PCM_PLAYBACK &&
1790 usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
1791 const char *mixer_path;
1792 if (swap_channels) {
1793 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
1794 audio_route_apply_and_update_path(adev->audio_route, mixer_path);
1795 } else {
1796 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
1797 audio_route_apply_and_update_path(adev->audio_route, mixer_path);
1798 }
1799 break;
1800 }
1801 }
1802 }
1803 return 0;
1804}