1/*
2 * Copyright (C) 2013-2016 The Android Open Source Project
3 *
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#define LOG_TAG "msm8974_platform"
17/*#define LOG_NDEBUG 0*/
18#define LOG_NDDEBUG 0
19
20#include <stdlib.h>
21#include <dlfcn.h>
22#include <cutils/log.h>
23#include <cutils/str_parms.h>
24#include <cutils/properties.h>
25#include <audio_hw.h>
26#include <platform_api.h>
27#include "platform.h"
28#include "audio_extn.h"
29#include <linux/msm_audio.h>
30
31#define MIXER_XML_DEFAULT_PATH "/system/etc/mixer_paths.xml"
32#define MIXER_XML_BASE_STRING "/system/etc/mixer_paths"
33#define TOMTOM_8226_SND_CARD_NAME "msm8226-tomtom-snd-card"
34#define TOMTOM_MIXER_FILE_SUFFIX "wcd9330"
35
36#define LIB_ACDB_LOADER "libacdbloader.so"
37#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
38#define CVD_VERSION_MIXER_CTL "CVD Version"
39
40#define min(a, b) ((a) < (b) ? (a) : (b))
41
42/*
43 * This file will have a maximum of 38 bytes:
44 *
45 * 4 bytes: number of audio blocks
46 * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
47 * Maximum 10 * 3 bytes: SAD blocks
48 */
49#define MAX_SAD_BLOCKS      10
50#define SAD_BLOCK_SIZE      3
51
52#define MAX_CVD_VERSION_STRING_SIZE    100
53
54/* EDID format ID for LPCM audio */
55#define EDID_FORMAT_LPCM    1
56
57/* Retry for delay in FW loading*/
58#define RETRY_NUMBER 10
59#define RETRY_US 500000
60#define MAX_SND_CARD 8
61
62#define MAX_SND_CARD_NAME_LEN 31
63
64#define DEFAULT_APP_TYPE_RX_PATH  0x11130
65
66#define TOSTRING_(x) #x
67#define TOSTRING(x) TOSTRING_(x)
68
69struct audio_block_header
70{
71    int reserved;
72    int length;
73};
74
75enum {
76    CAL_MODE_SEND           = 0x1,
77    CAL_MODE_PERSIST        = 0x2,
78    CAL_MODE_RTAC           = 0x4
79};
80
81#define PLATFORM_CONFIG_KEY_OPERATOR_INFO "operator_info"
82
83struct operator_info {
84    struct listnode list;
85    char *name;
86    char *mccmnc;
87};
88
89struct operator_specific_device {
90    struct listnode list;
91    char *operator;
92    char *mixer_path;
93    int acdb_id;
94};
95
96static struct listnode operator_info_list;
97static struct listnode *operator_specific_device_table[SND_DEVICE_MAX];
98
99/* Audio calibration related functions */
100typedef void (*acdb_deallocate_t)();
101typedef int  (*acdb_init_v2_cvd_t)(char *, char *, int);
102typedef int  (*acdb_init_v2_t)(char *);
103typedef int  (*acdb_init_t)();
104typedef void (*acdb_send_audio_cal_t)(int, int);
105typedef void (*acdb_send_voice_cal_t)(int, int);
106typedef int (*acdb_reload_vocvoltable_t)(int);
107typedef int (*acdb_send_gain_dep_cal_t)(int, int, int, int, int);
108
109/* Audio calibration related functions */
110struct platform_data {
111    struct audio_device *adev;
112    bool fluence_in_spkr_mode;
113    bool fluence_in_voice_call;
114    bool fluence_in_voice_comm;
115    bool fluence_in_voice_rec;
116    /* 0 = no fluence, 1 = fluence, 2 = fluence pro */
117    int  fluence_type;
118    int  source_mic_type;
119    bool speaker_lr_swap;
120
121    void *acdb_handle;
122    acdb_deallocate_t          acdb_deallocate;
123    acdb_send_audio_cal_t      acdb_send_audio_cal;
124    acdb_send_voice_cal_t      acdb_send_voice_cal;
125    acdb_reload_vocvoltable_t  acdb_reload_vocvoltable;
126    acdb_send_gain_dep_cal_t   acdb_send_gain_dep_cal;
127    struct csd_data *csd;
128    char ec_ref_mixer_path[64];
129
130    char *snd_card_name;
131    int max_vol_index;
132    int max_mic_count;
133
134    void *hw_info;
135};
136
137static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
138    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
139                                            DEEP_BUFFER_PCM_DEVICE},
140    [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
141                                            LOWLATENCY_PCM_DEVICE},
142    [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
143                                         MULTIMEDIA2_PCM_DEVICE},
144    [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {PLAYBACK_OFFLOAD_DEVICE,
145                                        PLAYBACK_OFFLOAD_DEVICE},
146    [USECASE_AUDIO_PLAYBACK_TTS] = {MULTIMEDIA2_PCM_DEVICE,
147                                        MULTIMEDIA2_PCM_DEVICE},
148    [USECASE_AUDIO_PLAYBACK_ULL] = {MULTIMEDIA3_PCM_DEVICE,
149                                    MULTIMEDIA3_PCM_DEVICE},
150
151    [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE,
152                              AUDIO_RECORD_PCM_DEVICE},
153    [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
154                                          LOWLATENCY_PCM_DEVICE},
155
156    [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE,
157                            VOICE_CALL_PCM_DEVICE},
158    [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
159    [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
160    [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
161    [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
162    [USECASE_VOICEMMODE1_CALL] = {VOICEMMODE1_CALL_PCM_DEVICE,
163                                  VOICEMMODE1_CALL_PCM_DEVICE},
164    [USECASE_VOICEMMODE2_CALL] = {VOICEMMODE2_CALL_PCM_DEVICE,
165                                  VOICEMMODE2_CALL_PCM_DEVICE},
166
167    [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
168                                   AUDIO_RECORD_PCM_DEVICE},
169    [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
170                                     AUDIO_RECORD_PCM_DEVICE},
171    [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
172                                                AUDIO_RECORD_PCM_DEVICE},
173    [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
174
175    [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
176    [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
177
178    [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
179                                          AFE_PROXY_RECORD_PCM_DEVICE},
180    [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
181                                        AFE_PROXY_RECORD_PCM_DEVICE},
182    [USECASE_AUDIO_DSM_FEEDBACK] = {QUAT_MI2S_PCM_DEVICE, QUAT_MI2S_PCM_DEVICE},
183
184};
185
186/* Array to store sound devices */
187static const char * const device_table[SND_DEVICE_MAX] = {
188    [SND_DEVICE_NONE] = "none",
189    /* Playback sound devices */
190    [SND_DEVICE_OUT_HANDSET] = "handset",
191    [SND_DEVICE_OUT_SPEAKER] = "speaker",
192    [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
193    [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
194    [SND_DEVICE_OUT_HEADPHONES] = "headphones",
195    [SND_DEVICE_OUT_LINE] = "line",
196    [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
197    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = "speaker-safe-and-headphones",
198    [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
199    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = "speaker-safe-and-line",
200    [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
201    [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
202    [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
203    [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
204    [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
205    [SND_DEVICE_OUT_HDMI] = "hdmi",
206    [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
207    [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
208    [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
209    [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
210    [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
211    [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
212    [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
213    [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
214    [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
215    [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
216    [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = "voice-speaker-hfp",
217
218    /* Capture sound devices */
219    [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
220    [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
221    [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
222    [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
223    [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
224    [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
225    [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
226    [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
227    [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = "dmic-endfire",
228
229    [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
230    [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
231    [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
232    [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
233    [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
234    [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
235    [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
236    [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
237    [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = "speaker-dmic-endfire",
238
239    [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
240    [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
241
242    [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
243    [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
244    [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
245    [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
246    [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
247    [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
248
249    [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
250    [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
251    [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
252    [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
253    [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = "voice-speaker-mic-hfp",
254    [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
255    [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
256    [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
257    [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
258
259    [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
260    [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
261    [SND_DEVICE_IN_VOICE_REC_MIC_AEC] = "voice-rec-mic",
262    [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
263    [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
264    [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "headset-mic",
265
266    [SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
267    [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = "unprocessed-stereo-mic",
268    [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "unprocessed-three-mic",
269    [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = "unprocessed-quad-mic",
270    [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = "unprocessed-headset-mic",
271
272    [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
273
274    [SND_DEVICE_IN_THREE_MIC] = "three-mic",
275    [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
276    [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
277    [SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
278    [SND_DEVICE_IN_HANDSET_QMIC] = "quad-mic",
279    [SND_DEVICE_IN_HANDSET_TMIC_AEC] = "three-mic",
280    [SND_DEVICE_IN_HANDSET_QMIC_AEC] = "quad-mic",
281};
282
283/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
284static int acdb_device_table[SND_DEVICE_MAX] = {
285    [SND_DEVICE_NONE] = -1,
286    [SND_DEVICE_OUT_HANDSET] = 7,
287    [SND_DEVICE_OUT_SPEAKER] = 15,
288    [SND_DEVICE_OUT_SPEAKER_REVERSE] = 15,
289    [SND_DEVICE_OUT_SPEAKER_SAFE] = 15,
290    [SND_DEVICE_OUT_HEADPHONES] = 10,
291    [SND_DEVICE_OUT_LINE] = 77,
292    [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
293    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = 10,
294    [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 77,
295    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = 77,
296    [SND_DEVICE_OUT_VOICE_HANDSET] = ACDB_ID_VOICE_HANDSET,
297    [SND_DEVICE_OUT_VOICE_SPEAKER] = ACDB_ID_VOICE_SPEAKER,
298    [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
299    [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
300    [SND_DEVICE_OUT_VOICE_LINE] = 77,
301    [SND_DEVICE_OUT_HDMI] = 18,
302    [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 15,
303    [SND_DEVICE_OUT_BT_SCO] = 22,
304    [SND_DEVICE_OUT_BT_SCO_WB] = 39,
305    [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = ACDB_ID_VOICE_HANDSET_TMUS,
306    [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
307    [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
308    [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
309    [SND_DEVICE_OUT_VOICE_TX] = 45,
310    [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
311    [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
312    [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = ACDB_ID_VOICE_SPEAKER,
313
314    [SND_DEVICE_IN_HANDSET_MIC] = 4,
315    [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
316    [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
317    [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
318    [SND_DEVICE_IN_HANDSET_DMIC] = 41,
319    [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
320    [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
321    [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
322    [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = 34,
323
324    [SND_DEVICE_IN_SPEAKER_MIC] = 11,
325    [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
326    [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
327    [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
328    [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
329    [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
330    [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
331    [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
332    [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = 35,
333
334    [SND_DEVICE_IN_HEADSET_MIC] = ACDB_ID_HEADSET_MIC_AEC,
335    [SND_DEVICE_IN_HEADSET_MIC_AEC] = ACDB_ID_HEADSET_MIC_AEC,
336
337    [SND_DEVICE_IN_HDMI_MIC] = 4,
338    [SND_DEVICE_IN_BT_SCO_MIC] = 21,
339    [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 21,
340    [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
341    [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 38,
342    [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
343
344    [SND_DEVICE_IN_VOICE_DMIC] = 41,
345    [SND_DEVICE_IN_VOICE_DMIC_TMUS] = ACDB_ID_VOICE_DMIC_EF_TMUS,
346    [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
347    [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = 11,
348    [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
349    [SND_DEVICE_IN_VOICE_HEADSET_MIC] = ACDB_ID_HEADSET_MIC_AEC,
350    [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
351    [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
352    [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
353
354    [SND_DEVICE_IN_VOICE_REC_MIC] = ACDB_ID_VOICE_REC_MIC,
355    [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 113,
356    [SND_DEVICE_IN_VOICE_REC_MIC_AEC] = 112,
357    [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 35,
358    [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 43,
359    [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = ACDB_ID_HEADSET_MIC_AEC,
360
361    [SND_DEVICE_IN_UNPROCESSED_MIC] = ACDB_ID_VOICE_REC_MIC,
362    [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = ACDB_ID_HEADSET_MIC_AEC,
363    [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = 35,
364    [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = 125,
365    [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = 125,
366
367    [SND_DEVICE_IN_VOICE_RX] = 44,
368
369    [SND_DEVICE_IN_THREE_MIC] = 46,
370    [SND_DEVICE_IN_QUAD_MIC] = 46,
371    [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
372    [SND_DEVICE_IN_HANDSET_TMIC] = 125,
373    [SND_DEVICE_IN_HANDSET_QMIC] = 125,
374    [SND_DEVICE_IN_HANDSET_TMIC_AEC] = 125, /* override this for new target to 140 */
375    [SND_DEVICE_IN_HANDSET_QMIC_AEC] = 125, /* override this for new target to 140 */
376};
377
378struct name_to_index {
379    char name[100];
380    unsigned int index;
381};
382
383#define TO_NAME_INDEX(X)   #X, X
384
385/* Used to get index from parsed string */
386static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
387    /* out */
388    {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
389    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
390    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
391    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
392    {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
393    {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
394    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
395    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES)},
396    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
397    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE)},
398    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
399    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
400    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_HFP)},
401    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
402    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
403    {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
404    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
405    {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
406    {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
407    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET_TMUS)},
408    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
409    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
410    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
411    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
412
413    /* in */
414    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
415    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
416    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
417    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
418    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
419    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
420    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
421    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
422    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
423    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
424    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_STEREO)},
425
426    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
427    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
428    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
429    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
430    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
431    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
432    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
433    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
434    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
435
436    {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
437    {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_AEC)},
438
439    {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
440    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
441    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
442    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
443    {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
444    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
445
446    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
447    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
448    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
449    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP)},
450    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
451    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
452    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
453    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
454    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
455
456    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
457    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
458    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_AEC)},
459    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
460    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
461    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_HEADSET_MIC)},
462
463    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_MIC)},
464    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC)},
465    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_STEREO_MIC)},
466    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_THREE_MIC)},
467    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_QUAD_MIC)},
468
469    {TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
470    {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
471    {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
472    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
473    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
474    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC_AEC)},
475    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC_AEC)},
476};
477
478static char * backend_tag_table[SND_DEVICE_MAX] = {0};
479static char * hw_interface_table[SND_DEVICE_MAX] = {0};
480
481static const struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
482    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
483    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
484    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
485    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
486    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_TTS)},
487    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
488    {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
489    {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
490    {TO_NAME_INDEX(USECASE_VOICE_CALL)},
491    {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
492    {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
493    {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
494    {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
495    {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK)},
496    {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
497    {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
498    {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
499};
500
501#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
502#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
503
504static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
505static bool is_tmus = false;
506
507static void check_operator()
508{
509    char value[PROPERTY_VALUE_MAX];
510    int mccmnc;
511    property_get("gsm.sim.operator.numeric",value,"0");
512    mccmnc = atoi(value);
513    ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
514    switch(mccmnc) {
515    /* TMUS MCC(310), MNC(490, 260, 026) */
516    case 310490:
517    case 310260:
518    case 310026:
519    /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
520    case 310800:
521    case 310660:
522    case 310580:
523    case 310310:
524    case 310270:
525    case 310250:
526    case 310240:
527    case 310230:
528    case 310220:
529    case 310210:
530    case 310200:
531    case 310160:
532        is_tmus = true;
533        break;
534    }
535}
536
537bool is_operator_tmus()
538{
539    pthread_once(&check_op_once_ctl, check_operator);
540    return is_tmus;
541}
542
543static char *get_current_operator()
544{
545    struct listnode *node;
546    struct operator_info *info_item;
547    char mccmnc[PROPERTY_VALUE_MAX];
548    char *ret = NULL;
549
550    property_get("gsm.sim.operator.numeric",mccmnc,"0");
551
552    list_for_each(node, &operator_info_list) {
553        info_item = node_to_item(node, struct operator_info, list);
554        if (strstr(info_item->mccmnc, mccmnc) != NULL) {
555            ret = info_item->name;
556        }
557    }
558
559    return ret;
560}
561
562static struct operator_specific_device *get_operator_specific_device(snd_device_t snd_device)
563{
564    struct listnode *node;
565    struct operator_specific_device *ret = NULL;
566    struct operator_specific_device *device_item;
567    char *operator_name;
568
569    operator_name = get_current_operator();
570    if (operator_name == NULL)
571        return ret;
572
573    list_for_each(node, operator_specific_device_table[snd_device]) {
574        device_item = node_to_item(node, struct operator_specific_device, list);
575        if (strcmp(operator_name, device_item->operator) == 0) {
576            ret = device_item;
577        }
578    }
579
580    return ret;
581}
582
583
584static int get_operator_specific_device_acdb_id(snd_device_t snd_device)
585{
586    struct operator_specific_device *device;
587    int ret = acdb_device_table[snd_device];
588
589    device = get_operator_specific_device(snd_device);
590    if (device != NULL)
591        ret = device->acdb_id;
592
593    return ret;
594}
595
596static const char *get_operator_specific_device_mixer_path(snd_device_t snd_device)
597{
598    struct operator_specific_device *device;
599    const char *ret = device_table[snd_device];
600
601    device = get_operator_specific_device(snd_device);
602    if (device != NULL)
603        ret = device->mixer_path;
604
605    return ret;
606}
607
608bool platform_send_gain_dep_cal(void *platform, int level)
609{
610    bool ret_val = false;
611    struct platform_data *my_data = (struct platform_data *)platform;
612    struct audio_device *adev = my_data->adev;
613    int acdb_dev_id, app_type;
614    int acdb_dev_type = MSM_SNDDEV_CAP_RX;
615    int mode = CAL_MODE_RTAC;
616    struct listnode *node;
617    struct audio_usecase *usecase;
618
619    if (my_data->acdb_send_gain_dep_cal == NULL) {
620        ALOGE("%s: dlsym error for acdb_send_gain_dep_cal", __func__);
621        return ret_val;
622    }
623
624    if (!voice_is_in_call(adev)) {
625        ALOGV("%s: Not Voice call usecase, apply new cal for level %d",
626               __func__, level);
627        app_type = DEFAULT_APP_TYPE_RX_PATH;
628
629        // find the current active sound device
630        list_for_each(node, &adev->usecase_list) {
631            usecase = node_to_item(node, struct audio_usecase, list);
632
633            if (usecase != NULL &&
634                usecase->type == PCM_PLAYBACK &&
635                (usecase->stream.out->devices == AUDIO_DEVICE_OUT_SPEAKER)) {
636
637                ALOGV("%s: out device is %d", __func__,  usecase->out_snd_device);
638                if (audio_extn_spkr_prot_is_enabled()) {
639                    acdb_dev_id = audio_extn_spkr_prot_get_acdb_id(usecase->out_snd_device);
640                } else {
641                    acdb_dev_id = acdb_device_table[usecase->out_snd_device];
642                }
643
644                if (!my_data->acdb_send_gain_dep_cal(acdb_dev_id, app_type,
645                                                     acdb_dev_type, mode, level)) {
646                    // set ret_val true if at least one calibration is set successfully
647                    ret_val = true;
648                } else {
649                    ALOGE("%s: my_data->acdb_send_gain_dep_cal failed ", __func__);
650                }
651            } else {
652                ALOGW("%s: Usecase list is empty", __func__);
653            }
654        }
655    } else {
656        ALOGW("%s: Voice call in progress .. ignore setting new cal",
657              __func__);
658    }
659    return ret_val;
660}
661
662void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
663{
664    struct platform_data *my_data = (struct platform_data *)adev->platform;
665    snd_device_t snd_device = SND_DEVICE_NONE;
666
667    if (strcmp(my_data->ec_ref_mixer_path, "")) {
668        ALOGV("%s: diabling %s", __func__, my_data->ec_ref_mixer_path);
669        audio_route_reset_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
670    }
671
672    if (enable) {
673        strcpy(my_data->ec_ref_mixer_path, "echo-reference");
674        if (out_device != AUDIO_DEVICE_NONE) {
675            snd_device = platform_get_output_snd_device(adev->platform, out_device);
676            platform_add_backend_name(adev->platform, my_data->ec_ref_mixer_path, snd_device);
677        }
678
679        ALOGV("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
680        audio_route_apply_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
681    }
682}
683
684static struct csd_data *open_csd_client(bool i2s_ext_modem)
685{
686    struct csd_data *csd = calloc(1, sizeof(struct csd_data));
687
688    csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
689    if (csd->csd_client == NULL) {
690        ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
691        goto error;
692    } else {
693        ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
694
695        csd->deinit = (deinit_t)dlsym(csd->csd_client,
696                                             "csd_client_deinit");
697        if (csd->deinit == NULL) {
698            ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
699                  dlerror());
700            goto error;
701        }
702        csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
703                                             "csd_client_disable_device");
704        if (csd->disable_device == NULL) {
705            ALOGE("%s: dlsym error %s for csd_client_disable_device",
706                  __func__, dlerror());
707            goto error;
708        }
709        csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
710                                               "csd_client_enable_device_config");
711        if (csd->enable_device_config == NULL) {
712            ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
713                  __func__, dlerror());
714            goto error;
715        }
716        csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
717                                             "csd_client_enable_device");
718        if (csd->enable_device == NULL) {
719            ALOGE("%s: dlsym error %s for csd_client_enable_device",
720                  __func__, dlerror());
721            goto error;
722        }
723        csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
724                                             "csd_client_start_voice");
725        if (csd->start_voice == NULL) {
726            ALOGE("%s: dlsym error %s for csd_client_start_voice",
727                  __func__, dlerror());
728            goto error;
729        }
730        csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
731                                             "csd_client_stop_voice");
732        if (csd->stop_voice == NULL) {
733            ALOGE("%s: dlsym error %s for csd_client_stop_voice",
734                  __func__, dlerror());
735            goto error;
736        }
737        csd->volume = (volume_t)dlsym(csd->csd_client,
738                                             "csd_client_volume");
739        if (csd->volume == NULL) {
740            ALOGE("%s: dlsym error %s for csd_client_volume",
741                  __func__, dlerror());
742            goto error;
743        }
744        csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
745                                             "csd_client_mic_mute");
746        if (csd->mic_mute == NULL) {
747            ALOGE("%s: dlsym error %s for csd_client_mic_mute",
748                  __func__, dlerror());
749            goto error;
750        }
751        csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
752                                             "csd_client_slow_talk");
753        if (csd->slow_talk == NULL) {
754            ALOGE("%s: dlsym error %s for csd_client_slow_talk",
755                  __func__, dlerror());
756            goto error;
757        }
758        csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
759                                             "csd_client_start_playback");
760        if (csd->start_playback == NULL) {
761            ALOGE("%s: dlsym error %s for csd_client_start_playback",
762                  __func__, dlerror());
763            goto error;
764        }
765        csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
766                                             "csd_client_stop_playback");
767        if (csd->stop_playback == NULL) {
768            ALOGE("%s: dlsym error %s for csd_client_stop_playback",
769                  __func__, dlerror());
770            goto error;
771        }
772        csd->start_record = (start_record_t)dlsym(csd->csd_client,
773                                             "csd_client_start_record");
774        if (csd->start_record == NULL) {
775            ALOGE("%s: dlsym error %s for csd_client_start_record",
776                  __func__, dlerror());
777            goto error;
778        }
779        csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
780                                             "csd_client_stop_record");
781        if (csd->stop_record == NULL) {
782            ALOGE("%s: dlsym error %s for csd_client_stop_record",
783                  __func__, dlerror());
784            goto error;
785        }
786
787        csd->get_sample_rate = (get_sample_rate_t)dlsym(csd->csd_client,
788                                             "csd_client_get_sample_rate");
789        if (csd->get_sample_rate == NULL) {
790            ALOGE("%s: dlsym error %s for csd_client_get_sample_rate",
791                  __func__, dlerror());
792
793            goto error;
794        }
795
796        csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
797
798        if (csd->init == NULL) {
799            ALOGE("%s: dlsym error %s for csd_client_init",
800                  __func__, dlerror());
801            goto error;
802        } else {
803            csd->init(i2s_ext_modem);
804        }
805    }
806    return csd;
807
808error:
809    free(csd);
810    csd = NULL;
811    return csd;
812}
813
814void close_csd_client(struct csd_data *csd)
815{
816    if (csd != NULL) {
817        csd->deinit();
818        dlclose(csd->csd_client);
819        free(csd);
820        csd = NULL;
821    }
822}
823
824static void platform_csd_init(struct platform_data *my_data)
825{
826#ifdef PLATFORM_MSM8084
827    int32_t modems, (*count_modems)(void);
828    const char *name = "libdetectmodem.so";
829    const char *func = "count_modems";
830    const char *error;
831
832    my_data->csd = NULL;
833
834    void *lib = dlopen(name, RTLD_NOW);
835    error = dlerror();
836    if (!lib) {
837        ALOGE("%s: could not find %s: %s", __func__, name, error);
838        return;
839    }
840
841    count_modems = NULL;
842    *(void **)(&count_modems) = dlsym(lib, func);
843    error = dlerror();
844    if (!count_modems) {
845        ALOGE("%s: could not find symbol %s in %s: %s",
846              __func__, func, name, error);
847        goto done;
848    }
849
850    modems = count_modems();
851    if (modems < 0) {
852        ALOGE("%s: count_modems failed\n", __func__);
853        goto done;
854    }
855
856    ALOGD("%s: num_modems %d\n", __func__, modems);
857    if (modems > 0)
858        my_data->csd = open_csd_client(false /*is_i2s_ext_modem*/);
859
860done:
861    dlclose(lib);
862#else
863     my_data->csd = NULL;
864#endif
865}
866
867static void set_platform_defaults(struct platform_data * my_data)
868{
869    int32_t dev;
870    for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
871        backend_tag_table[dev] = NULL;
872        hw_interface_table[dev] = NULL;
873        operator_specific_device_table[dev] = NULL;
874    }
875
876    // To overwrite these go to the audio_platform_info.xml file.
877    backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
878    backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_NREC] = strdup("bt-sco");
879    backend_tag_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
880    backend_tag_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
881    backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
882    backend_tag_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
883    backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
884    backend_tag_table[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = strdup("bt-sco-wb");
885    backend_tag_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
886    backend_tag_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
887
888    hw_interface_table[SND_DEVICE_OUT_HANDSET] = strdup("SLIMBUS_0_RX");
889    hw_interface_table[SND_DEVICE_OUT_SPEAKER] = strdup("SLIMBUS_0_RX");
890    hw_interface_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = strdup("SLIMBUS_0_RX");
891    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE] = strdup("SLIMBUS_0_RX");
892    hw_interface_table[SND_DEVICE_OUT_HEADPHONES] = strdup("SLIMBUS_0_RX");
893    hw_interface_table[SND_DEVICE_OUT_LINE] = strdup("SLIMBUS_0_RX");
894    hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = strdup("SLIMBUS_0_RX");
895    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = strdup("SLIMBUS_0_RX");
896    hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_LINE] = strdup("SLIMBUS_0_RX");
897    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = strdup("SLIMBUS_0_RX");
898    hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET] = strdup("SLIMBUS_0_RX");
899    hw_interface_table[SND_DEVICE_OUT_VOICE_HAC_HANDSET] = strdup("SLIMBUS_0_RX");
900    hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER] = strdup("SLIMBUS_0_RX");
901    hw_interface_table[SND_DEVICE_OUT_VOICE_HEADPHONES] = strdup("SLIMBUS_0_RX");
902    hw_interface_table[SND_DEVICE_OUT_VOICE_LINE] = strdup("SLIMBUS_0_RX");
903    hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI_RX");
904    hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
905    hw_interface_table[SND_DEVICE_OUT_BT_SCO] = strdup("SEC_AUX_PCM_RX");
906    hw_interface_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("SEC_AUX_PCM_RX");
907    hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = strdup("SLIMBUS_0_RX");
908    hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = strdup("SLIMBUS_0_RX");
909    hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = strdup("SLIMBUS_0_RX");
910    hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("SLIMBUS_0_RX");
911    hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
912    hw_interface_table[SND_DEVICE_OUT_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
913    hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
914
915    my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
916}
917
918void get_cvd_version(char *cvd_version, struct audio_device *adev)
919{
920    struct mixer_ctl *ctl;
921    int count;
922    int ret = 0;
923
924    ctl = mixer_get_ctl_by_name(adev->mixer, CVD_VERSION_MIXER_CTL);
925    if (!ctl) {
926        ALOGE("%s: Could not get ctl for mixer cmd - %s",  __func__, CVD_VERSION_MIXER_CTL);
927        goto done;
928    }
929    mixer_ctl_update(ctl);
930
931    count = mixer_ctl_get_num_values(ctl);
932    if (count > MAX_CVD_VERSION_STRING_SIZE)
933        count = MAX_CVD_VERSION_STRING_SIZE - 1;
934
935    ret = mixer_ctl_get_array(ctl, cvd_version, count);
936    if (ret != 0) {
937        ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
938        goto done;
939    }
940
941done:
942    return;
943}
944
945void *platform_init(struct audio_device *adev)
946{
947    char value[PROPERTY_VALUE_MAX];
948    struct platform_data *my_data = NULL;
949    int retry_num = 0, snd_card_num = 0, key = 0, ret = 0;
950    bool dual_mic_config = false, use_default_mixer_path = true;
951    const char *snd_card_name;
952    char *cvd_version = NULL;
953    char *snd_internal_name = NULL;
954    char *tmp = NULL;
955    char mixer_xml_file[MIXER_PATH_MAX_LENGTH]= {0};
956    char platform_info_file[MIXER_PATH_MAX_LENGTH]= {0};
957    struct snd_card_split *snd_split_handle = NULL;
958    my_data = calloc(1, sizeof(struct platform_data));
959
960    my_data->adev = adev;
961
962    list_init(&operator_info_list);
963
964    set_platform_defaults(my_data);
965
966    while (snd_card_num < MAX_SND_CARD) {
967        adev->mixer = mixer_open(snd_card_num);
968
969        while (!adev->mixer && retry_num < RETRY_NUMBER) {
970            usleep(RETRY_US);
971            adev->mixer = mixer_open(snd_card_num);
972            retry_num++;
973        }
974
975        if (!adev->mixer) {
976            ALOGE("%s: Unable to open the mixer card: %d", __func__,
977                   snd_card_num);
978            retry_num = 0;
979            snd_card_num++;
980            continue;
981        }
982
983        snd_card_name = mixer_get_name(adev->mixer);
984        my_data->hw_info = hw_info_init(snd_card_name);
985
986        audio_extn_set_snd_card_split(snd_card_name);
987        snd_split_handle = audio_extn_get_snd_card_split();
988
989        /* Get the codec internal name from the sound card and/or form factor
990         * name and form the mixer paths and platfor info file name dynamically.
991         * This is generic way of picking any codec and forma factor name based
992         * mixer and platform info files in future with no code change.
993
994         * current code extends and looks for any of the exteneded mixer path and
995         * platform info file present based on codec and form factor.
996
997         * order of picking appropriate file is
998         * <i>   mixer_paths_<codec_name>_<form_factor>.xml, if file not present
999         * <ii>  mixer_paths_<codec_name>.xml, if file not present
1000         * <iii> mixer_paths.xml
1001
1002         * same order is followed for audio_platform_info.xml as well
1003         */
1004
1005        // need to carryforward old file name
1006        if (!strncmp(snd_card_name, TOMTOM_8226_SND_CARD_NAME,
1007                     min(strlen(TOMTOM_8226_SND_CARD_NAME), strlen(snd_card_name)))) {
1008            snprintf(mixer_xml_file, sizeof(mixer_xml_file), "%s_%s.xml",
1009                             MIXER_XML_BASE_STRING, TOMTOM_MIXER_FILE_SUFFIX );
1010        } else {
1011
1012            snprintf(mixer_xml_file, sizeof(mixer_xml_file), "%s_%s_%s.xml",
1013                             MIXER_XML_BASE_STRING, snd_split_handle->snd_card,
1014                             snd_split_handle->form_factor);
1015
1016            if (F_OK != access(mixer_xml_file, 0)) {
1017                memset(mixer_xml_file, 0, sizeof(mixer_xml_file));
1018                snprintf(mixer_xml_file, sizeof(mixer_xml_file), "%s_%s.xml",
1019                             MIXER_XML_BASE_STRING, snd_split_handle->snd_card);
1020
1021                if (F_OK != access(mixer_xml_file, 0)) {
1022                    memset(mixer_xml_file, 0, sizeof(mixer_xml_file));
1023                    strlcpy(mixer_xml_file, MIXER_XML_DEFAULT_PATH, MIXER_PATH_MAX_LENGTH);
1024                }
1025            }
1026
1027            snprintf(platform_info_file, sizeof(platform_info_file), "%s_%s_%s.xml",
1028                             PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card,
1029                             snd_split_handle->form_factor);
1030
1031            if (F_OK != access(platform_info_file, 0)) {
1032                memset(platform_info_file, 0, sizeof(platform_info_file));
1033                snprintf(platform_info_file, sizeof(platform_info_file), "%s_%s.xml",
1034                             PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card);
1035
1036                if (F_OK != access(platform_info_file, 0)) {
1037                    memset(platform_info_file, 0, sizeof(platform_info_file));
1038                    strlcpy(platform_info_file, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH);
1039                }
1040            }
1041        }
1042
1043        /* Initialize platform specific ids and/or backends*/
1044        platform_info_init(platform_info_file, my_data);
1045
1046        /* validate the sound card name
1047         * my_data->snd_card_name can contain
1048         *     <a> complete sound card name, i.e. <device>-<codec>-<form_factor>-snd-card
1049         *         example: msm8994-tomtom-mtp-snd-card
1050         *     <b> or sub string of the card name, i.e. <device>-<codec>
1051         *         example: msm8994-tomtom
1052         * snd_card_name is truncated to 32 charaters as per mixer_get_name() implementation
1053         * so use min of my_data->snd_card_name and snd_card_name length for comparison
1054         */
1055
1056        if (my_data->snd_card_name != NULL &&
1057                strncmp(snd_card_name, my_data->snd_card_name,
1058                        min(strlen(snd_card_name), strlen(my_data->snd_card_name))) != 0) {
1059            ALOGI("%s: found valid sound card %s, but not primary sound card %s",
1060                   __func__, snd_card_name, my_data->snd_card_name);
1061            retry_num = 0;
1062            snd_card_num++;
1063            hw_info_deinit(my_data->hw_info);
1064            my_data->hw_info = NULL;
1065            continue;
1066        }
1067        ALOGI("%s: found sound card %s, primary sound card expeted is %s",
1068              __func__, snd_card_name, my_data->snd_card_name);
1069
1070        ALOGD("%s: Loading mixer file: %s", __func__, mixer_xml_file);
1071        adev->audio_route = audio_route_init(snd_card_num, mixer_xml_file);
1072
1073        if (!adev->audio_route) {
1074            ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
1075            goto init_failed;
1076        }
1077        adev->snd_card = snd_card_num;
1078        ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
1079        break;
1080    }
1081
1082    if (snd_card_num >= MAX_SND_CARD) {
1083        ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
1084        goto init_failed;
1085    }
1086
1087    //set max volume step for voice call
1088    property_get("ro.config.vc_call_vol_steps", value, TOSTRING(MAX_VOL_INDEX));
1089    my_data->max_vol_index = atoi(value);
1090
1091    property_get("persist.audio.dualmic.config",value,"");
1092    if (!strcmp("endfire", value)) {
1093        dual_mic_config = true;
1094    }
1095
1096    my_data->source_mic_type = SOURCE_DUAL_MIC;
1097
1098    my_data->fluence_in_spkr_mode = false;
1099    my_data->fluence_in_voice_call = false;
1100    my_data->fluence_in_voice_comm = false;
1101    my_data->fluence_in_voice_rec = false;
1102
1103    property_get("ro.qc.sdk.audio.fluencetype", value, "none");
1104    if (!strcmp("fluencepro", value)) {
1105        my_data->fluence_type = FLUENCE_PRO_ENABLE;
1106    } else if (!strcmp("fluence", value) || (dual_mic_config)) {
1107        my_data->fluence_type = FLUENCE_ENABLE;
1108    } else if (!strcmp("none", value)) {
1109        my_data->fluence_type = FLUENCE_DISABLE;
1110    }
1111
1112    if (my_data->fluence_type != FLUENCE_DISABLE) {
1113        property_get("persist.audio.fluence.voicecall",value,"");
1114        if (!strcmp("true", value)) {
1115            my_data->fluence_in_voice_call = true;
1116        }
1117
1118        property_get("persist.audio.fluence.voicecomm",value,"");
1119        if (!strcmp("true", value)) {
1120            my_data->fluence_in_voice_comm = true;
1121        }
1122
1123        property_get("persist.audio.fluence.voicerec",value,"");
1124        if (!strcmp("true", value)) {
1125            my_data->fluence_in_voice_rec = true;
1126        }
1127
1128        property_get("persist.audio.fluence.speaker",value,"");
1129        if (!strcmp("true", value)) {
1130            my_data->fluence_in_spkr_mode = true;
1131        }
1132    }
1133
1134    // support max to mono, example if max count is 3, usecase supports Three, dual and mono mic
1135    switch (my_data->max_mic_count) {
1136        case 4:
1137            my_data->source_mic_type |= SOURCE_QUAD_MIC;
1138        case 3:
1139            my_data->source_mic_type |= SOURCE_THREE_MIC;
1140        case 2:
1141            my_data->source_mic_type |= SOURCE_DUAL_MIC;
1142        case 1:
1143            my_data->source_mic_type |= SOURCE_MONO_MIC;
1144            break;
1145        default:
1146            ALOGE("%s: max_mic_count (%d), is not supported, setting to default",
1147                   __func__, my_data->max_mic_count);
1148            my_data->source_mic_type = SOURCE_MONO_MIC|SOURCE_DUAL_MIC;
1149            break;
1150        }
1151
1152    ALOGV("%s: Fluence_Type(%d) max_mic_count(%d) mic_type(0x%x) fluence_in_voice_call(%d)"
1153          " fluence_in_voice_comm(%d) fluence_in_voice_rec(%d) fluence_in_spkr_mode(%d) ",
1154          __func__, my_data->fluence_type, my_data->max_mic_count, my_data->source_mic_type,
1155          my_data->fluence_in_voice_call, my_data->fluence_in_voice_comm,
1156          my_data->fluence_in_voice_rec, my_data->fluence_in_spkr_mode);
1157
1158    my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
1159    if (my_data->acdb_handle == NULL) {
1160        ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
1161    } else {
1162        ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
1163        my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
1164                                                    "acdb_loader_deallocate_ACDB");
1165        if (!my_data->acdb_deallocate)
1166            ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
1167                  __func__, LIB_ACDB_LOADER);
1168
1169        my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
1170                                                    "acdb_loader_send_audio_cal");
1171        if (!my_data->acdb_send_audio_cal)
1172            ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
1173                  __func__, LIB_ACDB_LOADER);
1174
1175        my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
1176                                                    "acdb_loader_send_voice_cal");
1177        if (!my_data->acdb_send_voice_cal)
1178            ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
1179                  __func__, LIB_ACDB_LOADER);
1180
1181        my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
1182                                                    "acdb_loader_reload_vocvoltable");
1183        if (!my_data->acdb_reload_vocvoltable)
1184            ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
1185                  __func__, LIB_ACDB_LOADER);
1186
1187        my_data->acdb_send_gain_dep_cal = (acdb_send_gain_dep_cal_t)dlsym(my_data->acdb_handle,
1188                                                    "acdb_loader_send_gain_dep_cal");
1189        if (!my_data->acdb_send_gain_dep_cal)
1190            ALOGV("%s: Could not find the symbol acdb_loader_send_gain_dep_cal from %s",
1191                  __func__, LIB_ACDB_LOADER);
1192
1193#if defined (PLATFORM_MSM8994) || (PLATFORM_MSM8996)
1194        acdb_init_v2_cvd_t acdb_init;
1195        acdb_init = (acdb_init_v2_cvd_t)dlsym(my_data->acdb_handle,
1196                                              "acdb_loader_init_v2");
1197        if (acdb_init == NULL) {
1198            ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
1199            goto acdb_init_fail;
1200        }
1201
1202        cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
1203        get_cvd_version(cvd_version, adev);
1204        if (!cvd_version)
1205            ALOGE("failed to allocate cvd_version");
1206        else
1207            acdb_init((char *)snd_card_name, cvd_version, 0);
1208        free(cvd_version);
1209#elif defined (PLATFORM_MSM8084)
1210        acdb_init_v2_t acdb_init;
1211        acdb_init = (acdb_init_v2_t)dlsym(my_data->acdb_handle,
1212                                          "acdb_loader_init_v2");
1213        if (acdb_init == NULL) {
1214            ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
1215            goto acdb_init_fail;
1216        }
1217        acdb_init((char *)snd_card_name);
1218#else
1219        acdb_init_t acdb_init;
1220        acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
1221                                                    "acdb_loader_init_ACDB");
1222        if (acdb_init == NULL)
1223            ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
1224        else
1225            acdb_init();
1226#endif
1227    }
1228
1229acdb_init_fail:
1230
1231    audio_extn_spkr_prot_init(adev);
1232
1233    audio_extn_hwdep_cal_send(adev->snd_card, my_data->acdb_handle);
1234
1235    /* load csd client */
1236    platform_csd_init(my_data);
1237
1238    return my_data;
1239
1240init_failed:
1241    if (my_data)
1242        free(my_data);
1243    return NULL;
1244}
1245
1246void platform_deinit(void *platform)
1247{
1248    int32_t dev;
1249    struct operator_info *info_item;
1250    struct operator_specific_device *device_item;
1251    struct listnode *node;
1252
1253    struct platform_data *my_data = (struct platform_data *)platform;
1254    close_csd_client(my_data->csd);
1255
1256    hw_info_deinit(my_data->hw_info);
1257
1258    for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
1259        if (backend_tag_table[dev])
1260            free(backend_tag_table[dev]);
1261        if (hw_interface_table[dev])
1262            free(hw_interface_table[dev]);
1263        if (operator_specific_device_table[dev]) {
1264            while (!list_empty(operator_specific_device_table[dev])) {
1265                node = list_head(operator_specific_device_table[dev]);
1266                list_remove(node);
1267                device_item = node_to_item(node, struct operator_specific_device, list);
1268                free(device_item->operator);
1269                free(device_item->mixer_path);
1270                free(device_item);
1271            }
1272            free(operator_specific_device_table[dev]);
1273        }
1274    }
1275
1276    if (my_data->snd_card_name)
1277        free(my_data->snd_card_name);
1278
1279    while (!list_empty(&operator_info_list)) {
1280        node = list_head(&operator_info_list);
1281        list_remove(node);
1282        info_item = node_to_item(node, struct operator_info, list);
1283        free(info_item->name);
1284        free(info_item->mccmnc);
1285        free(info_item);
1286    }
1287
1288    free(platform);
1289}
1290
1291const char *platform_get_snd_device_name(snd_device_t snd_device)
1292{
1293    if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
1294        if (operator_specific_device_table[snd_device] != NULL) {
1295            return get_operator_specific_device_mixer_path(snd_device);
1296        }
1297        return device_table[snd_device];
1298    } else
1299        return "none";
1300}
1301
1302int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
1303                                      char *device_name)
1304{
1305    struct platform_data *my_data = (struct platform_data *)platform;
1306
1307    if (platform == NULL || device_name == NULL) {
1308        ALOGW("%s: something wrong, use legacy get_snd_device name", __func__);
1309        device_name = platform_get_snd_device_name(snd_device);
1310    } else if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
1311        if (operator_specific_device_table[snd_device] != NULL) {
1312            strlcpy(device_name, get_operator_specific_device_mixer_path(snd_device),
1313                    DEVICE_NAME_MAX_SIZE);
1314        } else {
1315            strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
1316        }
1317        hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
1318    } else {
1319        strlcpy(device_name, "none", DEVICE_NAME_MAX_SIZE);
1320    }
1321
1322    return 0;
1323}
1324
1325void platform_add_backend_name(void *platform, char *mixer_path,
1326                               snd_device_t snd_device)
1327{
1328    struct platform_data *my_data = (struct platform_data *)platform;
1329
1330    if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1331        ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1332        return;
1333    }
1334
1335    const char * suffix = backend_tag_table[snd_device];
1336
1337    if (suffix != NULL) {
1338        strcat(mixer_path, " ");
1339        strcat(mixer_path, suffix);
1340    }
1341}
1342
1343bool platform_check_backends_match(snd_device_t snd_device1, snd_device_t snd_device2)
1344{
1345    bool result = true;
1346
1347    ALOGV("%s: snd_device1 = %s, snd_device2 = %s", __func__,
1348                platform_get_snd_device_name(snd_device1),
1349                platform_get_snd_device_name(snd_device2));
1350
1351    if ((snd_device1 < SND_DEVICE_MIN) || (snd_device1 >= SND_DEVICE_MAX)) {
1352        ALOGE("%s: Invalid snd_device = %s", __func__,
1353                platform_get_snd_device_name(snd_device1));
1354        return false;
1355    }
1356    if ((snd_device2 < SND_DEVICE_MIN) || (snd_device2 >= SND_DEVICE_MAX)) {
1357        ALOGE("%s: Invalid snd_device = %s", __func__,
1358                platform_get_snd_device_name(snd_device2));
1359        return false;
1360    }
1361    const char * be_itf1 = hw_interface_table[snd_device1];
1362    const char * be_itf2 = hw_interface_table[snd_device2];
1363
1364    if (NULL != be_itf1 && NULL != be_itf2) {
1365        if ((NULL == strstr(be_itf2, be_itf1)) && (NULL == strstr(be_itf1, be_itf2)))
1366            result = false;
1367    }
1368
1369    ALOGV("%s: be_itf1 = %s, be_itf2 = %s, match %d", __func__, be_itf1, be_itf2, result);
1370    return result;
1371}
1372
1373int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
1374{
1375    int device_id;
1376    if (device_type == PCM_PLAYBACK)
1377        device_id = pcm_device_table[usecase][0];
1378    else
1379        device_id = pcm_device_table[usecase][1];
1380    return device_id;
1381}
1382
1383static int find_index(const struct name_to_index * table, int32_t len,
1384                      const char * name)
1385{
1386    int ret = 0;
1387    int32_t i;
1388
1389    if (table == NULL) {
1390        ALOGE("%s: table is NULL", __func__);
1391        ret = -ENODEV;
1392        goto done;
1393    }
1394
1395    if (name == NULL) {
1396        ALOGE("null key");
1397        ret = -ENODEV;
1398        goto done;
1399    }
1400
1401    for (i=0; i < len; i++) {
1402        if (!strcmp(table[i].name, name)) {
1403            ret = table[i].index;
1404            goto done;
1405        }
1406    }
1407    ALOGE("%s: Could not find index for name = %s",
1408            __func__, name);
1409    ret = -ENODEV;
1410done:
1411    return ret;
1412}
1413
1414int platform_get_snd_device_index(char *device_name)
1415{
1416    return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
1417}
1418
1419int platform_get_usecase_index(const char *usecase_name)
1420{
1421    return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
1422}
1423
1424void platform_add_operator_specific_device(snd_device_t snd_device,
1425                                           const char *operator,
1426                                           const char *mixer_path,
1427                                           unsigned int acdb_id)
1428{
1429    struct operator_specific_device *device;
1430
1431    if (operator_specific_device_table[snd_device] == NULL) {
1432        operator_specific_device_table[snd_device] =
1433            (struct listnode *)calloc(1, sizeof(struct listnode));
1434        list_init(operator_specific_device_table[snd_device]);
1435    }
1436
1437    device = (struct operator_specific_device *)calloc(1, sizeof(struct operator_specific_device));
1438
1439    device->operator = strdup(operator);
1440    device->mixer_path = strdup(mixer_path);
1441    device->acdb_id = acdb_id;
1442
1443    list_add_tail(operator_specific_device_table[snd_device], &device->list);
1444
1445    ALOGD("%s: device[%s] -> operator[%s] mixer_path[%s] acdb_id[%d]", __func__,
1446            platform_get_snd_device_name(snd_device), operator, mixer_path, acdb_id);
1447
1448}
1449
1450int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
1451{
1452    int ret = 0;
1453
1454    if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1455        ALOGE("%s: Invalid snd_device = %d",
1456            __func__, snd_device);
1457        ret = -EINVAL;
1458        goto done;
1459    }
1460
1461    ALOGV("%s: acdb_device_table[%s]: old = %d new = %d", __func__,
1462          platform_get_snd_device_name(snd_device), acdb_device_table[snd_device], acdb_id);
1463    acdb_device_table[snd_device] = acdb_id;
1464done:
1465    return ret;
1466}
1467
1468int platform_get_snd_device_acdb_id(snd_device_t snd_device)
1469{
1470    if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1471        ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1472        return -EINVAL;
1473    }
1474
1475    if (operator_specific_device_table[snd_device] != NULL)
1476        return get_operator_specific_device_acdb_id(snd_device);
1477    else
1478        return acdb_device_table[snd_device];
1479}
1480
1481int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
1482{
1483    struct platform_data *my_data = (struct platform_data *)platform;
1484    int acdb_dev_id, acdb_dev_type;
1485
1486    acdb_dev_id = acdb_device_table[audio_extn_get_spkr_prot_snd_device(snd_device)];
1487    if (acdb_dev_id < 0) {
1488        ALOGE("%s: Could not find acdb id for device(%d)",
1489              __func__, snd_device);
1490        return -EINVAL;
1491    }
1492    if (my_data->acdb_send_audio_cal) {
1493        ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
1494              __func__, snd_device, acdb_dev_id);
1495        if (snd_device >= SND_DEVICE_OUT_BEGIN &&
1496                snd_device < SND_DEVICE_OUT_END)
1497            acdb_dev_type = ACDB_DEV_TYPE_OUT;
1498        else
1499            acdb_dev_type = ACDB_DEV_TYPE_IN;
1500        my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
1501    }
1502    return 0;
1503}
1504
1505int platform_switch_voice_call_device_pre(void *platform)
1506{
1507    struct platform_data *my_data = (struct platform_data *)platform;
1508    int ret = 0;
1509
1510    if (my_data->csd != NULL &&
1511        voice_is_in_call(my_data->adev)) {
1512        /* This must be called before disabling mixer controls on APQ side */
1513        ret = my_data->csd->disable_device();
1514        if (ret < 0) {
1515            ALOGE("%s: csd_client_disable_device, failed, error %d",
1516                  __func__, ret);
1517        }
1518    }
1519    return ret;
1520}
1521
1522int platform_switch_voice_call_enable_device_config(void *platform,
1523                                                    snd_device_t out_snd_device,
1524                                                    snd_device_t in_snd_device)
1525{
1526    struct platform_data *my_data = (struct platform_data *)platform;
1527    int acdb_rx_id, acdb_tx_id;
1528    int ret = 0;
1529
1530    if (my_data->csd == NULL)
1531        return ret;
1532
1533    if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1534        audio_extn_spkr_prot_is_enabled())
1535        acdb_rx_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_SPEAKER_PROTECTED);
1536    else
1537        acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
1538
1539    acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
1540
1541    if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1542        ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
1543        if (ret < 0) {
1544            ALOGE("%s: csd_enable_device_config, failed, error %d",
1545                  __func__, ret);
1546        }
1547    } else {
1548        ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1549              acdb_rx_id, acdb_tx_id);
1550    }
1551
1552    return ret;
1553}
1554
1555int platform_switch_voice_call_device_post(void *platform,
1556                                           snd_device_t out_snd_device,
1557                                           snd_device_t in_snd_device)
1558{
1559    struct platform_data *my_data = (struct platform_data *)platform;
1560    int acdb_rx_id, acdb_tx_id;
1561
1562    if (my_data->acdb_send_voice_cal == NULL) {
1563        ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
1564    } else {
1565        if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1566            audio_extn_spkr_prot_is_enabled())
1567            out_snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
1568
1569        acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
1570        acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
1571
1572        if (acdb_rx_id > 0 && acdb_tx_id > 0)
1573            my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
1574        else
1575            ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1576                  acdb_rx_id, acdb_tx_id);
1577    }
1578
1579    return 0;
1580}
1581
1582int platform_switch_voice_call_usecase_route_post(void *platform,
1583                                                  snd_device_t out_snd_device,
1584                                                  snd_device_t in_snd_device)
1585{
1586    struct platform_data *my_data = (struct platform_data *)platform;
1587    int acdb_rx_id, acdb_tx_id;
1588    int ret = 0;
1589
1590    if (my_data->csd == NULL)
1591        return ret;
1592
1593    if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1594        audio_extn_spkr_prot_is_enabled())
1595        acdb_rx_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED);
1596    else
1597        acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
1598
1599    acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
1600
1601    if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1602        ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
1603                                          my_data->adev->acdb_settings);
1604        if (ret < 0) {
1605            ALOGE("%s: csd_enable_device, failed, error %d", __func__, ret);
1606        }
1607    } else {
1608        ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1609              acdb_rx_id, acdb_tx_id);
1610    }
1611
1612    return ret;
1613}
1614
1615int platform_start_voice_call(void *platform, uint32_t vsid)
1616{
1617    struct platform_data *my_data = (struct platform_data *)platform;
1618    int ret = 0;
1619
1620    if (my_data->csd != NULL) {
1621        ret = my_data->csd->start_voice(vsid);
1622        if (ret < 0) {
1623            ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
1624        }
1625    }
1626    return ret;
1627}
1628
1629int platform_stop_voice_call(void *platform, uint32_t vsid)
1630{
1631    struct platform_data *my_data = (struct platform_data *)platform;
1632    int ret = 0;
1633
1634    if (my_data->csd != NULL) {
1635        ret = my_data->csd->stop_voice(vsid);
1636        if (ret < 0) {
1637            ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
1638        }
1639    }
1640    return ret;
1641}
1642
1643int platform_get_sample_rate(void *platform, uint32_t *rate)
1644{
1645    struct platform_data *my_data = (struct platform_data *)platform;
1646    int ret = 0;
1647
1648    if (my_data->csd != NULL) {
1649        ret = my_data->csd->get_sample_rate(rate);
1650        if (ret < 0) {
1651            ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret);
1652        }
1653    }
1654    return ret;
1655}
1656
1657void platform_set_speaker_gain_in_combo(struct audio_device *adev,
1658                                        snd_device_t snd_device,
1659                                        bool enable)
1660{
1661    const char* name;
1662    switch (snd_device) {
1663        case SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES:
1664            if (enable)
1665                name = "spkr-gain-in-headphone-combo";
1666            else
1667                name = "speaker-gain-default";
1668            break;
1669        case SND_DEVICE_OUT_SPEAKER_AND_LINE:
1670            if (enable)
1671                name = "spkr-gain-in-line-combo";
1672            else
1673                name = "speaker-gain-default";
1674            break;
1675        case SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES:
1676            if (enable)
1677                name = "spkr-safe-gain-in-headphone-combo";
1678            else
1679                name = "speaker-safe-gain-default";
1680            break;
1681        case SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE:
1682            if (enable)
1683                name = "spkr-safe-gain-in-line-combo";
1684            else
1685                name = "speaker-safe-gain-default";
1686            break;
1687        default:
1688            return;
1689    }
1690
1691    audio_route_apply_and_update_path(adev->audio_route, name);
1692}
1693
1694int platform_set_voice_volume(void *platform, int volume)
1695{
1696    struct platform_data *my_data = (struct platform_data *)platform;
1697    struct audio_device *adev = my_data->adev;
1698    struct mixer_ctl *ctl;
1699    const char *mixer_ctl_name = "Voice Rx Gain";
1700    int vol_index = 0, ret = 0;
1701    uint32_t set_values[ ] = {0,
1702                              ALL_SESSION_VSID,
1703                              DEFAULT_VOLUME_RAMP_DURATION_MS};
1704
1705    // Voice volume levels are mapped to adsp volume levels as follows.
1706    // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1  0 -> 0
1707    // But this values don't changed in kernel. So, below change is need.
1708    vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, my_data->max_vol_index);
1709    set_values[0] = vol_index;
1710
1711    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1712    if (!ctl) {
1713        ALOGE("%s: Could not get ctl for mixer cmd - %s",
1714              __func__, mixer_ctl_name);
1715        return -EINVAL;
1716    }
1717    ALOGV("Setting voice volume index: %d", set_values[0]);
1718    mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1719
1720    if (my_data->csd != NULL) {
1721        ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
1722                                   DEFAULT_VOLUME_RAMP_DURATION_MS);
1723        if (ret < 0) {
1724            ALOGE("%s: csd_volume error %d", __func__, ret);
1725        }
1726    }
1727    return ret;
1728}
1729
1730int platform_set_mic_mute(void *platform, bool state)
1731{
1732    struct platform_data *my_data = (struct platform_data *)platform;
1733    struct audio_device *adev = my_data->adev;
1734    struct mixer_ctl *ctl;
1735    const char *mixer_ctl_name = "Voice Tx Mute";
1736    int ret = 0;
1737    uint32_t set_values[ ] = {0,
1738                              ALL_SESSION_VSID,
1739                              DEFAULT_MUTE_RAMP_DURATION_MS};
1740
1741    if (adev->mode != AUDIO_MODE_IN_CALL &&
1742        adev->mode != AUDIO_MODE_IN_COMMUNICATION)
1743        return 0;
1744
1745    if (adev->enable_hfp)
1746        mixer_ctl_name = "HFP Tx Mute";
1747
1748    set_values[0] = state;
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        return -EINVAL;
1754    }
1755    ALOGV("Setting voice mute state: %d", state);
1756    mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1757
1758    if (my_data->csd != NULL) {
1759        ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state,
1760                                     DEFAULT_MUTE_RAMP_DURATION_MS);
1761        if (ret < 0) {
1762            ALOGE("%s: csd_mic_mute error %d", __func__, ret);
1763        }
1764    }
1765    return ret;
1766}
1767
1768int platform_set_device_mute(void *platform, bool state, char *dir)
1769{
1770    struct platform_data *my_data = (struct platform_data *)platform;
1771    struct audio_device *adev = my_data->adev;
1772    struct mixer_ctl *ctl;
1773    char *mixer_ctl_name = NULL;
1774    int ret = 0;
1775    uint32_t set_values[ ] = {0,
1776                              ALL_SESSION_VSID,
1777                              0};
1778    if(dir == NULL) {
1779        ALOGE("%s: Invalid direction:%s", __func__, dir);
1780        return -EINVAL;
1781    }
1782
1783    if (!strncmp("rx", dir, sizeof("rx"))) {
1784        mixer_ctl_name = "Voice Rx Device Mute";
1785    } else if (!strncmp("tx", dir, sizeof("tx"))) {
1786        mixer_ctl_name = "Voice Tx Device Mute";
1787    } else {
1788        return -EINVAL;
1789    }
1790
1791    set_values[0] = state;
1792    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1793    if (!ctl) {
1794        ALOGE("%s: Could not get ctl for mixer cmd - %s",
1795              __func__, mixer_ctl_name);
1796        return -EINVAL;
1797    }
1798
1799    ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
1800          __func__,state, mixer_ctl_name);
1801    mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1802
1803    return ret;
1804}
1805
1806bool platform_can_split_snd_device(snd_device_t snd_device,
1807                                   int *num_devices,
1808                                   snd_device_t *new_snd_devices)
1809{
1810    bool status = false;
1811
1812    if (NULL == num_devices || NULL == new_snd_devices) {
1813        ALOGE("%s: NULL pointer ..", __func__);
1814        return false;
1815    }
1816
1817    /*
1818     * If wired headset/headphones/line devices share the same backend
1819     * with speaker/earpiece this routine returns false.
1820     */
1821    if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES &&
1822        !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HEADPHONES)) {
1823        *num_devices = 2;
1824        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
1825        new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
1826        status = true;
1827    } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_LINE &&
1828               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_LINE)) {
1829        *num_devices = 2;
1830        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
1831        new_snd_devices[1] = SND_DEVICE_OUT_LINE;
1832        status = true;
1833    } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES &&
1834               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_HEADPHONES)) {
1835        *num_devices = 2;
1836        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
1837        new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
1838        status = true;
1839    } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE &&
1840               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_LINE)) {
1841        *num_devices = 2;
1842        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
1843        new_snd_devices[1] = SND_DEVICE_OUT_LINE;
1844        status = true;
1845    }
1846    return status;
1847}
1848
1849snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
1850{
1851    struct platform_data *my_data = (struct platform_data *)platform;
1852    struct audio_device *adev = my_data->adev;
1853    audio_mode_t mode = adev->mode;
1854    snd_device_t snd_device = SND_DEVICE_NONE;
1855
1856    ALOGV("%s: enter: output devices(%#x)", __func__, devices);
1857    if (devices == AUDIO_DEVICE_NONE ||
1858        devices & AUDIO_DEVICE_BIT_IN) {
1859        ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
1860        goto exit;
1861    }
1862
1863    if (popcount(devices) == 2) {
1864        if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1865                        AUDIO_DEVICE_OUT_SPEAKER) ||
1866                devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1867                            AUDIO_DEVICE_OUT_SPEAKER)) {
1868            snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1869        } else if (devices == (AUDIO_DEVICE_OUT_LINE |
1870                               AUDIO_DEVICE_OUT_SPEAKER)) {
1871            snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
1872        } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1873                               AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
1874                   devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1875                               AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
1876            snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES;
1877        } else if (devices == (AUDIO_DEVICE_OUT_LINE |
1878                               AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
1879            snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE;
1880        } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
1881                               AUDIO_DEVICE_OUT_SPEAKER)) {
1882            snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
1883        } else {
1884            ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
1885            goto exit;
1886        }
1887        if (snd_device != SND_DEVICE_NONE) {
1888            goto exit;
1889        }
1890    }
1891
1892    if (popcount(devices) != 1) {
1893        ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
1894        goto exit;
1895    }
1896
1897    if (voice_is_in_call(adev) || adev->enable_voicerx) {
1898        if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1899            devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1900            devices & AUDIO_DEVICE_OUT_LINE) {
1901            if (voice_is_in_call(adev) &&
1902                (adev->voice.tty_mode == TTY_MODE_FULL))
1903                snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
1904            else if (voice_is_in_call(adev) &&
1905                (adev->voice.tty_mode == TTY_MODE_VCO))
1906                snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
1907            else if (voice_is_in_call(adev) &&
1908                (adev->voice.tty_mode == TTY_MODE_HCO))
1909                snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
1910            else {
1911                if (devices & AUDIO_DEVICE_OUT_LINE)
1912                    snd_device = SND_DEVICE_OUT_VOICE_LINE;
1913                else
1914                    snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
1915                }
1916        } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
1917            if (adev->bt_wb_speech_enabled) {
1918                snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1919            } else {
1920                snd_device = SND_DEVICE_OUT_BT_SCO;
1921            }
1922        } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
1923            if (!adev->enable_hfp) {
1924                snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
1925            } else {
1926                snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_HFP;
1927            }
1928        } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
1929            if(adev->voice.hac)
1930                snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1931            else if (is_operator_tmus())
1932                snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
1933            else
1934                snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
1935        } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1936            snd_device = SND_DEVICE_OUT_VOICE_TX;
1937
1938        if (snd_device != SND_DEVICE_NONE) {
1939            goto exit;
1940        }
1941    }
1942
1943    if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1944        devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1945        snd_device = SND_DEVICE_OUT_HEADPHONES;
1946    } else if (devices & AUDIO_DEVICE_OUT_LINE) {
1947        snd_device = SND_DEVICE_OUT_LINE;
1948    } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
1949        snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
1950    } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
1951        if (my_data->speaker_lr_swap)
1952            snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
1953        else
1954            snd_device = SND_DEVICE_OUT_SPEAKER;
1955    } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
1956        if (adev->bt_wb_speech_enabled) {
1957            snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1958        } else {
1959            snd_device = SND_DEVICE_OUT_BT_SCO;
1960        }
1961    } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1962        snd_device = SND_DEVICE_OUT_HDMI ;
1963    } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
1964        /*HAC support for voice-ish audio (eg visual voicemail)*/
1965        if(adev->voice.hac)
1966            snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
1967        else
1968            snd_device = SND_DEVICE_OUT_HANDSET;
1969    } else {
1970        ALOGE("%s: Unknown device(s) %#x", __func__, devices);
1971    }
1972exit:
1973    ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
1974    return snd_device;
1975}
1976
1977snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
1978{
1979    struct platform_data *my_data = (struct platform_data *)platform;
1980    struct audio_device *adev = my_data->adev;
1981    audio_source_t  source = (adev->active_input == NULL) ?
1982                                AUDIO_SOURCE_DEFAULT : adev->active_input->source;
1983
1984    audio_mode_t    mode   = adev->mode;
1985    audio_devices_t in_device = ((adev->active_input == NULL) ?
1986                                    AUDIO_DEVICE_NONE : adev->active_input->device)
1987                                & ~AUDIO_DEVICE_BIT_IN;
1988    audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1989                                AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1990    snd_device_t snd_device = SND_DEVICE_NONE;
1991    int channel_count = popcount(channel_mask);
1992
1993    ALOGV("%s: enter: out_device(%#x) in_device(%#x) channel_count (%d) channel_mask (0x%x)",
1994          __func__, out_device, in_device, channel_count, channel_mask);
1995    if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
1996        if (adev->voice.tty_mode != TTY_MODE_OFF) {
1997            if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1998                out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
1999                out_device & AUDIO_DEVICE_OUT_LINE) {
2000                switch (adev->voice.tty_mode) {
2001                case TTY_MODE_FULL:
2002                    snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
2003                    break;
2004                case TTY_MODE_VCO:
2005                    snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
2006                    break;
2007                case TTY_MODE_HCO:
2008                    snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
2009                    break;
2010                default:
2011                    ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
2012                }
2013                goto exit;
2014            }
2015        }
2016        if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
2017            if (my_data->fluence_in_voice_call == false) {
2018                snd_device = SND_DEVICE_IN_HANDSET_MIC;
2019            } else {
2020                if (is_operator_tmus())
2021                    snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS;
2022                else
2023                    snd_device = SND_DEVICE_IN_VOICE_DMIC;
2024            }
2025        } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
2026            snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
2027        } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
2028            if (adev->bt_wb_speech_enabled) {
2029                if (adev->bluetooth_nrec)
2030                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2031                else
2032                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
2033            } else {
2034                if (adev->bluetooth_nrec)
2035                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2036                else
2037                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
2038            }
2039        } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
2040                   out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
2041                   out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
2042                   out_device & AUDIO_DEVICE_OUT_LINE) {
2043            if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode) {
2044                if (my_data->source_mic_type & SOURCE_DUAL_MIC) {
2045                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
2046                } else {
2047                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
2048                }
2049            }
2050
2051            //select default
2052            if (snd_device == SND_DEVICE_NONE) {
2053                if (!adev->enable_hfp) {
2054                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
2055                } else {
2056                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP;
2057                    platform_set_echo_reference(adev, true, out_device);
2058                }
2059            }
2060        } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX) {
2061            snd_device = SND_DEVICE_IN_VOICE_RX;
2062        }
2063    } else if (source == AUDIO_SOURCE_CAMCORDER) {
2064        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
2065            in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2066            snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
2067        }
2068    } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
2069        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2070            if (my_data->fluence_in_voice_rec && channel_count == 1) {
2071                if ((my_data->fluence_type == FLUENCE_PRO_ENABLE) &&
2072                    (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
2073                    if (adev->active_input->enable_aec)
2074                        snd_device = SND_DEVICE_IN_HANDSET_QMIC_AEC;
2075                    else
2076                        snd_device = SND_DEVICE_IN_HANDSET_QMIC;
2077                } else if ((my_data->fluence_type == FLUENCE_PRO_ENABLE) &&
2078                    (my_data->source_mic_type & SOURCE_THREE_MIC)) {
2079                    if (adev->active_input->enable_aec)
2080                        snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC;
2081                    else
2082                        snd_device = SND_DEVICE_IN_HANDSET_TMIC;
2083                } else if (((my_data->fluence_type == FLUENCE_PRO_ENABLE) ||
2084                    (my_data->fluence_type == FLUENCE_ENABLE)) &&
2085                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
2086                    if (adev->active_input->enable_aec)
2087                        snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
2088                    else
2089                        snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
2090                }
2091                platform_set_echo_reference(adev, true, out_device);
2092            } else if ((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) &&
2093                       (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
2094                snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
2095            } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) &&
2096                       (my_data->source_mic_type & SOURCE_THREE_MIC)) {
2097                snd_device = SND_DEVICE_IN_THREE_MIC;
2098            } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_4) &&
2099                       (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
2100                snd_device = SND_DEVICE_IN_QUAD_MIC;
2101            }
2102            if (snd_device == SND_DEVICE_NONE) {
2103                if (adev->active_input->enable_ns)
2104                    snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
2105                else if (adev->active_input->enable_aec) {
2106                    snd_device = SND_DEVICE_IN_VOICE_REC_MIC_AEC;
2107                    platform_set_echo_reference(adev, true, out_device);
2108               } else
2109                    snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
2110            }
2111        } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2112            snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
2113        }
2114    } else if (source == AUDIO_SOURCE_UNPROCESSED) {
2115        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2116            if (((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) ||
2117                 (channel_mask == AUDIO_CHANNEL_IN_STEREO)) &&
2118                       (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
2119                snd_device = SND_DEVICE_IN_UNPROCESSED_STEREO_MIC;
2120            } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) &&
2121                       (my_data->source_mic_type & SOURCE_THREE_MIC)) {
2122                snd_device = SND_DEVICE_IN_UNPROCESSED_THREE_MIC;
2123            } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_4) &&
2124                       (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
2125                snd_device = SND_DEVICE_IN_UNPROCESSED_QUAD_MIC;
2126            } else {
2127                snd_device = SND_DEVICE_IN_UNPROCESSED_MIC;
2128            }
2129        } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2130            snd_device = SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC;
2131        }
2132    } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2133               mode == AUDIO_MODE_IN_COMMUNICATION) {
2134        if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE))
2135            in_device = AUDIO_DEVICE_IN_BACK_MIC;
2136        if (adev->active_input) {
2137            if (adev->active_input->enable_aec &&
2138                    adev->active_input->enable_ns) {
2139                if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2140                    if (my_data->fluence_in_spkr_mode &&
2141                            my_data->fluence_in_voice_comm &&
2142                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
2143                        snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
2144                    } else {
2145                        snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
2146                    }
2147                } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2148                    if (my_data->fluence_in_voice_comm &&
2149                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
2150                        snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
2151                    } else {
2152                        snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
2153                    }
2154                } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2155                    snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
2156                }
2157                platform_set_echo_reference(adev, true, out_device);
2158            } else if (adev->active_input->enable_aec) {
2159                if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2160                    if (my_data->fluence_in_spkr_mode &&
2161                            my_data->fluence_in_voice_comm &&
2162                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
2163                        snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
2164                    } else {
2165                        snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
2166                    }
2167                } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2168                    if (my_data->fluence_in_voice_comm &&
2169                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
2170                        snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
2171                    } else {
2172                        snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
2173                    }
2174               } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2175                   snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
2176               }
2177               platform_set_echo_reference(adev, true, out_device);
2178            } else if (adev->active_input->enable_ns) {
2179                if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2180                    if (my_data->fluence_in_spkr_mode &&
2181                            my_data->fluence_in_voice_comm &&
2182                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
2183                        snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
2184                    } else {
2185                        snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
2186                    }
2187                } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2188                    if (my_data->fluence_in_voice_comm &&
2189                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
2190                        snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
2191                    } else {
2192                        snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
2193                    }
2194                }
2195            }
2196        }
2197    } else if (source == AUDIO_SOURCE_DEFAULT) {
2198        goto exit;
2199    }
2200
2201
2202    if (snd_device != SND_DEVICE_NONE) {
2203        goto exit;
2204    }
2205
2206    if (in_device != AUDIO_DEVICE_NONE &&
2207            !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
2208            !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
2209        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2210            if ((my_data->source_mic_type & SOURCE_QUAD_MIC) &&
2211                (int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_4) {
2212                snd_device = SND_DEVICE_IN_QUAD_MIC;
2213            } else if ((my_data->source_mic_type & SOURCE_THREE_MIC) &&
2214                       (int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) {
2215                snd_device = SND_DEVICE_IN_THREE_MIC;
2216            } else if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
2217                       channel_count == 2) {
2218                snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
2219            } else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
2220                       channel_count == 1) {
2221                snd_device = SND_DEVICE_IN_HANDSET_MIC;
2222            } else {
2223                ALOGE("%s: something wrong (1): source type (%d) channel_count (%d) .."
2224                      " channel mask (0x%x) no combination found .. setting to mono", __func__,
2225                       my_data->source_mic_type, channel_count, channel_mask);
2226                snd_device = SND_DEVICE_IN_HANDSET_MIC;
2227            }
2228        } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2229            if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
2230                    channel_count == 2) {
2231                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
2232            } else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
2233                    channel_count == 1) {
2234                snd_device = SND_DEVICE_IN_SPEAKER_MIC;
2235            } else {
2236                ALOGE("%s: something wrong (2): source type (%d) channel_count (%d) .."
2237                      " no combination found .. setting to mono", __func__,
2238                       my_data->source_mic_type, channel_count);
2239                snd_device = SND_DEVICE_IN_SPEAKER_MIC;
2240            }
2241        } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2242            snd_device = SND_DEVICE_IN_HEADSET_MIC;
2243        } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
2244            if (adev->bt_wb_speech_enabled) {
2245                if (adev->bluetooth_nrec)
2246                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2247                else
2248                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
2249            } else {
2250                if (adev->bluetooth_nrec)
2251                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2252                else
2253                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
2254            }
2255        } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
2256            snd_device = SND_DEVICE_IN_HDMI_MIC;
2257        } else {
2258            ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
2259            ALOGW("%s: Using default handset-mic", __func__);
2260            snd_device = SND_DEVICE_IN_HANDSET_MIC;
2261        }
2262    } else {
2263        if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
2264            snd_device = SND_DEVICE_IN_HANDSET_MIC;
2265        } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
2266            snd_device = SND_DEVICE_IN_HEADSET_MIC;
2267        } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
2268                   out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
2269                   out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
2270                   out_device & AUDIO_DEVICE_OUT_LINE) {
2271            if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
2272                    channel_count == 2) {
2273                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
2274            } else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
2275                          channel_count == 1) {
2276                snd_device = SND_DEVICE_IN_SPEAKER_MIC;
2277            } else {
2278                ALOGE("%s: something wrong (3): source type (%d) channel_count (%d) .."
2279                      " no combination found .. setting to mono", __func__,
2280                       my_data->source_mic_type, channel_count);
2281                snd_device = SND_DEVICE_IN_SPEAKER_MIC;
2282            }
2283        } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
2284            if (adev->bt_wb_speech_enabled) {
2285                if (adev->bluetooth_nrec)
2286                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2287                else
2288                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
2289            } else {
2290                if (adev->bluetooth_nrec)
2291                    snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2292                else
2293                    snd_device = SND_DEVICE_IN_BT_SCO_MIC;
2294            }
2295        } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
2296            snd_device = SND_DEVICE_IN_HDMI_MIC;
2297        } else {
2298            ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
2299            ALOGW("%s: Using default handset-mic", __func__);
2300            snd_device = SND_DEVICE_IN_HANDSET_MIC;
2301        }
2302    }
2303exit:
2304    ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
2305    return snd_device;
2306}
2307
2308int platform_set_hdmi_channels(void *platform,  int channel_count)
2309{
2310    struct platform_data *my_data = (struct platform_data *)platform;
2311    struct audio_device *adev = my_data->adev;
2312    struct mixer_ctl *ctl;
2313    const char *channel_cnt_str = NULL;
2314    const char *mixer_ctl_name = "HDMI_RX Channels";
2315    switch (channel_count) {
2316    case 8:
2317        channel_cnt_str = "Eight"; break;
2318    case 7:
2319        channel_cnt_str = "Seven"; break;
2320    case 6:
2321        channel_cnt_str = "Six"; break;
2322    case 5:
2323        channel_cnt_str = "Five"; break;
2324    case 4:
2325        channel_cnt_str = "Four"; break;
2326    case 3:
2327        channel_cnt_str = "Three"; break;
2328    default:
2329        channel_cnt_str = "Two"; break;
2330    }
2331    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2332    if (!ctl) {
2333        ALOGE("%s: Could not get ctl for mixer cmd - %s",
2334              __func__, mixer_ctl_name);
2335        return -EINVAL;
2336    }
2337    ALOGV("HDMI channel count: %s", channel_cnt_str);
2338    mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
2339    return 0;
2340}
2341
2342int platform_edid_get_max_channels(void *platform)
2343{
2344    struct platform_data *my_data = (struct platform_data *)platform;
2345    struct audio_device *adev = my_data->adev;
2346    char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
2347    char *sad = block;
2348    int num_audio_blocks;
2349    int channel_count;
2350    int max_channels = 0;
2351    int i, ret, count;
2352
2353    struct mixer_ctl *ctl;
2354
2355    ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
2356    if (!ctl) {
2357        ALOGE("%s: Could not get ctl for mixer cmd - %s",
2358              __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
2359        return 0;
2360    }
2361
2362    mixer_ctl_update(ctl);
2363
2364    count = mixer_ctl_get_num_values(ctl);
2365
2366    /* Read SAD blocks, clamping the maximum size for safety */
2367    if (count > (int)sizeof(block))
2368        count = (int)sizeof(block);
2369
2370    ret = mixer_ctl_get_array(ctl, block, count);
2371    if (ret != 0) {
2372        ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
2373        return 0;
2374    }
2375
2376    /* Calculate the number of SAD blocks */
2377    num_audio_blocks = count / SAD_BLOCK_SIZE;
2378
2379    for (i = 0; i < num_audio_blocks; i++) {
2380        /* Only consider LPCM blocks */
2381        if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
2382            sad += 3;
2383            continue;
2384        }
2385
2386        channel_count = (sad[0] & 0x7) + 1;
2387        if (channel_count > max_channels)
2388            max_channels = channel_count;
2389
2390        /* Advance to next block */
2391        sad += 3;
2392    }
2393
2394    return max_channels;
2395}
2396
2397int platform_set_incall_recording_session_id(void *platform,
2398                                             uint32_t session_id, int rec_mode)
2399{
2400    int ret = 0;
2401    struct platform_data *my_data = (struct platform_data *)platform;
2402    struct audio_device *adev = my_data->adev;
2403    struct mixer_ctl *ctl;
2404    const char *mixer_ctl_name = "Voc VSID";
2405    int num_ctl_values;
2406    int i;
2407
2408    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2409    if (!ctl) {
2410        ALOGE("%s: Could not get ctl for mixer cmd - %s",
2411              __func__, mixer_ctl_name);
2412        ret = -EINVAL;
2413    } else {
2414        num_ctl_values = mixer_ctl_get_num_values(ctl);
2415        for (i = 0; i < num_ctl_values; i++) {
2416            if (mixer_ctl_set_value(ctl, i, session_id)) {
2417                ALOGV("Error: invalid session_id: %x", session_id);
2418                ret = -EINVAL;
2419                break;
2420            }
2421        }
2422    }
2423
2424    if (my_data->csd != NULL) {
2425        ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
2426        if (ret < 0) {
2427            ALOGE("%s: csd_client_start_record failed, error %d",
2428                  __func__, ret);
2429        }
2430    }
2431
2432    return ret;
2433}
2434
2435int platform_stop_incall_recording_usecase(void *platform)
2436{
2437    int ret = 0;
2438    struct platform_data *my_data = (struct platform_data *)platform;
2439
2440    if (my_data->csd != NULL) {
2441        ret = my_data->csd->stop_record(ALL_SESSION_VSID);
2442        if (ret < 0) {
2443            ALOGE("%s: csd_client_stop_record failed, error %d",
2444                  __func__, ret);
2445        }
2446    }
2447
2448    return ret;
2449}
2450
2451int platform_start_incall_music_usecase(void *platform)
2452{
2453    int ret = 0;
2454    struct platform_data *my_data = (struct platform_data *)platform;
2455
2456    if (my_data->csd != NULL) {
2457        ret = my_data->csd->start_playback(ALL_SESSION_VSID);
2458        if (ret < 0) {
2459            ALOGE("%s: csd_client_start_playback failed, error %d",
2460                  __func__, ret);
2461        }
2462    }
2463
2464    return ret;
2465}
2466
2467int platform_stop_incall_music_usecase(void *platform)
2468{
2469    int ret = 0;
2470    struct platform_data *my_data = (struct platform_data *)platform;
2471
2472    if (my_data->csd != NULL) {
2473        ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
2474        if (ret < 0) {
2475            ALOGE("%s: csd_client_stop_playback failed, error %d",
2476                  __func__, ret);
2477        }
2478    }
2479
2480    return ret;
2481}
2482
2483int platform_set_parameters(void *platform, struct str_parms *parms)
2484{
2485    struct platform_data *my_data = (struct platform_data *)platform;
2486    char value[128];
2487    char *kv_pairs = str_parms_to_str(parms);
2488    int ret = 0, err;
2489
2490    if (kv_pairs == NULL) {
2491        ret = -EINVAL;
2492        ALOGE("%s: key-value pair is NULL",__func__);
2493        goto done;
2494    }
2495
2496    ALOGV("%s: enter: %s", __func__, kv_pairs);
2497
2498    err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_SOUNDCARD_NAME,
2499                            value, sizeof(value));
2500    if (err >= 0) {
2501        str_parms_del(parms, PLATFORM_CONFIG_KEY_SOUNDCARD_NAME);
2502        my_data->snd_card_name = strdup(value);
2503        ALOGV("%s: sound card name %s", __func__, my_data->snd_card_name);
2504    }
2505
2506    err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO,
2507                            value, sizeof(value));
2508    if (err >= 0) {
2509        struct operator_info *info;
2510        char *str = value;
2511        char *name;
2512
2513        str_parms_del(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO);
2514        info = (struct operator_info *)calloc(1, sizeof(struct operator_info));
2515        name = strtok(str, ";");
2516        info->name = strdup(name);
2517        info->mccmnc = strdup(str + strlen(name) + 1);
2518
2519        list_add_tail(&operator_info_list, &info->list);
2520        ALOGV("%s: add operator[%s] mccmnc[%s]", __func__, info->name, info->mccmnc);
2521    }
2522
2523    memset(value, 0, sizeof(value));
2524    err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_MAX_MIC_COUNT,
2525                            value, sizeof(value));
2526    if (err >= 0) {
2527        str_parms_del(parms, PLATFORM_CONFIG_KEY_MAX_MIC_COUNT);
2528        my_data->max_mic_count = atoi(value);
2529        ALOGV("%s: max_mic_count %s/%d", __func__, value, my_data->max_mic_count);
2530    }
2531
2532done:
2533    ALOGV("%s: exit with code(%d)", __func__, ret);
2534    if (kv_pairs != NULL)
2535        free(kv_pairs);
2536
2537    return ret;
2538}
2539
2540/* Delay in Us */
2541int64_t platform_render_latency(audio_usecase_t usecase)
2542{
2543    switch (usecase) {
2544        case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
2545            return DEEP_BUFFER_PLATFORM_DELAY;
2546        case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
2547            return LOW_LATENCY_PLATFORM_DELAY;
2548        default:
2549            return 0;
2550    }
2551}
2552
2553bool platform_check_and_set_capture_backend_cfg(struct audio_device* adev,
2554         struct audio_usecase *usecase, snd_device_t snd_device)
2555{
2556    enum pcm_format  in_pcm_format = PCM_FORMAT_S16_LE;
2557
2558    if (adev && adev->active_input)
2559        in_pcm_format = adev->active_input->config.format;
2560
2561    // allow 24 bit recording only if voice call is not active
2562    if (!voice_is_in_call(adev) &&
2563        adev->mode != AUDIO_MODE_IN_COMMUNICATION &&
2564        in_pcm_format == PCM_FORMAT_S24_LE) {
2565        audio_route_apply_and_update_path(adev->audio_route, "set-capture-format-24le");
2566    } else {
2567        audio_route_apply_and_update_path(adev->audio_route, "set-capture-format-default");
2568    }
2569
2570    return true;
2571}
2572
2573int platform_set_snd_device_backend(snd_device_t device, const char *backend_tag,
2574                                    const char * hw_interface)
2575{
2576    int ret = 0;
2577
2578    if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
2579        ALOGE("%s: Invalid snd_device = %d",
2580            __func__, device);
2581        ret = -EINVAL;
2582        goto done;
2583    }
2584
2585    ALOGV("%s: backend_tag_table[%s]: old = %s new = %s", __func__,
2586          platform_get_snd_device_name(device),
2587          backend_tag_table[device] != NULL ? backend_tag_table[device]: "null", backend_tag);
2588    if (backend_tag_table[device]) {
2589        free(backend_tag_table[device]);
2590    }
2591    backend_tag_table[device] = strdup(backend_tag);
2592
2593    if (hw_interface != NULL) {
2594        if (hw_interface_table[device])
2595            free(hw_interface_table[device]);
2596        ALOGV("%s: hw_interface_table[%d] = %s", __func__, device, hw_interface);
2597        hw_interface_table[device] = strdup(hw_interface);
2598    }
2599done:
2600    return ret;
2601}
2602
2603int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
2604{
2605    int ret = 0;
2606    if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
2607        ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
2608        ret = -EINVAL;
2609        goto done;
2610    }
2611
2612    if ((type != 0) && (type != 1)) {
2613        ALOGE("%s: invalid usecase type", __func__);
2614        ret = -EINVAL;
2615    }
2616    ALOGV("%s: pcm_device_table[%d][%d] = %d", __func__, usecase, type, pcm_id);
2617    pcm_device_table[usecase][type] = pcm_id;
2618done:
2619    return ret;
2620}
2621
2622#define DEFAULT_NOMINAL_SPEAKER_GAIN 20
2623int ramp_speaker_gain(struct audio_device *adev, bool ramp_up, int target_ramp_up_gain) {
2624    // backup_gain: gain to try to set in case of an error during ramp
2625    int start_gain, end_gain, step, backup_gain, i;
2626    bool error = false;
2627    const struct mixer_ctl *ctl;
2628    const char *mixer_ctl_name_gain_left = "Left Speaker Gain";
2629    const char *mixer_ctl_name_gain_right = "Right Speaker Gain";
2630    struct mixer_ctl *ctl_left = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_left);
2631    struct mixer_ctl *ctl_right = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_right);
2632    if (!ctl_left || !ctl_right) {
2633        ALOGE("%s: Could not get ctl for mixer cmd - %s or %s, not applying speaker gain ramp",
2634                      __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
2635        return -EINVAL;
2636    } else if ((mixer_ctl_get_num_values(ctl_left) != 1)
2637            || (mixer_ctl_get_num_values(ctl_right) != 1)) {
2638        ALOGE("%s: Unexpected num values for mixer cmd - %s or %s, not applying speaker gain ramp",
2639                              __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
2640        return -EINVAL;
2641    }
2642    if (ramp_up) {
2643        start_gain = 0;
2644        end_gain = target_ramp_up_gain > 0 ? target_ramp_up_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
2645        step = +1;
2646        backup_gain = end_gain;
2647    } else {
2648        // using same gain on left and right
2649        const int left_gain = mixer_ctl_get_value(ctl_left, 0);
2650        start_gain = left_gain > 0 ? left_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
2651        end_gain = 0;
2652        step = -1;
2653        backup_gain = start_gain;
2654    }
2655    for (i = start_gain ; i != (end_gain + step) ; i += step) {
2656        //ALOGV("setting speaker gain to %d", i);
2657        if (mixer_ctl_set_value(ctl_left, 0, i)) {
2658            ALOGE("%s: error setting %s to %d during gain ramp",
2659                    __func__, mixer_ctl_name_gain_left, i);
2660            error = true;
2661            break;
2662        }
2663        if (mixer_ctl_set_value(ctl_right, 0, i)) {
2664            ALOGE("%s: error setting %s to %d during gain ramp",
2665                    __func__, mixer_ctl_name_gain_right, i);
2666            error = true;
2667            break;
2668        }
2669        usleep(1000);
2670    }
2671    if (error) {
2672        // an error occured during the ramp, let's still try to go back to a safe volume
2673        if (mixer_ctl_set_value(ctl_left, 0, backup_gain)) {
2674            ALOGE("%s: error restoring left gain to %d", __func__, backup_gain);
2675        }
2676        if (mixer_ctl_set_value(ctl_right, 0, backup_gain)) {
2677            ALOGE("%s: error restoring right gain to %d", __func__, backup_gain);
2678        }
2679    }
2680    return start_gain;
2681}
2682
2683int platform_swap_lr_channels(struct audio_device *adev, bool swap_channels)
2684{
2685    // only update if there is active pcm playback on speaker
2686    struct audio_usecase *usecase;
2687    struct listnode *node;
2688    struct platform_data *my_data = (struct platform_data *)adev->platform;
2689
2690    if (my_data->speaker_lr_swap != swap_channels) {
2691        my_data->speaker_lr_swap = swap_channels;
2692
2693        list_for_each(node, &adev->usecase_list) {
2694            usecase = node_to_item(node, struct audio_usecase, list);
2695            if (usecase->type == PCM_PLAYBACK &&
2696                    usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
2697                /*
2698                 * If acdb tuning is different for SPEAKER_REVERSE, it is must
2699                 * to perform device switch to disable the current backend to
2700                 * enable it with new acdb data.
2701                 */
2702                if (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
2703                    acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE]) {
2704                    const int initial_skpr_gain = ramp_speaker_gain(adev, false /*ramp_up*/, -1);
2705                    select_devices(adev, usecase->id);
2706                    if (initial_skpr_gain != -EINVAL) {
2707                        ramp_speaker_gain(adev, true /*ramp_up*/, initial_skpr_gain);
2708                    }
2709                } else {
2710                    const char *mixer_path;
2711                    if (swap_channels) {
2712                        mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
2713                        audio_route_apply_and_update_path(adev->audio_route, mixer_path);
2714                    } else {
2715                        mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
2716                        audio_route_apply_and_update_path(adev->audio_route, mixer_path);
2717                    }
2718                }
2719                break;
2720            }
2721        }
2722    }
2723    return 0;
2724}
2725