Home | History | Annotate | Download | only in msm8916
      1 /*
      2  * Copyright (C) 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 
     17 #define LOG_TAG "msm8916_platform"
     18 /*#define LOG_NDEBUG 0*/
     19 #define LOG_NDDEBUG 0
     20 
     21 #include <stdlib.h>
     22 #include <dlfcn.h>
     23 #include <fcntl.h>
     24 #include <sys/ioctl.h>
     25 #include <cutils/log.h>
     26 #include <cutils/properties.h>
     27 #include <cutils/str_parms.h>
     28 #include <audio_hw.h>
     29 #include <platform_api.h>
     30 #include "platform.h"
     31 #include "audio_extn.h"
     32 #include "voice_extn.h"
     33 #include "sound/msmcal-hwdep.h"
     34 #include "audio_extn/tfa_98xx.h"
     35 #include <dirent.h>
     36 #define MAX_MIXER_XML_PATH  100
     37 #define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
     38 #define MIXER_XML_PATH_MTP "/system/etc/mixer_paths_mtp.xml"
     39 #define MIXER_XML_PATH_MSM8909_PM8916 "/system/etc/mixer_paths_msm8909_pm8916.xml"
     40 #define MIXER_XML_PATH_L9300 "/system/etc/mixer_paths_l9300.xml"
     41 
     42 #define LIB_ACDB_LOADER "libacdbloader.so"
     43 #define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
     44 #define CVD_VERSION_MIXER_CTL "CVD Version"
     45 
     46 /*
     47  * This file will have a maximum of 38 bytes:
     48  *
     49  * 4 bytes: number of audio blocks
     50  * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
     51  * Maximum 10 * 3 bytes: SAD blocks
     52  */
     53 #define MAX_SAD_BLOCKS      10
     54 #define SAD_BLOCK_SIZE      3
     55 #define MAX_CVD_VERSION_STRING_SIZE    100
     56 
     57 /* EDID format ID for LPCM audio */
     58 #define EDID_FORMAT_LPCM    1
     59 
     60 /* fallback app type if the default app type from acdb loader fails */
     61 #define DEFAULT_APP_TYPE_RX_PATH  0x11130
     62 #define DEFAULT_APP_TYPE_TX_PATH  0x11132
     63 #define DEFAULT_RX_BACKEND "SLIMBUS_0_RX"
     64 
     65 /* Retry for delay in FW loading*/
     66 #define RETRY_NUMBER 20
     67 #define RETRY_US 500000
     68 #define MAX_SND_CARD 8
     69 
     70 #define SAMPLE_RATE_8KHZ  8000
     71 #define SAMPLE_RATE_16KHZ 16000
     72 
     73 #define MAX_SET_CAL_BYTE_SIZE 65536
     74 
     75 #define MAX_CAL_NAME 20
     76 
     77 #define QMIC_FLAG 0x00000004
     78 
     79 #define TOSTRING_(x) #x
     80 #define TOSTRING(x) TOSTRING_(x)
     81 
     82 char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = {
     83         [WCD9XXX_MBHC_CAL] = "mbhc_cal",
     84 };
     85 
     86 struct audio_block_header
     87 {
     88     int reserved;
     89     int length;
     90 };
     91 
     92 enum {
     93     CAL_MODE_SEND           = 0x1,
     94     CAL_MODE_PERSIST        = 0x2,
     95     CAL_MODE_RTAC           = 0x4
     96 };
     97 
     98 enum {
     99     BUFF_IDX_0 = 0,
    100     BUFF_IDX_1 = 1,
    101 };
    102 
    103 #define PLATFORM_CONFIG_KEY_OPERATOR_INFO "operator_info"
    104 
    105 struct operator_info {
    106     struct listnode list;
    107     char *name;
    108     char *mccmnc;
    109 };
    110 
    111 struct operator_specific_device {
    112     struct listnode list;
    113     char *operator;
    114     char *mixer_path;
    115     int acdb_id;
    116 };
    117 
    118 static struct listnode operator_info_list;
    119 static struct listnode *operator_specific_device_table[SND_DEVICE_MAX];
    120 
    121 /* Audio calibration related functions */
    122 typedef void (*acdb_deallocate_t)();
    123 typedef int  (*acdb_init_v2_cvd_t)(const char *, char *, int);
    124 typedef void (*acdb_send_audio_cal_t)(int, int);
    125 typedef void (*acdb_send_audio_cal_v3_t)(int, int, int , int, int);
    126 typedef void (*acdb_send_voice_cal_t)(int, int);
    127 typedef int (*acdb_reload_vocvoltable_t)(int);
    128 typedef int (*acdb_loader_get_calibration_t)(char *attr, int size, void *data);
    129 acdb_loader_get_calibration_t acdb_loader_get_calibration;
    130 
    131 struct platform_data {
    132     struct audio_device *adev;
    133     bool fluence_in_spkr_mode;
    134     bool fluence_in_voice_call;
    135     bool fluence_in_voice_rec;
    136     int  fluence_type;
    137     char fluence_cap[PROPERTY_VALUE_MAX];
    138     int  fluence_mode;
    139     bool ec_ref_enabled;
    140     bool gsm_mode_enabled;
    141     /* Audio calibration related functions */
    142     void                       *acdb_handle;
    143     acdb_init_v2_cvd_t         acdb_init;
    144     acdb_deallocate_t          acdb_deallocate;
    145     acdb_send_audio_cal_t      acdb_send_audio_cal;
    146     acdb_send_audio_cal_v3_t   acdb_send_audio_cal_v3;
    147     acdb_send_voice_cal_t      acdb_send_voice_cal;
    148     acdb_reload_vocvoltable_t  acdb_reload_vocvoltable;
    149     void *hw_info;
    150     char ec_ref_mixer_path[64];
    151     bool speaker_lr_swap;
    152 
    153     int max_vol_index;
    154 };
    155 
    156 int pcm_device_table[AUDIO_USECASE_MAX][2] = {
    157     [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
    158                                             DEEP_BUFFER_PCM_DEVICE},
    159     [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
    160                                            LOWLATENCY_PCM_DEVICE},
    161     [USECASE_AUDIO_PLAYBACK_HIFI] = {MULTIMEDIA2_PCM_DEVICE,
    162                                         MULTIMEDIA2_PCM_DEVICE},
    163     [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
    164                      {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
    165     [USECASE_AUDIO_PLAYBACK_ULL] = {MULTIMEDIA3_PCM_DEVICE, MULTIMEDIA3_PCM_DEVICE},
    166     [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
    167     [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
    168                                           LOWLATENCY_PCM_DEVICE},
    169     [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
    170     [USECASE_AUDIO_HFP_SCO_WB] = {HFP_PCM_RX, HFP_SCO_RX},
    171     [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE, VOICE_CALL_PCM_DEVICE},
    172     [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
    173     [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
    174     [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
    175     [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
    176     [USECASE_VOICEMMODE1_CALL] = {-1, -1}, /* pcm ids updated from platform info file */
    177     [USECASE_VOICEMMODE2_CALL] = {-1, -1}, /* pcm ids updated from platform info file */
    178     [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
    179                                    AUDIO_RECORD_PCM_DEVICE},
    180     [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
    181                                      AUDIO_RECORD_PCM_DEVICE},
    182     [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
    183                                                 AUDIO_RECORD_PCM_DEVICE},
    184     [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
    185     [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
    186     [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
    187                                           AFE_PROXY_RECORD_PCM_DEVICE},
    188     [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
    189                                         AFE_PROXY_RECORD_PCM_DEVICE},
    190 };
    191 
    192 /* Array to store sound devices */
    193 static const char * const device_table[SND_DEVICE_MAX] = {
    194     [SND_DEVICE_NONE] = "none",
    195     /* Playback sound devices */
    196     [SND_DEVICE_OUT_HANDSET] = "handset",
    197     [SND_DEVICE_OUT_SPEAKER] = "speaker",
    198     [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
    199     [SND_DEVICE_OUT_HEADPHONES] = "headphones",
    200     [SND_DEVICE_OUT_LINE] = "line",
    201     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
    202     [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
    203     [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
    204     [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
    205     [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
    206     [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = "voice-speaker-hfp",
    207     [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
    208     [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
    209     [SND_DEVICE_OUT_HDMI] = "hdmi",
    210     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
    211     [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
    212     [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
    213     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
    214     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
    215     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
    216     [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
    217     [SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy",
    218     [SND_DEVICE_OUT_USB_HEADSET] = "usb-headphones",
    219     [SND_DEVICE_OUT_USB_HEADPHONES] = "usb-headphones",
    220     [SND_DEVICE_OUT_VOICE_USB_HEADSET] = "usb-headphones",
    221     [SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = "usb-headphones",
    222     [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
    223     [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
    224     [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
    225 
    226     /* Capture sound devices */
    227     [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
    228     [SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = "handset-mic-ext",
    229     [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
    230     [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
    231     [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
    232     [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
    233     [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
    234     [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
    235     [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
    236     [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
    237     [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
    238     [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
    239     [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
    240     [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
    241     [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
    242     [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
    243     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
    244     [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
    245     [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = "headset-mic",
    246     [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
    247     [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = "voice-speaker-mic-hfp",
    248     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
    249     [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
    250     [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
    251     [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
    252     [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
    253     [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
    254     [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
    255     [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
    256     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
    257     [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = "voice-speaker-qmic",
    258     [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
    259     [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
    260     [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
    261     [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
    262     [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
    263     [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
    264     [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
    265     [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
    266     [SND_DEVICE_IN_USB_HEADSET_MIC] = "usb-headset-mic",
    267     [SND_DEVICE_IN_CAPTURE_FM] = "capture-fm",
    268     [SND_DEVICE_IN_AANC_HANDSET_MIC] = "aanc-handset-mic",
    269     [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
    270     [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = "handset-stereo-dmic-ef",
    271     [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = "speaker-stereo-dmic-ef",
    272     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
    273     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE] = "voice-speaker-dmic-broadside",
    274     [SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE] = "speaker-dmic-broadside",
    275     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE] = "speaker-dmic-broadside",
    276     [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = "speaker-dmic-broadside",
    277     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = "speaker-dmic-broadside",
    278     [SND_DEVICE_IN_HANDSET_QMIC] = "quad-mic",
    279     [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = "quad-mic",
    280     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
    281     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
    282 };
    283 
    284 /* ACDB IDs (audio DSP path configuration IDs) for each sound device */
    285 static int acdb_device_table[SND_DEVICE_MAX] = {
    286     [SND_DEVICE_NONE] = -1,
    287     [SND_DEVICE_OUT_HANDSET] = 7,
    288     [SND_DEVICE_OUT_SPEAKER] = 14,
    289     [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
    290     [SND_DEVICE_OUT_LINE] = 10,
    291     [SND_DEVICE_OUT_HEADPHONES] = 10,
    292     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
    293     [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 10,
    294     [SND_DEVICE_OUT_VOICE_HANDSET] = 7,
    295     [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
    296     [SND_DEVICE_OUT_VOICE_LINE] = 10,
    297     [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
    298     [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
    299     [SND_DEVICE_OUT_HDMI] = 18,
    300     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
    301     [SND_DEVICE_OUT_BT_SCO] = 22,
    302     [SND_DEVICE_OUT_BT_SCO_WB] = 39,
    303     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
    304     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
    305     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
    306     [SND_DEVICE_OUT_VOICE_TX] = 45,
    307     [SND_DEVICE_OUT_AFE_PROXY] = 0,
    308     [SND_DEVICE_OUT_USB_HEADSET] = 45,
    309     [SND_DEVICE_OUT_VOICE_USB_HEADSET] = 45,
    310     [SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = 45,
    311     [SND_DEVICE_OUT_USB_HEADPHONES] = 45,
    312     [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
    313     [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
    314     [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
    315     [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = 140,
    316 
    317     [SND_DEVICE_IN_HANDSET_MIC] = 4,
    318     [SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = 4,
    319     [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
    320     [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
    321     [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
    322     [SND_DEVICE_IN_HANDSET_DMIC] = 41,
    323     [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
    324     [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
    325     [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
    326     [SND_DEVICE_IN_SPEAKER_MIC] = 11,
    327     [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
    328     [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
    329     [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
    330     [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
    331     [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
    332     [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
    333     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
    334     [SND_DEVICE_IN_HEADSET_MIC] = 8,
    335     [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = 47,
    336     [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
    337     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
    338     [SND_DEVICE_IN_HDMI_MIC] = 4,
    339     [SND_DEVICE_IN_BT_SCO_MIC] = 21,
    340     [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 122,
    341     [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
    342     [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 123,
    343     [SND_DEVICE_IN_CAMCORDER_MIC] = 4,
    344     [SND_DEVICE_IN_VOICE_DMIC] = 41,
    345     [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = 141,
    346     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
    347     [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = 19,
    348     [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
    349     [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
    350     [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
    351     [SND_DEVICE_IN_VOICE_REC_MIC] = 4,
    352     [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107,
    353     [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34,
    354     [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 41,
    355     [SND_DEVICE_IN_VOICE_RX] = 44,
    356     [SND_DEVICE_IN_USB_HEADSET_MIC] = 44,
    357     [SND_DEVICE_IN_CAPTURE_FM] = 0,
    358     [SND_DEVICE_IN_AANC_HANDSET_MIC] = 104,
    359     [SND_DEVICE_IN_QUAD_MIC] = 46,
    360     [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = 34,
    361     [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = 35,
    362     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
    363     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE] = 12,
    364     [SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE] = 12,
    365     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE] = 119,
    366     [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = 121,
    367     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = 120,
    368     [SND_DEVICE_IN_HANDSET_QMIC] = 125,
    369     [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
    370     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
    371     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
    372 };
    373 
    374 struct name_to_index {
    375     char name[100];
    376     unsigned int index;
    377 };
    378 
    379 #define TO_NAME_INDEX(X)   #X, X
    380 
    381 /* Used to get index from parsed sting */
    382 static struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
    383     {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
    384     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
    385     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
    386     {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
    387     {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
    388     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
    389     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
    390     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
    391     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
    392     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
    393     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_HFP)},
    394     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
    395     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
    396     {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
    397     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
    398     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
    399     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
    400     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
    401     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
    402     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
    403     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TX)},
    404     {TO_NAME_INDEX(SND_DEVICE_OUT_AFE_PROXY)},
    405     {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET)},
    406     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_USB_HEADSET)},
    407     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_USB_HEADPHONES)},
    408     {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADPHONES)},
    409     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)},
    410     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
    411     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
    412     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
    413     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_EXTERNAL)},
    414     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
    415     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
    416     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
    417     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
    418     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
    419     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
    420     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
    421     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
    422     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
    423     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
    424     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
    425     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
    426     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
    427     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
    428     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
    429     {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
    430     {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_FLUENCE)},
    431     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
    432     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP)},
    433     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
    434     {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
    435     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
    436     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
    437     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
    438     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
    439     {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
    440     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
    441     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
    442     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_QMIC)},
    443     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
    444     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
    445     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
    446     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
    447     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
    448     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
    449     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
    450     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_RX)},
    451     {TO_NAME_INDEX(SND_DEVICE_IN_USB_HEADSET_MIC)},
    452     {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_FM)},
    453     {TO_NAME_INDEX(SND_DEVICE_IN_AANC_HANDSET_MIC)},
    454     {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
    455     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_STEREO_DMIC)},
    456     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_STEREO_DMIC)},
    457     {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
    458     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE)},
    459     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE)},
    460     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE)},
    461     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE)},
    462     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)},
    463     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
    464     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
    465     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
    466     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
    467 };
    468 
    469 static char * backend_table[SND_DEVICE_MAX] = {0};
    470 static char * hw_interface_table[SND_DEVICE_MAX] = {0};
    471 
    472 static struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
    473     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
    474     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
    475     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_HIFI)},
    476     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
    477     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
    478     {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
    479     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
    480     {TO_NAME_INDEX(USECASE_VOICE_CALL)},
    481     {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
    482     {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
    483     {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
    484     {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
    485     {TO_NAME_INDEX(USECASE_VOICEMMODE1_CALL)},
    486     {TO_NAME_INDEX(USECASE_VOICEMMODE2_CALL)},
    487     {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
    488     {TO_NAME_INDEX(USECASE_AUDIO_SPKR_CALIB_TX)},
    489 };
    490 
    491 #define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
    492 #define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
    493 
    494 static void query_platform(const char *snd_card_name,
    495                                       char *mixer_xml_path)
    496 {
    497     if (!strncmp(snd_card_name, "msm8x16-snd-card-mtp",
    498                  sizeof("msm8x16-snd-card-mtp"))) {
    499         strlcpy(mixer_xml_path, MIXER_XML_PATH_MTP,
    500                 sizeof(MIXER_XML_PATH_MTP));
    501     } else if (!strncmp(snd_card_name, "msm8909-pm8916-snd-card",
    502                  sizeof("msm8909-pm8916-snd-card"))) {
    503         strlcpy(mixer_xml_path, MIXER_XML_PATH_MSM8909_PM8916,
    504                 sizeof(MIXER_XML_PATH_MSM8909_PM8916));
    505     } else if (!strncmp(snd_card_name, "msm8952-snd-card-mtp",
    506                  sizeof("msm8952-snd-card-mtp"))) {
    507         strlcpy(mixer_xml_path, MIXER_XML_PATH_MTP,
    508                 sizeof(MIXER_XML_PATH_MTP));
    509     } else if (!strncmp(snd_card_name, "msm8952-l9300-snd-card",
    510                  sizeof("msm8952-l9300-snd-card"))) {
    511         strlcpy(mixer_xml_path, MIXER_XML_PATH_L9300,
    512                 sizeof(MIXER_XML_PATH_L9300));
    513     } else {
    514         strlcpy(mixer_xml_path, MIXER_XML_PATH,
    515                 sizeof(MIXER_XML_PATH));
    516     }
    517 }
    518 
    519 static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
    520 static bool is_tmus = false;
    521 
    522 static void check_operator()
    523 {
    524     char value[PROPERTY_VALUE_MAX];
    525     int mccmnc;
    526     property_get("gsm.sim.operator.numeric",value,"0");
    527     mccmnc = atoi(value);
    528     ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
    529     switch(mccmnc) {
    530     /* TMUS MCC(310), MNC(490, 260, 026) */
    531     case 310490:
    532     case 310260:
    533     case 310026:
    534     /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
    535     case 310800:
    536     case 310660:
    537     case 310580:
    538     case 310310:
    539     case 310270:
    540     case 310250:
    541     case 310240:
    542     case 310230:
    543     case 310220:
    544     case 310210:
    545     case 310200:
    546     case 310160:
    547         is_tmus = true;
    548         break;
    549     }
    550 }
    551 
    552 bool is_operator_tmus()
    553 {
    554     pthread_once(&check_op_once_ctl, check_operator);
    555     return is_tmus;
    556 }
    557 
    558 static char *get_current_operator()
    559 {
    560     struct listnode *node;
    561     struct operator_info *info_item;
    562     char mccmnc[PROPERTY_VALUE_MAX];
    563     char *ret = NULL;
    564 
    565     property_get("gsm.sim.operator.numeric",mccmnc,"00000");
    566 
    567     list_for_each(node, &operator_info_list) {
    568         info_item = node_to_item(node, struct operator_info, list);
    569         if (strstr(info_item->mccmnc, mccmnc) != NULL) {
    570             ret = info_item->name;
    571         }
    572     }
    573 
    574     return ret;
    575 }
    576 
    577 static struct operator_specific_device *get_operator_specific_device(snd_device_t snd_device)
    578 {
    579     struct listnode *node;
    580     struct operator_specific_device *ret = NULL;
    581     struct operator_specific_device *device_item;
    582     char *operator_name;
    583 
    584     operator_name = get_current_operator();
    585     if (operator_name == NULL)
    586         return ret;
    587 
    588     list_for_each(node, operator_specific_device_table[snd_device]) {
    589         device_item = node_to_item(node, struct operator_specific_device, list);
    590         if (strcmp(operator_name, device_item->operator) == 0) {
    591             ret = device_item;
    592         }
    593     }
    594 
    595     return ret;
    596 }
    597 
    598 static int get_operator_specific_device_acdb_id(snd_device_t snd_device)
    599 {
    600     struct operator_specific_device *device;
    601     int ret = acdb_device_table[snd_device];
    602 
    603     device = get_operator_specific_device(snd_device);
    604     if (device != NULL)
    605         ret = device->acdb_id;
    606 
    607     return ret;
    608 }
    609 
    610 static const char *get_operator_specific_device_mixer_path(snd_device_t snd_device)
    611 {
    612     struct operator_specific_device *device;
    613     const char *ret = device_table[snd_device];
    614 
    615     device = get_operator_specific_device(snd_device);
    616     if (device != NULL)
    617         ret = device->mixer_path;
    618 
    619     return ret;
    620 }
    621 
    622 bool platform_send_gain_dep_cal(void *platform __unused, int level __unused)
    623 {
    624     return true;
    625 }
    626 
    627 void platform_set_echo_reference(struct audio_device *adev, bool enable,
    628     audio_devices_t out_device)
    629 {
    630     struct platform_data *my_data = (struct platform_data *)adev->platform;
    631     snd_device_t snd_device = SND_DEVICE_NONE;
    632 
    633     if (strcmp(my_data->ec_ref_mixer_path, "")) {
    634         ALOGV("%s: disabling %s", __func__, my_data->ec_ref_mixer_path);
    635         audio_route_reset_and_update_path(adev->audio_route,
    636             my_data->ec_ref_mixer_path);
    637     }
    638 
    639     if (enable) {
    640         if (out_device != AUDIO_DEVICE_NONE) {
    641             snd_device = platform_get_output_snd_device(adev->platform, out_device);
    642             platform_add_backend_name(adev->platform, my_data->ec_ref_mixer_path, snd_device);
    643         }
    644 
    645         strlcpy(my_data->ec_ref_mixer_path, "echo-reference",
    646             sizeof(my_data->ec_ref_mixer_path));
    647 
    648         ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
    649         audio_route_apply_and_update_path(adev->audio_route,
    650             my_data->ec_ref_mixer_path);
    651     }
    652 }
    653 
    654 static void set_platform_defaults()
    655 {
    656     int32_t dev;
    657     for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
    658         backend_table[dev] = NULL;
    659         hw_interface_table[dev] = NULL;
    660     }
    661 
    662     // TBD - do these go to the platform-info.xml file.
    663     // will help in avoiding strdups here
    664     backend_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
    665     backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
    666     backend_table[SND_DEVICE_IN_BT_SCO_MIC_NREC] = strdup("bt-sco");
    667     backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = strdup("bt-sco-wb");
    668     backend_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
    669     backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
    670     backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
    671     backend_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
    672     backend_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
    673     backend_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
    674     backend_table[SND_DEVICE_OUT_AFE_PROXY] = strdup("afe-proxy");
    675     backend_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("usb-headphones");
    676     backend_table[SND_DEVICE_OUT_VOICE_USB_HEADSET] = strdup("usb-headphones");
    677     backend_table[SND_DEVICE_OUT_USB_HEADPHONES] = strdup("usb-headphones");
    678     backend_table[SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = strdup("usb-headphones");
    679     backend_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] =
    680         strdup("speaker-and-usb-headphones");
    681     backend_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
    682     backend_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("capture-fm");
    683 }
    684 
    685 void get_cvd_version(char *cvd_version, struct audio_device *adev)
    686 {
    687     struct mixer_ctl *ctl;
    688     int count;
    689     int ret = 0;
    690 
    691     ctl = mixer_get_ctl_by_name(adev->mixer, CVD_VERSION_MIXER_CTL);
    692     if (!ctl) {
    693         ALOGE("%s: Could not get ctl for mixer cmd - %s",  __func__, CVD_VERSION_MIXER_CTL);
    694         goto done;
    695     }
    696     mixer_ctl_update(ctl);
    697 
    698     count = mixer_ctl_get_num_values(ctl);
    699     if (count > MAX_CVD_VERSION_STRING_SIZE)
    700         count = MAX_CVD_VERSION_STRING_SIZE -1;
    701 
    702     ret = mixer_ctl_get_array(ctl, cvd_version, count);
    703     if (ret != 0) {
    704         ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
    705         goto done;
    706     }
    707 
    708 done:
    709     return;
    710 }
    711 
    712 static int hw_util_open(int card_no)
    713 {
    714     int fd = -1;
    715     char dev_name[256];
    716 
    717     snprintf(dev_name, sizeof(dev_name), "/dev/snd/hwC%uD%u",
    718                                card_no, WCD9XXX_CODEC_HWDEP_NODE);
    719     ALOGD("%s Opening device %s\n", __func__, dev_name);
    720     fd = open(dev_name, O_WRONLY);
    721     if (fd < 0) {
    722         ALOGE("%s: cannot open device '%s'\n", __func__, dev_name);
    723         return fd;
    724     }
    725     ALOGD("%s success", __func__);
    726     return fd;
    727 }
    728 
    729 struct param_data {
    730     int    use_case;
    731     int    acdb_id;
    732     int    get_size;
    733     int    buff_size;
    734     int    data_size;
    735     void   *buff;
    736 };
    737 
    738 static int send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration,
    739                           struct platform_data *plat_data __unused, int fd)
    740 {
    741     int ret = 0, type;
    742 
    743     for (type = WCD9XXX_ANC_CAL; type < WCD9XXX_MAX_CAL; type++) {
    744         struct wcdcal_ioctl_buffer codec_buffer;
    745         struct param_data calib;
    746 
    747         if (type != WCD9XXX_MBHC_CAL)
    748             continue;
    749 
    750         calib.get_size = 1;
    751         ret = acdb_loader_get_calibration(cal_name_info[type], sizeof(struct param_data),
    752                                                                  &calib);
    753         if (ret < 0) {
    754             ALOGE("%s get_calibration failed\n", __func__);
    755             return ret;
    756         }
    757         calib.get_size = 0;
    758         calib.buff = malloc(calib.buff_size);
    759         if(calib.buff == NULL) {
    760             ALOGE("%s mem allocation for %d bytes for %s failed\n"
    761                 , __func__, calib.buff_size, cal_name_info[type]);
    762             return -1;
    763         }
    764         ret = acdb_loader_get_calibration(cal_name_info[type],
    765                               sizeof(struct param_data), &calib);
    766         if (ret < 0) {
    767             ALOGE("%s get_calibration failed type=%s calib.size=%d\n"
    768                 , __func__, cal_name_info[type], codec_buffer.size);
    769             free(calib.buff);
    770             return ret;
    771         }
    772         codec_buffer.buffer = calib.buff;
    773         codec_buffer.size = calib.data_size;
    774         codec_buffer.cal_type = type;
    775         if (ioctl(fd, SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE, &codec_buffer) < 0)
    776             ALOGE("Failed to call ioctl  for %s err=%d calib.size=%d",
    777                 cal_name_info[type], errno, codec_buffer.size);
    778         ALOGD("%s cal sent for %s calib.size=%d"
    779             , __func__, cal_name_info[type], codec_buffer.size);
    780         free(calib.buff);
    781     }
    782     return ret;
    783 }
    784 
    785 static void audio_hwdep_send_cal(struct platform_data *plat_data)
    786 {
    787     int fd;
    788 
    789     fd = hw_util_open(plat_data->adev->snd_card);
    790     if (fd == -1) {
    791         ALOGE("%s error open\n", __func__);
    792         return;
    793     }
    794 
    795     acdb_loader_get_calibration = (acdb_loader_get_calibration_t)
    796           dlsym(plat_data->acdb_handle, "acdb_loader_get_calibration");
    797 
    798     if (acdb_loader_get_calibration == NULL) {
    799         ALOGE("%s: ERROR. dlsym Error:%s acdb_loader_get_calibration", __func__,
    800            dlerror());
    801         return;
    802     }
    803     if (send_codec_cal(acdb_loader_get_calibration, plat_data, fd) < 0)
    804         ALOGE("%s: Could not send anc cal", __FUNCTION__);
    805 }
    806 
    807 
    808 int platform_acdb_init(void *platform)
    809 {
    810     struct platform_data *my_data = (struct platform_data *)platform;
    811     char *cvd_version = NULL;
    812     int key = 0;
    813     const char *snd_card_name;
    814     int result;
    815     char value[PROPERTY_VALUE_MAX];
    816     cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
    817     if (!cvd_version)
    818         ALOGE("Failed to allocate cvd version");
    819     else
    820         get_cvd_version(cvd_version, my_data->adev);
    821 
    822     property_get("audio.ds1.metainfo.key",value,"0");
    823     key = atoi(value);
    824     snd_card_name = mixer_get_name(my_data->adev->mixer);
    825 
    826     result = my_data->acdb_init(snd_card_name, cvd_version, key);
    827 
    828     if (cvd_version)
    829         free(cvd_version);
    830     if (!result) {
    831         ALOGD("ACDB initialized");
    832         audio_hwdep_send_cal(my_data);
    833     } else {
    834         ALOGD("ACDB initialization failed");
    835     }
    836     return result;
    837 }
    838 
    839 void *platform_init(struct audio_device *adev)
    840 {
    841     char platform[PROPERTY_VALUE_MAX] = {0};
    842     char baseband[PROPERTY_VALUE_MAX] = {0};
    843     char value[PROPERTY_VALUE_MAX] = {0};
    844     struct platform_data *my_data = NULL;
    845     int retry_num = 0, snd_card_num = 0, key = 0;
    846     const char *snd_card_name;
    847     char mixer_xml_path[MAX_MIXER_XML_PATH] = {0};
    848     char ffspEnable[PROPERTY_VALUE_MAX] = {0};
    849     char *cvd_version = NULL;
    850     int idx;
    851 
    852     my_data = calloc(1, sizeof(struct platform_data));
    853     if (!my_data) {
    854         ALOGE("failed to allocate platform data");
    855         return NULL;
    856     }
    857 
    858     list_init(&operator_info_list);
    859     bool card_verifed[MAX_SND_CARD] = {0};
    860     const int retry_limit = property_get_int32("audio.snd_card.open.retries", RETRY_NUMBER);
    861 
    862     for (;;) {
    863         if (snd_card_num >= MAX_SND_CARD) {
    864             if (retry_num++ >= retry_limit) {
    865                 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
    866                 free(my_data);
    867                 my_data = NULL;
    868                 return NULL;
    869             }
    870 
    871             snd_card_num = 0;
    872             usleep(RETRY_US);
    873             continue;
    874         }
    875 
    876         if (card_verifed[snd_card_num]) {
    877             ++snd_card_num;
    878             continue;
    879         }
    880 
    881         adev->mixer = mixer_open(snd_card_num);
    882 
    883         if (!adev->mixer) {
    884             ALOGE("%s: Unable to open the mixer card: %d", __func__,
    885                snd_card_num);
    886             ++snd_card_num;
    887             continue;
    888         }
    889 
    890         card_verifed[snd_card_num] = true;
    891 
    892         snd_card_name = mixer_get_name(adev->mixer);
    893         ALOGV("%s: snd_card_name: %s", __func__, snd_card_name);
    894 
    895         my_data->hw_info = hw_info_init(snd_card_name);
    896         if (!my_data->hw_info) {
    897             ALOGE("%s: Failed to init hardware info", __func__);
    898         } else {
    899             query_platform(snd_card_name, mixer_xml_path);
    900             ALOGD("%s: mixer path file is %s", __func__,
    901                                     mixer_xml_path);
    902             adev->audio_route = audio_route_init(snd_card_num,
    903                                                  mixer_xml_path);
    904             if (!adev->audio_route) {
    905                 ALOGE("%s: Failed to init audio route controls, aborting.",
    906                        __func__);
    907                 hw_info_deinit(my_data->hw_info);
    908                 my_data->hw_info = NULL;
    909                 free(my_data);
    910                 my_data = NULL;
    911                 mixer_close(adev->mixer);
    912                 adev->mixer = NULL;
    913                 return NULL;
    914             }
    915             adev->snd_card = snd_card_num;
    916             ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
    917             break;
    918         }
    919         ++snd_card_num;
    920         mixer_close(adev->mixer);
    921         adev->mixer = NULL;
    922     }
    923 
    924     //set max volume step for voice call
    925     property_get("ro.config.vc_call_vol_steps", value, TOSTRING(MAX_VOL_INDEX));
    926     my_data->max_vol_index = atoi(value);
    927 
    928     my_data->adev = adev;
    929     my_data->fluence_in_spkr_mode = false;
    930     my_data->fluence_in_voice_call = false;
    931     my_data->fluence_in_voice_rec = false;
    932     my_data->fluence_type = FLUENCE_NONE;
    933     my_data->fluence_mode = FLUENCE_ENDFIRE;
    934 
    935     property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
    936     if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
    937         my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
    938     } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
    939         my_data->fluence_type = FLUENCE_DUAL_MIC;
    940     } else {
    941         my_data->fluence_type = FLUENCE_NONE;
    942     }
    943 
    944     if (my_data->fluence_type != FLUENCE_NONE) {
    945         property_get("persist.audio.fluence.voicecall",value,"");
    946         if (!strncmp("true", value, sizeof("true"))) {
    947             my_data->fluence_in_voice_call = true;
    948         }
    949 
    950         property_get("persist.audio.fluence.voicerec",value,"");
    951         if (!strncmp("true", value, sizeof("true"))) {
    952             my_data->fluence_in_voice_rec = true;
    953         }
    954 
    955         property_get("persist.audio.fluence.speaker",value,"");
    956         if (!strncmp("true", value, sizeof("true"))) {
    957             my_data->fluence_in_spkr_mode = true;
    958         }
    959 
    960         property_get("persist.audio.fluence.mode",value,"");
    961         if (!strncmp("broadside", value, sizeof("broadside"))) {
    962             my_data->fluence_mode = FLUENCE_BROADSIDE;
    963         }
    964     }
    965 
    966     property_get("persist.audio.FFSP.enable", ffspEnable, "");
    967     if (!strncmp("true", ffspEnable, sizeof("true"))) {
    968         acdb_device_table[SND_DEVICE_OUT_SPEAKER] = 131;
    969         acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = 131;
    970         acdb_device_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 131;
    971         acdb_device_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 131;
    972     }
    973 
    974     my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
    975     if (my_data->acdb_handle == NULL) {
    976         ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
    977     } else {
    978         ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
    979         my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
    980                                                     "acdb_loader_deallocate_ACDB");
    981         if (!my_data->acdb_deallocate)
    982             ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
    983                   __func__, LIB_ACDB_LOADER);
    984 
    985         my_data->acdb_send_audio_cal_v3 = (acdb_send_audio_cal_v3_t)dlsym(my_data->acdb_handle,
    986                                                     "acdb_loader_send_audio_cal_v3");
    987         if (!my_data->acdb_send_audio_cal_v3)
    988             ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
    989                   __func__, LIB_ACDB_LOADER);
    990 
    991         my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
    992                                                     "acdb_loader_send_audio_cal");
    993         if (!my_data->acdb_send_audio_cal)
    994             ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
    995                   __func__, LIB_ACDB_LOADER);
    996 
    997         my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
    998                                                     "acdb_loader_send_voice_cal");
    999         if (!my_data->acdb_send_voice_cal)
   1000             ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
   1001                   __func__, LIB_ACDB_LOADER);
   1002 
   1003         my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
   1004                                                     "acdb_loader_reload_vocvoltable");
   1005         if (!my_data->acdb_reload_vocvoltable)
   1006             ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
   1007                   __func__, LIB_ACDB_LOADER);
   1008 
   1009         my_data->acdb_init = (acdb_init_v2_cvd_t)dlsym(my_data->acdb_handle,
   1010                                                     "acdb_loader_init_v2");
   1011         if (my_data->acdb_init == NULL) {
   1012             ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
   1013             goto acdb_init_fail;
   1014         }
   1015         platform_acdb_init(my_data);
   1016     }
   1017 
   1018 acdb_init_fail:
   1019 
   1020     set_platform_defaults();
   1021 
   1022     /* Initialize ACDB and PCM ID's */
   1023     platform_info_init(PLATFORM_INFO_XML_PATH, my_data);
   1024 
   1025 
   1026     /* Read one time ssr property */
   1027     audio_extn_spkr_prot_init(adev);
   1028 
   1029     return my_data;
   1030 }
   1031 
   1032 void platform_deinit(void *platform)
   1033 {
   1034     struct platform_data *my_data = (struct platform_data *)platform;
   1035 
   1036     int32_t dev;
   1037     struct operator_info *info_item;
   1038     struct operator_specific_device *device_item;
   1039     struct listnode *node;
   1040 
   1041     hw_info_deinit(my_data->hw_info);
   1042 
   1043     for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
   1044         if (backend_table[dev]) {
   1045             free(backend_table[dev]);
   1046             backend_table[dev]= NULL;
   1047         }
   1048         if (operator_specific_device_table[dev]) {
   1049             while (!list_empty(operator_specific_device_table[dev])) {
   1050                 node = list_head(operator_specific_device_table[dev]);
   1051                 list_remove(node);
   1052                 device_item = node_to_item(node, struct operator_specific_device, list);
   1053                 free(device_item->operator);
   1054                 free(device_item->mixer_path);
   1055                 free(device_item);
   1056             }
   1057             free(operator_specific_device_table[dev]);
   1058         }
   1059     }
   1060 
   1061     while (!list_empty(&operator_info_list)) {
   1062         node = list_head(&operator_info_list);
   1063         list_remove(node);
   1064         info_item = node_to_item(node, struct operator_info, list);
   1065         free(info_item->name);
   1066         free(info_item->mccmnc);
   1067         free(info_item);
   1068     }
   1069 
   1070     mixer_close(my_data->adev->mixer);
   1071     free(platform);
   1072 }
   1073 
   1074 const char *platform_get_snd_device_name(snd_device_t snd_device)
   1075 {
   1076     if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
   1077         if (operator_specific_device_table[snd_device] != NULL) {
   1078             return get_operator_specific_device_mixer_path(snd_device);
   1079         }
   1080         return device_table[snd_device];
   1081     } else
   1082         return "none";
   1083 }
   1084 
   1085 int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
   1086                                       char *device_name)
   1087 {
   1088     struct platform_data *my_data = (struct platform_data *)platform;
   1089 
   1090     if (platform == NULL) {
   1091         ALOGW("%s: something wrong, use legacy get_snd_device name", __func__);
   1092         strlcpy(device_name, platform_get_snd_device_name(snd_device),
   1093                  DEVICE_NAME_MAX_SIZE);
   1094     } else if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
   1095         if (operator_specific_device_table[snd_device] != NULL) {
   1096             strlcpy(device_name, get_operator_specific_device_mixer_path(snd_device),
   1097                      DEVICE_NAME_MAX_SIZE);
   1098         } else {
   1099             strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
   1100         }
   1101         hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
   1102     } else {
   1103         strlcpy(device_name, "none", DEVICE_NAME_MAX_SIZE);
   1104         return -EINVAL;
   1105     }
   1106 
   1107     return 0;
   1108 }
   1109 
   1110 bool platform_check_and_set_playback_backend_cfg(struct audio_device* adev __unused,
   1111                                               struct audio_usecase *usecase __unused,
   1112                                               snd_device_t snd_device __unused)
   1113 {
   1114     return false;
   1115 }
   1116 
   1117 bool platform_check_and_set_capture_backend_cfg(struct audio_device* adev __unused,
   1118                                               struct audio_usecase *usecase __unused,
   1119                                               snd_device_t snd_device __unused)
   1120 {
   1121     return false;
   1122 }
   1123 
   1124 bool platform_add_gain_level_mapping(struct amp_db_and_gain_table *tbl_entry __unused)
   1125 {
   1126     return false;
   1127 }
   1128 
   1129 int platform_get_gain_level_mapping(struct amp_db_and_gain_table *mapping_tbl __unused,
   1130                                     int table_size __unused)
   1131 {
   1132     return 0;
   1133 }
   1134 
   1135 void platform_add_backend_name(void *platform, char *mixer_path,
   1136                                snd_device_t snd_device)
   1137 {
   1138 
   1139     struct platform_data *my_data = (struct platform_data *)platform;
   1140 
   1141     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
   1142         ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
   1143         return;
   1144     }
   1145 
   1146     const char * suffix = backend_table[snd_device];
   1147 
   1148     if (suffix != NULL) {
   1149         strlcat(mixer_path, " ", MIXER_PATH_MAX_LENGTH);
   1150         strlcat(mixer_path, suffix, MIXER_PATH_MAX_LENGTH);
   1151     }
   1152 }
   1153 
   1154 bool platform_check_backends_match(snd_device_t snd_device1, snd_device_t snd_device2)
   1155 {
   1156     bool result = true;
   1157 
   1158     ALOGV("%s: snd_device1 = %s, snd_device2 = %s", __func__,
   1159                 platform_get_snd_device_name(snd_device1),
   1160                 platform_get_snd_device_name(snd_device2));
   1161 
   1162     if ((snd_device1 < SND_DEVICE_MIN) || (snd_device1 >= SND_DEVICE_MAX)) {
   1163         ALOGE("%s: Invalid snd_device = %s", __func__,
   1164                 platform_get_snd_device_name(snd_device1));
   1165         return false;
   1166     }
   1167     if ((snd_device2 < SND_DEVICE_MIN) || (snd_device2 >= SND_DEVICE_MAX)) {
   1168         ALOGE("%s: Invalid snd_device = %s", __func__,
   1169                 platform_get_snd_device_name(snd_device2));
   1170         return false;
   1171     }
   1172     const char * be_itf1 = hw_interface_table[snd_device1];
   1173     const char * be_itf2 = hw_interface_table[snd_device2];
   1174 
   1175     if (NULL != be_itf1 && NULL != be_itf2) {
   1176         if ((NULL == strstr(be_itf2, be_itf1)) && (NULL == strstr(be_itf1, be_itf2)))
   1177             result = false;
   1178     } else if (NULL != be_itf2 && (NULL == strstr(be_itf2, DEFAULT_RX_BACKEND))) {
   1179         result = false;
   1180     } else if (NULL != be_itf1 && (NULL == strstr(be_itf1, DEFAULT_RX_BACKEND))) {
   1181         result = false;
   1182     }
   1183 
   1184     ALOGV("%s: be_itf1 = %s, be_itf2 = %s, match %d", __func__, be_itf1, be_itf2, result);
   1185     return result;
   1186 }
   1187 
   1188 int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
   1189 {
   1190     int device_id = -1;
   1191 
   1192     if (device_type == PCM_PLAYBACK)
   1193         device_id = pcm_device_table[usecase][0];
   1194     else
   1195         device_id = pcm_device_table[usecase][1];
   1196     return device_id;
   1197 }
   1198 
   1199 static int find_index(struct name_to_index * table, int32_t len, const char * name)
   1200 {
   1201     int ret = 0;
   1202     int32_t i;
   1203 
   1204     if (table == NULL) {
   1205         ALOGE("%s: table is NULL", __func__);
   1206         ret = -ENODEV;
   1207         goto done;
   1208     }
   1209 
   1210     if (name == NULL) {
   1211         ALOGE("null key");
   1212         ret = -ENODEV;
   1213         goto done;
   1214     }
   1215 
   1216     for (i=0; i < len; i++) {
   1217         const char* tn = table[i].name;
   1218         size_t len = strlen(tn);
   1219         if (strncmp(tn, name, len) == 0) {
   1220             if (strlen(name) != len) {
   1221                 continue; // substring
   1222             }
   1223             ret = table[i].index;
   1224             goto done;
   1225         }
   1226     }
   1227     ALOGE("%s: Could not find index for name = %s",
   1228             __func__, name);
   1229     ret = -ENODEV;
   1230 done:
   1231     return ret;
   1232 }
   1233 
   1234 int platform_get_snd_device_index(char *device_name)
   1235 {
   1236     return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
   1237 }
   1238 
   1239 int platform_get_usecase_index(const char *usecase_name)
   1240 {
   1241     return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
   1242 }
   1243 
   1244 void platform_add_operator_specific_device(snd_device_t snd_device,
   1245                                            const char *operator,
   1246                                            const char *mixer_path,
   1247                                            unsigned int acdb_id)
   1248 {
   1249     struct operator_specific_device *device;
   1250 
   1251     if (operator_specific_device_table[snd_device] == NULL) {
   1252         operator_specific_device_table[snd_device] =
   1253             (struct listnode *)calloc(1, sizeof(struct listnode));
   1254         list_init(operator_specific_device_table[snd_device]);
   1255     }
   1256 
   1257     device = (struct operator_specific_device *)calloc(1, sizeof(struct operator_specific_device));
   1258 
   1259     device->operator = strdup(operator);
   1260     device->mixer_path = strdup(mixer_path);
   1261     device->acdb_id = acdb_id;
   1262 
   1263     list_add_tail(operator_specific_device_table[snd_device], &device->list);
   1264 
   1265     ALOGD("%s: device[%s] -> operator[%s] mixer_path[%s] acdb_id[%d]", __func__,
   1266             platform_get_snd_device_name(snd_device), operator, mixer_path, acdb_id);
   1267 
   1268 }
   1269 
   1270 int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
   1271 {
   1272     int ret = 0;
   1273 
   1274     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
   1275         ALOGE("%s: Invalid snd_device = %d",
   1276             __func__, snd_device);
   1277         ret = -EINVAL;
   1278         goto done;
   1279     }
   1280     ALOGV("%s: acdb_device_table[%s]: old = %d new = %d", __func__,
   1281           platform_get_snd_device_name(snd_device), acdb_device_table[snd_device], acdb_id);
   1282     acdb_device_table[snd_device] = acdb_id;
   1283 done:
   1284     return ret;
   1285 }
   1286 
   1287 int platform_get_default_app_type_v2(void *platform, usecase_type_t type, int *app_type)
   1288 {
   1289     ALOGV("%s: platform: %p, type: %d", __func__, platform, type);
   1290     int rc = 0;
   1291     if (type == PCM_CAPTURE) {
   1292         *app_type = DEFAULT_APP_TYPE_TX_PATH;
   1293     } else if (type == PCM_PLAYBACK) {
   1294         *app_type =  DEFAULT_APP_TYPE_RX_PATH;
   1295     } else {
   1296         rc = -EINVAL;
   1297     }
   1298     return rc;
   1299 }
   1300 
   1301 int platform_get_snd_device_acdb_id(snd_device_t snd_device)
   1302 {
   1303     if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
   1304         ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
   1305         return -EINVAL;
   1306     }
   1307 
   1308     if (operator_specific_device_table[snd_device] != NULL)
   1309         return get_operator_specific_device_acdb_id(snd_device);
   1310     else
   1311         return acdb_device_table[snd_device];
   1312 }
   1313 
   1314 int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
   1315 {
   1316     struct platform_data *my_data = (struct platform_data *)platform;
   1317     int acdb_dev_id, acdb_dev_type;
   1318     int sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
   1319 
   1320     acdb_dev_id = acdb_device_table[audio_extn_get_spkr_prot_snd_device(snd_device)];
   1321     if (acdb_dev_id < 0) {
   1322         ALOGE("%s: Could not find acdb id for device(%d)",
   1323               __func__, snd_device);
   1324         return -EINVAL;
   1325     }
   1326         ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
   1327               __func__, snd_device, acdb_dev_id);
   1328     if (snd_device >= SND_DEVICE_OUT_BEGIN && snd_device < SND_DEVICE_OUT_END)
   1329         acdb_dev_type = ACDB_DEV_TYPE_OUT;
   1330     else
   1331         acdb_dev_type = ACDB_DEV_TYPE_IN;
   1332 
   1333     if ((my_data->acdb_send_audio_cal_v3) &&
   1334         (snd_device == SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP) &&
   1335         !audio_extn_tfa_98xx_is_supported() ) {
   1336             /* TX path calibration */
   1337             my_data->acdb_send_audio_cal_v3(acdb_dev_id, ACDB_DEV_TYPE_IN,
   1338                                 DEFAULT_APP_TYPE_TX_PATH, sample_rate, BUFF_IDX_0);
   1339             my_data->acdb_send_audio_cal_v3(acdb_dev_id, ACDB_DEV_TYPE_OUT,
   1340                                 DEFAULT_APP_TYPE_RX_PATH, sample_rate, BUFF_IDX_0);
   1341     } else if ((my_data->acdb_send_audio_cal_v3) &&
   1342                (snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_HFP) &&
   1343                !audio_extn_tfa_98xx_is_supported()) {
   1344             /* RX path calibration */
   1345             ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
   1346                        __func__, snd_device, acdb_dev_id);
   1347             my_data->acdb_send_audio_cal_v3(acdb_dev_id, ACDB_DEV_TYPE_IN,
   1348                                 DEFAULT_APP_TYPE_TX_PATH, sample_rate, BUFF_IDX_1);
   1349             my_data->acdb_send_audio_cal_v3(acdb_dev_id, ACDB_DEV_TYPE_OUT,
   1350                                 DEFAULT_APP_TYPE_RX_PATH, sample_rate, BUFF_IDX_1);
   1351     } else if (my_data->acdb_send_audio_cal) {
   1352         my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
   1353     }
   1354     return 0;
   1355 }
   1356 
   1357 int platform_switch_voice_call_device_pre(void *platform __unused)
   1358 {
   1359     return 0;
   1360 }
   1361 
   1362 int platform_switch_voice_call_enable_device_config(void *platform __unused,
   1363                                                     snd_device_t out_snd_device __unused,
   1364                                                     snd_device_t in_snd_device __unused)
   1365 {
   1366     return 0;
   1367 }
   1368 
   1369 int platform_switch_voice_call_device_post(void *platform,
   1370                                            snd_device_t out_snd_device,
   1371                                            snd_device_t in_snd_device)
   1372 {
   1373     struct platform_data *my_data = (struct platform_data *)platform;
   1374     int acdb_rx_id, acdb_tx_id;
   1375 
   1376     if (my_data->acdb_send_voice_cal == NULL) {
   1377         ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
   1378     } else {
   1379         if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
   1380             audio_extn_spkr_prot_is_enabled())
   1381             out_snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
   1382 
   1383         acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
   1384         acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
   1385 
   1386         if (acdb_rx_id > 0 && acdb_tx_id > 0)
   1387             my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
   1388         else
   1389             ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
   1390                   acdb_rx_id, acdb_tx_id);
   1391     }
   1392 
   1393     return 0;
   1394 }
   1395 
   1396 int platform_switch_voice_call_usecase_route_post(void *platform __unused,
   1397                                                   snd_device_t out_snd_device __unused,
   1398                                                   snd_device_t in_snd_device __unused)
   1399 {
   1400     return 0;
   1401 }
   1402 
   1403 int platform_start_voice_call(void *platform __unused, uint32_t vsid __unused)
   1404 {
   1405     return 0;
   1406 }
   1407 
   1408 int platform_stop_voice_call(void *platform __unused, uint32_t vsid __unused)
   1409 {
   1410     return 0;
   1411 }
   1412 
   1413 int platform_get_sample_rate(void *platform __unused, uint32_t *rate __unused)
   1414 {
   1415     return 0;
   1416 }
   1417 
   1418 void platform_set_speaker_gain_in_combo(struct audio_device *adev __unused,
   1419                                         snd_device_t snd_device __unused,
   1420                                         bool enable __unused)
   1421 {
   1422     return;
   1423 }
   1424 
   1425 int platform_set_voice_volume(void *platform, int volume)
   1426 {
   1427     struct platform_data *my_data = (struct platform_data *)platform;
   1428     struct audio_device *adev = my_data->adev;
   1429     struct mixer_ctl *ctl;
   1430     const char *mixer_ctl_name = "Voice Rx Gain";
   1431     int vol_index = 0, ret = 0;
   1432     uint32_t set_values[ ] = {0,
   1433                               ALL_SESSION_VSID,
   1434                               DEFAULT_VOLUME_RAMP_DURATION_MS};
   1435 
   1436     // Voice volume levels are mapped to adsp volume levels as follows.
   1437     // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1  0 -> 0
   1438     // But this values don't changed in kernel. So, below change is need.
   1439     vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, my_data->max_vol_index);
   1440     set_values[0] = vol_index;
   1441 
   1442     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
   1443     if (!ctl) {
   1444         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   1445               __func__, mixer_ctl_name);
   1446         return -EINVAL;
   1447     }
   1448     ALOGV("Setting voice volume index: %d", set_values[0]);
   1449     ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
   1450 
   1451     return ret;
   1452 }
   1453 
   1454 int platform_set_mic_mute(void *platform, bool state)
   1455 {
   1456     struct platform_data *my_data = (struct platform_data *)platform;
   1457     struct audio_device *adev = my_data->adev;
   1458     struct mixer_ctl *ctl;
   1459     const char *mixer_ctl_name = "Voice Tx Mute";
   1460     int ret = 0;
   1461     uint32_t set_values[ ] = {0,
   1462                               ALL_SESSION_VSID,
   1463                               DEFAULT_MUTE_RAMP_DURATION_MS};
   1464 
   1465     if (audio_extn_hfp_is_active(adev))
   1466         mixer_ctl_name = "HFP TX Mute";
   1467 
   1468     set_values[0] = state;
   1469     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
   1470     if (!ctl) {
   1471         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   1472               __func__, mixer_ctl_name);
   1473         return -EINVAL;
   1474     }
   1475     ALOGV("Setting voice mute state: %d", state);
   1476     // "HFP TX mute" mixer control has xcount of 1.
   1477     if (audio_extn_hfp_is_active(adev))
   1478         ret = mixer_ctl_set_array(ctl, set_values, 1 /*count*/);
   1479     else
   1480         ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
   1481     return ret;
   1482 }
   1483 
   1484 int platform_set_device_mute(void *platform, bool state, char *dir)
   1485 {
   1486     struct platform_data *my_data = (struct platform_data *)platform;
   1487     struct audio_device *adev = my_data->adev;
   1488     struct mixer_ctl *ctl;
   1489     char *mixer_ctl_name = NULL;
   1490     int ret = 0;
   1491     uint32_t set_values[ ] = {0,
   1492                               ALL_SESSION_VSID,
   1493                               0};
   1494     if(dir == NULL) {
   1495         ALOGE("%s: Invalid direction:%s", __func__, dir);
   1496         return -EINVAL;
   1497     }
   1498 
   1499     if (!strncmp("rx", dir, sizeof("rx"))) {
   1500         mixer_ctl_name = "Voice Rx Device Mute";
   1501     } else if (!strncmp("tx", dir, sizeof("tx"))) {
   1502         mixer_ctl_name = "Voice Tx Device Mute";
   1503     } else {
   1504         return -EINVAL;
   1505     }
   1506 
   1507     set_values[0] = state;
   1508     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
   1509     if (!ctl) {
   1510         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   1511               __func__, mixer_ctl_name);
   1512         return -EINVAL;
   1513     }
   1514 
   1515     ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
   1516           __func__,state, mixer_ctl_name);
   1517     mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
   1518 
   1519     return ret;
   1520 }
   1521 
   1522 int platform_can_split_snd_device(snd_device_t snd_device,
   1523                                    int *num_devices,
   1524                                    snd_device_t *new_snd_devices)
   1525 {
   1526     int ret = -EINVAL;
   1527 
   1528     if (NULL == num_devices || NULL == new_snd_devices) {
   1529         ALOGE("%s: NULL pointer ..", __func__);
   1530         return -EINVAL;
   1531     }
   1532 
   1533     /*
   1534      * If wired headset/headphones/line devices share the same backend
   1535      * with speaker/earpiece this routine -EINVAL.
   1536      */
   1537     if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES &&
   1538         !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HEADPHONES)) {
   1539         *num_devices = 2;
   1540         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
   1541         new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
   1542         ret = 0;
   1543     } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_LINE &&
   1544                !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_LINE)) {
   1545         *num_devices = 2;
   1546         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
   1547         new_snd_devices[1] = SND_DEVICE_OUT_LINE;
   1548         ret = 0;
   1549     }
   1550     return ret;
   1551 }
   1552 
   1553 snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
   1554 {
   1555     struct platform_data *my_data = (struct platform_data *)platform;
   1556     struct audio_device *adev = my_data->adev;
   1557     audio_mode_t mode = adev->mode;
   1558     snd_device_t snd_device = SND_DEVICE_NONE;
   1559 
   1560     audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
   1561                                 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
   1562     int channel_count = popcount(channel_mask);
   1563 
   1564     ALOGV("%s: enter: output devices(%#x)", __func__, devices);
   1565     if (devices == AUDIO_DEVICE_NONE ||
   1566         devices & AUDIO_DEVICE_BIT_IN) {
   1567         ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
   1568         goto exit;
   1569     }
   1570 
   1571     if (popcount(devices) == 2) {
   1572         if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
   1573                         AUDIO_DEVICE_OUT_SPEAKER)) {
   1574             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
   1575         } else if (devices == (AUDIO_DEVICE_OUT_LINE |
   1576                                AUDIO_DEVICE_OUT_SPEAKER)) {
   1577                 snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
   1578         } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
   1579                                AUDIO_DEVICE_OUT_SPEAKER)) {
   1580             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
   1581         } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
   1582                                AUDIO_DEVICE_OUT_SPEAKER)) {
   1583             snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
   1584         } else if (devices == (AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
   1585                                AUDIO_DEVICE_OUT_SPEAKER)) {
   1586             snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
   1587         } else {
   1588             ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
   1589             goto exit;
   1590         }
   1591         if (snd_device != SND_DEVICE_NONE) {
   1592             goto exit;
   1593         }
   1594     }
   1595 
   1596     if (popcount(devices) != 1) {
   1597         ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
   1598         goto exit;
   1599     }
   1600 
   1601     if (mode == AUDIO_MODE_IN_CALL || audio_extn_hfp_is_active(adev)) {
   1602         if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
   1603             devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
   1604             devices & AUDIO_DEVICE_OUT_LINE) {
   1605             if (adev->voice.tty_mode != TTY_MODE_OFF) {
   1606                 switch (adev->voice.tty_mode) {
   1607                 case TTY_MODE_FULL:
   1608                     snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
   1609                     break;
   1610                 case TTY_MODE_VCO:
   1611                     snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
   1612                     break;
   1613                 case TTY_MODE_HCO:
   1614                     snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
   1615                     break;
   1616                 default:
   1617                     ALOGE("%s: Invalid TTY mode (%#x)",
   1618                           __func__, adev->voice.tty_mode);
   1619                 }
   1620             } else if (devices & AUDIO_DEVICE_OUT_LINE) {
   1621                 snd_device = SND_DEVICE_OUT_VOICE_LINE;
   1622             } else {
   1623                 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
   1624             }
   1625         } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
   1626             if (adev->bt_wb_speech_enabled)
   1627                 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
   1628             else
   1629                 snd_device = SND_DEVICE_OUT_BT_SCO;
   1630         } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
   1631             if (audio_extn_hfp_is_active(adev))
   1632                 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_HFP;
   1633             else
   1634                 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
   1635         } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
   1636                    devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
   1637             snd_device = SND_DEVICE_OUT_USB_HEADSET;
   1638         } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
   1639                 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
   1640         } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
   1641             snd_device = SND_DEVICE_OUT_VOICE_TX;
   1642 
   1643         if (snd_device != SND_DEVICE_NONE) {
   1644             goto exit;
   1645         }
   1646     }
   1647 
   1648     if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
   1649         devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
   1650                 snd_device = SND_DEVICE_OUT_HEADPHONES;
   1651     } else if (devices & AUDIO_DEVICE_OUT_LINE) {
   1652         snd_device = SND_DEVICE_OUT_LINE;
   1653     } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
   1654         if (my_data->speaker_lr_swap)
   1655             snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
   1656         else
   1657             snd_device = SND_DEVICE_OUT_SPEAKER;
   1658     } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
   1659         if (adev->bt_wb_speech_enabled)
   1660             snd_device = SND_DEVICE_OUT_BT_SCO_WB;
   1661         else
   1662             snd_device = SND_DEVICE_OUT_BT_SCO;
   1663     } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
   1664         snd_device = SND_DEVICE_OUT_HDMI ;
   1665     } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
   1666                devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
   1667         snd_device = SND_DEVICE_OUT_USB_HEADSET;
   1668     } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
   1669         snd_device = SND_DEVICE_OUT_HANDSET;
   1670     } else {
   1671         ALOGE("%s: Unknown device(s) %#x", __func__, devices);
   1672     }
   1673 exit:
   1674     ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
   1675     return snd_device;
   1676 }
   1677 
   1678 snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
   1679 {
   1680     struct platform_data *my_data = (struct platform_data *)platform;
   1681     struct audio_device *adev = my_data->adev;
   1682     audio_source_t  source = (adev->active_input == NULL) ?
   1683                                 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
   1684 
   1685     audio_mode_t    mode   = adev->mode;
   1686     audio_devices_t in_device = ((adev->active_input == NULL) ?
   1687                                     AUDIO_DEVICE_NONE : adev->active_input->device)
   1688                                 & ~AUDIO_DEVICE_BIT_IN;
   1689     audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
   1690                                 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
   1691     snd_device_t snd_device = SND_DEVICE_NONE;
   1692     int channel_count = popcount(channel_mask);
   1693 
   1694     ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
   1695           __func__, out_device, in_device);
   1696 
   1697     if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
   1698         audio_extn_hfp_is_active(adev))) {
   1699         if (adev->voice.tty_mode != TTY_MODE_OFF) {
   1700             if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
   1701                 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
   1702                 out_device & AUDIO_DEVICE_OUT_LINE) {
   1703                 switch (adev->voice.tty_mode) {
   1704                 case TTY_MODE_FULL:
   1705                     snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
   1706                     break;
   1707                 case TTY_MODE_VCO:
   1708                     snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
   1709                     break;
   1710                 case TTY_MODE_HCO:
   1711                     snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
   1712                     break;
   1713                 default:
   1714                     ALOGE("%s: Invalid TTY mode (%#x)",
   1715                           __func__, adev->voice.tty_mode);
   1716                 }
   1717                 goto exit;
   1718             }
   1719         }
   1720         if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
   1721             out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
   1722             out_device & AUDIO_DEVICE_OUT_LINE) {
   1723             if (my_data->fluence_type == FLUENCE_NONE ||
   1724                 my_data->fluence_in_voice_call == false) {
   1725                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
   1726                 if (audio_extn_hfp_is_active(adev))
   1727                     platform_set_echo_reference(adev, true, out_device);
   1728             } else {
   1729                 snd_device = SND_DEVICE_IN_VOICE_DMIC;
   1730                 adev->acdb_settings |= DMIC_FLAG;
   1731             }
   1732         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
   1733             snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
   1734             if (audio_extn_hfp_is_active(adev))
   1735                 platform_set_echo_reference(adev, true, out_device);
   1736         } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
   1737             if (adev->bt_wb_speech_enabled) {
   1738                 if (adev->bluetooth_nrec)
   1739                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
   1740                 else
   1741                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
   1742             } else {
   1743                 if (adev->bluetooth_nrec)
   1744                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
   1745                 else
   1746                     snd_device = SND_DEVICE_IN_BT_SCO_MIC;
   1747             }
   1748         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
   1749             if (my_data->fluence_type != FLUENCE_NONE &&
   1750                 my_data->fluence_in_voice_call &&
   1751                 my_data->fluence_in_spkr_mode) {
   1752                     if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
   1753                        adev->acdb_settings |= QMIC_FLAG;
   1754                        snd_device = SND_DEVICE_IN_VOICE_SPEAKER_QMIC;
   1755                     } else {
   1756                        adev->acdb_settings |= DMIC_FLAG;
   1757                        if (my_data->fluence_mode == FLUENCE_BROADSIDE)
   1758                            snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE;
   1759                        else
   1760                            snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
   1761                     }
   1762             } else {
   1763                 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
   1764                 if (audio_extn_hfp_is_active(adev)) {
   1765                     snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP;
   1766                     platform_set_echo_reference(adev, true, out_device);
   1767                 } else {
   1768                     snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
   1769                 }
   1770             }
   1771         } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
   1772             snd_device = SND_DEVICE_IN_VOICE_RX;
   1773     } else if (source == AUDIO_SOURCE_CAMCORDER) {
   1774         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
   1775             in_device & AUDIO_DEVICE_IN_BACK_MIC) {
   1776             if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
   1777                 channel_count == 2)
   1778                 snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
   1779             else
   1780                 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
   1781         }
   1782     } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
   1783         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
   1784             if (channel_count == 2) {
   1785                 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
   1786                 adev->acdb_settings |= DMIC_FLAG;
   1787             } else if (adev->active_input->enable_ns)
   1788                 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
   1789             else if (my_data->fluence_type != FLUENCE_NONE &&
   1790                      my_data->fluence_in_voice_rec) {
   1791                 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
   1792                 adev->acdb_settings |= DMIC_FLAG;
   1793             } else {
   1794                 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
   1795             }
   1796         }
   1797     } else if ((source == AUDIO_SOURCE_VOICE_COMMUNICATION) ||
   1798               (mode == AUDIO_MODE_IN_COMMUNICATION)) {
   1799         if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
   1800             in_device = AUDIO_DEVICE_IN_BACK_MIC;
   1801         if (adev->active_input) {
   1802             if (my_data->fluence_type != FLUENCE_NONE &&
   1803                 adev->active_input->enable_aec &&
   1804                 adev->active_input->enable_ns) {
   1805                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
   1806                     if (my_data->fluence_in_spkr_mode) {
   1807                         if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
   1808                             snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
   1809                         } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
   1810                             if (my_data->fluence_mode == FLUENCE_BROADSIDE)
   1811                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
   1812                             else
   1813                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
   1814                         }
   1815                         adev->acdb_settings |= DMIC_FLAG;
   1816                     } else
   1817                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
   1818                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
   1819                     if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
   1820                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
   1821                         adev->acdb_settings |= DMIC_FLAG;
   1822                     } else
   1823                         snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
   1824                 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
   1825                     snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
   1826                 }
   1827                 platform_set_echo_reference(adev, true, out_device);
   1828             } else if (my_data->fluence_type != FLUENCE_NONE &&
   1829                        adev->active_input->enable_aec) {
   1830                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
   1831                     if (my_data->fluence_in_spkr_mode) {
   1832                         if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
   1833                             snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
   1834                         } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
   1835                             if (my_data->fluence_mode == FLUENCE_BROADSIDE)
   1836                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
   1837                             else
   1838                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
   1839                         }
   1840                         adev->acdb_settings |= DMIC_FLAG;
   1841                     } else
   1842                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
   1843                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
   1844                     if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
   1845                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
   1846                         adev->acdb_settings |= DMIC_FLAG;
   1847                     } else
   1848                         snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
   1849                 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
   1850                     snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
   1851                 }
   1852                 platform_set_echo_reference(adev, true, out_device);
   1853             } else if (my_data->fluence_type != FLUENCE_NONE &&
   1854                        adev->active_input->enable_ns) {
   1855                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
   1856                     if (my_data->fluence_in_spkr_mode) {
   1857                         if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
   1858                             snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
   1859                         } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
   1860                             if (my_data->fluence_mode == FLUENCE_BROADSIDE)
   1861                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
   1862                             else
   1863                                 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
   1864                         }
   1865                         adev->acdb_settings |= DMIC_FLAG;
   1866                     } else
   1867                         snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
   1868                 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
   1869                     if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
   1870                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
   1871                         adev->acdb_settings |= DMIC_FLAG;
   1872                     } else
   1873                         snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
   1874                 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
   1875                     snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
   1876                 }
   1877                 platform_set_echo_reference(adev, false, out_device);
   1878             } else
   1879                 platform_set_echo_reference(adev, false, out_device);
   1880         }
   1881     } else if (source == AUDIO_SOURCE_FM_TUNER) {
   1882         snd_device = SND_DEVICE_IN_CAPTURE_FM;
   1883     } else if (source == AUDIO_SOURCE_DEFAULT) {
   1884         goto exit;
   1885     }
   1886 
   1887 
   1888     if (snd_device != SND_DEVICE_NONE) {
   1889         goto exit;
   1890     }
   1891 
   1892     if (in_device != AUDIO_DEVICE_NONE &&
   1893             !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
   1894             !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
   1895         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
   1896             if (my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC) &&
   1897                     channel_count == 2)
   1898                 snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
   1899             else
   1900                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
   1901         } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
   1902             snd_device = SND_DEVICE_IN_SPEAKER_MIC;
   1903         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
   1904             snd_device = SND_DEVICE_IN_HEADSET_MIC;
   1905         } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
   1906             if (adev->bt_wb_speech_enabled) {
   1907                 if (adev->bluetooth_nrec)
   1908                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
   1909                 else
   1910                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
   1911             } else {
   1912                 if (adev->bluetooth_nrec)
   1913                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
   1914                 else
   1915                     snd_device = SND_DEVICE_IN_BT_SCO_MIC;
   1916             }
   1917         } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
   1918             snd_device = SND_DEVICE_IN_HDMI_MIC;
   1919         } else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
   1920                    in_device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) {
   1921             snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
   1922         } else if (in_device & AUDIO_DEVICE_IN_FM_TUNER) {
   1923             snd_device = SND_DEVICE_IN_CAPTURE_FM;
   1924         } else {
   1925             ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
   1926             ALOGW("%s: Using default handset-mic", __func__);
   1927             snd_device = SND_DEVICE_IN_HANDSET_MIC;
   1928         }
   1929     } else {
   1930         if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
   1931             snd_device = SND_DEVICE_IN_HANDSET_MIC;
   1932         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
   1933             snd_device = SND_DEVICE_IN_HEADSET_MIC;
   1934         } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
   1935             if (channel_count > 1)
   1936                 snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
   1937             else
   1938                 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
   1939         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
   1940                        out_device & AUDIO_DEVICE_OUT_LINE) {
   1941             snd_device = SND_DEVICE_IN_HANDSET_MIC;
   1942         } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
   1943             if (adev->bt_wb_speech_enabled) {
   1944                 if (adev->bluetooth_nrec)
   1945                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
   1946                 else
   1947                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
   1948             } else {
   1949                 if (adev->bluetooth_nrec)
   1950                     snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
   1951                 else
   1952                     snd_device = SND_DEVICE_IN_BT_SCO_MIC;
   1953             }
   1954         } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
   1955             snd_device = SND_DEVICE_IN_HDMI_MIC;
   1956         } else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
   1957                    out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
   1958             snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
   1959         } else {
   1960             ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
   1961             ALOGW("%s: Using default handset-mic", __func__);
   1962             snd_device = SND_DEVICE_IN_HANDSET_MIC;
   1963         }
   1964     }
   1965 exit:
   1966     ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
   1967     return snd_device;
   1968 }
   1969 
   1970 int platform_set_hdmi_channels(void *platform,  int channel_count)
   1971 {
   1972     struct platform_data *my_data = (struct platform_data *)platform;
   1973     struct audio_device *adev = my_data->adev;
   1974     struct mixer_ctl *ctl;
   1975     const char *channel_cnt_str = NULL;
   1976     const char *mixer_ctl_name = "HDMI_RX Channels";
   1977     switch (channel_count) {
   1978     case 8:
   1979         channel_cnt_str = "Eight"; break;
   1980     case 7:
   1981         channel_cnt_str = "Seven"; break;
   1982     case 6:
   1983         channel_cnt_str = "Six"; break;
   1984     case 5:
   1985         channel_cnt_str = "Five"; break;
   1986     case 4:
   1987         channel_cnt_str = "Four"; break;
   1988     case 3:
   1989         channel_cnt_str = "Three"; break;
   1990     default:
   1991         channel_cnt_str = "Two"; break;
   1992     }
   1993     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
   1994     if (!ctl) {
   1995         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   1996               __func__, mixer_ctl_name);
   1997         return -EINVAL;
   1998     }
   1999     ALOGV("HDMI channel count: %s", channel_cnt_str);
   2000     mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
   2001     return 0;
   2002 }
   2003 
   2004 int platform_edid_get_max_channels(void *platform)
   2005 {
   2006     struct platform_data *my_data = (struct platform_data *)platform;
   2007     struct audio_device *adev = my_data->adev;
   2008     char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
   2009     char *sad = block;
   2010     int num_audio_blocks;
   2011     int channel_count;
   2012     int max_channels = 0;
   2013     int i, ret, count;
   2014 
   2015     struct mixer_ctl *ctl;
   2016 
   2017     ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
   2018     if (!ctl) {
   2019         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   2020               __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
   2021         return 0;
   2022     }
   2023 
   2024     mixer_ctl_update(ctl);
   2025 
   2026     count = mixer_ctl_get_num_values(ctl);
   2027 
   2028     /* Read SAD blocks, clamping the maximum size for safety */
   2029     if (count > (int)sizeof(block))
   2030         count = (int)sizeof(block);
   2031 
   2032     ret = mixer_ctl_get_array(ctl, block, count);
   2033     if (ret != 0) {
   2034         ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
   2035         return 0;
   2036     }
   2037 
   2038     /* Calculate the number of SAD blocks */
   2039     num_audio_blocks = count / SAD_BLOCK_SIZE;
   2040 
   2041     for (i = 0; i < num_audio_blocks; i++) {
   2042         /* Only consider LPCM blocks */
   2043         if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
   2044             sad += 3;
   2045             continue;
   2046         }
   2047 
   2048         channel_count = (sad[0] & 0x7) + 1;
   2049         if (channel_count > max_channels)
   2050             max_channels = channel_count;
   2051 
   2052         /* Advance to next block */
   2053         sad += 3;
   2054     }
   2055 
   2056     return max_channels;
   2057 }
   2058 
   2059 int platform_set_incall_recording_session_id(void *platform,
   2060                                              uint32_t session_id,
   2061                                              int rec_mode __unused)
   2062 {
   2063     int ret = 0;
   2064     struct platform_data *my_data = (struct platform_data *)platform;
   2065     struct audio_device *adev = my_data->adev;
   2066     struct mixer_ctl *ctl;
   2067     const char *mixer_ctl_name = "Voc VSID";
   2068     int num_ctl_values;
   2069     int i;
   2070 
   2071     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
   2072     if (!ctl) {
   2073         ALOGE("%s: Could not get ctl for mixer cmd - %s",
   2074               __func__, mixer_ctl_name);
   2075         ret = -EINVAL;
   2076     } else {
   2077         num_ctl_values = mixer_ctl_get_num_values(ctl);
   2078         for (i = 0; i < num_ctl_values; i++) {
   2079             if (mixer_ctl_set_value(ctl, i, session_id)) {
   2080                 ALOGV("Error: invalid session_id: %x", session_id);
   2081                 ret = -EINVAL;
   2082                 break;
   2083             }
   2084         }
   2085     }
   2086     return ret;
   2087 }
   2088 
   2089 int platform_stop_incall_recording_usecase(void *platform __unused)
   2090 {
   2091     return 0;
   2092 }
   2093 
   2094 int platform_start_incall_music_usecase(void *platform __unused)
   2095 {
   2096     return 0;
   2097 }
   2098 
   2099 int platform_stop_incall_music_usecase(void *platform __unused)
   2100 {
   2101     return 0;
   2102 }
   2103 
   2104 int platform_set_parameters(void *platform, struct str_parms *parms)
   2105 {
   2106     struct platform_data *my_data = (struct platform_data *)platform;
   2107     char value[128];
   2108     char *kv_pairs = str_parms_to_str(parms);
   2109     int ret = 0, err;
   2110 
   2111     if (kv_pairs == NULL) {
   2112         ret = -EINVAL;
   2113         ALOGE("%s: key-value pair is NULL",__func__);
   2114         goto done;
   2115     }
   2116 
   2117     ALOGV("%s: enter: %s", __func__, kv_pairs);
   2118 
   2119     err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO,
   2120                             value, sizeof(value));
   2121     if (err >= 0) {
   2122         struct operator_info *info;
   2123         char *str = value;
   2124         char *name;
   2125 
   2126         str_parms_del(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO);
   2127         info = (struct operator_info *)calloc(1, sizeof(struct operator_info));
   2128         name = strtok(str, ";");
   2129         info->name = strdup(name);
   2130         info->mccmnc = strdup(str + strlen(name) + 1);
   2131 
   2132         list_add_tail(&operator_info_list, &info->list);
   2133         ALOGV("%s: add operator[%s] mccmnc[%s]", __func__, info->name, info->mccmnc);
   2134     }
   2135 
   2136     audio_extn_hfp_set_parameters(my_data->adev, parms);
   2137 done:
   2138     ALOGV("%s: exit with code(%d)", __func__, ret);
   2139     if (kv_pairs != NULL)
   2140         free(kv_pairs);
   2141 
   2142     return ret;
   2143 }
   2144 
   2145 /* Delay in Us */
   2146 int64_t platform_render_latency(audio_usecase_t usecase)
   2147 {
   2148     switch (usecase) {
   2149         case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
   2150             return DEEP_BUFFER_PLATFORM_DELAY;
   2151         case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
   2152             return LOW_LATENCY_PLATFORM_DELAY;
   2153         default:
   2154             return 0;
   2155     }
   2156 }
   2157 
   2158 int platform_set_snd_device_backend(snd_device_t device, const char *backend, const char * hw_interface)
   2159 {
   2160     int ret = 0;
   2161 
   2162     if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
   2163         ALOGE("%s: Invalid snd_device = %d",
   2164             __func__, device);
   2165         ret = -EINVAL;
   2166         goto done;
   2167     }
   2168 
   2169     ALOGV("%s: backend_tag_table[%s]: old = %s new = %s", __func__,
   2170           platform_get_snd_device_name(device),
   2171           backend_table[device] != NULL ? backend_table[device]: "null", backend);
   2172     if (backend_table[device]) {
   2173         free(backend_table[device]);
   2174     }
   2175     backend_table[device] = strdup(backend);
   2176 
   2177     if (hw_interface != NULL) {
   2178         if (hw_interface_table[device])
   2179             free(hw_interface_table[device]);
   2180         ALOGV("%s: hw_interface_table[%d] = %s", __func__, device, hw_interface);
   2181         hw_interface_table[device] = strdup(hw_interface);
   2182     }
   2183 done:
   2184     return ret;
   2185 }
   2186 
   2187 int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
   2188 {
   2189     int ret = 0;
   2190     if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
   2191         ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
   2192         ret = -EINVAL;
   2193         goto done;
   2194     }
   2195 
   2196     if ((type != 0) && (type != 1)) {
   2197         ALOGE("%s: invalid usecase type", __func__);
   2198         ret = -EINVAL;
   2199     }
   2200     pcm_device_table[usecase][type] = pcm_id;
   2201 done:
   2202     return ret;
   2203 }
   2204 
   2205 #define DEFAULT_NOMINAL_SPEAKER_GAIN 20
   2206 int ramp_speaker_gain(struct audio_device *adev, bool ramp_up, int target_ramp_up_gain) {
   2207     // backup_gain: gain to try to set in case of an error during ramp
   2208     int start_gain, end_gain, step, backup_gain, i;
   2209     bool error = false;
   2210     const struct mixer_ctl *ctl;
   2211     const char *mixer_ctl_name_gain_left = "Left Speaker Gain";
   2212     const char *mixer_ctl_name_gain_right = "Right Speaker Gain";
   2213     struct mixer_ctl *ctl_left = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_left);
   2214     struct mixer_ctl *ctl_right = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name_gain_right);
   2215     if (!ctl_left || !ctl_right) {
   2216         ALOGE("%s: Could not get ctl for mixer cmd - %s or %s, not applying speaker gain ramp",
   2217                       __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
   2218         return -EINVAL;
   2219     } else if ((mixer_ctl_get_num_values(ctl_left) != 1)
   2220             || (mixer_ctl_get_num_values(ctl_right) != 1)) {
   2221         ALOGE("%s: Unexpected num values for mixer cmd - %s or %s, not applying speaker gain ramp",
   2222                               __func__, mixer_ctl_name_gain_left, mixer_ctl_name_gain_right);
   2223         return -EINVAL;
   2224     }
   2225     if (ramp_up) {
   2226         start_gain = 0;
   2227         end_gain = target_ramp_up_gain > 0 ? target_ramp_up_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
   2228         step = +1;
   2229         backup_gain = end_gain;
   2230     } else {
   2231         // using same gain on left and right
   2232         const int left_gain = mixer_ctl_get_value(ctl_left, 0);
   2233         start_gain = left_gain > 0 ? left_gain : DEFAULT_NOMINAL_SPEAKER_GAIN;
   2234         end_gain = 0;
   2235         step = -1;
   2236         backup_gain = start_gain;
   2237     }
   2238     for (i = start_gain ; i != (end_gain + step) ; i += step) {
   2239         //ALOGV("setting speaker gain to %d", i);
   2240         if (mixer_ctl_set_value(ctl_left, 0, i)) {
   2241             ALOGE("%s: error setting %s to %d during gain ramp",
   2242                     __func__, mixer_ctl_name_gain_left, i);
   2243             error = true;
   2244             break;
   2245         }
   2246         if (mixer_ctl_set_value(ctl_right, 0, i)) {
   2247             ALOGE("%s: error setting %s to %d during gain ramp",
   2248                     __func__, mixer_ctl_name_gain_right, i);
   2249             error = true;
   2250             break;
   2251         }
   2252         usleep(1000);
   2253     }
   2254     if (error) {
   2255         // an error occured during the ramp, let's still try to go back to a safe volume
   2256         if (mixer_ctl_set_value(ctl_left, 0, backup_gain)) {
   2257             ALOGE("%s: error restoring left gain to %d", __func__, backup_gain);
   2258         }
   2259         if (mixer_ctl_set_value(ctl_right, 0, backup_gain)) {
   2260             ALOGE("%s: error restoring right gain to %d", __func__, backup_gain);
   2261         }
   2262     }
   2263     return start_gain;
   2264 }
   2265 
   2266 int platform_set_swap_mixer(struct audio_device *adev, bool swap_channels)
   2267 {
   2268     const char *mixer_ctl_name = "Swap channel";
   2269     struct mixer_ctl *ctl;
   2270     const char *mixer_path;
   2271     struct platform_data *my_data = (struct platform_data *)adev->platform;
   2272 
   2273     // forced to set to swap, but device not rotated ... ignore set
   2274     if (swap_channels && !my_data->speaker_lr_swap)
   2275         return 0;
   2276 
   2277     ALOGV("%s:", __func__);
   2278 
   2279     if (swap_channels) {
   2280         mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
   2281         audio_route_apply_and_update_path(adev->audio_route, mixer_path);
   2282     } else {
   2283         mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
   2284         audio_route_apply_and_update_path(adev->audio_route, mixer_path);
   2285     }
   2286 
   2287     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
   2288     if (!ctl) {
   2289         ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
   2290         return -EINVAL;
   2291     }
   2292 
   2293     if (mixer_ctl_set_value(ctl, 0, swap_channels) < 0) {
   2294         ALOGE("%s: Could not set reverse cotrol %d",__func__, swap_channels);
   2295         return -EINVAL;
   2296     }
   2297 
   2298     ALOGV("platfor_force_swap_channel :: Channel orientation ( %s ) ",
   2299            swap_channels?"R --> L":"L --> R");
   2300 
   2301     return 0;
   2302 }
   2303 
   2304 int platform_check_and_set_swap_lr_channels(struct audio_device *adev, bool swap_channels)
   2305 {
   2306     // only update if there is active pcm playback on speaker
   2307     struct audio_usecase *usecase;
   2308     struct listnode *node;
   2309     struct platform_data *my_data = (struct platform_data *)adev->platform;
   2310 
   2311     my_data->speaker_lr_swap = swap_channels;
   2312 
   2313     return platform_set_swap_channels(adev, swap_channels);
   2314 }
   2315 
   2316 int platform_set_swap_channels(struct audio_device *adev, bool swap_channels)
   2317 {
   2318     // only update if there is active pcm playback on speaker
   2319     struct audio_usecase *usecase;
   2320     struct listnode *node;
   2321     struct platform_data *my_data = (struct platform_data *)adev->platform;
   2322 
   2323     // do not swap channels in audio modes with concurrent capture and playback
   2324     // as this may break the echo reference
   2325     if ((adev->mode == AUDIO_MODE_IN_COMMUNICATION) || (adev->mode == AUDIO_MODE_IN_CALL)) {
   2326         ALOGV("%s: will not swap due to audio mode %d", __func__, adev->mode);
   2327         return 0;
   2328     }
   2329 
   2330     list_for_each(node, &adev->usecase_list) {
   2331         usecase = node_to_item(node, struct audio_usecase, list);
   2332         if (usecase->type == PCM_PLAYBACK &&
   2333                 usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
   2334             /*
   2335              * If acdb tuning is different for SPEAKER_REVERSE, it is must
   2336              * to perform device switch to disable the current backend to
   2337              * enable it with new acdb data.
   2338              */
   2339             if (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
   2340                 acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE]) {
   2341                 const int initial_skpr_gain = ramp_speaker_gain(adev, false /*ramp_up*/, -1);
   2342                 select_devices(adev, usecase->id);
   2343                 if (initial_skpr_gain != -EINVAL)
   2344                     ramp_speaker_gain(adev, true /*ramp_up*/, initial_skpr_gain);
   2345 
   2346             } else {
   2347                 platform_set_swap_mixer(adev, swap_channels);
   2348             }
   2349             break;
   2350         }
   2351     }
   2352 
   2353     return 0;
   2354 }
   2355 
   2356 int platform_snd_card_update(void *platform __unused,
   2357                              card_status_t status __unused)
   2358 {
   2359     return -1;
   2360 }
   2361 
   2362 int platform_send_audio_calibration_v2(void *platform __unused,
   2363                                        struct audio_usecase *usecase __unused,
   2364                                        int app_type __unused,
   2365                                        int sample_rate __unused)
   2366 {
   2367     return -ENOSYS;
   2368 }
   2369 
   2370 void platform_check_and_update_copp_sample_rate(void* platform __unused,
   2371                                                snd_device_t snd_device __unused,
   2372                                                 unsigned int stream_sr __unused,
   2373                                                 int* sample_rate __unused)
   2374 {
   2375 
   2376 }
   2377 
   2378 int platform_get_snd_device_backend_index(snd_device_t snd_device __unused)
   2379 {
   2380     return -ENOSYS;
   2381 }
   2382 
   2383 bool platform_supports_app_type_cfg() { return false; }
   2384 
   2385 void platform_add_app_type(const char *uc_type __unused,
   2386                            const char *mode __unused,
   2387                            int bw __unused, int app_type __unused,
   2388                            int max_sr __unused) {}
   2389 
   2390 int platform_get_app_type_v2(void *platform __unused,
   2391                              enum usecase_type_t type __unused,
   2392                              const char *mode __unused,
   2393                              int bw __unused, int sr __unused,
   2394                              int *app_type __unused) {
   2395     return -ENOSYS;
   2396 }
   2397 
   2398 int platform_set_sidetone(struct audio_device *adev,
   2399                           snd_device_t out_snd_device,
   2400                           bool enable, char *str)
   2401 {
   2402     int ret;
   2403     if (out_snd_device == SND_DEVICE_OUT_USB_HEADSET ||
   2404         out_snd_device == SND_DEVICE_OUT_VOICE_USB_HEADSET) {
   2405             ret = audio_extn_usb_enable_sidetone(out_snd_device, enable);
   2406             if (ret)
   2407                 ALOGI("%s: usb device %d does not support device sidetone\n",
   2408                   __func__, out_snd_device);
   2409     } else {
   2410         ALOGV("%s: sidetone out device(%d) mixer cmd = %s\n",
   2411               __func__, out_snd_device, str);
   2412 
   2413         if (enable)
   2414             audio_route_apply_and_update_path(adev->audio_route, str);
   2415         else
   2416             audio_route_reset_and_update_path(adev->audio_route, str);
   2417     }
   2418     return 0;
   2419 }
   2420 
   2421 int platform_get_mmap_data_fd(void *platform __unused, int fe_dev __unused, int dir __unused,
   2422                               int *fd __unused, uint32_t *size __unused)
   2423 {
   2424     return -ENOSYS;
   2425 }
   2426