Home | History | Annotate | Download | only in msm8974
      1 /*
      2  * Copyright (C) 2013-2014 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 
     17 #define LOG_TAG "msm8974_platform"
     18 /*#define LOG_NDEBUG 0*/
     19 #define LOG_NDDEBUG 0
     20 
     21 #include <stdlib.h>
     22 #include <dlfcn.h>
     23 #include <cutils/log.h>
     24 #include <cutils/str_parms.h>
     25 #include <cutils/properties.h>
     26 #include <audio_hw.h>
     27 #include <platform_api.h>
     28 #include "platform.h"
     29 
     30 #define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
     31 #define LIB_ACDB_LOADER "libacdbloader.so"
     32 #define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
     33 
     34 #define DUALMIC_CONFIG_NONE 0      /* Target does not contain 2 mics */
     35 #define DUALMIC_CONFIG_ENDFIRE 1
     36 #define DUALMIC_CONFIG_BROADSIDE 2
     37 
     38 /*
     39  * This file will have a maximum of 38 bytes:
     40  *
     41  * 4 bytes: number of audio blocks
     42  * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
     43  * Maximum 10 * 3 bytes: SAD blocks
     44  */
     45 #define MAX_SAD_BLOCKS      10
     46 #define SAD_BLOCK_SIZE      3
     47 
     48 /* EDID format ID for LPCM audio */
     49 #define EDID_FORMAT_LPCM    1
     50 
     51 /* Retry for delay in FW loading*/
     52 #define RETRY_NUMBER 10
     53 #define RETRY_US 500000
     54 #define MAX_SND_CARD 8
     55 
     56 struct audio_block_header
     57 {
     58     int reserved;
     59     int length;
     60 };
     61 
     62 /* Audio calibration related functions */
     63 typedef void (*acdb_deallocate_t)();
     64 #ifdef PLATFORM_MSM8084
     65 typedef int  (*acdb_init_t)(char *);
     66 #else
     67 typedef int  (*acdb_init_t)();
     68 #endif
     69 typedef void (*acdb_send_audio_cal_t)(int, int);
     70 typedef void (*acdb_send_voice_cal_t)(int, int);
     71 typedef int (*acdb_reload_vocvoltable_t)(int);
     72 
     73 /* Audio calibration related functions */
     74 struct platform_data {
     75     struct audio_device *adev;
     76     bool fluence_in_spkr_mode;
     77     bool fluence_in_voice_call;
     78     bool fluence_in_voice_comm;
     79     bool fluence_in_voice_rec;
     80     int  dualmic_config;
     81     void *acdb_handle;
     82     acdb_init_t                acdb_init;
     83     acdb_deallocate_t          acdb_deallocate;
     84     acdb_send_audio_cal_t      acdb_send_audio_cal;
     85     acdb_send_voice_cal_t      acdb_send_voice_cal;
     86     acdb_reload_vocvoltable_t  acdb_reload_vocvoltable;
     87     struct csd_data *csd;
     88     bool ext_speaker;
     89     bool ext_earpiece;
     90 };
     91 
     92 static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
     93     [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
     94                                             DEEP_BUFFER_PCM_DEVICE},
     95     [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
     96                                             LOWLATENCY_PCM_DEVICE},
     97     [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
     98                                          MULTIMEDIA2_PCM_DEVICE},
     99     [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {PLAYBACK_OFFLOAD_DEVICE,
    100                                         PLAYBACK_OFFLOAD_DEVICE},
    101     [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE,
    102                               AUDIO_RECORD_PCM_DEVICE},
    103     [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
    104                                           LOWLATENCY_PCM_DEVICE},
    105     [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE,
    106                             VOICE_CALL_PCM_DEVICE},
    107     [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
    108     [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
    109     [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
    110     [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
    111     [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
    112                                    AUDIO_RECORD_PCM_DEVICE},
    113     [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
    114                                      AUDIO_RECORD_PCM_DEVICE},
    115     [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
    116                                                 AUDIO_RECORD_PCM_DEVICE},
    117     [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
    118 
    119     [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
    120                                           AFE_PROXY_RECORD_PCM_DEVICE},
    121     [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
    122                                         AFE_PROXY_RECORD_PCM_DEVICE},
    123 
    124 };
    125 
    126 /* Array to store sound devices */
    127 static const char * const device_table[SND_DEVICE_MAX] = {
    128     [SND_DEVICE_NONE] = "none",
    129     /* Playback sound devices */
    130     [SND_DEVICE_OUT_HANDSET] = "handset",
    131     [SND_DEVICE_OUT_SPEAKER] = "speaker",
    132     [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
    133     [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
    134     [SND_DEVICE_OUT_HEADPHONES] = "headphones",
    135     [SND_DEVICE_OUT_LINE] = "line",
    136     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
    137     [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
    138     [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
    139     [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
    140     [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
    141     [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
    142     [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
    143     [SND_DEVICE_OUT_HDMI] = "hdmi",
    144     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
    145     [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
    146     [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
    147     [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
    148     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
    149     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
    150     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
    151     [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
    152 
    153     /* Capture sound devices */
    154     [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
    155     [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
    156     [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
    157     [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
    158     [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
    159     [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
    160     [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
    161     [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
    162     [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = "dmic-endfire",
    163 
    164     [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
    165     [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
    166     [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
    167     [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
    168     [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
    169     [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
    170     [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
    171     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
    172     [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = "speaker-dmic-endfire",
    173 
    174     [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
    175     [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
    176 
    177     [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
    178     [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
    179     [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
    180 
    181     [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
    182 
    183     [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
    184     [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
    185     [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
    186     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
    187     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
    188     [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
    189     [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
    190     [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
    191 
    192     [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
    193     [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
    194     [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
    195     [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
    196 
    197     [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
    198 };
    199 
    200 /* ACDB IDs (audio DSP path configuration IDs) for each sound device */
    201 static int acdb_device_table[SND_DEVICE_MAX] = {
    202     [SND_DEVICE_NONE] = -1,
    203     [SND_DEVICE_OUT_HANDSET] = 7,
    204     [SND_DEVICE_OUT_SPEAKER] = 15,
    205     [SND_DEVICE_OUT_SPEAKER_REVERSE] = 15,
    206     [SND_DEVICE_OUT_SPEAKER_SAFE] = 15,
    207     [SND_DEVICE_OUT_HEADPHONES] = 10,
    208     [SND_DEVICE_OUT_LINE] = 77,
    209     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
    210     [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 77,
    211     [SND_DEVICE_OUT_VOICE_HANDSET] = ACDB_ID_VOICE_HANDSET,
    212     [SND_DEVICE_OUT_VOICE_SPEAKER] = ACDB_ID_VOICE_SPEAKER,
    213     [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
    214     [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
    215     [SND_DEVICE_OUT_VOICE_LINE] = 77,
    216     [SND_DEVICE_OUT_HDMI] = 18,
    217     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 15,
    218     [SND_DEVICE_OUT_BT_SCO] = 22,
    219     [SND_DEVICE_OUT_BT_SCO_WB] = 39,
    220     [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = ACDB_ID_VOICE_HANDSET_TMUS,
    221     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
    222     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
    223     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
    224     [SND_DEVICE_OUT_VOICE_TX] = 45,
    225 
    226     [SND_DEVICE_IN_HANDSET_MIC] = 4,
    227     [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
    228     [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
    229     [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
    230     [SND_DEVICE_IN_HANDSET_DMIC] = 41,
    231     [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
    232     [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
    233     [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
    234     [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = 34,
    235 
    236     [SND_DEVICE_IN_SPEAKER_MIC] = 11,
    237     [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
    238     [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
    239     [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
    240     [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
    241     [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
    242     [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
    243     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
    244     [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = 35,
    245 
    246     [SND_DEVICE_IN_HEADSET_MIC] = 8,
    247     [SND_DEVICE_IN_HEADSET_MIC_AEC] = ACDB_ID_HEADSET_MIC_AEC,
    248 
    249     [SND_DEVICE_IN_HDMI_MIC] = 4,
    250     [SND_DEVICE_IN_BT_SCO_MIC] = 21,
    251     [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
    252 
    253     [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
    254 
    255     [SND_DEVICE_IN_VOICE_DMIC] = 41,
    256     [SND_DEVICE_IN_VOICE_DMIC_TMUS] = ACDB_ID_VOICE_DMIC_EF_TMUS,
    257     [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
    258     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
    259     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
    260     [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
    261     [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
    262     [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
    263 
    264     [SND_DEVICE_IN_VOICE_REC_MIC] = 62,
    265     [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 113,
    266     [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 35,
    267     [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 43,
    268 
    269     [SND_DEVICE_IN_VOICE_RX] = 44,
    270 };
    271 
    272 struct name_to_index {
    273     char name[100];
    274     unsigned int index;
    275 };
    276 
    277 #define TO_NAME_INDEX(X)   #X, X
    278 
    279 /* Used to get index from parsed string */
    280 static const struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
    281     /* out */
    282     {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
    283     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
    284     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
    285     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
    286     {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
    287     {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
    288     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
    289     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
    290     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
    291     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
    292     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
    293     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
    294     {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
    295     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
    296     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
    297     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
    298     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET_TMUS)},
    299     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
    300     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
    301     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
    302     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
    303 
    304     /* in */
    305     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
    306     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
    307     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
    308     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
    309     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
    310     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
    311     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
    312     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
    313     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_STEREO)},
    314 
    315     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
    316     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
    317     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
    318     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
    319     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
    320     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
    321     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
    322     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
    323     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
    324 
    325     {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
    326 
    327     {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
    328     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
    329     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
    330 
    331     {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
    332 
    333     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
    334     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
    335     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
    336     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
    337     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
    338     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
    339     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
    340     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
    341 
    342     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
    343     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
    344     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
    345     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
    346 };
    347 
    348 static char * backend_table[SND_DEVICE_MAX] = {0};
    349 
    350 static const struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
    351     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
    352     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
    353     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
    354     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
    355     {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
    356     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
    357     {TO_NAME_INDEX(USECASE_VOICE_CALL)},
    358     {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
    359     {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
    360     {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
    361     {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
    362     {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK)},
    363     {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
    364     {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
    365     {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
    366 };
    367 
    368 #define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
    369 #define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
    370 
    371 static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
    372 static bool is_tmus = false;
    373 
    374 static void check_operator()
    375 {
    376     char value[PROPERTY_VALUE_MAX];
    377     int mccmnc;
    378     property_get("gsm.sim.operator.numeric",value,"0");
    379     mccmnc = atoi(value);
    380     ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
    381     switch(mccmnc) {
    382     /* TMUS MCC(310), MNC(490, 260, 026) */
    383     case 310490:
    384     case 310260:
    385     case 310026:
    386     /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
    387     case 310800:
    388     case 310660:
    389     case 310580:
    390     case 310310:
    391     case 310270:
    392     case 310250:
    393     case 310240:
    394     case 310230:
    395     case 310220:
    396     case 310210:
    397     case 310200:
    398     case 310160:
    399         is_tmus = true;
    400         break;
    401     }
    402 }
    403 
    404 bool is_operator_tmus()
    405 {
    406     pthread_once(&check_op_once_ctl, check_operator);
    407     return is_tmus;
    408 }
    409 
    410 void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
    411 {
    412     char mixer_path[50] = { 0 } ;
    413     snd_device_t snd_device = SND_DEVICE_NONE;
    414     struct listnode *node;
    415     struct audio_usecase *usecase;
    416 
    417     strcpy(mixer_path, "echo-reference");
    418     if (out_device != AUDIO_DEVICE_NONE) {
    419         snd_device = platform_get_output_snd_device(adev->platform, out_device);
    420         platform_add_backend_name(adev->platform, mixer_path, snd_device);
    421     }
    422 
    423     if (enable)
    424         audio_route_apply_and_update_path(adev->audio_route, mixer_path);
    425     else
    426         audio_route_reset_and_update_path(adev->audio_route, mixer_path);
    427 
    428     ALOGV("Setting EC Reference: %d for %s", enable, mixer_path);
    429 }
    430 
    431 static struct csd_data *open_csd_client(bool i2s_ext_modem)
    432 {
    433     struct csd_data *csd = calloc(1, sizeof(struct csd_data));
    434 
    435     csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
    436     if (csd->csd_client == NULL) {
    437         ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
    438         goto error;
    439     } else {
    440         ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
    441 
    442         csd->deinit = (deinit_t)dlsym(csd->csd_client,
    443                                              "csd_client_deinit");
    444         if (csd->deinit == NULL) {
    445             ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
    446                   dlerror());
    447             goto error;
    448         }
    449         csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
    450                                              "csd_client_disable_device");
    451         if (csd->disable_device == NULL) {
    452             ALOGE("%s: dlsym error %s for csd_client_disable_device",
    453                   __func__, dlerror());
    454             goto error;
    455         }
    456         csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
    457                                                "csd_client_enable_device_config");
    458         if (csd->enable_device_config == NULL) {
    459             ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
    460                   __func__, dlerror());
    461             goto error;
    462         }
    463         csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
    464                                              "csd_client_enable_device");
    465         if (csd->enable_device == NULL) {
    466             ALOGE("%s: dlsym error %s for csd_client_enable_device",
    467                   __func__, dlerror());
    468             goto error;
    469         }
    470         csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
    471                                              "csd_client_start_voice");
    472         if (csd->start_voice == NULL) {
    473             ALOGE("%s: dlsym error %s for csd_client_start_voice",
    474                   __func__, dlerror());
    475             goto error;
    476         }
    477         csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
    478                                              "csd_client_stop_voice");
    479         if (csd->stop_voice == NULL) {
    480             ALOGE("%s: dlsym error %s for csd_client_stop_voice",
    481                   __func__, dlerror());
    482             goto error;
    483         }
    484         csd->volume = (volume_t)dlsym(csd->csd_client,
    485                                              "csd_client_volume");
    486         if (csd->volume == NULL) {
    487             ALOGE("%s: dlsym error %s for csd_client_volume",
    488                   __func__, dlerror());
    489             goto error;
    490         }
    491         csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
    492                                              "csd_client_mic_mute");
    493         if (csd->mic_mute == NULL) {
    494             ALOGE("%s: dlsym error %s for csd_client_mic_mute",
    495                   __func__, dlerror());
    496             goto error;
    497         }
    498         csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
    499                                              "csd_client_slow_talk");
    500         if (csd->slow_talk == NULL) {
    501             ALOGE("%s: dlsym error %s for csd_client_slow_talk",
    502                   __func__, dlerror());
    503             goto error;
    504         }
    505         csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
    506                                              "csd_client_start_playback");
    507         if (csd->start_playback == NULL) {
    508             ALOGE("%s: dlsym error %s for csd_client_start_playback",
    509                   __func__, dlerror());
    510             goto error;
    511         }
    512         csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
    513                                              "csd_client_stop_playback");
    514         if (csd->stop_playback == NULL) {
    515             ALOGE("%s: dlsym error %s for csd_client_stop_playback",
    516                   __func__, dlerror());
    517             goto error;
    518         }
    519         csd->start_record = (start_record_t)dlsym(csd->csd_client,
    520                                              "csd_client_start_record");
    521         if (csd->start_record == NULL) {
    522             ALOGE("%s: dlsym error %s for csd_client_start_record",
    523                   __func__, dlerror());
    524             goto error;
    525         }
    526         csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
    527                                              "csd_client_stop_record");
    528         if (csd->stop_record == NULL) {
    529             ALOGE("%s: dlsym error %s for csd_client_stop_record",
    530                   __func__, dlerror());
    531             goto error;
    532         }
    533 
    534         csd->get_sample_rate = (get_sample_rate_t)dlsym(csd->csd_client,
    535                                              "csd_client_get_sample_rate");
    536         if (csd->get_sample_rate == NULL) {
    537             ALOGE("%s: dlsym error %s for csd_client_get_sample_rate",
    538                   __func__, dlerror());
    539 
    540             goto error;
    541         }
    542 
    543         csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
    544 
    545         if (csd->init == NULL) {
    546             ALOGE("%s: dlsym error %s for csd_client_init",
    547                   __func__, dlerror());
    548             goto error;
    549         } else {
    550             csd->init(i2s_ext_modem);
    551         }
    552     }
    553     return csd;
    554 
    555 error:
    556     free(csd);
    557     csd = NULL;
    558     return csd;
    559 }
    560 
    561 void close_csd_client(struct csd_data *csd)
    562 {
    563     if (csd != NULL) {
    564         csd->deinit();
    565         dlclose(csd->csd_client);
    566         free(csd);
    567         csd = NULL;
    568     }
    569 }
    570 
    571 static void platform_csd_init(struct platform_data *my_data)
    572 {
    573 #ifdef PLATFORM_MSM8084
    574     int32_t modems, (*count_modems)(void);
    575     const char *name = "libdetectmodem.so";
    576     const char *func = "count_modems";
    577     const char *error;
    578 
    579     my_data->csd = NULL;
    580 
    581     void *lib = dlopen(name, RTLD_NOW);
    582     error = dlerror();
    583     if (!lib) {
    584         ALOGE("%s: could not find %s: %s", __func__, name, error);
    585         return;
    586     }
    587 
    588     count_modems = NULL;
    589     *(void **)(&count_modems) = dlsym(lib, func);
    590     error = dlerror();
    591     if (!count_modems) {
    592         ALOGE("%s: could not find symbol %s in %s: %s",
    593               __func__, func, name, error);
    594         goto done;
    595     }
    596 
    597     modems = count_modems();
    598     if (modems < 0) {
    599         ALOGE("%s: count_modems failed\n", __func__);
    600         goto done;
    601     }
    602 
    603     ALOGD("%s: num_modems %d\n", __func__, modems);
    604     if (modems > 0)
    605         my_data->csd = open_csd_client(false /*is_i2s_ext_modem*/);
    606 
    607 done:
    608     dlclose(lib);
    609 #else
    610      my_data->csd = NULL;
    611 #endif
    612 }
    613 
    614 static void set_platform_defaults(struct platform_data * my_data)
    615 {
    616     int32_t dev;
    617     for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
    618         backend_table[dev] = NULL;
    619     }
    620 
    621     // TBD - do these go to the platform-info.xml file.
    622     // will help in avoiding strdups here
    623     backend_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
    624     backend_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
    625     backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
    626     backend_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
    627     backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
    628     backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
    629     backend_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
    630     backend_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
    631 
    632     if (my_data->ext_speaker) {
    633         backend_table[SND_DEVICE_OUT_SPEAKER] = strdup("speaker");
    634         backend_table[SND_DEVICE_OUT_SPEAKER_SAFE] = strdup("speaker");
    635         backend_table[SND_DEVICE_OUT_VOICE_SPEAKER] = strdup("speaker");
    636         backend_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = strdup("speaker");
    637         backend_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] =
    638             strdup("speaker-and-headphones");
    639         backend_table[SND_DEVICE_OUT_SPEAKER_AND_LINE] =
    640             strdup("speaker-and-line");
    641     }
    642 
    643     if (my_data->ext_earpiece) {
    644         backend_table[SND_DEVICE_OUT_VOICE_HANDSET] = strdup("handset");
    645         backend_table[SND_DEVICE_OUT_VOICE_HAC_HANDSET] = strdup("handset");
    646         backend_table[SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = strdup("handset");
    647         backend_table[SND_DEVICE_OUT_HANDSET] = strdup("handset");
    648         backend_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("handset");
    649     }
    650 }
    651 
    652 void *platform_init(struct audio_device *adev)
    653 {
    654     char value[PROPERTY_VALUE_MAX];
    655     struct platform_data *my_data;
    656     int retry_num = 0, snd_card_num = 0;
    657     const char *snd_card_name;
    658 
    659     while (snd_card_num < MAX_SND_CARD) {
    660         adev->mixer = mixer_open(snd_card_num);
    661 
    662         while (!adev->mixer && retry_num < RETRY_NUMBER) {
    663             usleep(RETRY_US);
    664             adev->mixer = mixer_open(snd_card_num);
    665             retry_num++;
    666         }
    667 
    668         if (!adev->mixer) {
    669             ALOGE("%s: Unable to open the mixer card: %d", __func__,
    670                    snd_card_num);
    671             retry_num = 0;
    672             snd_card_num++;
    673             continue;
    674         }
    675 
    676         snd_card_name = mixer_get_name(adev->mixer);
    677         ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
    678 
    679         adev->audio_route = audio_route_init(snd_card_num, MIXER_XML_PATH);
    680         if (!adev->audio_route) {
    681             ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
    682             return NULL;
    683         }
    684         adev->snd_card = snd_card_num;
    685         ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
    686         break;
    687     }
    688 
    689     if (snd_card_num >= MAX_SND_CARD) {
    690         ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
    691         return NULL;
    692     }
    693 
    694     my_data = calloc(1, sizeof(struct platform_data));
    695 
    696     my_data->adev = adev;
    697     my_data->dualmic_config = DUALMIC_CONFIG_NONE;
    698     my_data->fluence_in_spkr_mode = false;
    699     my_data->fluence_in_voice_call = false;
    700     my_data->fluence_in_voice_comm = false;
    701     my_data->fluence_in_voice_rec = false;
    702 
    703     /*
    704      * The default assumption is that earpiece (handset), speaker and headphones
    705      * devices are connected to internal HW codec and communicated through
    706      * slimbus backend. If any platform communicates with speaker or earpiece
    707      * or headphones through non-slimbus backend such as MI2S or AUXPCM etc.,
    708      * the ext_xxxx flags must be set accordingly.
    709      */
    710     if (strstr(snd_card_name, "tfa9890_stereo")) {
    711         my_data->ext_speaker = true;
    712         my_data->ext_earpiece = true;
    713     } else if (strstr(snd_card_name, "tfa9890")) {
    714         my_data->ext_speaker = true;
    715     }
    716 
    717     property_get("persist.audio.dualmic.config",value,"");
    718     if (!strcmp("broadside", value)) {
    719         ALOGE("%s: Unsupported dualmic configuration", __func__);
    720     } else if (!strcmp("endfire", value)) {
    721         my_data->dualmic_config = DUALMIC_CONFIG_ENDFIRE;
    722     }
    723 
    724     if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
    725         property_get("persist.audio.fluence.voicecall",value,"");
    726         if (!strcmp("true", value)) {
    727             my_data->fluence_in_voice_call = true;
    728         }
    729 
    730         property_get("persist.audio.fluence.voicecomm",value,"");
    731         if (!strcmp("true", value)) {
    732             my_data->fluence_in_voice_comm = true;
    733         }
    734 
    735         property_get("persist.audio.fluence.voicerec",value,"");
    736         if (!strcmp("true", value)) {
    737             my_data->fluence_in_voice_rec = true;
    738         }
    739 
    740         property_get("persist.audio.fluence.speaker",value,"");
    741         if (!strcmp("true", value)) {
    742             my_data->fluence_in_spkr_mode = true;
    743         }
    744     }
    745 
    746     my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
    747     if (my_data->acdb_handle == NULL) {
    748         ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
    749     } else {
    750         ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
    751         my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
    752                                                     "acdb_loader_deallocate_ACDB");
    753         if (!my_data->acdb_deallocate)
    754             ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
    755                   __func__, LIB_ACDB_LOADER);
    756 
    757         my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
    758                                                     "acdb_loader_send_audio_cal");
    759         if (!my_data->acdb_send_audio_cal)
    760             ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
    761                   __func__, LIB_ACDB_LOADER);
    762 
    763         my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
    764                                                     "acdb_loader_send_voice_cal");
    765         if (!my_data->acdb_send_voice_cal)
    766             ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
    767                   __func__, LIB_ACDB_LOADER);
    768 
    769         my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
    770                                                     "acdb_loader_reload_vocvoltable");
    771         if (!my_data->acdb_reload_vocvoltable)
    772             ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
    773                   __func__, LIB_ACDB_LOADER);
    774 #ifdef PLATFORM_MSM8084
    775         my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
    776                                                     "acdb_loader_init_v2");
    777         if (my_data->acdb_init == NULL)
    778             ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
    779         else
    780             my_data->acdb_init((char *)snd_card_name);
    781 #else
    782         my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
    783                                                     "acdb_loader_init_ACDB");
    784         if (my_data->acdb_init == NULL)
    785             ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
    786         else
    787             my_data->acdb_init();
    788 #endif
    789 
    790     }
    791 
    792     set_platform_defaults(my_data);
    793 
    794     /* Initialize platform specific ids and/or backends*/
    795     platform_info_init();
    796 
    797     /* load csd client */
    798     platform_csd_init(my_data);
    799 
    800     return my_data;
    801 }
    802 
    803 void platform_deinit(void *platform)
    804 {
    805     struct platform_data *my_data = (struct platform_data *)platform;
    806     close_csd_client(my_data->csd);
    807     free(platform);
    808 }
    809 
    810 const char *platform_get_snd_device_name(snd_device_t snd_device)
    811 {
    812     if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
    813         return device_table[snd_device];
    814     else
    815         return "none";
    816 }
    817 
    818 void platform_add_backend_name(void *platform, char *mixer_path,
    819                                snd_device_t snd_device)
    820 {
    821     struct platform_data *my_data = (struct platform_data *)platform;
    822 
    823     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
    824         ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
    825         return;
    826     }
    827 
    828     const char * suffix = backend_table[snd_device];
    829 
    830     if (suffix != NULL) {
    831         strcat(mixer_path, " ");
    832         strcat(mixer_path, suffix);
    833     }
    834 }
    835 
    836 int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
    837 {
    838     int device_id;
    839     if (device_type == PCM_PLAYBACK)
    840         device_id = pcm_device_table[usecase][0];
    841     else
    842         device_id = pcm_device_table[usecase][1];
    843     return device_id;
    844 }
    845 
    846 static int find_index(const struct name_to_index * table, int32_t len,
    847                       const char * name)
    848 {
    849     int ret = 0;
    850     int32_t i;
    851 
    852     if (table == NULL) {
    853         ALOGE("%s: table is NULL", __func__);
    854         ret = -ENODEV;
    855         goto done;
    856     }
    857 
    858     if (name == NULL) {
    859         ALOGE("null key");
    860         ret = -ENODEV;
    861         goto done;
    862     }
    863 
    864     for (i=0; i < len; i++) {
    865         if (!strcmp(table[i].name, name)) {
    866             ret = table[i].index;
    867             goto done;
    868         }
    869     }
    870     ALOGE("%s: Could not find index for name = %s",
    871             __func__, name);
    872     ret = -ENODEV;
    873 done:
    874     return ret;
    875 }
    876 
    877 int platform_get_snd_device_index(char *device_name)
    878 {
    879     return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
    880 }
    881 
    882 int platform_get_usecase_index(const char *usecase_name)
    883 {
    884     return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
    885 }
    886 
    887 int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
    888 {
    889     int ret = 0;
    890 
    891     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
    892         ALOGE("%s: Invalid snd_device = %d",
    893             __func__, snd_device);
    894         ret = -EINVAL;
    895         goto done;
    896     }
    897 
    898     acdb_device_table[snd_device] = acdb_id;
    899 done:
    900     return ret;
    901 }
    902 
    903 int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
    904 {
    905     struct platform_data *my_data = (struct platform_data *)platform;
    906     int acdb_dev_id, acdb_dev_type;
    907 
    908     acdb_dev_id = acdb_device_table[snd_device];
    909     if (acdb_dev_id < 0) {
    910         ALOGE("%s: Could not find acdb id for device(%d)",
    911               __func__, snd_device);
    912         return -EINVAL;
    913     }
    914     if (my_data->acdb_send_audio_cal) {
    915         ALOGD("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
    916               __func__, snd_device, acdb_dev_id);
    917         if (snd_device >= SND_DEVICE_OUT_BEGIN &&
    918                 snd_device < SND_DEVICE_OUT_END)
    919             acdb_dev_type = ACDB_DEV_TYPE_OUT;
    920         else
    921             acdb_dev_type = ACDB_DEV_TYPE_IN;
    922         my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
    923     }
    924     return 0;
    925 }
    926 
    927 int platform_switch_voice_call_device_pre(void *platform)
    928 {
    929     struct platform_data *my_data = (struct platform_data *)platform;
    930     int ret = 0;
    931 
    932     if (my_data->csd != NULL &&
    933         voice_is_in_call(my_data->adev)) {
    934         /* This must be called before disabling mixer controls on APQ side */
    935         ret = my_data->csd->disable_device();
    936         if (ret < 0) {
    937             ALOGE("%s: csd_client_disable_device, failed, error %d",
    938                   __func__, ret);
    939         }
    940     }
    941     return ret;
    942 }
    943 
    944 int platform_switch_voice_call_enable_device_config(void *platform,
    945                                                     snd_device_t out_snd_device,
    946                                                     snd_device_t in_snd_device)
    947 {
    948     struct platform_data *my_data = (struct platform_data *)platform;
    949     int acdb_rx_id, acdb_tx_id;
    950     int ret = 0;
    951 
    952     if (my_data->csd == NULL)
    953         return ret;
    954 
    955     acdb_rx_id = acdb_device_table[out_snd_device];
    956 
    957     acdb_tx_id = acdb_device_table[in_snd_device];
    958 
    959     if (acdb_rx_id > 0 && acdb_tx_id > 0) {
    960         ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
    961         if (ret < 0) {
    962             ALOGE("%s: csd_enable_device_config, failed, error %d",
    963                   __func__, ret);
    964         }
    965     } else {
    966         ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
    967               acdb_rx_id, acdb_tx_id);
    968     }
    969 
    970     return ret;
    971 }
    972 
    973 int platform_switch_voice_call_device_post(void *platform,
    974                                            snd_device_t out_snd_device,
    975                                            snd_device_t in_snd_device)
    976 {
    977     struct platform_data *my_data = (struct platform_data *)platform;
    978     int acdb_rx_id, acdb_tx_id;
    979 
    980     if (my_data->acdb_send_voice_cal == NULL) {
    981         ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
    982     } else {
    983         acdb_rx_id = acdb_device_table[out_snd_device];
    984         acdb_tx_id = acdb_device_table[in_snd_device];
    985 
    986         if (acdb_rx_id > 0 && acdb_tx_id > 0)
    987             my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
    988         else
    989             ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
    990                   acdb_rx_id, acdb_tx_id);
    991     }
    992 
    993     return 0;
    994 }
    995 
    996 int platform_switch_voice_call_usecase_route_post(void *platform,
    997                                                   snd_device_t out_snd_device,
    998                                                   snd_device_t in_snd_device)
    999 {
   1000     struct platform_data *my_data = (struct platform_data *)platform;
   1001     int acdb_rx_id, acdb_tx_id;
   1002     int ret = 0;
   1003 
   1004     if (my_data->csd == NULL)
   1005         return ret;
   1006 
   1007     acdb_rx_id = acdb_device_table[out_snd_device];
   1008 
   1009     acdb_tx_id = acdb_device_table[in_snd_device];
   1010 
   1011     if (acdb_rx_id > 0 && acdb_tx_id > 0) {
   1012         ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
   1013                                           my_data->adev->acdb_settings);
   1014         if (ret < 0) {
   1015             ALOGE("%s: csd_enable_device, failed, error %d", __func__, ret);
   1016         }
   1017     } else {
   1018         ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
   1019               acdb_rx_id, acdb_tx_id);
   1020     }
   1021 
   1022     return ret;
   1023 }
   1024 
   1025 int platform_start_voice_call(void *platform, uint32_t vsid)
   1026 {
   1027     struct platform_data *my_data = (struct platform_data *)platform;
   1028     int ret = 0;
   1029 
   1030     if (my_data->csd != NULL) {
   1031         ret = my_data->csd->start_voice(vsid);
   1032         if (ret < 0) {
   1033             ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
   1034         }
   1035     }
   1036     return ret;
   1037 }
   1038 
   1039 int platform_stop_voice_call(void *platform, uint32_t vsid)
   1040 {
   1041     struct platform_data *my_data = (struct platform_data *)platform;
   1042     int ret = 0;
   1043 
   1044     if (my_data->csd != NULL) {
   1045         ret = my_data->csd->stop_voice(vsid);
   1046         if (ret < 0) {
   1047             ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
   1048         }
   1049     }
   1050     return ret;
   1051 }
   1052 
   1053 int platform_get_sample_rate(void *platform, uint32_t *rate)
   1054 {
   1055     struct platform_data *my_data = (struct platform_data *)platform;
   1056     int ret = 0;
   1057 
   1058     if (my_data->csd != NULL) {
   1059         ret = my_data->csd->get_sample_rate(rate);
   1060         if (ret < 0) {
   1061             ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret);
   1062         }
   1063     }
   1064     return ret;
   1065 }
   1066 
   1067 int platform_set_voice_volume(void *platform, int volume)
   1068 {
   1069     struct platform_data *my_data = (struct platform_data *)platform;
   1070     struct audio_device *adev = my_data->adev;
   1071     struct mixer_ctl *ctl;
   1072     const char *mixer_ctl_name = "Voice Rx Gain";
   1073     int vol_index = 0, ret = 0;
   1074     uint32_t set_values[ ] = {0,
   1075                               ALL_SESSION_VSID,
   1076                               DEFAULT_VOLUME_RAMP_DURATION_MS};
   1077 
   1078     // Voice volume levels are mapped to adsp volume levels as follows.
   1079     // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1  0 -> 0
   1080     // But this values don't changed in kernel. So, below change is need.
   1081     vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
   1082     set_values[0] = vol_index;
   1083 
   1084     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
   1085     if (!ctl) {
   1086         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   1087               __func__, mixer_ctl_name);
   1088         return -EINVAL;
   1089     }
   1090     ALOGV("Setting voice volume index: %d", set_values[0]);
   1091     mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
   1092 
   1093     if (my_data->csd != NULL) {
   1094         ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
   1095                                    DEFAULT_VOLUME_RAMP_DURATION_MS);
   1096         if (ret < 0) {
   1097             ALOGE("%s: csd_volume error %d", __func__, ret);
   1098         }
   1099     }
   1100     return ret;
   1101 }
   1102 
   1103 int platform_set_mic_mute(void *platform, bool state)
   1104 {
   1105     struct platform_data *my_data = (struct platform_data *)platform;
   1106     struct audio_device *adev = my_data->adev;
   1107     struct mixer_ctl *ctl;
   1108     const char *mixer_ctl_name = "Voice Tx Mute";
   1109     int ret = 0;
   1110     uint32_t set_values[ ] = {0,
   1111                               ALL_SESSION_VSID,
   1112                               DEFAULT_MUTE_RAMP_DURATION_MS};
   1113 
   1114     if (adev->mode != AUDIO_MODE_IN_CALL)
   1115         return 0;
   1116 
   1117     set_values[0] = state;
   1118     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
   1119     if (!ctl) {
   1120         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   1121               __func__, mixer_ctl_name);
   1122         return -EINVAL;
   1123     }
   1124     ALOGV("Setting voice mute state: %d", state);
   1125     mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
   1126 
   1127     if (my_data->csd != NULL) {
   1128         ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state,
   1129                                      DEFAULT_MUTE_RAMP_DURATION_MS);
   1130         if (ret < 0) {
   1131             ALOGE("%s: csd_mic_mute error %d", __func__, ret);
   1132         }
   1133     }
   1134     return ret;
   1135 }
   1136 
   1137 int platform_set_device_mute(void *platform, bool state, char *dir)
   1138 {
   1139     struct platform_data *my_data = (struct platform_data *)platform;
   1140     struct audio_device *adev = my_data->adev;
   1141     struct mixer_ctl *ctl;
   1142     char *mixer_ctl_name = NULL;
   1143     int ret = 0;
   1144     uint32_t set_values[ ] = {0,
   1145                               ALL_SESSION_VSID,
   1146                               0};
   1147     if(dir == NULL) {
   1148         ALOGE("%s: Invalid direction:%s", __func__, dir);
   1149         return -EINVAL;
   1150     }
   1151 
   1152     if (!strncmp("rx", dir, sizeof("rx"))) {
   1153         mixer_ctl_name = "Voice Rx Device Mute";
   1154     } else if (!strncmp("tx", dir, sizeof("tx"))) {
   1155         mixer_ctl_name = "Voice Tx Device Mute";
   1156     } else {
   1157         return -EINVAL;
   1158     }
   1159 
   1160     set_values[0] = state;
   1161     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
   1162     if (!ctl) {
   1163         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   1164               __func__, mixer_ctl_name);
   1165         return -EINVAL;
   1166     }
   1167 
   1168     ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
   1169           __func__,state, mixer_ctl_name);
   1170     mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
   1171 
   1172     return ret;
   1173 }
   1174 
   1175 snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
   1176 {
   1177     struct platform_data *my_data = (struct platform_data *)platform;
   1178     struct audio_device *adev = my_data->adev;
   1179     audio_mode_t mode = adev->mode;
   1180     snd_device_t snd_device = SND_DEVICE_NONE;
   1181 
   1182     ALOGV("%s: enter: output devices(%#x)", __func__, devices);
   1183     if (devices == AUDIO_DEVICE_NONE ||
   1184         devices & AUDIO_DEVICE_BIT_IN) {
   1185         ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
   1186         goto exit;
   1187     }
   1188 
   1189     if (voice_is_in_call(adev) || adev->enable_voicerx) {
   1190         if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
   1191             devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
   1192             devices & AUDIO_DEVICE_OUT_LINE) {
   1193             if (voice_is_in_call(adev) &&
   1194                 (adev->voice.tty_mode == TTY_MODE_FULL))
   1195                 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
   1196             else if (voice_is_in_call(adev) &&
   1197                 (adev->voice.tty_mode == TTY_MODE_VCO))
   1198                 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
   1199             else if (voice_is_in_call(adev) &&
   1200                 (adev->voice.tty_mode == TTY_MODE_HCO))
   1201                 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
   1202             else {
   1203                 if (devices & AUDIO_DEVICE_OUT_LINE)
   1204                     snd_device = SND_DEVICE_OUT_VOICE_LINE;
   1205                 else
   1206                     snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
   1207                 }
   1208         } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
   1209             if (adev->bt_wb_speech_enabled) {
   1210                 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
   1211             } else {
   1212                 snd_device = SND_DEVICE_OUT_BT_SCO;
   1213             }
   1214         } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
   1215             snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
   1216         } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
   1217             if(adev->voice.hac)
   1218                 snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
   1219             else if (is_operator_tmus())
   1220                 snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
   1221             else
   1222                 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
   1223         } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
   1224             snd_device = SND_DEVICE_OUT_VOICE_TX;
   1225 
   1226         if (snd_device != SND_DEVICE_NONE) {
   1227             goto exit;
   1228         }
   1229     }
   1230 
   1231     if (popcount(devices) == 2) {
   1232         if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
   1233                         AUDIO_DEVICE_OUT_SPEAKER)) {
   1234             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
   1235         } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
   1236                                AUDIO_DEVICE_OUT_SPEAKER)) {
   1237             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
   1238         } else if (devices == (AUDIO_DEVICE_OUT_LINE |
   1239                                AUDIO_DEVICE_OUT_SPEAKER)) {
   1240             snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
   1241         } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
   1242                                AUDIO_DEVICE_OUT_SPEAKER)) {
   1243             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
   1244         } else {
   1245             ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
   1246             goto exit;
   1247         }
   1248         if (snd_device != SND_DEVICE_NONE) {
   1249             goto exit;
   1250         }
   1251     }
   1252 
   1253     if (popcount(devices) != 1) {
   1254         ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
   1255         goto exit;
   1256     }
   1257 
   1258     if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
   1259         devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
   1260         snd_device = SND_DEVICE_OUT_HEADPHONES;
   1261     } else if (devices & AUDIO_DEVICE_OUT_LINE) {
   1262         snd_device = SND_DEVICE_OUT_LINE;
   1263     } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
   1264         snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
   1265     } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
   1266         if (adev->speaker_lr_swap)
   1267             snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
   1268         else
   1269             snd_device = SND_DEVICE_OUT_SPEAKER;
   1270     } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
   1271         if (adev->bt_wb_speech_enabled) {
   1272             snd_device = SND_DEVICE_OUT_BT_SCO_WB;
   1273         } else {
   1274             snd_device = SND_DEVICE_OUT_BT_SCO;
   1275         }
   1276     } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
   1277         snd_device = SND_DEVICE_OUT_HDMI ;
   1278     } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
   1279         /*HAC support for voice-ish audio (eg visual voicemail)*/
   1280         if(adev->voice.hac)
   1281             snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
   1282         else
   1283             snd_device = SND_DEVICE_OUT_HANDSET;
   1284     } else {
   1285         ALOGE("%s: Unknown device(s) %#x", __func__, devices);
   1286     }
   1287 exit:
   1288     ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
   1289     return snd_device;
   1290 }
   1291 
   1292 snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
   1293 {
   1294     struct platform_data *my_data = (struct platform_data *)platform;
   1295     struct audio_device *adev = my_data->adev;
   1296     audio_source_t  source = (adev->active_input == NULL) ?
   1297                                 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
   1298 
   1299     audio_mode_t    mode   = adev->mode;
   1300     audio_devices_t in_device = ((adev->active_input == NULL) ?
   1301                                     AUDIO_DEVICE_NONE : adev->active_input->device)
   1302                                 & ~AUDIO_DEVICE_BIT_IN;
   1303     audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
   1304                                 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
   1305     snd_device_t snd_device = SND_DEVICE_NONE;
   1306     int channel_count = popcount(channel_mask);
   1307 
   1308     ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
   1309           __func__, out_device, in_device);
   1310     if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
   1311         if (adev->voice.tty_mode != TTY_MODE_OFF) {
   1312             if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
   1313                 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
   1314                 out_device & AUDIO_DEVICE_OUT_LINE) {
   1315                 switch (adev->voice.tty_mode) {
   1316                 case TTY_MODE_FULL:
   1317                     snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
   1318                     break;
   1319                 case TTY_MODE_VCO:
   1320                     snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
   1321                     break;
   1322                 case TTY_MODE_HCO:
   1323                     snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
   1324                     break;
   1325                 default:
   1326                     ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
   1327                 }
   1328                 goto exit;
   1329             }
   1330         }
   1331         if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
   1332             if (my_data->fluence_in_voice_call == false) {
   1333                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
   1334             } else {
   1335                 if (is_operator_tmus())
   1336                     snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS;
   1337                 else
   1338                     snd_device = SND_DEVICE_IN_VOICE_DMIC;
   1339             }
   1340         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
   1341             snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
   1342         } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
   1343             if (adev->bt_wb_speech_enabled) {
   1344                 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
   1345             } else {
   1346                 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
   1347             }
   1348         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
   1349             out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
   1350             out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
   1351             out_device & AUDIO_DEVICE_OUT_LINE) {
   1352             if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
   1353                     my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
   1354                 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
   1355             } else {
   1356                 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
   1357             }
   1358         } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
   1359             snd_device = SND_DEVICE_IN_VOICE_RX;
   1360     } else if (source == AUDIO_SOURCE_CAMCORDER) {
   1361         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
   1362             in_device & AUDIO_DEVICE_IN_BACK_MIC) {
   1363             snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
   1364         }
   1365     } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
   1366         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
   1367             if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
   1368                 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
   1369                     snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
   1370                 else if (my_data->fluence_in_voice_rec &&
   1371                          adev->active_input->enable_ns)
   1372                     snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
   1373             }
   1374 
   1375             if (snd_device == SND_DEVICE_NONE) {
   1376                 if (adev->active_input->enable_ns)
   1377                     snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
   1378                 else
   1379                     snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
   1380             }
   1381         }
   1382     } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
   1383         if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE))
   1384             in_device = AUDIO_DEVICE_IN_BACK_MIC;
   1385         if (adev->active_input) {
   1386             if (adev->active_input->enable_aec &&
   1387                     adev->active_input->enable_ns) {
   1388                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
   1389                     if (my_data->fluence_in_spkr_mode &&
   1390                             my_data->fluence_in_voice_comm &&
   1391                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
   1392                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
   1393                     } else
   1394                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
   1395                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
   1396                     if (my_data->fluence_in_voice_comm &&
   1397                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
   1398                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
   1399                     } else
   1400                         snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
   1401                 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
   1402                     snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
   1403                 }
   1404                 platform_set_echo_reference(adev, true, out_device);
   1405             } else if (adev->active_input->enable_aec) {
   1406                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
   1407                     if (my_data->fluence_in_spkr_mode &&
   1408                             my_data->fluence_in_voice_comm &&
   1409                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
   1410                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
   1411                     } else
   1412                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
   1413                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
   1414                     if (my_data->fluence_in_voice_comm &&
   1415                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
   1416                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
   1417                     } else
   1418                         snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
   1419                } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
   1420                    snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
   1421                }
   1422                 platform_set_echo_reference(adev, true, out_device);
   1423             } else if (adev->active_input->enable_ns) {
   1424                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
   1425                     if (my_data->fluence_in_spkr_mode &&
   1426                             my_data->fluence_in_voice_comm &&
   1427                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
   1428                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
   1429                     } else
   1430                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
   1431                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
   1432                     if (my_data->fluence_in_voice_comm &&
   1433                             my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
   1434                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
   1435                     } else
   1436                         snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
   1437                 }
   1438             }
   1439         }
   1440     } else if (source == AUDIO_SOURCE_DEFAULT) {
   1441         goto exit;
   1442     }
   1443 
   1444 
   1445     if (snd_device != SND_DEVICE_NONE) {
   1446         goto exit;
   1447     }
   1448 
   1449     if (in_device != AUDIO_DEVICE_NONE &&
   1450             !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
   1451             !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
   1452         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
   1453             if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
   1454                     channel_count == 2)
   1455                 snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
   1456             else
   1457                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
   1458         } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
   1459             if (my_data->dualmic_config != DUALMIC_CONFIG_NONE &&
   1460                     channel_count == 2)
   1461                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
   1462             else
   1463                 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
   1464         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
   1465             snd_device = SND_DEVICE_IN_HEADSET_MIC;
   1466         } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
   1467             if (adev->bt_wb_speech_enabled) {
   1468                 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
   1469             } else {
   1470                 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
   1471             }
   1472         } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
   1473             snd_device = SND_DEVICE_IN_HDMI_MIC;
   1474         } else {
   1475             ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
   1476             ALOGW("%s: Using default handset-mic", __func__);
   1477             snd_device = SND_DEVICE_IN_HANDSET_MIC;
   1478         }
   1479     } else {
   1480         if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
   1481             snd_device = SND_DEVICE_IN_HANDSET_MIC;
   1482         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
   1483             snd_device = SND_DEVICE_IN_HEADSET_MIC;
   1484         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
   1485                    out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
   1486                    out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
   1487                    out_device & AUDIO_DEVICE_OUT_LINE) {
   1488             if (channel_count == 2)
   1489                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
   1490             else
   1491                 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
   1492         } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
   1493             if (adev->bt_wb_speech_enabled) {
   1494                 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
   1495             } else {
   1496                 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
   1497             }
   1498         } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
   1499             snd_device = SND_DEVICE_IN_HDMI_MIC;
   1500         } else {
   1501             ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
   1502             ALOGW("%s: Using default handset-mic", __func__);
   1503             snd_device = SND_DEVICE_IN_HANDSET_MIC;
   1504         }
   1505     }
   1506 exit:
   1507     ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
   1508     return snd_device;
   1509 }
   1510 
   1511 int platform_set_hdmi_channels(void *platform,  int channel_count)
   1512 {
   1513     struct platform_data *my_data = (struct platform_data *)platform;
   1514     struct audio_device *adev = my_data->adev;
   1515     struct mixer_ctl *ctl;
   1516     const char *channel_cnt_str = NULL;
   1517     const char *mixer_ctl_name = "HDMI_RX Channels";
   1518     switch (channel_count) {
   1519     case 8:
   1520         channel_cnt_str = "Eight"; break;
   1521     case 7:
   1522         channel_cnt_str = "Seven"; break;
   1523     case 6:
   1524         channel_cnt_str = "Six"; break;
   1525     case 5:
   1526         channel_cnt_str = "Five"; break;
   1527     case 4:
   1528         channel_cnt_str = "Four"; break;
   1529     case 3:
   1530         channel_cnt_str = "Three"; break;
   1531     default:
   1532         channel_cnt_str = "Two"; break;
   1533     }
   1534     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
   1535     if (!ctl) {
   1536         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   1537               __func__, mixer_ctl_name);
   1538         return -EINVAL;
   1539     }
   1540     ALOGV("HDMI channel count: %s", channel_cnt_str);
   1541     mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
   1542     return 0;
   1543 }
   1544 
   1545 int platform_edid_get_max_channels(void *platform)
   1546 {
   1547     struct platform_data *my_data = (struct platform_data *)platform;
   1548     struct audio_device *adev = my_data->adev;
   1549     char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
   1550     char *sad = block;
   1551     int num_audio_blocks;
   1552     int channel_count;
   1553     int max_channels = 0;
   1554     int i, ret, count;
   1555 
   1556     struct mixer_ctl *ctl;
   1557 
   1558     ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
   1559     if (!ctl) {
   1560         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   1561               __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
   1562         return 0;
   1563     }
   1564 
   1565     mixer_ctl_update(ctl);
   1566 
   1567     count = mixer_ctl_get_num_values(ctl);
   1568 
   1569     /* Read SAD blocks, clamping the maximum size for safety */
   1570     if (count > (int)sizeof(block))
   1571         count = (int)sizeof(block);
   1572 
   1573     ret = mixer_ctl_get_array(ctl, block, count);
   1574     if (ret != 0) {
   1575         ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
   1576         return 0;
   1577     }
   1578 
   1579     /* Calculate the number of SAD blocks */
   1580     num_audio_blocks = count / SAD_BLOCK_SIZE;
   1581 
   1582     for (i = 0; i < num_audio_blocks; i++) {
   1583         /* Only consider LPCM blocks */
   1584         if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
   1585             sad += 3;
   1586             continue;
   1587         }
   1588 
   1589         channel_count = (sad[0] & 0x7) + 1;
   1590         if (channel_count > max_channels)
   1591             max_channels = channel_count;
   1592 
   1593         /* Advance to next block */
   1594         sad += 3;
   1595     }
   1596 
   1597     return max_channels;
   1598 }
   1599 
   1600 int platform_set_incall_recording_session_id(void *platform,
   1601                                              uint32_t session_id, int rec_mode)
   1602 {
   1603     int ret = 0;
   1604     struct platform_data *my_data = (struct platform_data *)platform;
   1605     struct audio_device *adev = my_data->adev;
   1606     struct mixer_ctl *ctl;
   1607     const char *mixer_ctl_name = "Voc VSID";
   1608     int num_ctl_values;
   1609     int i;
   1610 
   1611     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
   1612     if (!ctl) {
   1613         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   1614               __func__, mixer_ctl_name);
   1615         ret = -EINVAL;
   1616     } else {
   1617         num_ctl_values = mixer_ctl_get_num_values(ctl);
   1618         for (i = 0; i < num_ctl_values; i++) {
   1619             if (mixer_ctl_set_value(ctl, i, session_id)) {
   1620                 ALOGV("Error: invalid session_id: %x", session_id);
   1621                 ret = -EINVAL;
   1622                 break;
   1623             }
   1624         }
   1625     }
   1626 
   1627     if (my_data->csd != NULL) {
   1628         ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
   1629         if (ret < 0) {
   1630             ALOGE("%s: csd_client_start_record failed, error %d",
   1631                   __func__, ret);
   1632         }
   1633     }
   1634 
   1635     return ret;
   1636 }
   1637 
   1638 int platform_stop_incall_recording_usecase(void *platform)
   1639 {
   1640     int ret = 0;
   1641     struct platform_data *my_data = (struct platform_data *)platform;
   1642 
   1643     if (my_data->csd != NULL) {
   1644         ret = my_data->csd->stop_record(ALL_SESSION_VSID);
   1645         if (ret < 0) {
   1646             ALOGE("%s: csd_client_stop_record failed, error %d",
   1647                   __func__, ret);
   1648         }
   1649     }
   1650 
   1651     return ret;
   1652 }
   1653 
   1654 int platform_start_incall_music_usecase(void *platform)
   1655 {
   1656     int ret = 0;
   1657     struct platform_data *my_data = (struct platform_data *)platform;
   1658 
   1659     if (my_data->csd != NULL) {
   1660         ret = my_data->csd->start_playback(ALL_SESSION_VSID);
   1661         if (ret < 0) {
   1662             ALOGE("%s: csd_client_start_playback failed, error %d",
   1663                   __func__, ret);
   1664         }
   1665     }
   1666 
   1667     return ret;
   1668 }
   1669 
   1670 int platform_stop_incall_music_usecase(void *platform)
   1671 {
   1672     int ret = 0;
   1673     struct platform_data *my_data = (struct platform_data *)platform;
   1674 
   1675     if (my_data->csd != NULL) {
   1676         ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
   1677         if (ret < 0) {
   1678             ALOGE("%s: csd_client_stop_playback failed, error %d",
   1679                   __func__, ret);
   1680         }
   1681     }
   1682 
   1683     return ret;
   1684 }
   1685 
   1686 /* Delay in Us */
   1687 int64_t platform_render_latency(audio_usecase_t usecase)
   1688 {
   1689     switch (usecase) {
   1690         case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
   1691             return DEEP_BUFFER_PLATFORM_DELAY;
   1692         case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
   1693             return LOW_LATENCY_PLATFORM_DELAY;
   1694         default:
   1695             return 0;
   1696     }
   1697 }
   1698 
   1699 int platform_set_snd_device_backend(snd_device_t device, const char *backend)
   1700 {
   1701     int ret = 0;
   1702 
   1703     if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
   1704         ALOGE("%s: Invalid snd_device = %d",
   1705             __func__, device);
   1706         ret = -EINVAL;
   1707         goto done;
   1708     }
   1709 
   1710     if (backend_table[device]) {
   1711         free(backend_table[device]);
   1712     }
   1713     backend_table[device] = strdup(backend);
   1714 done:
   1715     return ret;
   1716 }
   1717 
   1718 int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
   1719 {
   1720     int ret = 0;
   1721     if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
   1722         ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
   1723         ret = -EINVAL;
   1724         goto done;
   1725     }
   1726 
   1727     if ((type != 0) && (type != 1)) {
   1728         ALOGE("%s: invalid usecase type", __func__);
   1729         ret = -EINVAL;
   1730     }
   1731     pcm_device_table[usecase][type] = pcm_id;
   1732 done:
   1733     return ret;
   1734 }
   1735