blob: 921c384af9d876d3c6d2da46438b6354580dfb89 [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"
29
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070030#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
Uday Kishore Pasupuleti11dd2232015-06-24 14:18:01 -070031#define MIXER_XML_PATH_WCD9330 "/system/etc/mixer_paths_wcd9330.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;
Eric Laurentb23d5282013-05-14 15:27:20 -070082 void *acdb_handle;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -070083 acdb_init_t acdb_init;
84 acdb_deallocate_t acdb_deallocate;
85 acdb_send_audio_cal_t acdb_send_audio_cal;
86 acdb_send_voice_cal_t acdb_send_voice_cal;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -070087 acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
88 struct csd_data *csd;
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -050089 bool ext_speaker;
90 bool ext_earpiece;
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -080091 char ec_ref_mixer_path[64];
Eric Laurentb23d5282013-05-14 15:27:20 -070092};
93
Haynes Mathew George98c95622014-06-20 19:14:25 -070094static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -070095 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
96 DEEP_BUFFER_PCM_DEVICE},
97 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
98 LOWLATENCY_PCM_DEVICE},
99 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
100 MULTIMEDIA2_PCM_DEVICE},
101 [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {PLAYBACK_OFFLOAD_DEVICE,
102 PLAYBACK_OFFLOAD_DEVICE},
103 [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE,
104 AUDIO_RECORD_PCM_DEVICE},
105 [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
106 LOWLATENCY_PCM_DEVICE},
107 [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE,
108 VOICE_CALL_PCM_DEVICE},
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700109 [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
110 [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
111 [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
112 [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
113 [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
114 AUDIO_RECORD_PCM_DEVICE},
115 [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
116 AUDIO_RECORD_PCM_DEVICE},
117 [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
118 AUDIO_RECORD_PCM_DEVICE},
Ravi Kumar Alamanda8e6e98f2013-11-05 15:57:39 -0800119 [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700120
121 [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
122 AFE_PROXY_RECORD_PCM_DEVICE},
123 [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
124 AFE_PROXY_RECORD_PCM_DEVICE},
125
Eric Laurentb23d5282013-05-14 15:27:20 -0700126};
127
128/* Array to store sound devices */
129static const char * const device_table[SND_DEVICE_MAX] = {
130 [SND_DEVICE_NONE] = "none",
131 /* Playback sound devices */
132 [SND_DEVICE_OUT_HANDSET] = "handset",
133 [SND_DEVICE_OUT_SPEAKER] = "speaker",
134 [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700135 [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
Eric Laurentb23d5282013-05-14 15:27:20 -0700136 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500137 [SND_DEVICE_OUT_LINE] = "line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700138 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Eric Laurent744996b2014-10-01 11:40:40 -0500139 [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700140 [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500141 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
Eric Laurentb23d5282013-05-14 15:27:20 -0700142 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
143 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500144 [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
Eric Laurentb23d5282013-05-14 15:27:20 -0700145 [SND_DEVICE_OUT_HDMI] = "hdmi",
146 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
147 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700148 [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700149 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
150 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
151 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
152 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700153 [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
Eric Laurentb23d5282013-05-14 15:27:20 -0700154
155 /* Capture sound devices */
156 [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700157 [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700158 [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
159 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
160 [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
161 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
162 [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
163 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
164 [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = "dmic-endfire",
165
166 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
167 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
168 [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
169 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
170 [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
171 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
172 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
173 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
174 [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = "speaker-dmic-endfire",
175
176 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
Eric Laurentcefbbac2014-09-04 13:54:10 -0500177 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700178
Eric Laurentb23d5282013-05-14 15:27:20 -0700179 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
180 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700181 [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700182
Eric Laurentb23d5282013-05-14 15:27:20 -0700183 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700184
185 [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
186 [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
187 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
188 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
189 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700190 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
191 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
192 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700193
Eric Laurentb23d5282013-05-14 15:27:20 -0700194 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700195 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
196 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
197 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700198
199 [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
Eric Laurentb23d5282013-05-14 15:27:20 -0700200};
201
202/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700203static int acdb_device_table[SND_DEVICE_MAX] = {
Eric Laurentb23d5282013-05-14 15:27:20 -0700204 [SND_DEVICE_NONE] = -1,
205 [SND_DEVICE_OUT_HANDSET] = 7,
206 [SND_DEVICE_OUT_SPEAKER] = 15,
207 [SND_DEVICE_OUT_SPEAKER_REVERSE] = 15,
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700208 [SND_DEVICE_OUT_SPEAKER_SAFE] = 15,
Eric Laurentb23d5282013-05-14 15:27:20 -0700209 [SND_DEVICE_OUT_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500210 [SND_DEVICE_OUT_LINE] = 77,
Eric Laurentb23d5282013-05-14 15:27:20 -0700211 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500212 [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 77,
Ravi Kumar Alamanda235c3482014-08-21 17:32:44 -0700213 [SND_DEVICE_OUT_VOICE_HANDSET] = ACDB_ID_VOICE_HANDSET,
214 [SND_DEVICE_OUT_VOICE_SPEAKER] = ACDB_ID_VOICE_SPEAKER,
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500215 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
Eric Laurentb23d5282013-05-14 15:27:20 -0700216 [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
Eric Laurent744996b2014-10-01 11:40:40 -0500217 [SND_DEVICE_OUT_VOICE_LINE] = 77,
Eric Laurentb23d5282013-05-14 15:27:20 -0700218 [SND_DEVICE_OUT_HDMI] = 18,
219 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 15,
220 [SND_DEVICE_OUT_BT_SCO] = 22,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700221 [SND_DEVICE_OUT_BT_SCO_WB] = 39,
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700222 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = ACDB_ID_VOICE_HANDSET_TMUS,
Eric Laurentb23d5282013-05-14 15:27:20 -0700223 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
224 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
225 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700226 [SND_DEVICE_OUT_VOICE_TX] = 45,
Eric Laurentb23d5282013-05-14 15:27:20 -0700227
228 [SND_DEVICE_IN_HANDSET_MIC] = 4,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700229 [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
230 [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
231 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
232 [SND_DEVICE_IN_HANDSET_DMIC] = 41,
233 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
234 [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
235 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
236 [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = 34,
237
238 [SND_DEVICE_IN_SPEAKER_MIC] = 11,
239 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
240 [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
241 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
242 [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
243 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
244 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
245 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
246 [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = 35,
247
Eric Laurentb23d5282013-05-14 15:27:20 -0700248 [SND_DEVICE_IN_HEADSET_MIC] = 8,
Eric Laurentcefbbac2014-09-04 13:54:10 -0500249 [SND_DEVICE_IN_HEADSET_MIC_AEC] = ACDB_ID_HEADSET_MIC_AEC,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700250
Eric Laurentb23d5282013-05-14 15:27:20 -0700251 [SND_DEVICE_IN_HDMI_MIC] = 4,
252 [SND_DEVICE_IN_BT_SCO_MIC] = 21,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700253 [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700254
Eric Laurentb23d5282013-05-14 15:27:20 -0700255 [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700256
257 [SND_DEVICE_IN_VOICE_DMIC] = 41,
258 [SND_DEVICE_IN_VOICE_DMIC_TMUS] = ACDB_ID_VOICE_DMIC_EF_TMUS,
259 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
260 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
261 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
Eric Laurentb23d5282013-05-14 15:27:20 -0700262 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
263 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
264 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700265
Eric Laurentb23d5282013-05-14 15:27:20 -0700266 [SND_DEVICE_IN_VOICE_REC_MIC] = 62,
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700267 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 113,
268 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 35,
269 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 43,
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700270
271 [SND_DEVICE_IN_VOICE_RX] = 44,
Eric Laurentb23d5282013-05-14 15:27:20 -0700272};
273
Haynes Mathew George98c95622014-06-20 19:14:25 -0700274struct name_to_index {
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700275 char name[100];
276 unsigned int index;
277};
278
279#define TO_NAME_INDEX(X) #X, X
280
Haynes Mathew George98c95622014-06-20 19:14:25 -0700281/* Used to get index from parsed string */
282static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
283 /* out */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700284 {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
285 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
286 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700287 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700288 {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500289 {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700290 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
Eric Laurent744996b2014-10-01 11:40:40 -0500291 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700292 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
293 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
294 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
Eric Laurent09f2e0e2014-07-29 16:02:32 -0500295 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700296 {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
297 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
298 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
299 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700300 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET_TMUS)},
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500301 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700302 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
303 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
304 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700305
306 /* in */
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700307 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700308 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700309 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
310 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
311 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
312 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
313 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
314 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
315 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_STEREO)},
316
317 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700318 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700319 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
320 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
321 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
322 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
323 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
324 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
325 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
326
327 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
328
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700329 {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
330 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
331 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700332
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700333 {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700334
335 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
336 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
337 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
338 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
339 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700340 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
341 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
342 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700343
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700344 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700345 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
346 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
347 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
Haynes Mathew George98c95622014-06-20 19:14:25 -0700348};
349
350static char * backend_table[SND_DEVICE_MAX] = {0};
351
352static const struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
353 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
354 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
355 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
356 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
357 {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
358 {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
359 {TO_NAME_INDEX(USECASE_VOICE_CALL)},
360 {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
361 {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
362 {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
363 {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
364 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK)},
365 {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
366 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
367 {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700368};
369
Haynes Mathew George7ff216f2013-09-11 19:51:41 -0700370#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
371#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
372
Eric Laurentb23d5282013-05-14 15:27:20 -0700373static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
374static bool is_tmus = false;
375
376static void check_operator()
377{
378 char value[PROPERTY_VALUE_MAX];
379 int mccmnc;
380 property_get("gsm.sim.operator.numeric",value,"0");
381 mccmnc = atoi(value);
382 ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
383 switch(mccmnc) {
384 /* TMUS MCC(310), MNC(490, 260, 026) */
385 case 310490:
386 case 310260:
387 case 310026:
sangwon.jeonb891db52013-09-14 17:39:15 +0900388 /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
389 case 310800:
390 case 310660:
391 case 310580:
392 case 310310:
393 case 310270:
394 case 310250:
395 case 310240:
396 case 310230:
397 case 310220:
398 case 310210:
399 case 310200:
400 case 310160:
Eric Laurentb23d5282013-05-14 15:27:20 -0700401 is_tmus = true;
402 break;
403 }
404}
405
406bool is_operator_tmus()
407{
408 pthread_once(&check_op_once_ctl, check_operator);
409 return is_tmus;
410}
411
Eric Laurentcefbbac2014-09-04 13:54:10 -0500412void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
Eric Laurentb23d5282013-05-14 15:27:20 -0700413{
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800414 struct platform_data *my_data = (struct platform_data *)adev->platform;
Eric Laurentcefbbac2014-09-04 13:54:10 -0500415 snd_device_t snd_device = SND_DEVICE_NONE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700416
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800417 if (strcmp(my_data->ec_ref_mixer_path, "")) {
418 ALOGV("%s: diabling %s", __func__, my_data->ec_ref_mixer_path);
419 audio_route_reset_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
Eric Laurentcefbbac2014-09-04 13:54:10 -0500420 }
421
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800422 if (enable) {
423 strcpy(my_data->ec_ref_mixer_path, "echo-reference");
424 if (out_device != AUDIO_DEVICE_NONE) {
425 snd_device = platform_get_output_snd_device(adev->platform, out_device);
426 platform_add_backend_name(adev->platform, my_data->ec_ref_mixer_path, snd_device);
427 }
Eric Laurentcefbbac2014-09-04 13:54:10 -0500428
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -0800429 ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
430 audio_route_apply_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
431 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700432}
433
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700434static struct csd_data *open_csd_client(bool i2s_ext_modem)
435{
436 struct csd_data *csd = calloc(1, sizeof(struct csd_data));
437
438 csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
439 if (csd->csd_client == NULL) {
440 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
441 goto error;
442 } else {
443 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
444
445 csd->deinit = (deinit_t)dlsym(csd->csd_client,
446 "csd_client_deinit");
447 if (csd->deinit == NULL) {
448 ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
449 dlerror());
450 goto error;
451 }
452 csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
453 "csd_client_disable_device");
454 if (csd->disable_device == NULL) {
455 ALOGE("%s: dlsym error %s for csd_client_disable_device",
456 __func__, dlerror());
457 goto error;
458 }
459 csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
460 "csd_client_enable_device_config");
461 if (csd->enable_device_config == NULL) {
462 ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
463 __func__, dlerror());
464 goto error;
465 }
466 csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
467 "csd_client_enable_device");
468 if (csd->enable_device == NULL) {
469 ALOGE("%s: dlsym error %s for csd_client_enable_device",
470 __func__, dlerror());
471 goto error;
472 }
473 csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
474 "csd_client_start_voice");
475 if (csd->start_voice == NULL) {
476 ALOGE("%s: dlsym error %s for csd_client_start_voice",
477 __func__, dlerror());
478 goto error;
479 }
480 csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
481 "csd_client_stop_voice");
482 if (csd->stop_voice == NULL) {
483 ALOGE("%s: dlsym error %s for csd_client_stop_voice",
484 __func__, dlerror());
485 goto error;
486 }
487 csd->volume = (volume_t)dlsym(csd->csd_client,
488 "csd_client_volume");
489 if (csd->volume == NULL) {
490 ALOGE("%s: dlsym error %s for csd_client_volume",
491 __func__, dlerror());
492 goto error;
493 }
494 csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
495 "csd_client_mic_mute");
496 if (csd->mic_mute == NULL) {
497 ALOGE("%s: dlsym error %s for csd_client_mic_mute",
498 __func__, dlerror());
499 goto error;
500 }
501 csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
502 "csd_client_slow_talk");
503 if (csd->slow_talk == NULL) {
504 ALOGE("%s: dlsym error %s for csd_client_slow_talk",
505 __func__, dlerror());
506 goto error;
507 }
508 csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
509 "csd_client_start_playback");
510 if (csd->start_playback == NULL) {
511 ALOGE("%s: dlsym error %s for csd_client_start_playback",
512 __func__, dlerror());
513 goto error;
514 }
515 csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
516 "csd_client_stop_playback");
517 if (csd->stop_playback == NULL) {
518 ALOGE("%s: dlsym error %s for csd_client_stop_playback",
519 __func__, dlerror());
520 goto error;
521 }
522 csd->start_record = (start_record_t)dlsym(csd->csd_client,
523 "csd_client_start_record");
524 if (csd->start_record == NULL) {
525 ALOGE("%s: dlsym error %s for csd_client_start_record",
526 __func__, dlerror());
527 goto error;
528 }
529 csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
530 "csd_client_stop_record");
531 if (csd->stop_record == NULL) {
532 ALOGE("%s: dlsym error %s for csd_client_stop_record",
533 __func__, dlerror());
534 goto error;
535 }
536
537 csd->get_sample_rate = (get_sample_rate_t)dlsym(csd->csd_client,
538 "csd_client_get_sample_rate");
539 if (csd->get_sample_rate == NULL) {
540 ALOGE("%s: dlsym error %s for csd_client_get_sample_rate",
541 __func__, dlerror());
542
543 goto error;
544 }
545
546 csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
547
548 if (csd->init == NULL) {
549 ALOGE("%s: dlsym error %s for csd_client_init",
550 __func__, dlerror());
551 goto error;
552 } else {
553 csd->init(i2s_ext_modem);
554 }
555 }
556 return csd;
557
558error:
559 free(csd);
560 csd = NULL;
561 return csd;
562}
563
564void close_csd_client(struct csd_data *csd)
565{
566 if (csd != NULL) {
567 csd->deinit();
568 dlclose(csd->csd_client);
569 free(csd);
570 csd = NULL;
571 }
572}
573
574static void platform_csd_init(struct platform_data *my_data)
575{
576#ifdef PLATFORM_MSM8084
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700577 int32_t modems, (*count_modems)(void);
578 const char *name = "libdetectmodem.so";
579 const char *func = "count_modems";
580 const char *error;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700581
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700582 my_data->csd = NULL;
583
584 void *lib = dlopen(name, RTLD_NOW);
585 error = dlerror();
586 if (!lib) {
587 ALOGE("%s: could not find %s: %s", __func__, name, error);
588 return;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700589 }
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700590
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700591 count_modems = NULL;
592 *(void **)(&count_modems) = dlsym(lib, func);
593 error = dlerror();
594 if (!count_modems) {
595 ALOGE("%s: could not find symbol %s in %s: %s",
596 __func__, func, name, error);
597 goto done;
598 }
599
600 modems = count_modems();
601 if (modems < 0) {
602 ALOGE("%s: count_modems failed\n", __func__);
603 goto done;
604 }
605
606 ALOGD("%s: num_modems %d\n", __func__, modems);
607 if (modems > 0)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700608 my_data->csd = open_csd_client(false /*is_i2s_ext_modem*/);
Iliyan Malchevae9a10c2014-08-09 13:07:21 -0700609
610done:
611 dlclose(lib);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700612#else
613 my_data->csd = NULL;
614#endif
615}
616
Haynes Mathew George98c95622014-06-20 19:14:25 -0700617static void set_platform_defaults(struct platform_data * my_data)
618{
619 int32_t dev;
620 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
621 backend_table[dev] = NULL;
622 }
623
624 // TBD - do these go to the platform-info.xml file.
625 // will help in avoiding strdups here
626 backend_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
627 backend_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
628 backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
629 backend_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
630 backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
631 backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -0700632 backend_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
633 backend_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700634
635 if (my_data->ext_speaker) {
636 backend_table[SND_DEVICE_OUT_SPEAKER] = strdup("speaker");
Eric Laurent1b0d8ce2014-09-11 09:59:28 -0700637 backend_table[SND_DEVICE_OUT_SPEAKER_SAFE] = strdup("speaker");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700638 backend_table[SND_DEVICE_OUT_VOICE_SPEAKER] = strdup("speaker");
639 backend_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = strdup("speaker");
640 backend_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] =
641 strdup("speaker-and-headphones");
Eric Laurent744996b2014-10-01 11:40:40 -0500642 backend_table[SND_DEVICE_OUT_SPEAKER_AND_LINE] =
643 strdup("speaker-and-line");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700644 }
645
646 if (my_data->ext_earpiece) {
647 backend_table[SND_DEVICE_OUT_VOICE_HANDSET] = strdup("handset");
Eric Laurent9d0d3f12014-07-25 12:40:29 -0500648 backend_table[SND_DEVICE_OUT_VOICE_HAC_HANDSET] = strdup("handset");
Haynes Mathew George98c95622014-06-20 19:14:25 -0700649 backend_table[SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = strdup("handset");
650 backend_table[SND_DEVICE_OUT_HANDSET] = strdup("handset");
651 backend_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("handset");
652 }
653}
654
Eric Laurentb23d5282013-05-14 15:27:20 -0700655void *platform_init(struct audio_device *adev)
656{
657 char value[PROPERTY_VALUE_MAX];
658 struct platform_data *my_data;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700659 int retry_num = 0, snd_card_num = 0;
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700660 const char *snd_card_name;
sangwoo1b9f4b32013-06-21 18:22:55 -0700661
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700662 while (snd_card_num < MAX_SND_CARD) {
663 adev->mixer = mixer_open(snd_card_num);
sangwoo1b9f4b32013-06-21 18:22:55 -0700664
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700665 while (!adev->mixer && retry_num < RETRY_NUMBER) {
666 usleep(RETRY_US);
667 adev->mixer = mixer_open(snd_card_num);
668 retry_num++;
669 }
670
671 if (!adev->mixer) {
672 ALOGE("%s: Unable to open the mixer card: %d", __func__,
673 snd_card_num);
674 retry_num = 0;
675 snd_card_num++;
676 continue;
677 }
678
679 snd_card_name = mixer_get_name(adev->mixer);
680 ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
681
Uday Kishore Pasupuleti11dd2232015-06-24 14:18:01 -0700682 if (!strncmp(snd_card_name, "msm8226-tomtom-snd-card",
683 sizeof("msm8226-tomtom-snd-card"))) {
684 ALOGD("%s: Call MIXER_XML_PATH_WCD9330", __func__);
685 adev->audio_route = audio_route_init(snd_card_num,
686 MIXER_XML_PATH_WCD9330);
687 } else {
688 adev->audio_route = audio_route_init(snd_card_num, MIXER_XML_PATH);
689 }
690
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700691 if (!adev->audio_route) {
692 ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
693 return NULL;
694 }
695 adev->snd_card = snd_card_num;
696 ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
697 break;
sangwoo1b9f4b32013-06-21 18:22:55 -0700698 }
699
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700700 if (snd_card_num >= MAX_SND_CARD) {
701 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
sangwoo1b9f4b32013-06-21 18:22:55 -0700702 return NULL;
703 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700704
705 my_data = calloc(1, sizeof(struct platform_data));
706
707 my_data->adev = adev;
708 my_data->dualmic_config = DUALMIC_CONFIG_NONE;
709 my_data->fluence_in_spkr_mode = false;
710 my_data->fluence_in_voice_call = false;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700711 my_data->fluence_in_voice_comm = false;
Eric Laurentb23d5282013-05-14 15:27:20 -0700712 my_data->fluence_in_voice_rec = false;
713
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500714 /*
715 * The default assumption is that earpiece (handset), speaker and headphones
716 * devices are connected to internal HW codec and communicated through
717 * slimbus backend. If any platform communicates with speaker or earpiece
718 * or headphones through non-slimbus backend such as MI2S or AUXPCM etc.,
719 * the ext_xxxx flags must be set accordingly.
720 */
721 if (strstr(snd_card_name, "tfa9890_stereo")) {
722 my_data->ext_speaker = true;
723 my_data->ext_earpiece = true;
724 } else if (strstr(snd_card_name, "tfa9890")) {
725 my_data->ext_speaker = true;
726 }
727
Eric Laurentb23d5282013-05-14 15:27:20 -0700728 property_get("persist.audio.dualmic.config",value,"");
729 if (!strcmp("broadside", value)) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700730 ALOGE("%s: Unsupported dualmic configuration", __func__);
Eric Laurentb23d5282013-05-14 15:27:20 -0700731 } else if (!strcmp("endfire", value)) {
732 my_data->dualmic_config = DUALMIC_CONFIG_ENDFIRE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700733 }
734
735 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
736 property_get("persist.audio.fluence.voicecall",value,"");
737 if (!strcmp("true", value)) {
738 my_data->fluence_in_voice_call = true;
739 }
740
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700741 property_get("persist.audio.fluence.voicecomm",value,"");
742 if (!strcmp("true", value)) {
743 my_data->fluence_in_voice_comm = true;
744 }
745
Eric Laurentb23d5282013-05-14 15:27:20 -0700746 property_get("persist.audio.fluence.voicerec",value,"");
747 if (!strcmp("true", value)) {
748 my_data->fluence_in_voice_rec = true;
749 }
750
751 property_get("persist.audio.fluence.speaker",value,"");
752 if (!strcmp("true", value)) {
753 my_data->fluence_in_spkr_mode = true;
754 }
755 }
756
757 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
758 if (my_data->acdb_handle == NULL) {
759 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
760 } else {
761 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
762 my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
763 "acdb_loader_deallocate_ACDB");
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700764 if (!my_data->acdb_deallocate)
765 ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
766 __func__, LIB_ACDB_LOADER);
767
Eric Laurentb23d5282013-05-14 15:27:20 -0700768 my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
769 "acdb_loader_send_audio_cal");
770 if (!my_data->acdb_send_audio_cal)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700771 ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
Eric Laurentb23d5282013-05-14 15:27:20 -0700772 __func__, LIB_ACDB_LOADER);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700773
Eric Laurentb23d5282013-05-14 15:27:20 -0700774 my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
775 "acdb_loader_send_voice_cal");
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700776 if (!my_data->acdb_send_voice_cal)
777 ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
778 __func__, LIB_ACDB_LOADER);
779
780 my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
781 "acdb_loader_reload_vocvoltable");
782 if (!my_data->acdb_reload_vocvoltable)
783 ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
784 __func__, LIB_ACDB_LOADER);
785#ifdef PLATFORM_MSM8084
786 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
787 "acdb_loader_init_v2");
788 if (my_data->acdb_init == NULL)
789 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
790 else
Haynes Mathew George98c95622014-06-20 19:14:25 -0700791 my_data->acdb_init((char *)snd_card_name);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700792#else
Eric Laurentb23d5282013-05-14 15:27:20 -0700793 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
794 "acdb_loader_init_ACDB");
795 if (my_data->acdb_init == NULL)
796 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
797 else
798 my_data->acdb_init();
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700799#endif
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700800
Eric Laurentb23d5282013-05-14 15:27:20 -0700801 }
802
Haynes Mathew George98c95622014-06-20 19:14:25 -0700803 set_platform_defaults(my_data);
804
805 /* Initialize platform specific ids and/or backends*/
806 platform_info_init();
807
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700808 /* load csd client */
809 platform_csd_init(my_data);
810
Eric Laurentb23d5282013-05-14 15:27:20 -0700811 return my_data;
812}
813
814void platform_deinit(void *platform)
815{
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700816 struct platform_data *my_data = (struct platform_data *)platform;
817 close_csd_client(my_data->csd);
Eric Laurentb23d5282013-05-14 15:27:20 -0700818 free(platform);
819}
820
821const char *platform_get_snd_device_name(snd_device_t snd_device)
822{
823 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
824 return device_table[snd_device];
825 else
Ravi Kumar Alamanda64026462014-09-15 00:08:58 -0700826 return "none";
Eric Laurentb23d5282013-05-14 15:27:20 -0700827}
828
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500829void platform_add_backend_name(void *platform, char *mixer_path,
830 snd_device_t snd_device)
Eric Laurentb23d5282013-05-14 15:27:20 -0700831{
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500832 struct platform_data *my_data = (struct platform_data *)platform;
833
Haynes Mathew George98c95622014-06-20 19:14:25 -0700834 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
835 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
836 return;
Ravi Kumar Alamanda1de6e5a2014-06-19 21:55:39 -0500837 }
Haynes Mathew George98c95622014-06-20 19:14:25 -0700838
839 const char * suffix = backend_table[snd_device];
840
841 if (suffix != NULL) {
842 strcat(mixer_path, " ");
843 strcat(mixer_path, suffix);
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500844 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700845}
846
847int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
848{
849 int device_id;
850 if (device_type == PCM_PLAYBACK)
851 device_id = pcm_device_table[usecase][0];
852 else
853 device_id = pcm_device_table[usecase][1];
854 return device_id;
855}
856
Haynes Mathew George98c95622014-06-20 19:14:25 -0700857static int find_index(const struct name_to_index * table, int32_t len,
858 const char * name)
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700859{
860 int ret = 0;
Haynes Mathew George98c95622014-06-20 19:14:25 -0700861 int32_t i;
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700862
Haynes Mathew George98c95622014-06-20 19:14:25 -0700863 if (table == NULL) {
864 ALOGE("%s: table is NULL", __func__);
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700865 ret = -ENODEV;
866 goto done;
867 }
868
Haynes Mathew George98c95622014-06-20 19:14:25 -0700869 if (name == NULL) {
870 ALOGE("null key");
871 ret = -ENODEV;
872 goto done;
873 }
874
875 for (i=0; i < len; i++) {
876 if (!strcmp(table[i].name, name)) {
877 ret = table[i].index;
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700878 goto done;
879 }
880 }
Haynes Mathew George98c95622014-06-20 19:14:25 -0700881 ALOGE("%s: Could not find index for name = %s",
882 __func__, name);
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700883 ret = -ENODEV;
884done:
885 return ret;
886}
887
Haynes Mathew George98c95622014-06-20 19:14:25 -0700888int platform_get_snd_device_index(char *device_name)
889{
890 return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
891}
892
893int platform_get_usecase_index(const char *usecase_name)
894{
895 return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
896}
897
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700898int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
899{
900 int ret = 0;
901
902 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
903 ALOGE("%s: Invalid snd_device = %d",
904 __func__, snd_device);
905 ret = -EINVAL;
906 goto done;
907 }
908
909 acdb_device_table[snd_device] = acdb_id;
910done:
911 return ret;
912}
913
Eric Laurentb23d5282013-05-14 15:27:20 -0700914int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
915{
916 struct platform_data *my_data = (struct platform_data *)platform;
917 int acdb_dev_id, acdb_dev_type;
918
919 acdb_dev_id = acdb_device_table[snd_device];
920 if (acdb_dev_id < 0) {
921 ALOGE("%s: Could not find acdb id for device(%d)",
922 __func__, snd_device);
923 return -EINVAL;
924 }
925 if (my_data->acdb_send_audio_cal) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -0700926 ALOGD("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
Eric Laurentb23d5282013-05-14 15:27:20 -0700927 __func__, snd_device, acdb_dev_id);
928 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
929 snd_device < SND_DEVICE_OUT_END)
930 acdb_dev_type = ACDB_DEV_TYPE_OUT;
931 else
932 acdb_dev_type = ACDB_DEV_TYPE_IN;
933 my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
934 }
935 return 0;
936}
937
938int platform_switch_voice_call_device_pre(void *platform)
939{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700940 struct platform_data *my_data = (struct platform_data *)platform;
941 int ret = 0;
942
943 if (my_data->csd != NULL &&
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -0700944 voice_is_in_call(my_data->adev)) {
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -0700945 /* This must be called before disabling mixer controls on APQ side */
946 ret = my_data->csd->disable_device();
947 if (ret < 0) {
948 ALOGE("%s: csd_client_disable_device, failed, error %d",
949 __func__, ret);
950 }
951 }
952 return ret;
953}
954
955int platform_switch_voice_call_enable_device_config(void *platform,
956 snd_device_t out_snd_device,
957 snd_device_t in_snd_device)
958{
959 struct platform_data *my_data = (struct platform_data *)platform;
960 int acdb_rx_id, acdb_tx_id;
961 int ret = 0;
962
963 if (my_data->csd == NULL)
964 return ret;
965
966 acdb_rx_id = acdb_device_table[out_snd_device];
967
968 acdb_tx_id = acdb_device_table[in_snd_device];
969
970 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
971 ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
972 if (ret < 0) {
973 ALOGE("%s: csd_enable_device_config, failed, error %d",
974 __func__, ret);
975 }
976 } else {
977 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
978 acdb_rx_id, acdb_tx_id);
979 }
980
981 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -0700982}
983
984int platform_switch_voice_call_device_post(void *platform,
985 snd_device_t out_snd_device,
986 snd_device_t in_snd_device)
987{
988 struct platform_data *my_data = (struct platform_data *)platform;
989 int acdb_rx_id, acdb_tx_id;
990
991 if (my_data->acdb_send_voice_cal == NULL) {
992 ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
993 } else {
994 acdb_rx_id = acdb_device_table[out_snd_device];
995 acdb_tx_id = acdb_device_table[in_snd_device];
996
997 if (acdb_rx_id > 0 && acdb_tx_id > 0)
998 my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
999 else
1000 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1001 acdb_rx_id, acdb_tx_id);
1002 }
1003
1004 return 0;
1005}
1006
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001007int platform_switch_voice_call_usecase_route_post(void *platform,
1008 snd_device_t out_snd_device,
1009 snd_device_t in_snd_device)
1010{
1011 struct platform_data *my_data = (struct platform_data *)platform;
1012 int acdb_rx_id, acdb_tx_id;
1013 int ret = 0;
1014
1015 if (my_data->csd == NULL)
1016 return ret;
1017
1018 acdb_rx_id = acdb_device_table[out_snd_device];
1019
1020 acdb_tx_id = acdb_device_table[in_snd_device];
1021
1022 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1023 ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
1024 my_data->adev->acdb_settings);
1025 if (ret < 0) {
1026 ALOGE("%s: csd_enable_device, failed, error %d", __func__, ret);
1027 }
1028 } else {
1029 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1030 acdb_rx_id, acdb_tx_id);
1031 }
1032
1033 return ret;
1034}
1035
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001036int platform_start_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001037{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001038 struct platform_data *my_data = (struct platform_data *)platform;
1039 int ret = 0;
1040
1041 if (my_data->csd != NULL) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001042 ret = my_data->csd->start_voice(vsid);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001043 if (ret < 0) {
1044 ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
1045 }
1046 }
1047 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001048}
1049
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001050int platform_stop_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001051{
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001052 struct platform_data *my_data = (struct platform_data *)platform;
1053 int ret = 0;
1054
1055 if (my_data->csd != NULL) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001056 ret = my_data->csd->stop_voice(vsid);
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001057 if (ret < 0) {
1058 ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
1059 }
1060 }
1061 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001062}
1063
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001064int platform_get_sample_rate(void *platform, uint32_t *rate)
1065{
1066 struct platform_data *my_data = (struct platform_data *)platform;
1067 int ret = 0;
1068
1069 if (my_data->csd != NULL) {
1070 ret = my_data->csd->get_sample_rate(rate);
1071 if (ret < 0) {
1072 ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret);
1073 }
1074 }
1075 return ret;
1076}
1077
Eric Laurentb23d5282013-05-14 15:27:20 -07001078int platform_set_voice_volume(void *platform, int volume)
1079{
1080 struct platform_data *my_data = (struct platform_data *)platform;
1081 struct audio_device *adev = my_data->adev;
1082 struct mixer_ctl *ctl;
sangwoo53b2cf02013-07-25 19:18:44 -07001083 const char *mixer_ctl_name = "Voice Rx Gain";
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001084 int vol_index = 0, ret = 0;
1085 uint32_t set_values[ ] = {0,
1086 ALL_SESSION_VSID,
1087 DEFAULT_VOLUME_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001088
1089 // Voice volume levels are mapped to adsp volume levels as follows.
1090 // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0
1091 // But this values don't changed in kernel. So, below change is need.
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001092 vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
1093 set_values[0] = vol_index;
Eric Laurentb23d5282013-05-14 15:27:20 -07001094
1095 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1096 if (!ctl) {
1097 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1098 __func__, mixer_ctl_name);
1099 return -EINVAL;
1100 }
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001101 ALOGV("Setting voice volume index: %d", set_values[0]);
1102 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1103
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001104 if (my_data->csd != NULL) {
1105 ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
1106 DEFAULT_VOLUME_RAMP_DURATION_MS);
1107 if (ret < 0) {
1108 ALOGE("%s: csd_volume error %d", __func__, ret);
1109 }
1110 }
1111 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001112}
1113
1114int platform_set_mic_mute(void *platform, bool state)
1115{
1116 struct platform_data *my_data = (struct platform_data *)platform;
1117 struct audio_device *adev = my_data->adev;
1118 struct mixer_ctl *ctl;
1119 const char *mixer_ctl_name = "Voice Tx Mute";
sangwoo53b2cf02013-07-25 19:18:44 -07001120 int ret = 0;
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001121 uint32_t set_values[ ] = {0,
1122 ALL_SESSION_VSID,
1123 DEFAULT_MUTE_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001124
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001125 if (adev->mode != AUDIO_MODE_IN_CALL)
1126 return 0;
1127
1128 set_values[0] = state;
1129 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1130 if (!ctl) {
1131 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1132 __func__, mixer_ctl_name);
1133 return -EINVAL;
1134 }
1135 ALOGV("Setting voice mute state: %d", state);
1136 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1137
1138 if (my_data->csd != NULL) {
1139 ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state,
1140 DEFAULT_MUTE_RAMP_DURATION_MS);
sangwoo53b2cf02013-07-25 19:18:44 -07001141 if (ret < 0) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001142 ALOGE("%s: csd_mic_mute error %d", __func__, ret);
sangwoo53b2cf02013-07-25 19:18:44 -07001143 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001144 }
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001145 return ret;
1146}
Eric Laurentb23d5282013-05-14 15:27:20 -07001147
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001148int platform_set_device_mute(void *platform, bool state, char *dir)
1149{
1150 struct platform_data *my_data = (struct platform_data *)platform;
1151 struct audio_device *adev = my_data->adev;
1152 struct mixer_ctl *ctl;
1153 char *mixer_ctl_name = NULL;
1154 int ret = 0;
1155 uint32_t set_values[ ] = {0,
1156 ALL_SESSION_VSID,
1157 0};
1158 if(dir == NULL) {
1159 ALOGE("%s: Invalid direction:%s", __func__, dir);
1160 return -EINVAL;
1161 }
1162
1163 if (!strncmp("rx", dir, sizeof("rx"))) {
1164 mixer_ctl_name = "Voice Rx Device Mute";
1165 } else if (!strncmp("tx", dir, sizeof("tx"))) {
1166 mixer_ctl_name = "Voice Tx Device Mute";
1167 } else {
1168 return -EINVAL;
1169 }
1170
1171 set_values[0] = state;
1172 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1173 if (!ctl) {
1174 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1175 __func__, mixer_ctl_name);
1176 return -EINVAL;
1177 }
1178
1179 ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
1180 __func__,state, mixer_ctl_name);
1181 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1182
1183 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001184}
1185
1186snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
1187{
1188 struct platform_data *my_data = (struct platform_data *)platform;
1189 struct audio_device *adev = my_data->adev;
1190 audio_mode_t mode = adev->mode;
1191 snd_device_t snd_device = SND_DEVICE_NONE;
1192
1193 ALOGV("%s: enter: output devices(%#x)", __func__, devices);
1194 if (devices == AUDIO_DEVICE_NONE ||
1195 devices & AUDIO_DEVICE_BIT_IN) {
1196 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
1197 goto exit;
1198 }
1199
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001200 if (voice_is_in_call(adev) || adev->enable_voicerx) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001201 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001202 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1203 devices & AUDIO_DEVICE_OUT_LINE) {
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001204 if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001205 (adev->voice.tty_mode == TTY_MODE_FULL))
Eric Laurentb23d5282013-05-14 15:27:20 -07001206 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001207 else if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001208 (adev->voice.tty_mode == TTY_MODE_VCO))
Eric Laurentb23d5282013-05-14 15:27:20 -07001209 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001210 else if (voice_is_in_call(adev) &&
Eric Laurentcefbbac2014-09-04 13:54:10 -05001211 (adev->voice.tty_mode == TTY_MODE_HCO))
Eric Laurentb23d5282013-05-14 15:27:20 -07001212 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001213 else {
1214 if (devices & AUDIO_DEVICE_OUT_LINE)
1215 snd_device = SND_DEVICE_OUT_VOICE_LINE;
1216 else
1217 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
1218 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001219 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001220 if (adev->bt_wb_speech_enabled) {
1221 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1222 } else {
1223 snd_device = SND_DEVICE_OUT_BT_SCO;
1224 }
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001225 } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001226 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
1227 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurent9d0d3f12014-07-25 12:40:29 -05001228 if(adev->voice.hac)
1229 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1230 else if (is_operator_tmus())
Eric Laurentb23d5282013-05-14 15:27:20 -07001231 snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
1232 else
Eric Laurentb4d368e2014-06-25 10:21:54 -05001233 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -07001234 } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1235 snd_device = SND_DEVICE_OUT_VOICE_TX;
1236
Eric Laurentb23d5282013-05-14 15:27:20 -07001237 if (snd_device != SND_DEVICE_NONE) {
1238 goto exit;
1239 }
1240 }
1241
1242 if (popcount(devices) == 2) {
1243 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1244 AUDIO_DEVICE_OUT_SPEAKER)) {
1245 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1246 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1247 AUDIO_DEVICE_OUT_SPEAKER)) {
1248 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
Eric Laurent744996b2014-10-01 11:40:40 -05001249 } else if (devices == (AUDIO_DEVICE_OUT_LINE |
1250 AUDIO_DEVICE_OUT_SPEAKER)) {
1251 snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001252 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
1253 AUDIO_DEVICE_OUT_SPEAKER)) {
1254 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
1255 } else {
1256 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
1257 goto exit;
1258 }
1259 if (snd_device != SND_DEVICE_NONE) {
1260 goto exit;
1261 }
1262 }
1263
1264 if (popcount(devices) != 1) {
1265 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
1266 goto exit;
1267 }
1268
1269 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1270 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1271 snd_device = SND_DEVICE_OUT_HEADPHONES;
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001272 } else if (devices & AUDIO_DEVICE_OUT_LINE) {
1273 snd_device = SND_DEVICE_OUT_LINE;
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001274 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
1275 snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001276 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
1277 if (adev->speaker_lr_swap)
1278 snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
1279 else
1280 snd_device = SND_DEVICE_OUT_SPEAKER;
1281 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001282 if (adev->bt_wb_speech_enabled) {
1283 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1284 } else {
1285 snd_device = SND_DEVICE_OUT_BT_SCO;
1286 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001287 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1288 snd_device = SND_DEVICE_OUT_HDMI ;
1289 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurent9d0d3f12014-07-25 12:40:29 -05001290 /*HAC support for voice-ish audio (eg visual voicemail)*/
1291 if(adev->voice.hac)
1292 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1293 else
1294 snd_device = SND_DEVICE_OUT_HANDSET;
Eric Laurentb23d5282013-05-14 15:27:20 -07001295 } else {
1296 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
1297 }
1298exit:
1299 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
1300 return snd_device;
1301}
1302
1303snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
1304{
1305 struct platform_data *my_data = (struct platform_data *)platform;
1306 struct audio_device *adev = my_data->adev;
1307 audio_source_t source = (adev->active_input == NULL) ?
1308 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
1309
1310 audio_mode_t mode = adev->mode;
1311 audio_devices_t in_device = ((adev->active_input == NULL) ?
1312 AUDIO_DEVICE_NONE : adev->active_input->device)
1313 & ~AUDIO_DEVICE_BIT_IN;
1314 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1315 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1316 snd_device_t snd_device = SND_DEVICE_NONE;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001317 int channel_count = popcount(channel_mask);
Eric Laurentb23d5282013-05-14 15:27:20 -07001318
1319 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
1320 __func__, out_device, in_device);
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -07001321 if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001322 if (adev->voice.tty_mode != TTY_MODE_OFF) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001323 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001324 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1325 out_device & AUDIO_DEVICE_OUT_LINE) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001326 switch (adev->voice.tty_mode) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001327 case TTY_MODE_FULL:
1328 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
1329 break;
1330 case TTY_MODE_VCO:
1331 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
1332 break;
1333 case TTY_MODE_HCO:
1334 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
1335 break;
1336 default:
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001337 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
Eric Laurentb23d5282013-05-14 15:27:20 -07001338 }
1339 goto exit;
1340 }
1341 }
Eric Laurentb991fb02014-08-29 15:23:17 -05001342 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001343 if (my_data->fluence_in_voice_call == false) {
1344 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1345 } else {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001346 if (is_operator_tmus())
1347 snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001348 else
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001349 snd_device = SND_DEVICE_IN_VOICE_DMIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001350 }
1351 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1352 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
1353 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001354 if (adev->bt_wb_speech_enabled) {
1355 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1356 } else {
1357 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1358 }
Eric Laurentb991fb02014-08-29 15:23:17 -05001359 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001360 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
Eric Laurentb991fb02014-08-29 15:23:17 -05001361 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1362 out_device & AUDIO_DEVICE_OUT_LINE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001363 if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001364 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1365 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001366 } else {
1367 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
1368 }
Ravi Kumar Alamanda99c752d2014-08-20 17:55:26 -07001369 } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1370 snd_device = SND_DEVICE_IN_VOICE_RX;
Eric Laurentb23d5282013-05-14 15:27:20 -07001371 } else if (source == AUDIO_SOURCE_CAMCORDER) {
1372 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
1373 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1374 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
1375 }
1376 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1377 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001378 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001379 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001380 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
1381 else if (my_data->fluence_in_voice_rec &&
1382 adev->active_input->enable_ns)
1383 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001384 }
1385
1386 if (snd_device == SND_DEVICE_NONE) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001387 if (adev->active_input->enable_ns)
1388 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
1389 else
1390 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001391 }
1392 }
1393 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001394 if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE))
Eric Laurentb23d5282013-05-14 15:27:20 -07001395 in_device = AUDIO_DEVICE_IN_BACK_MIC;
1396 if (adev->active_input) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001397 if (adev->active_input->enable_aec &&
1398 adev->active_input->enable_ns) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001399 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001400 if (my_data->fluence_in_spkr_mode &&
1401 my_data->fluence_in_voice_comm &&
1402 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1403 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
1404 } else
1405 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001406 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001407 if (my_data->fluence_in_voice_comm &&
1408 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1409 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
1410 } else
1411 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
Eric Laurentcefbbac2014-09-04 13:54:10 -05001412 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1413 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001414 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05001415 platform_set_echo_reference(adev, true, out_device);
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001416 } else if (adev->active_input->enable_aec) {
1417 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1418 if (my_data->fluence_in_spkr_mode &&
1419 my_data->fluence_in_voice_comm &&
1420 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1421 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
1422 } else
1423 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
1424 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1425 if (my_data->fluence_in_voice_comm &&
1426 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1427 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
1428 } else
1429 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
Eric Laurentcefbbac2014-09-04 13:54:10 -05001430 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1431 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
1432 }
Ravi Kumar Alamandaf2829012014-11-12 16:16:10 -08001433 platform_set_echo_reference(adev, true, out_device);
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001434 } else if (adev->active_input->enable_ns) {
1435 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1436 if (my_data->fluence_in_spkr_mode &&
1437 my_data->fluence_in_voice_comm &&
1438 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1439 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
1440 } else
1441 snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
1442 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1443 if (my_data->fluence_in_voice_comm &&
1444 my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
1445 snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
1446 } else
1447 snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
1448 }
Eric Laurentcefbbac2014-09-04 13:54:10 -05001449 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001450 }
1451 } else if (source == AUDIO_SOURCE_DEFAULT) {
1452 goto exit;
1453 }
1454
1455
1456 if (snd_device != SND_DEVICE_NONE) {
1457 goto exit;
1458 }
1459
1460 if (in_device != AUDIO_DEVICE_NONE &&
1461 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
1462 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
1463 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001464 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
1465 channel_count == 2)
1466 snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
1467 else
1468 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001469 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001470 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
1471 channel_count == 2)
1472 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
1473 else
1474 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001475 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1476 snd_device = SND_DEVICE_IN_HEADSET_MIC;
1477 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001478 if (adev->bt_wb_speech_enabled) {
1479 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1480 } else {
1481 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1482 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001483 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
1484 snd_device = SND_DEVICE_IN_HDMI_MIC;
1485 } else {
1486 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
1487 ALOGW("%s: Using default handset-mic", __func__);
1488 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1489 }
1490 } else {
1491 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
1492 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1493 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1494 snd_device = SND_DEVICE_IN_HEADSET_MIC;
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001495 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
Eric Laurent1b0d8ce2014-09-11 09:59:28 -07001496 out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001497 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
Eric Laurent09f2e0e2014-07-29 16:02:32 -05001498 out_device & AUDIO_DEVICE_OUT_LINE) {
Ravi Kumar Alamanda3ad4e1b2014-06-03 00:08:15 -07001499 if (channel_count == 2)
1500 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
1501 else
1502 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001503 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -07001504 if (adev->bt_wb_speech_enabled) {
1505 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1506 } else {
1507 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1508 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001509 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1510 snd_device = SND_DEVICE_IN_HDMI_MIC;
1511 } else {
1512 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
1513 ALOGW("%s: Using default handset-mic", __func__);
1514 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1515 }
1516 }
1517exit:
1518 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
1519 return snd_device;
1520}
1521
1522int platform_set_hdmi_channels(void *platform, int channel_count)
1523{
1524 struct platform_data *my_data = (struct platform_data *)platform;
1525 struct audio_device *adev = my_data->adev;
1526 struct mixer_ctl *ctl;
1527 const char *channel_cnt_str = NULL;
1528 const char *mixer_ctl_name = "HDMI_RX Channels";
1529 switch (channel_count) {
1530 case 8:
1531 channel_cnt_str = "Eight"; break;
1532 case 7:
1533 channel_cnt_str = "Seven"; break;
1534 case 6:
1535 channel_cnt_str = "Six"; break;
1536 case 5:
1537 channel_cnt_str = "Five"; break;
1538 case 4:
1539 channel_cnt_str = "Four"; break;
1540 case 3:
1541 channel_cnt_str = "Three"; break;
1542 default:
1543 channel_cnt_str = "Two"; break;
1544 }
1545 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1546 if (!ctl) {
1547 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1548 __func__, mixer_ctl_name);
1549 return -EINVAL;
1550 }
1551 ALOGV("HDMI channel count: %s", channel_cnt_str);
1552 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
1553 return 0;
1554}
1555
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001556int platform_edid_get_max_channels(void *platform)
Eric Laurentb23d5282013-05-14 15:27:20 -07001557{
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001558 struct platform_data *my_data = (struct platform_data *)platform;
1559 struct audio_device *adev = my_data->adev;
Eric Laurentb23d5282013-05-14 15:27:20 -07001560 char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
1561 char *sad = block;
1562 int num_audio_blocks;
1563 int channel_count;
1564 int max_channels = 0;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001565 int i, ret, count;
Eric Laurentb23d5282013-05-14 15:27:20 -07001566
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001567 struct mixer_ctl *ctl;
1568
1569 ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
1570 if (!ctl) {
1571 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1572 __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
Eric Laurentb23d5282013-05-14 15:27:20 -07001573 return 0;
1574 }
1575
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001576 mixer_ctl_update(ctl);
1577
1578 count = mixer_ctl_get_num_values(ctl);
Eric Laurentb23d5282013-05-14 15:27:20 -07001579
1580 /* Read SAD blocks, clamping the maximum size for safety */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001581 if (count > (int)sizeof(block))
1582 count = (int)sizeof(block);
Eric Laurentb23d5282013-05-14 15:27:20 -07001583
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001584 ret = mixer_ctl_get_array(ctl, block, count);
1585 if (ret != 0) {
1586 ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
1587 return 0;
1588 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001589
1590 /* Calculate the number of SAD blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001591 num_audio_blocks = count / SAD_BLOCK_SIZE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001592
1593 for (i = 0; i < num_audio_blocks; i++) {
1594 /* Only consider LPCM blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001595 if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
1596 sad += 3;
Eric Laurentb23d5282013-05-14 15:27:20 -07001597 continue;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001598 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001599
1600 channel_count = (sad[0] & 0x7) + 1;
1601 if (channel_count > max_channels)
1602 max_channels = channel_count;
1603
1604 /* Advance to next block */
1605 sad += 3;
1606 }
1607
1608 return max_channels;
1609}
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07001610
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07001611int platform_set_incall_recording_session_id(void *platform,
1612 uint32_t session_id, int rec_mode)
1613{
1614 int ret = 0;
1615 struct platform_data *my_data = (struct platform_data *)platform;
1616 struct audio_device *adev = my_data->adev;
1617 struct mixer_ctl *ctl;
1618 const char *mixer_ctl_name = "Voc VSID";
1619 int num_ctl_values;
1620 int i;
1621
1622 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1623 if (!ctl) {
1624 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1625 __func__, mixer_ctl_name);
1626 ret = -EINVAL;
1627 } else {
1628 num_ctl_values = mixer_ctl_get_num_values(ctl);
1629 for (i = 0; i < num_ctl_values; i++) {
1630 if (mixer_ctl_set_value(ctl, i, session_id)) {
1631 ALOGV("Error: invalid session_id: %x", session_id);
1632 ret = -EINVAL;
1633 break;
1634 }
1635 }
1636 }
1637
1638 if (my_data->csd != NULL) {
1639 ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
1640 if (ret < 0) {
1641 ALOGE("%s: csd_client_start_record failed, error %d",
1642 __func__, ret);
1643 }
1644 }
1645
1646 return ret;
1647}
1648
1649int platform_stop_incall_recording_usecase(void *platform)
1650{
1651 int ret = 0;
1652 struct platform_data *my_data = (struct platform_data *)platform;
1653
1654 if (my_data->csd != NULL) {
1655 ret = my_data->csd->stop_record(ALL_SESSION_VSID);
1656 if (ret < 0) {
1657 ALOGE("%s: csd_client_stop_record failed, error %d",
1658 __func__, ret);
1659 }
1660 }
1661
1662 return ret;
1663}
1664
1665int platform_start_incall_music_usecase(void *platform)
1666{
1667 int ret = 0;
1668 struct platform_data *my_data = (struct platform_data *)platform;
1669
1670 if (my_data->csd != NULL) {
1671 ret = my_data->csd->start_playback(ALL_SESSION_VSID);
1672 if (ret < 0) {
1673 ALOGE("%s: csd_client_start_playback failed, error %d",
1674 __func__, ret);
1675 }
1676 }
1677
1678 return ret;
1679}
1680
1681int platform_stop_incall_music_usecase(void *platform)
1682{
1683 int ret = 0;
1684 struct platform_data *my_data = (struct platform_data *)platform;
1685
1686 if (my_data->csd != NULL) {
1687 ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
1688 if (ret < 0) {
1689 ALOGE("%s: csd_client_stop_playback failed, error %d",
1690 __func__, ret);
1691 }
1692 }
1693
1694 return ret;
1695}
1696
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07001697/* Delay in Us */
1698int64_t platform_render_latency(audio_usecase_t usecase)
1699{
1700 switch (usecase) {
1701 case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
1702 return DEEP_BUFFER_PLATFORM_DELAY;
1703 case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
1704 return LOW_LATENCY_PLATFORM_DELAY;
1705 default:
1706 return 0;
1707 }
1708}
Haynes Mathew George98c95622014-06-20 19:14:25 -07001709
1710int platform_set_snd_device_backend(snd_device_t device, const char *backend)
1711{
1712 int ret = 0;
1713
1714 if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
1715 ALOGE("%s: Invalid snd_device = %d",
1716 __func__, device);
1717 ret = -EINVAL;
1718 goto done;
1719 }
1720
1721 if (backend_table[device]) {
1722 free(backend_table[device]);
1723 }
1724 backend_table[device] = strdup(backend);
1725done:
1726 return ret;
1727}
1728
1729int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
1730{
1731 int ret = 0;
1732 if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
1733 ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
1734 ret = -EINVAL;
1735 goto done;
1736 }
1737
1738 if ((type != 0) && (type != 1)) {
1739 ALOGE("%s: invalid usecase type", __func__);
1740 ret = -EINVAL;
1741 }
1742 pcm_device_table[usecase][type] = pcm_id;
1743done:
1744 return ret;
1745}