blob: 854acead141dd39ee19efbca6f44ceaeda87fbb9 [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},
Ravi Kumar Alamandaf78a4d92015-04-24 15:18:23 -0700105 [USECASE_AUDIO_PLAYBACK_TTS] = {MULTIMEDIA3_PCM_DEVICE,
106 MULTIMEDIA3_PCM_DEVICE},
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700107 [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE,
108 AUDIO_RECORD_PCM_DEVICE},
109 [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
110 LOWLATENCY_PCM_DEVICE},
111 [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE,
112 VOICE_CALL_PCM_DEVICE},
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700113 [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
114 [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
115 [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
116 [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
117 [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
118 AUDIO_RECORD_PCM_DEVICE},
119 [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
120 AUDIO_RECORD_PCM_DEVICE},
121 [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
122 AUDIO_RECORD_PCM_DEVICE},
Ravi Kumar Alamanda8e6e98f2013-11-05 15:57:39 -0800123 [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700124
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700125 [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
126 [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
127
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700128 [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
129 AFE_PROXY_RECORD_PCM_DEVICE},
130 [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
131 AFE_PROXY_RECORD_PCM_DEVICE},
zhaoyang yin4211fad2015-06-04 21:13:25 +0800132 [USECASE_AUDIO_DSM_FEEDBACK] = {QUAT_MI2S_PCM_DEVICE, QUAT_MI2S_PCM_DEVICE},
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700133
Eric Laurentb23d5282013-05-14 15:27:20 -0700134};
135
136/* Array to store sound devices */
137static const char * const device_table[SND_DEVICE_MAX] = {
138 [SND_DEVICE_NONE] = "none",
139 /* Playback sound devices */
140 [SND_DEVICE_OUT_HANDSET] = "handset",
141 [SND_DEVICE_OUT_SPEAKER] = "speaker",
142 [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700143 [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
Eric Laurentb23d5282013-05-14 15:27:20 -0700144 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500145 [SND_DEVICE_OUT_LINE] = "line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700146 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Eric Laurent744996b2014-10-01 11:40:40 -0500147 [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700148 [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500149 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
Eric Laurentb23d5282013-05-14 15:27:20 -0700150 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
151 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500152 [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700153 [SND_DEVICE_OUT_HDMI] = "hdmi",
154 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
155 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700156 [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700157 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
158 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
159 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
160 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700161 [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700162 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
163 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
Eric Laurentb23d5282013-05-14 15:27:20 -0700164
165 /* Capture sound devices */
166 [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700167 [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700168 [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
169 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
170 [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
171 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
172 [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
173 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
174 [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = "dmic-endfire",
175
176 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
177 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
178 [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
179 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
180 [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
181 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
182 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
183 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
184 [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = "speaker-dmic-endfire",
185
186 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
Eric Laurentcefbbac2014-09-04 13:54:10 -0500187 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700188
Eric Laurentb23d5282013-05-14 15:27:20 -0700189 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
190 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700191 [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700192
Eric Laurentb23d5282013-05-14 15:27:20 -0700193 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700194
195 [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
196 [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
197 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
198 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
199 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700200 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
201 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
202 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700203
Eric Laurentb23d5282013-05-14 15:27:20 -0700204 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700205 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
206 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
207 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700208
209 [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700210
211 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
Eric Laurentb23d5282013-05-14 15:27:20 -0700212};
213
214/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700215static int acdb_device_table[SND_DEVICE_MAX] = {
Eric Laurentb23d5282013-05-14 15:27:20 -0700216 [SND_DEVICE_NONE] = -1,
217 [SND_DEVICE_OUT_HANDSET] = 7,
218 [SND_DEVICE_OUT_SPEAKER] = 15,
219 [SND_DEVICE_OUT_SPEAKER_REVERSE] = 15,
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700220 [SND_DEVICE_OUT_SPEAKER_SAFE] = 15,
Eric Laurentb23d5282013-05-14 15:27:20 -0700221 [SND_DEVICE_OUT_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500222 [SND_DEVICE_OUT_LINE] = 77,
Eric Laurentb23d5282013-05-14 15:27:20 -0700223 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500224 [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 77,
Ravi Kumar Alamanda235c3482014-08-21 17:32:44 -0700225 [SND_DEVICE_OUT_VOICE_HANDSET] = ACDB_ID_VOICE_HANDSET,
226 [SND_DEVICE_OUT_VOICE_SPEAKER] = ACDB_ID_VOICE_SPEAKER,
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500227 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
Eric Laurentb23d5282013-05-14 15:27:20 -0700228 [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500229 [SND_DEVICE_OUT_VOICE_LINE] = 77,
Eric Laurentb23d5282013-05-14 15:27:20 -0700230 [SND_DEVICE_OUT_HDMI] = 18,
231 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 15,
232 [SND_DEVICE_OUT_BT_SCO] = 22,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700233 [SND_DEVICE_OUT_BT_SCO_WB] = 39,
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700234 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = ACDB_ID_VOICE_HANDSET_TMUS,
Eric Laurentb23d5282013-05-14 15:27:20 -0700235 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
236 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
237 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700238 [SND_DEVICE_OUT_VOICE_TX] = 45,
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700239 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
240 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
Eric Laurentb23d5282013-05-14 15:27:20 -0700241
242 [SND_DEVICE_IN_HANDSET_MIC] = 4,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700243 [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
244 [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
245 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
246 [SND_DEVICE_IN_HANDSET_DMIC] = 41,
247 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
248 [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
249 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
250 [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = 34,
251
252 [SND_DEVICE_IN_SPEAKER_MIC] = 11,
253 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
254 [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
255 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
256 [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
257 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
258 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
259 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
260 [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = 35,
261
Eric Laurentb23d5282013-05-14 15:27:20 -0700262 [SND_DEVICE_IN_HEADSET_MIC] = 8,
Eric Laurentcefbbac2014-09-04 13:54:10 -0500263 [SND_DEVICE_IN_HEADSET_MIC_AEC] = ACDB_ID_HEADSET_MIC_AEC,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700264
Eric Laurentb23d5282013-05-14 15:27:20 -0700265 [SND_DEVICE_IN_HDMI_MIC] = 4,
266 [SND_DEVICE_IN_BT_SCO_MIC] = 21,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700267 [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700268
Eric Laurentb23d5282013-05-14 15:27:20 -0700269 [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700270
271 [SND_DEVICE_IN_VOICE_DMIC] = 41,
272 [SND_DEVICE_IN_VOICE_DMIC_TMUS] = ACDB_ID_VOICE_DMIC_EF_TMUS,
273 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
274 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
275 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
Eric Laurentb23d5282013-05-14 15:27:20 -0700276 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
277 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
278 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700279
Eric Laurentb23d5282013-05-14 15:27:20 -0700280 [SND_DEVICE_IN_VOICE_REC_MIC] = 62,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700281 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 113,
282 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 35,
283 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 43,
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700284
285 [SND_DEVICE_IN_VOICE_RX] = 44,
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700286
287 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
Eric Laurentb23d5282013-05-14 15:27:20 -0700288};
289
Haynes Mathew George98c95622014-06-20 19:14:25 -0700290struct name_to_index {
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700291 char name[100];
292 unsigned int index;
293};
294
295#define TO_NAME_INDEX(X) #X, X
296
Haynes Mathew George98c95622014-06-20 19:14:25 -0700297/* Used to get index from parsed string */
298static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
299 /* out */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700300 {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
301 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
302 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700303 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700304 {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500305 {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700306 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
Eric Laurent744996b2014-10-01 11:40:40 -0500307 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700308 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
309 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
310 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500311 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700312 {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
313 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
314 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
315 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700316 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET_TMUS)},
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500317 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700318 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
319 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
320 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700321
322 /* in */
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700323 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
324 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700325 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700326 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700327 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
328 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
329 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
330 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
331 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
332 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
333 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_STEREO)},
334
335 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700336 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700337 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
338 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
339 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
340 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
341 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
342 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
343 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
344
345 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700346 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700347
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700348 {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
349 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
350 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700351
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700352 {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700353
354 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
355 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
356 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
357 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
358 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700359 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
360 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
361 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700362
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700363 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700364 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
365 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
366 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700367
368 {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700369};
370
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700371static char * backend_tag_table[SND_DEVICE_MAX] = {0};
372static char * hw_interface_table[SND_DEVICE_MAX] = {0};
Haynes Mathew George98c95622014-06-20 19:14:25 -0700373
374static const struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
375 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
376 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
377 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
378 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
379 {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
380 {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
381 {TO_NAME_INDEX(USECASE_VOICE_CALL)},
382 {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
383 {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
384 {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
385 {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
386 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK)},
387 {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
388 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
389 {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700390};
391
Haynes Mathew George7ff216f2013-09-11 19:51:41 -0700392#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
393#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
394
Eric Laurentb23d5282013-05-14 15:27:20 -0700395static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
396static bool is_tmus = false;
397
398static void check_operator()
399{
400 char value[PROPERTY_VALUE_MAX];
401 int mccmnc;
402 property_get("gsm.sim.operator.numeric",value,"0");
403 mccmnc = atoi(value);
404 ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
405 switch(mccmnc) {
406 /* TMUS MCC(310), MNC(490, 260, 026) */
407 case 310490:
408 case 310260:
409 case 310026:
sangwon.jeonb891db52013-09-14 17:39:15 +0900410 /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
411 case 310800:
412 case 310660:
413 case 310580:
414 case 310310:
415 case 310270:
416 case 310250:
417 case 310240:
418 case 310230:
419 case 310220:
420 case 310210:
421 case 310200:
422 case 310160:
Eric Laurentb23d5282013-05-14 15:27:20 -0700423 is_tmus = true;
424 break;
425 }
426}
427
428bool is_operator_tmus()
429{
430 pthread_once(&check_op_once_ctl, check_operator);
431 return is_tmus;
432}
433
Eric Laurentcefbbac2014-09-04 13:54:10 -0500434void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
Eric Laurentb23d5282013-05-14 15:27:20 -0700435{
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800436 struct platform_data *my_data = (struct platform_data *)adev->platform;
Eric Laurentcefbbac2014-09-04 13:54:10 -0500437 snd_device_t snd_device = SND_DEVICE_NONE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700438
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800439 if (strcmp(my_data->ec_ref_mixer_path, "")) {
440 ALOGV("%s: diabling %s", __func__, my_data->ec_ref_mixer_path);
441 audio_route_reset_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
Eric Laurentcefbbac2014-09-04 13:54:10 -0500442 }
443
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800444 if (enable) {
445 strcpy(my_data->ec_ref_mixer_path, "echo-reference");
446 if (out_device != AUDIO_DEVICE_NONE) {
447 snd_device = platform_get_output_snd_device(adev->platform, out_device);
448 platform_add_backend_name(adev->platform, my_data->ec_ref_mixer_path, snd_device);
449 }
Eric Laurentcefbbac2014-09-04 13:54:10 -0500450
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800451 ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
452 audio_route_apply_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
453 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700454}
455
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700456static struct csd_data *open_csd_client(bool i2s_ext_modem)
457{
458 struct csd_data *csd = calloc(1, sizeof(struct csd_data));
459
460 csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
461 if (csd->csd_client == NULL) {
462 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
463 goto error;
464 } else {
465 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
466
467 csd->deinit = (deinit_t)dlsym(csd->csd_client,
468 "csd_client_deinit");
469 if (csd->deinit == NULL) {
470 ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
471 dlerror());
472 goto error;
473 }
474 csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
475 "csd_client_disable_device");
476 if (csd->disable_device == NULL) {
477 ALOGE("%s: dlsym error %s for csd_client_disable_device",
478 __func__, dlerror());
479 goto error;
480 }
481 csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
482 "csd_client_enable_device_config");
483 if (csd->enable_device_config == NULL) {
484 ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
485 __func__, dlerror());
486 goto error;
487 }
488 csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
489 "csd_client_enable_device");
490 if (csd->enable_device == NULL) {
491 ALOGE("%s: dlsym error %s for csd_client_enable_device",
492 __func__, dlerror());
493 goto error;
494 }
495 csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
496 "csd_client_start_voice");
497 if (csd->start_voice == NULL) {
498 ALOGE("%s: dlsym error %s for csd_client_start_voice",
499 __func__, dlerror());
500 goto error;
501 }
502 csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
503 "csd_client_stop_voice");
504 if (csd->stop_voice == NULL) {
505 ALOGE("%s: dlsym error %s for csd_client_stop_voice",
506 __func__, dlerror());
507 goto error;
508 }
509 csd->volume = (volume_t)dlsym(csd->csd_client,
510 "csd_client_volume");
511 if (csd->volume == NULL) {
512 ALOGE("%s: dlsym error %s for csd_client_volume",
513 __func__, dlerror());
514 goto error;
515 }
516 csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
517 "csd_client_mic_mute");
518 if (csd->mic_mute == NULL) {
519 ALOGE("%s: dlsym error %s for csd_client_mic_mute",
520 __func__, dlerror());
521 goto error;
522 }
523 csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
524 "csd_client_slow_talk");
525 if (csd->slow_talk == NULL) {
526 ALOGE("%s: dlsym error %s for csd_client_slow_talk",
527 __func__, dlerror());
528 goto error;
529 }
530 csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
531 "csd_client_start_playback");
532 if (csd->start_playback == NULL) {
533 ALOGE("%s: dlsym error %s for csd_client_start_playback",
534 __func__, dlerror());
535 goto error;
536 }
537 csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
538 "csd_client_stop_playback");
539 if (csd->stop_playback == NULL) {
540 ALOGE("%s: dlsym error %s for csd_client_stop_playback",
541 __func__, dlerror());
542 goto error;
543 }
544 csd->start_record = (start_record_t)dlsym(csd->csd_client,
545 "csd_client_start_record");
546 if (csd->start_record == NULL) {
547 ALOGE("%s: dlsym error %s for csd_client_start_record",
548 __func__, dlerror());
549 goto error;
550 }
551 csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
552 "csd_client_stop_record");
553 if (csd->stop_record == NULL) {
554 ALOGE("%s: dlsym error %s for csd_client_stop_record",
555 __func__, dlerror());
556 goto error;
557 }
558
559 csd->get_sample_rate = (get_sample_rate_t)dlsym(csd->csd_client,
560 "csd_client_get_sample_rate");
561 if (csd->get_sample_rate == NULL) {
562 ALOGE("%s: dlsym error %s for csd_client_get_sample_rate",
563 __func__, dlerror());
564
565 goto error;
566 }
567
568 csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
569
570 if (csd->init == NULL) {
571 ALOGE("%s: dlsym error %s for csd_client_init",
572 __func__, dlerror());
573 goto error;
574 } else {
575 csd->init(i2s_ext_modem);
576 }
577 }
578 return csd;
579
580error:
581 free(csd);
582 csd = NULL;
583 return csd;
584}
585
586void close_csd_client(struct csd_data *csd)
587{
588 if (csd != NULL) {
589 csd->deinit();
590 dlclose(csd->csd_client);
591 free(csd);
592 csd = NULL;
593 }
594}
595
596static void platform_csd_init(struct platform_data *my_data)
597{
598#ifdef PLATFORM_MSM8084
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700599 int32_t modems, (*count_modems)(void);
600 const char *name = "libdetectmodem.so";
601 const char *func = "count_modems";
602 const char *error;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700603
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700604 my_data->csd = NULL;
605
606 void *lib = dlopen(name, RTLD_NOW);
607 error = dlerror();
608 if (!lib) {
609 ALOGE("%s: could not find %s: %s", __func__, name, error);
610 return;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700611 }
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700612
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700613 count_modems = NULL;
614 *(void **)(&count_modems) = dlsym(lib, func);
615 error = dlerror();
616 if (!count_modems) {
617 ALOGE("%s: could not find symbol %s in %s: %s",
618 __func__, func, name, error);
619 goto done;
620 }
621
622 modems = count_modems();
623 if (modems < 0) {
624 ALOGE("%s: count_modems failed\n", __func__);
625 goto done;
626 }
627
628 ALOGD("%s: num_modems %d\n", __func__, modems);
629 if (modems > 0)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700630 my_data->csd = open_csd_client(false /*is_i2s_ext_modem*/);
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700631
632done:
633 dlclose(lib);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700634#else
635 my_data->csd = NULL;
636#endif
637}
638
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700639static void set_platform_defaults(struct platform_data * my_data __unused)
Haynes Mathew George98c95622014-06-20 19:14:25 -0700640{
641 int32_t dev;
642 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700643 backend_tag_table[dev] = NULL;
644 hw_interface_table[dev] = NULL;
Haynes Mathew George98c95622014-06-20 19:14:25 -0700645 }
646
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700647 // To overwrite these go to the audio_platform_info.xml file.
648 backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
649 backend_tag_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
650 backend_tag_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
651 backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
652 backend_tag_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
653 backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
654 backend_tag_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
655 backend_tag_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700656
657 if (my_data->ext_speaker) {
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700658 backend_tag_table[SND_DEVICE_OUT_SPEAKER] = strdup("speaker");
659 backend_tag_table[SND_DEVICE_OUT_SPEAKER_SAFE] = strdup("speaker");
660 backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER] = strdup("speaker");
661 backend_tag_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = strdup("speaker");
662 backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] =
Haynes Mathew George98c95622014-06-20 19:14:25 -0700663 strdup("speaker-and-headphones");
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700664 backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_LINE] =
Eric Laurent744996b2014-10-01 11:40:40 -0500665 strdup("speaker-and-line");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700666 }
667
668 if (my_data->ext_earpiece) {
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700669 backend_tag_table[SND_DEVICE_OUT_VOICE_HANDSET] = strdup("handset");
670 backend_tag_table[SND_DEVICE_OUT_VOICE_HAC_HANDSET] = strdup("handset");
671 backend_tag_table[SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = strdup("handset");
672 backend_tag_table[SND_DEVICE_OUT_HANDSET] = strdup("handset");
673 backend_tag_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("handset");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700674 }
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700675
676 hw_interface_table[SND_DEVICE_OUT_HANDSET] = strdup("SLIMBUS_0_RX");
677 hw_interface_table[SND_DEVICE_OUT_SPEAKER] = strdup("SLIMBUS_0_RX");
678 hw_interface_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = strdup("SLIMBUS_0_RX");
679 hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE] = strdup("SLIMBUS_0_RX");
680 hw_interface_table[SND_DEVICE_OUT_HEADPHONES] = strdup("SLIMBUS_0_RX");
681 hw_interface_table[SND_DEVICE_OUT_LINE] = strdup("SLIMBUS_0_RX");
682 hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = strdup("SLIMBUS_0_RX");
683 hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_LINE] = strdup("SLIMBUS_0_RX");
684 hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET] = strdup("SLIMBUS_0_RX");
685 hw_interface_table[SND_DEVICE_OUT_VOICE_HAC_HANDSET] = strdup("SLIMBUS_0_RX");
686 hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER] = strdup("SLIMBUS_0_RX");
687 hw_interface_table[SND_DEVICE_OUT_VOICE_HEADPHONES] = strdup("SLIMBUS_0_RX");
688 hw_interface_table[SND_DEVICE_OUT_VOICE_LINE] = strdup("SLIMBUS_0_RX");
689 hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI_RX");
690 hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
691 hw_interface_table[SND_DEVICE_OUT_BT_SCO] = strdup("SEC_AUX_PCM_RX");
692 hw_interface_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("SEC_AUX_PCM_RX");
693 hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = strdup("SLIMBUS_0_RX");
694 hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = strdup("SLIMBUS_0_RX");
695 hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = strdup("SLIMBUS_0_RX");
696 hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("SLIMBUS_0_RX");
697 hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
698 hw_interface_table[SND_DEVICE_OUT_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
699 hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700700}
701
Eric Laurentb23d5282013-05-14 15:27:20 -0700702void *platform_init(struct audio_device *adev)
703{
704 char value[PROPERTY_VALUE_MAX];
705 struct platform_data *my_data;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700706 int retry_num = 0, snd_card_num = 0;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700707 const char *snd_card_name;
sangwoo1b9f4b32013-06-21 18:22:55 -0700708
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700709 while (snd_card_num < MAX_SND_CARD) {
710 adev->mixer = mixer_open(snd_card_num);
sangwoo1b9f4b32013-06-21 18:22:55 -0700711
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700712 while (!adev->mixer && retry_num < RETRY_NUMBER) {
713 usleep(RETRY_US);
714 adev->mixer = mixer_open(snd_card_num);
715 retry_num++;
716 }
717
718 if (!adev->mixer) {
719 ALOGE("%s: Unable to open the mixer card: %d", __func__,
720 snd_card_num);
721 retry_num = 0;
722 snd_card_num++;
723 continue;
724 }
725
726 snd_card_name = mixer_get_name(adev->mixer);
727 ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
728
729 adev->audio_route = audio_route_init(snd_card_num, MIXER_XML_PATH);
730 if (!adev->audio_route) {
731 ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
732 return NULL;
733 }
734 adev->snd_card = snd_card_num;
735 ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
736 break;
sangwoo1b9f4b32013-06-21 18:22:55 -0700737 }
738
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700739 if (snd_card_num >= MAX_SND_CARD) {
740 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
sangwoo1b9f4b32013-06-21 18:22:55 -0700741 return NULL;
742 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700743
744 my_data = calloc(1, sizeof(struct platform_data));
745
746 my_data->adev = adev;
747 my_data->dualmic_config = DUALMIC_CONFIG_NONE;
748 my_data->fluence_in_spkr_mode = false;
749 my_data->fluence_in_voice_call = false;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700750 my_data->fluence_in_voice_comm = false;
Eric Laurentb23d5282013-05-14 15:27:20 -0700751 my_data->fluence_in_voice_rec = false;
752
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500753 /*
754 * The default assumption is that earpiece (handset), speaker and headphones
755 * devices are connected to internal HW codec and communicated through
756 * slimbus backend. If any platform communicates with speaker or earpiece
757 * or headphones through non-slimbus backend such as MI2S or AUXPCM etc.,
758 * the ext_xxxx flags must be set accordingly.
759 */
760 if (strstr(snd_card_name, "tfa9890_stereo")) {
761 my_data->ext_speaker = true;
762 my_data->ext_earpiece = true;
763 } else if (strstr(snd_card_name, "tfa9890")) {
764 my_data->ext_speaker = true;
765 }
766
Eric Laurentb23d5282013-05-14 15:27:20 -0700767 property_get("persist.audio.dualmic.config",value,"");
768 if (!strcmp("broadside", value)) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700769 ALOGE("%s: Unsupported dualmic configuration", __func__);
Eric Laurentb23d5282013-05-14 15:27:20 -0700770 } else if (!strcmp("endfire", value)) {
771 my_data->dualmic_config = DUALMIC_CONFIG_ENDFIRE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700772 }
773
774 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
775 property_get("persist.audio.fluence.voicecall",value,"");
776 if (!strcmp("true", value)) {
777 my_data->fluence_in_voice_call = true;
778 }
779
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700780 property_get("persist.audio.fluence.voicecomm",value,"");
781 if (!strcmp("true", value)) {
782 my_data->fluence_in_voice_comm = true;
783 }
784
Eric Laurentb23d5282013-05-14 15:27:20 -0700785 property_get("persist.audio.fluence.voicerec",value,"");
786 if (!strcmp("true", value)) {
787 my_data->fluence_in_voice_rec = true;
788 }
789
790 property_get("persist.audio.fluence.speaker",value,"");
791 if (!strcmp("true", value)) {
792 my_data->fluence_in_spkr_mode = true;
793 }
794 }
795
796 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
797 if (my_data->acdb_handle == NULL) {
798 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
799 } else {
800 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
801 my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
802 "acdb_loader_deallocate_ACDB");
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700803 if (!my_data->acdb_deallocate)
804 ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
805 __func__, LIB_ACDB_LOADER);
806
Eric Laurentb23d5282013-05-14 15:27:20 -0700807 my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
808 "acdb_loader_send_audio_cal");
809 if (!my_data->acdb_send_audio_cal)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700810 ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
Eric Laurentb23d5282013-05-14 15:27:20 -0700811 __func__, LIB_ACDB_LOADER);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700812
Eric Laurentb23d5282013-05-14 15:27:20 -0700813 my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
814 "acdb_loader_send_voice_cal");
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700815 if (!my_data->acdb_send_voice_cal)
816 ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
817 __func__, LIB_ACDB_LOADER);
818
819 my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
820 "acdb_loader_reload_vocvoltable");
821 if (!my_data->acdb_reload_vocvoltable)
822 ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
823 __func__, LIB_ACDB_LOADER);
824#ifdef PLATFORM_MSM8084
825 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
826 "acdb_loader_init_v2");
827 if (my_data->acdb_init == NULL)
828 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
829 else
Haynes Mathew George98c95622014-06-20 19:14:25 -0700830 my_data->acdb_init((char *)snd_card_name);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700831#else
Eric Laurentb23d5282013-05-14 15:27:20 -0700832 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
833 "acdb_loader_init_ACDB");
834 if (my_data->acdb_init == NULL)
835 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
836 else
837 my_data->acdb_init();
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700838#endif
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700839
Eric Laurentb23d5282013-05-14 15:27:20 -0700840 }
841
Haynes Mathew George98c95622014-06-20 19:14:25 -0700842 set_platform_defaults(my_data);
843
844 /* Initialize platform specific ids and/or backends*/
Mekala Natarajan7aa15ea2015-05-27 15:50:50 -0700845 platform_info_init();
Ravi Kumar Alamanda76315572015-04-23 13:13:56 -0700846
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700847 audio_extn_spkr_prot_init(adev);
Haynes Mathew George98c95622014-06-20 19:14:25 -0700848
Ravi Kumar Alamanda76315572015-04-23 13:13:56 -0700849 audio_extn_hwdep_cal_send(adev->snd_card, my_data->acdb_handle);
850
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700851 /* load csd client */
852 platform_csd_init(my_data);
853
Eric Laurentb23d5282013-05-14 15:27:20 -0700854 return my_data;
855}
856
857void platform_deinit(void *platform)
858{
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700859 struct platform_data *my_data = (struct platform_data *)platform;
860 close_csd_client(my_data->csd);
Eric Laurentb23d5282013-05-14 15:27:20 -0700861 free(platform);
862}
863
864const char *platform_get_snd_device_name(snd_device_t snd_device)
865{
866 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
867 return device_table[snd_device];
868 else
Ravi Kumar Alamanda64026462014-09-15 00:08:58 -0700869 return "none";
Eric Laurentb23d5282013-05-14 15:27:20 -0700870}
871
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500872void platform_add_backend_name(void *platform, char *mixer_path,
873 snd_device_t snd_device)
Eric Laurentb23d5282013-05-14 15:27:20 -0700874{
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500875 struct platform_data *my_data = (struct platform_data *)platform;
876
Haynes Mathew George98c95622014-06-20 19:14:25 -0700877 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
878 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
879 return;
Ravi Kumar Alamanda1de6e5a2014-06-19 21:55:39 -0500880 }
Haynes Mathew George98c95622014-06-20 19:14:25 -0700881
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700882 const char * suffix = backend_tag_table[snd_device];
Haynes Mathew George98c95622014-06-20 19:14:25 -0700883
884 if (suffix != NULL) {
885 strcat(mixer_path, " ");
886 strcat(mixer_path, suffix);
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500887 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700888}
889
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700890bool platform_check_backends_match(snd_device_t snd_device1, snd_device_t snd_device2)
891{
892 bool result = true;
893
894 ALOGV("%s: snd_device1 = %s, snd_device2 = %s", __func__,
895 platform_get_snd_device_name(snd_device1),
896 platform_get_snd_device_name(snd_device2));
897
898 if ((snd_device1 < SND_DEVICE_MIN) || (snd_device1 >= SND_DEVICE_MAX)) {
899 ALOGE("%s: Invalid snd_device = %s", __func__,
900 platform_get_snd_device_name(snd_device1));
901 return false;
902 }
903 if ((snd_device2 < SND_DEVICE_MIN) || (snd_device2 >= SND_DEVICE_MAX)) {
904 ALOGE("%s: Invalid snd_device = %s", __func__,
905 platform_get_snd_device_name(snd_device2));
906 return false;
907 }
908 const char * be_itf1 = hw_interface_table[snd_device1];
909 const char * be_itf2 = hw_interface_table[snd_device2];
910
911 if (NULL != be_itf1 && NULL != be_itf2) {
912 if (0 != strcmp(be_itf1, be_itf2))
913 result = false;
914 }
915
916 ALOGV("%s: be_itf1 = %s, be_itf2 = %s, match %d", __func__, be_itf1, be_itf2, result);
917 return result;
918}
919
Eric Laurentb23d5282013-05-14 15:27:20 -0700920int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
921{
922 int device_id;
923 if (device_type == PCM_PLAYBACK)
924 device_id = pcm_device_table[usecase][0];
925 else
926 device_id = pcm_device_table[usecase][1];
927 return device_id;
928}
929
Haynes Mathew George98c95622014-06-20 19:14:25 -0700930static int find_index(const struct name_to_index * table, int32_t len,
931 const char * name)
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700932{
933 int ret = 0;
Haynes Mathew George98c95622014-06-20 19:14:25 -0700934 int32_t i;
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700935
Haynes Mathew George98c95622014-06-20 19:14:25 -0700936 if (table == NULL) {
937 ALOGE("%s: table is NULL", __func__);
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700938 ret = -ENODEV;
939 goto done;
940 }
941
Haynes Mathew George98c95622014-06-20 19:14:25 -0700942 if (name == NULL) {
943 ALOGE("null key");
944 ret = -ENODEV;
945 goto done;
946 }
947
948 for (i=0; i < len; i++) {
949 if (!strcmp(table[i].name, name)) {
950 ret = table[i].index;
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700951 goto done;
952 }
953 }
Haynes Mathew George98c95622014-06-20 19:14:25 -0700954 ALOGE("%s: Could not find index for name = %s",
955 __func__, name);
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700956 ret = -ENODEV;
957done:
958 return ret;
959}
960
Haynes Mathew George98c95622014-06-20 19:14:25 -0700961int platform_get_snd_device_index(char *device_name)
962{
963 return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
964}
965
966int platform_get_usecase_index(const char *usecase_name)
967{
968 return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
969}
970
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700971int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
972{
973 int ret = 0;
974
975 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
976 ALOGE("%s: Invalid snd_device = %d",
977 __func__, snd_device);
978 ret = -EINVAL;
979 goto done;
980 }
981
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -0700982 ALOGV("%s: acdb_device_table[%s]: old = %d new = %d", __func__,
983 platform_get_snd_device_name(snd_device), acdb_device_table[snd_device], acdb_id);
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700984 acdb_device_table[snd_device] = acdb_id;
985done:
986 return ret;
987}
988
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700989int platform_get_snd_device_acdb_id(snd_device_t snd_device)
990{
991 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
992 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
993 return -EINVAL;
994 }
995 return acdb_device_table[snd_device];
996}
997
Eric Laurentb23d5282013-05-14 15:27:20 -0700998int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
999{
1000 struct platform_data *my_data = (struct platform_data *)platform;
1001 int acdb_dev_id, acdb_dev_type;
1002
Ravi Kumar Alamandaadf0f3b2015-06-04 02:34:02 -07001003 acdb_dev_id = acdb_device_table[audio_extn_get_spkr_prot_snd_device(snd_device)];
Eric Laurentb23d5282013-05-14 15:27:20 -07001004 if (acdb_dev_id < 0) {
1005 ALOGE("%s: Could not find acdb id for device(%d)",
1006 __func__, snd_device);
1007 return -EINVAL;
1008 }
1009 if (my_data->acdb_send_audio_cal) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001010 ALOGD("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
Eric Laurentb23d5282013-05-14 15:27:20 -07001011 __func__, snd_device, acdb_dev_id);
1012 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
1013 snd_device < SND_DEVICE_OUT_END)
1014 acdb_dev_type = ACDB_DEV_TYPE_OUT;
1015 else
1016 acdb_dev_type = ACDB_DEV_TYPE_IN;
1017 my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
1018 }
1019 return 0;
1020}
1021
1022int platform_switch_voice_call_device_pre(void *platform)
1023{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001024 struct platform_data *my_data = (struct platform_data *)platform;
1025 int ret = 0;
1026
1027 if (my_data->csd != NULL &&
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001028 voice_is_in_call(my_data->adev)) {
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001029 /* This must be called before disabling mixer controls on APQ side */
1030 ret = my_data->csd->disable_device();
1031 if (ret < 0) {
1032 ALOGE("%s: csd_client_disable_device, failed, error %d",
1033 __func__, ret);
1034 }
1035 }
1036 return ret;
1037}
1038
1039int platform_switch_voice_call_enable_device_config(void *platform,
1040 snd_device_t out_snd_device,
1041 snd_device_t in_snd_device)
1042{
1043 struct platform_data *my_data = (struct platform_data *)platform;
1044 int acdb_rx_id, acdb_tx_id;
1045 int ret = 0;
1046
1047 if (my_data->csd == NULL)
1048 return ret;
1049
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001050 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1051 audio_extn_spkr_prot_is_enabled())
1052 acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
1053 else
1054 acdb_rx_id = acdb_device_table[out_snd_device];
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001055
1056 acdb_tx_id = acdb_device_table[in_snd_device];
1057
1058 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1059 ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
1060 if (ret < 0) {
1061 ALOGE("%s: csd_enable_device_config, failed, error %d",
1062 __func__, ret);
1063 }
1064 } else {
1065 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1066 acdb_rx_id, acdb_tx_id);
1067 }
1068
1069 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001070}
1071
1072int platform_switch_voice_call_device_post(void *platform,
1073 snd_device_t out_snd_device,
1074 snd_device_t in_snd_device)
1075{
1076 struct platform_data *my_data = (struct platform_data *)platform;
1077 int acdb_rx_id, acdb_tx_id;
1078
1079 if (my_data->acdb_send_voice_cal == NULL) {
1080 ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
1081 } else {
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001082 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1083 audio_extn_spkr_prot_is_enabled())
1084 out_snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
1085
Eric Laurentb23d5282013-05-14 15:27:20 -07001086 acdb_rx_id = acdb_device_table[out_snd_device];
1087 acdb_tx_id = acdb_device_table[in_snd_device];
1088
1089 if (acdb_rx_id > 0 && acdb_tx_id > 0)
1090 my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
1091 else
1092 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1093 acdb_rx_id, acdb_tx_id);
1094 }
1095
1096 return 0;
1097}
1098
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001099int platform_switch_voice_call_usecase_route_post(void *platform,
1100 snd_device_t out_snd_device,
1101 snd_device_t in_snd_device)
1102{
1103 struct platform_data *my_data = (struct platform_data *)platform;
1104 int acdb_rx_id, acdb_tx_id;
1105 int ret = 0;
1106
1107 if (my_data->csd == NULL)
1108 return ret;
1109
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -07001110 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1111 audio_extn_spkr_prot_is_enabled())
1112 acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED];
1113 else
1114 acdb_rx_id = acdb_device_table[out_snd_device];
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001115
1116 acdb_tx_id = acdb_device_table[in_snd_device];
1117
1118 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1119 ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
1120 my_data->adev->acdb_settings);
1121 if (ret < 0) {
1122 ALOGE("%s: csd_enable_device, failed, error %d", __func__, ret);
1123 }
1124 } else {
1125 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1126 acdb_rx_id, acdb_tx_id);
1127 }
1128
1129 return ret;
1130}
1131
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001132int platform_start_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001133{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001134 struct platform_data *my_data = (struct platform_data *)platform;
1135 int ret = 0;
1136
1137 if (my_data->csd != NULL) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001138 ret = my_data->csd->start_voice(vsid);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001139 if (ret < 0) {
1140 ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
1141 }
1142 }
1143 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001144}
1145
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001146int platform_stop_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001147{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001148 struct platform_data *my_data = (struct platform_data *)platform;
1149 int ret = 0;
1150
1151 if (my_data->csd != NULL) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001152 ret = my_data->csd->stop_voice(vsid);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001153 if (ret < 0) {
1154 ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
1155 }
1156 }
1157 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001158}
1159
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001160int platform_get_sample_rate(void *platform, uint32_t *rate)
1161{
1162 struct platform_data *my_data = (struct platform_data *)platform;
1163 int ret = 0;
1164
1165 if (my_data->csd != NULL) {
1166 ret = my_data->csd->get_sample_rate(rate);
1167 if (ret < 0) {
1168 ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret);
1169 }
1170 }
1171 return ret;
1172}
1173
Eric Laurentb23d5282013-05-14 15:27:20 -07001174int platform_set_voice_volume(void *platform, int volume)
1175{
1176 struct platform_data *my_data = (struct platform_data *)platform;
1177 struct audio_device *adev = my_data->adev;
1178 struct mixer_ctl *ctl;
sangwoo53b2cf02013-07-25 19:18:44 -07001179 const char *mixer_ctl_name = "Voice Rx Gain";
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001180 int vol_index = 0, ret = 0;
1181 uint32_t set_values[ ] = {0,
1182 ALL_SESSION_VSID,
1183 DEFAULT_VOLUME_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001184
1185 // Voice volume levels are mapped to adsp volume levels as follows.
1186 // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0
1187 // But this values don't changed in kernel. So, below change is need.
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001188 vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
1189 set_values[0] = vol_index;
Eric Laurentb23d5282013-05-14 15:27:20 -07001190
1191 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1192 if (!ctl) {
1193 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1194 __func__, mixer_ctl_name);
1195 return -EINVAL;
1196 }
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001197 ALOGV("Setting voice volume index: %d", set_values[0]);
1198 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1199
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001200 if (my_data->csd != NULL) {
1201 ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
1202 DEFAULT_VOLUME_RAMP_DURATION_MS);
1203 if (ret < 0) {
1204 ALOGE("%s: csd_volume error %d", __func__, ret);
1205 }
1206 }
1207 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001208}
1209
1210int platform_set_mic_mute(void *platform, bool state)
1211{
1212 struct platform_data *my_data = (struct platform_data *)platform;
1213 struct audio_device *adev = my_data->adev;
1214 struct mixer_ctl *ctl;
1215 const char *mixer_ctl_name = "Voice Tx Mute";
sangwoo53b2cf02013-07-25 19:18:44 -07001216 int ret = 0;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001217 uint32_t set_values[ ] = {0,
1218 ALL_SESSION_VSID,
1219 DEFAULT_MUTE_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001220
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001221 if (adev->mode != AUDIO_MODE_IN_CALL)
1222 return 0;
1223
1224 set_values[0] = state;
1225 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1226 if (!ctl) {
1227 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1228 __func__, mixer_ctl_name);
1229 return -EINVAL;
1230 }
1231 ALOGV("Setting voice mute state: %d", state);
1232 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1233
1234 if (my_data->csd != NULL) {
1235 ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state,
1236 DEFAULT_MUTE_RAMP_DURATION_MS);
sangwoo53b2cf02013-07-25 19:18:44 -07001237 if (ret < 0) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001238 ALOGE("%s: csd_mic_mute error %d", __func__, ret);
sangwoo53b2cf02013-07-25 19:18:44 -07001239 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001240 }
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001241 return ret;
1242}
Eric Laurentb23d5282013-05-14 15:27:20 -07001243
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001244int platform_set_device_mute(void *platform, bool state, char *dir)
1245{
1246 struct platform_data *my_data = (struct platform_data *)platform;
1247 struct audio_device *adev = my_data->adev;
1248 struct mixer_ctl *ctl;
1249 char *mixer_ctl_name = NULL;
1250 int ret = 0;
1251 uint32_t set_values[ ] = {0,
1252 ALL_SESSION_VSID,
1253 0};
1254 if(dir == NULL) {
1255 ALOGE("%s: Invalid direction:%s", __func__, dir);
1256 return -EINVAL;
1257 }
1258
1259 if (!strncmp("rx", dir, sizeof("rx"))) {
1260 mixer_ctl_name = "Voice Rx Device Mute";
1261 } else if (!strncmp("tx", dir, sizeof("tx"))) {
1262 mixer_ctl_name = "Voice Tx Device Mute";
1263 } else {
1264 return -EINVAL;
1265 }
1266
1267 set_values[0] = state;
1268 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1269 if (!ctl) {
1270 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1271 __func__, mixer_ctl_name);
1272 return -EINVAL;
1273 }
1274
1275 ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
1276 __func__,state, mixer_ctl_name);
1277 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1278
1279 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001280}
1281
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001282bool platform_can_split_snd_device(snd_device_t snd_device,
1283 int *num_devices,
1284 snd_device_t *new_snd_devices)
1285{
1286 bool status = false;
1287
1288 if (NULL == num_devices || NULL == new_snd_devices) {
1289 ALOGE("%s: NULL pointer ..", __func__);
1290 return false;
1291 }
1292
1293 /*
1294 * If wired headset/headphones/line devices share the same backend
1295 * with speaker/earpiece this routine returns false.
1296 */
1297 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES &&
1298 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HEADPHONES)) {
1299 *num_devices = 2;
1300 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
1301 new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
1302 status = true;
1303 } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_LINE &&
1304 !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_LINE)) {
1305 *num_devices = 2;
1306 new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
1307 new_snd_devices[1] = SND_DEVICE_OUT_LINE;
1308 status = true;
1309 }
1310 return status;
1311}
1312
Eric Laurentb23d5282013-05-14 15:27:20 -07001313snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
1314{
1315 struct platform_data *my_data = (struct platform_data *)platform;
1316 struct audio_device *adev = my_data->adev;
1317 audio_mode_t mode = adev->mode;
1318 snd_device_t snd_device = SND_DEVICE_NONE;
1319
1320 ALOGV("%s: enter: output devices(%#x)", __func__, devices);
1321 if (devices == AUDIO_DEVICE_NONE ||
1322 devices & AUDIO_DEVICE_BIT_IN) {
1323 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
1324 goto exit;
1325 }
1326
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001327 if (voice_is_in_call(adev) || adev->enable_voicerx) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001328 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001329 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1330 devices & AUDIO_DEVICE_OUT_LINE) {
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001331 if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001332 (adev->voice.tty_mode == TTY_MODE_FULL))
Eric Laurentb23d5282013-05-14 15:27:20 -07001333 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001334 else if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001335 (adev->voice.tty_mode == TTY_MODE_VCO))
Eric Laurentb23d5282013-05-14 15:27:20 -07001336 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001337 else if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001338 (adev->voice.tty_mode == TTY_MODE_HCO))
Eric Laurentb23d5282013-05-14 15:27:20 -07001339 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001340 else {
1341 if (devices & AUDIO_DEVICE_OUT_LINE)
1342 snd_device = SND_DEVICE_OUT_VOICE_LINE;
1343 else
1344 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
1345 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001346 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001347 if (adev->bt_wb_speech_enabled) {
1348 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1349 } else {
1350 snd_device = SND_DEVICE_OUT_BT_SCO;
1351 }
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001352 } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001353 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
1354 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurent9d0d3f12014-07-25 12:40:29 -05001355 if(adev->voice.hac)
1356 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1357 else if (is_operator_tmus())
Eric Laurentb23d5282013-05-14 15:27:20 -07001358 snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
1359 else
Eric Laurentb4d368e2014-06-25 10:21:54 -05001360 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -07001361 } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1362 snd_device = SND_DEVICE_OUT_VOICE_TX;
1363
Eric Laurentb23d5282013-05-14 15:27:20 -07001364 if (snd_device != SND_DEVICE_NONE) {
1365 goto exit;
1366 }
1367 }
1368
1369 if (popcount(devices) == 2) {
1370 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1371 AUDIO_DEVICE_OUT_SPEAKER)) {
1372 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1373 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1374 AUDIO_DEVICE_OUT_SPEAKER)) {
1375 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
Eric Laurent744996b2014-10-01 11:40:40 -05001376 } else if (devices == (AUDIO_DEVICE_OUT_LINE |
1377 AUDIO_DEVICE_OUT_SPEAKER)) {
1378 snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001379 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
1380 AUDIO_DEVICE_OUT_SPEAKER)) {
1381 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
1382 } else {
1383 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
1384 goto exit;
1385 }
1386 if (snd_device != SND_DEVICE_NONE) {
1387 goto exit;
1388 }
1389 }
1390
1391 if (popcount(devices) != 1) {
1392 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
1393 goto exit;
1394 }
1395
1396 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1397 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1398 snd_device = SND_DEVICE_OUT_HEADPHONES;
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001399 } else if (devices & AUDIO_DEVICE_OUT_LINE) {
1400 snd_device = SND_DEVICE_OUT_LINE;
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001401 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
1402 snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001403 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07001404 if (my_data->speaker_lr_swap)
Eric Laurentb23d5282013-05-14 15:27:20 -07001405 snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
1406 else
1407 snd_device = SND_DEVICE_OUT_SPEAKER;
1408 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001409 if (adev->bt_wb_speech_enabled) {
1410 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1411 } else {
1412 snd_device = SND_DEVICE_OUT_BT_SCO;
1413 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001414 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1415 snd_device = SND_DEVICE_OUT_HDMI ;
1416 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurent9d0d3f12014-07-25 12:40:29 -05001417 /*HAC support for voice-ish audio (eg visual voicemail)*/
1418 if(adev->voice.hac)
1419 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1420 else
1421 snd_device = SND_DEVICE_OUT_HANDSET;
Eric Laurentb23d5282013-05-14 15:27:20 -07001422 } else {
1423 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
1424 }
1425exit:
1426 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
1427 return snd_device;
1428}
1429
1430snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
1431{
1432 struct platform_data *my_data = (struct platform_data *)platform;
1433 struct audio_device *adev = my_data->adev;
1434 audio_source_t source = (adev->active_input == NULL) ?
1435 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
1436
1437 audio_mode_t mode = adev->mode;
1438 audio_devices_t in_device = ((adev->active_input == NULL) ?
1439 AUDIO_DEVICE_NONE : adev->active_input->device)
1440 & ~AUDIO_DEVICE_BIT_IN;
1441 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1442 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1443 snd_device_t snd_device = SND_DEVICE_NONE;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001444 int channel_count = popcount(channel_mask);
Eric Laurentb23d5282013-05-14 15:27:20 -07001445
1446 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
1447 __func__, out_device, in_device);
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001448 if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001449 if (adev->voice.tty_mode != TTY_MODE_OFF) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001450 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001451 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1452 out_device & AUDIO_DEVICE_OUT_LINE) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001453 switch (adev->voice.tty_mode) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001454 case TTY_MODE_FULL:
1455 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
1456 break;
1457 case TTY_MODE_VCO:
1458 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
1459 break;
1460 case TTY_MODE_HCO:
1461 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
1462 break;
1463 default:
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001464 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
Eric Laurentb23d5282013-05-14 15:27:20 -07001465 }
1466 goto exit;
1467 }
1468 }
Eric Laurentb991fb02014-08-29 15:23:17 -05001469 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001470 if (my_data->fluence_in_voice_call == false) {
1471 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1472 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001473 if (is_operator_tmus())
1474 snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001475 else
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001476 snd_device = SND_DEVICE_IN_VOICE_DMIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001477 }
1478 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1479 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
1480 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001481 if (adev->bt_wb_speech_enabled) {
1482 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1483 } else {
1484 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1485 }
Eric Laurentb991fb02014-08-29 15:23:17 -05001486 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001487 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
Eric Laurentb991fb02014-08-29 15:23:17 -05001488 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1489 out_device & AUDIO_DEVICE_OUT_LINE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001490 if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001491 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1492 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001493 } else {
1494 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
1495 }
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -07001496 } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1497 snd_device = SND_DEVICE_IN_VOICE_RX;
Eric Laurentb23d5282013-05-14 15:27:20 -07001498 } else if (source == AUDIO_SOURCE_CAMCORDER) {
1499 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
1500 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1501 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
1502 }
1503 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1504 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001505 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001506 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001507 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
1508 else if (my_data->fluence_in_voice_rec &&
1509 adev->active_input->enable_ns)
1510 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001511 }
1512
1513 if (snd_device == SND_DEVICE_NONE) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001514 if (adev->active_input->enable_ns)
1515 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
1516 else
1517 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001518 }
1519 }
1520 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001521 if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE))
Eric Laurentb23d5282013-05-14 15:27:20 -07001522 in_device = AUDIO_DEVICE_IN_BACK_MIC;
1523 if (adev->active_input) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001524 if (adev->active_input->enable_aec &&
1525 adev->active_input->enable_ns) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001526 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001527 if (my_data->fluence_in_spkr_mode &&
1528 my_data->fluence_in_voice_comm &&
1529 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1530 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
1531 } else
1532 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001533 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001534 if (my_data->fluence_in_voice_comm &&
1535 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1536 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
1537 } else
1538 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
Eric Laurentcefbbac2014-09-04 13:54:10 -05001539 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1540 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001541 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05001542 platform_set_echo_reference(adev, true, out_device);
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001543 } else if (adev->active_input->enable_aec) {
1544 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1545 if (my_data->fluence_in_spkr_mode &&
1546 my_data->fluence_in_voice_comm &&
1547 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1548 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
1549 } else
1550 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
1551 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1552 if (my_data->fluence_in_voice_comm &&
1553 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1554 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
1555 } else
1556 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
Eric Laurentcefbbac2014-09-04 13:54:10 -05001557 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1558 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
1559 }
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -08001560 platform_set_echo_reference(adev, true, out_device);
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001561 } else if (adev->active_input->enable_ns) {
1562 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1563 if (my_data->fluence_in_spkr_mode &&
1564 my_data->fluence_in_voice_comm &&
1565 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1566 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
1567 } else
1568 snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
1569 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1570 if (my_data->fluence_in_voice_comm &&
1571 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1572 snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
1573 } else
1574 snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
1575 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05001576 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001577 }
1578 } else if (source == AUDIO_SOURCE_DEFAULT) {
1579 goto exit;
1580 }
1581
1582
1583 if (snd_device != SND_DEVICE_NONE) {
1584 goto exit;
1585 }
1586
1587 if (in_device != AUDIO_DEVICE_NONE &&
1588 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
1589 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
1590 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001591 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
1592 channel_count == 2)
1593 snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
1594 else
1595 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001596 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001597 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
1598 channel_count == 2)
1599 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
1600 else
1601 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001602 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1603 snd_device = SND_DEVICE_IN_HEADSET_MIC;
1604 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001605 if (adev->bt_wb_speech_enabled) {
1606 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1607 } else {
1608 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1609 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001610 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
1611 snd_device = SND_DEVICE_IN_HDMI_MIC;
1612 } else {
1613 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
1614 ALOGW("%s: Using default handset-mic", __func__);
1615 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1616 }
1617 } else {
1618 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
1619 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1620 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1621 snd_device = SND_DEVICE_IN_HEADSET_MIC;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001622 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001623 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001624 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001625 out_device & AUDIO_DEVICE_OUT_LINE) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001626 if (channel_count == 2)
1627 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
1628 else
1629 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001630 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001631 if (adev->bt_wb_speech_enabled) {
1632 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1633 } else {
1634 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1635 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001636 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1637 snd_device = SND_DEVICE_IN_HDMI_MIC;
1638 } else {
1639 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
1640 ALOGW("%s: Using default handset-mic", __func__);
1641 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1642 }
1643 }
1644exit:
1645 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
1646 return snd_device;
1647}
1648
1649int platform_set_hdmi_channels(void *platform, int channel_count)
1650{
1651 struct platform_data *my_data = (struct platform_data *)platform;
1652 struct audio_device *adev = my_data->adev;
1653 struct mixer_ctl *ctl;
1654 const char *channel_cnt_str = NULL;
1655 const char *mixer_ctl_name = "HDMI_RX Channels";
1656 switch (channel_count) {
1657 case 8:
1658 channel_cnt_str = "Eight"; break;
1659 case 7:
1660 channel_cnt_str = "Seven"; break;
1661 case 6:
1662 channel_cnt_str = "Six"; break;
1663 case 5:
1664 channel_cnt_str = "Five"; break;
1665 case 4:
1666 channel_cnt_str = "Four"; break;
1667 case 3:
1668 channel_cnt_str = "Three"; break;
1669 default:
1670 channel_cnt_str = "Two"; break;
1671 }
1672 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1673 if (!ctl) {
1674 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1675 __func__, mixer_ctl_name);
1676 return -EINVAL;
1677 }
1678 ALOGV("HDMI channel count: %s", channel_cnt_str);
1679 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
1680 return 0;
1681}
1682
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001683int platform_edid_get_max_channels(void *platform)
Eric Laurentb23d5282013-05-14 15:27:20 -07001684{
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001685 struct platform_data *my_data = (struct platform_data *)platform;
1686 struct audio_device *adev = my_data->adev;
Eric Laurentb23d5282013-05-14 15:27:20 -07001687 char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
1688 char *sad = block;
1689 int num_audio_blocks;
1690 int channel_count;
1691 int max_channels = 0;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001692 int i, ret, count;
Eric Laurentb23d5282013-05-14 15:27:20 -07001693
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001694 struct mixer_ctl *ctl;
1695
1696 ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
1697 if (!ctl) {
1698 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1699 __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
Eric Laurentb23d5282013-05-14 15:27:20 -07001700 return 0;
1701 }
1702
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001703 mixer_ctl_update(ctl);
1704
1705 count = mixer_ctl_get_num_values(ctl);
Eric Laurentb23d5282013-05-14 15:27:20 -07001706
1707 /* Read SAD blocks, clamping the maximum size for safety */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001708 if (count > (int)sizeof(block))
1709 count = (int)sizeof(block);
Eric Laurentb23d5282013-05-14 15:27:20 -07001710
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001711 ret = mixer_ctl_get_array(ctl, block, count);
1712 if (ret != 0) {
1713 ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
1714 return 0;
1715 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001716
1717 /* Calculate the number of SAD blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001718 num_audio_blocks = count / SAD_BLOCK_SIZE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001719
1720 for (i = 0; i < num_audio_blocks; i++) {
1721 /* Only consider LPCM blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001722 if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
1723 sad += 3;
Eric Laurentb23d5282013-05-14 15:27:20 -07001724 continue;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001725 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001726
1727 channel_count = (sad[0] & 0x7) + 1;
1728 if (channel_count > max_channels)
1729 max_channels = channel_count;
1730
1731 /* Advance to next block */
1732 sad += 3;
1733 }
1734
1735 return max_channels;
1736}
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07001737
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001738int platform_set_incall_recording_session_id(void *platform,
1739 uint32_t session_id, int rec_mode)
1740{
1741 int ret = 0;
1742 struct platform_data *my_data = (struct platform_data *)platform;
1743 struct audio_device *adev = my_data->adev;
1744 struct mixer_ctl *ctl;
1745 const char *mixer_ctl_name = "Voc VSID";
1746 int num_ctl_values;
1747 int i;
1748
1749 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1750 if (!ctl) {
1751 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1752 __func__, mixer_ctl_name);
1753 ret = -EINVAL;
1754 } else {
1755 num_ctl_values = mixer_ctl_get_num_values(ctl);
1756 for (i = 0; i < num_ctl_values; i++) {
1757 if (mixer_ctl_set_value(ctl, i, session_id)) {
1758 ALOGV("Error: invalid session_id: %x", session_id);
1759 ret = -EINVAL;
1760 break;
1761 }
1762 }
1763 }
1764
1765 if (my_data->csd != NULL) {
1766 ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
1767 if (ret < 0) {
1768 ALOGE("%s: csd_client_start_record failed, error %d",
1769 __func__, ret);
1770 }
1771 }
1772
1773 return ret;
1774}
1775
1776int platform_stop_incall_recording_usecase(void *platform)
1777{
1778 int ret = 0;
1779 struct platform_data *my_data = (struct platform_data *)platform;
1780
1781 if (my_data->csd != NULL) {
1782 ret = my_data->csd->stop_record(ALL_SESSION_VSID);
1783 if (ret < 0) {
1784 ALOGE("%s: csd_client_stop_record failed, error %d",
1785 __func__, ret);
1786 }
1787 }
1788
1789 return ret;
1790}
1791
1792int platform_start_incall_music_usecase(void *platform)
1793{
1794 int ret = 0;
1795 struct platform_data *my_data = (struct platform_data *)platform;
1796
1797 if (my_data->csd != NULL) {
1798 ret = my_data->csd->start_playback(ALL_SESSION_VSID);
1799 if (ret < 0) {
1800 ALOGE("%s: csd_client_start_playback failed, error %d",
1801 __func__, ret);
1802 }
1803 }
1804
1805 return ret;
1806}
1807
1808int platform_stop_incall_music_usecase(void *platform)
1809{
1810 int ret = 0;
1811 struct platform_data *my_data = (struct platform_data *)platform;
1812
1813 if (my_data->csd != NULL) {
1814 ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
1815 if (ret < 0) {
1816 ALOGE("%s: csd_client_stop_playback failed, error %d",
1817 __func__, ret);
1818 }
1819 }
1820
1821 return ret;
1822}
1823
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07001824/* Delay in Us */
1825int64_t platform_render_latency(audio_usecase_t usecase)
1826{
1827 switch (usecase) {
1828 case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
1829 return DEEP_BUFFER_PLATFORM_DELAY;
1830 case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
1831 return LOW_LATENCY_PLATFORM_DELAY;
1832 default:
1833 return 0;
1834 }
1835}
Haynes Mathew George98c95622014-06-20 19:14:25 -07001836
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001837int platform_set_snd_device_backend(snd_device_t device, const char *backend_tag,
1838 const char * hw_interface)
Haynes Mathew George98c95622014-06-20 19:14:25 -07001839{
1840 int ret = 0;
1841
1842 if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
1843 ALOGE("%s: Invalid snd_device = %d",
1844 __func__, device);
1845 ret = -EINVAL;
1846 goto done;
1847 }
1848
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001849 ALOGV("%s: backend_tag_table[%s]: old = %s new = %s", __func__,
1850 platform_get_snd_device_name(device),
1851 backend_tag_table[device] != NULL ? backend_tag_table[device]: "null", backend_tag);
1852 if (backend_tag_table[device]) {
1853 free(backend_tag_table[device]);
Haynes Mathew George98c95622014-06-20 19:14:25 -07001854 }
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001855 backend_tag_table[device] = strdup(backend_tag);
1856
1857 if (hw_interface != NULL) {
1858 if (hw_interface_table[device])
1859 free(hw_interface_table[device]);
1860 ALOGV("%s: hw_interface_table[%d] = %s", __func__, device, hw_interface);
1861 hw_interface_table[device] = strdup(hw_interface);
1862 }
Haynes Mathew George98c95622014-06-20 19:14:25 -07001863done:
1864 return ret;
1865}
1866
1867int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
1868{
1869 int ret = 0;
1870 if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
1871 ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
1872 ret = -EINVAL;
1873 goto done;
1874 }
1875
1876 if ((type != 0) && (type != 1)) {
1877 ALOGE("%s: invalid usecase type", __func__);
1878 ret = -EINVAL;
1879 }
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001880 ALOGV("%s: pcm_device_table[%d][%d] = %d", __func__, usecase, type, pcm_id);
Haynes Mathew George98c95622014-06-20 19:14:25 -07001881 pcm_device_table[usecase][type] = pcm_id;
1882done:
1883 return ret;
1884}
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07001885
1886int platform_swap_lr_channels(struct audio_device *adev, bool swap_channels)
1887{
1888 // only update if there is active pcm playback on speaker
1889 struct audio_usecase *usecase;
1890 struct listnode *node;
1891 struct platform_data *my_data = (struct platform_data *)adev->platform;
1892
1893 if (my_data->speaker_lr_swap != swap_channels) {
1894 my_data->speaker_lr_swap = swap_channels;
1895
1896 list_for_each(node, &adev->usecase_list) {
1897 usecase = node_to_item(node, struct audio_usecase, list);
1898 if (usecase->type == PCM_PLAYBACK &&
1899 usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
1900 const char *mixer_path;
1901 if (swap_channels) {
1902 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
1903 audio_route_apply_and_update_path(adev->audio_route, mixer_path);
1904 } else {
1905 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
1906 audio_route_apply_and_update_path(adev->audio_route, mixer_path);
1907 }
1908 break;
1909 }
1910 }
1911 }
1912 return 0;
1913}