/*
** Copyright 2008, The Android Open-Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#include <math.h>

//#define LOG_NDEBUG 0
#define LOG_TAG "AudioHardwareQSD"
#include <utils/Log.h>
#include <utils/String8.h>
#include <hardware_legacy/power.h>

#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <fcntl.h>

#include <cutils/properties.h> // for property_get for the voice recognition mode switch

// hardware specific functions

#include "AudioHardware.h"
#include <media/AudioRecord.h>
#include <media/mediarecorder.h>

extern "C" {
#include "msm_audio.h"
#include <linux/a1026.h>
#include <linux/tpa2018d1.h>
}

#define LOG_SND_RPC 0  // Set to 1 to log sound RPC's
#define TX_PATH (1)

static const uint32_t SND_DEVICE_CURRENT = 256;
static const uint32_t SND_DEVICE_HANDSET = 0;
static const uint32_t SND_DEVICE_SPEAKER = 1;
static const uint32_t SND_DEVICE_BT = 3;
static const uint32_t SND_DEVICE_CARKIT = 4;
static const uint32_t SND_DEVICE_BT_EC_OFF = 45;
static const uint32_t SND_DEVICE_HEADSET = 2;
static const uint32_t SND_DEVICE_HEADSET_AND_SPEAKER = 10;
static const uint32_t SND_DEVICE_FM_HEADSET = 9;
static const uint32_t SND_DEVICE_FM_SPEAKER = 11;
static const uint32_t SND_DEVICE_NO_MIC_HEADSET = 8;
static const uint32_t SND_DEVICE_TTY_FULL = 5;
static const uint32_t SND_DEVICE_TTY_VCO = 6;
static const uint32_t SND_DEVICE_TTY_HCO = 7;
static const uint32_t SND_DEVICE_HANDSET_BACK_MIC = 20;
static const uint32_t SND_DEVICE_SPEAKER_BACK_MIC = 21;
static const uint32_t SND_DEVICE_NO_MIC_HEADSET_BACK_MIC = 28;
static const uint32_t SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC = 30;
namespace android {
static int support_a1026 = 1;
static bool support_tpa2018d1 = true;
static int fd_a1026 = -1;
static int old_pathid = -1;
static int new_pathid = -1;
static int curr_out_device = -1;
static int curr_mic_device = -1;
static int voice_started = 0;
static int fd_fm_device = -1;
static int stream_volume = -300;
// use VR mode on inputs: 1 == VR mode enabled when selected, 0 = VR mode disabled when selected
static int vr_mode_enabled;
static bool vr_mode_change = false;
static int vr_uses_ns = 0;
static int alt_enable = 0;
static int hac_enable = 0;
// enable or disable 2-mic noise suppression in call on receiver mode
static int enable1026 = 1;
//FIXME add new settings in A1026 driver for an incall no ns mode, based on the current vr no ns
#define A1026_PATH_INCALL_NO_NS_RECEIVER A1026_PATH_VR_NO_NS_RECEIVER

int errCount = 0;
static void * acoustic;
const uint32_t AudioHardware::inputSamplingRates[] = {
        8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
};

// ID string for audio wakelock
static const char kOutputWakelockStr[] = "AudioHardwareQSDOut";
static const char kInputWakelockStr[] = "AudioHardwareQSDIn";

// ----------------------------------------------------------------------------

AudioHardware::AudioHardware() :
    mA1026Init(false), mInit(false), mMicMute(true),
    mBluetoothNrec(true),
    mHACSetting(false),
    mBluetoothIdTx(0), mBluetoothIdRx(0),
    mOutput(0),
    mNoiseSuppressionState(A1026_NS_STATE_AUTO),
    mVoiceVolume(VOICE_VOLUME_MAX), mTTYMode(TTY_MODE_OFF)
{
    int (*snd_get_num)();
    int (*snd_get_bt_endpoint)(msm_bt_endpoint *);
    int (*set_acoustic_parameters)();
    int (*set_tpa2018d1_parameters)();

    struct msm_bt_endpoint *ept;

    doA1026_init();

    acoustic =:: dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW);
    if (acoustic == NULL ) {
        ALOGD("Could not open libhtc_acoustic.so");
        /* this is not really an error on non-htc devices... */
        mNumBTEndpoints = 0;
        mInit = true;
        return;
    }
    set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters");
    if ((*set_acoustic_parameters) == 0 ) {
        ALOGE("Could not open set_acoustic_parameters()");
        return;
    }

    set_tpa2018d1_parameters = (int (*)(void))::dlsym(acoustic, "set_tpa2018d1_parameters");
    if ((*set_tpa2018d1_parameters) == 0) {
        ALOGD("set_tpa2018d1_parameters() not present");
        support_tpa2018d1 = false;
    }

    int rc = set_acoustic_parameters();
    if (rc < 0) {
        ALOGD("Could not set acoustic parameters to share memory: %d", rc);
    }

    if (support_tpa2018d1) {
       rc = set_tpa2018d1_parameters();
       if (rc < 0) {
           support_tpa2018d1 = false;
           ALOGD("speaker amplifier tpa2018 is not supported\n");
       }
    }

    snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num");
    if ((*snd_get_num) == 0 ) {
        ALOGD("Could not open snd_get_num()");
    }

    mNumBTEndpoints = snd_get_num();
    ALOGV("mNumBTEndpoints = %d", mNumBTEndpoints);
    mBTEndpoints = new msm_bt_endpoint[mNumBTEndpoints];
    mInit = true;
    ALOGV("constructed %d SND endpoints)", mNumBTEndpoints);
    ept = mBTEndpoints;
    snd_get_bt_endpoint = (int (*)(msm_bt_endpoint *))::dlsym(acoustic, "snd_get_bt_endpoint");
    if ((*snd_get_bt_endpoint) == 0 ) {
        ALOGE("Could not open snd_get_bt_endpoint()");
        return;
    }
    snd_get_bt_endpoint(mBTEndpoints);

    for (int i = 0; i < mNumBTEndpoints; i++) {
        ALOGV("BT name %s (tx,rx)=(%d,%d)", mBTEndpoints[i].name, mBTEndpoints[i].tx, mBTEndpoints[i].rx);
    }

    // reset voice mode in case media_server crashed and restarted while in call
    int fd = open("/dev/msm_audio_ctl", O_RDWR);
    if (fd >= 0) {
        ioctl(fd, AUDIO_STOP_VOICE, NULL);
        close(fd);
    }

    vr_mode_change = false;
    vr_mode_enabled = 0;
    enable1026 = 1;
    char value[PROPERTY_VALUE_MAX];
    // Check the system property to enable or not the special recording modes
    property_get("media.a1026.enableA1026", value, "1");
    enable1026 = atoi(value);
    ALOGV("Enable mode selection for A1026 is %d", enable1026);
    // Check the system property for which VR mode to use
    property_get("media.a1026.nsForVoiceRec", value, "0");
    vr_uses_ns = atoi(value);
    ALOGV("Using Noise Suppression for Voice Rec is %d", vr_uses_ns);

    // Check the system property for enable or not the ALT function
    property_get("htc.audio.alt.enable", value, "0");
    alt_enable = atoi(value);
    ALOGV("Enable ALT function: %d", alt_enable);

    // Check the system property for enable or not the HAC function
    property_get("htc.audio.hac.enable", value, "0");
    hac_enable = atoi(value);
    ALOGV("Enable HAC function: %d", hac_enable);

    mInit = true;
}

AudioHardware::~AudioHardware()
{
    for (size_t index = 0; index < mInputs.size(); index++) {
        closeInputStream((AudioStreamIn*)mInputs[index]);
    }
    mInputs.clear();
    closeOutputStream((AudioStreamOut*)mOutput);
    mInit = false;
}

status_t AudioHardware::initCheck()
{
    return mInit ? NO_ERROR : NO_INIT;
}

AudioStreamOut* AudioHardware::openOutputStream(
        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
{
    { // scope for the lock
        Mutex::Autolock lock(mLock);

        // only one output stream allowed
        if (mOutput) {
            if (status) {
                *status = INVALID_OPERATION;
            }
            return 0;
        }

        // create new output stream
        AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx();
        status_t lStatus = out->set(this, devices, format, channels, sampleRate);
        if (status) {
            *status = lStatus;
        }
        if (lStatus == NO_ERROR) {
            mOutput = out;
        } else {
            delete out;
        }
    }
    return mOutput;
}

void AudioHardware::closeOutputStream(AudioStreamOut* out) {
    Mutex::Autolock lock(mLock);
    if (mOutput == 0 || mOutput != out) {
        ALOGW("Attempt to close invalid output stream");
    }
    else {
        delete mOutput;
        mOutput = 0;
    }
}

AudioStreamIn* AudioHardware::openInputStream(
        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status,
        AudioSystem::audio_in_acoustics acoustic_flags)
{
    // check for valid input source
    if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
        return 0;
    }

    mLock.lock();

    AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx();
    status_t lStatus = in->set(this, devices, format, channels, sampleRate, acoustic_flags);
    if (status) {
        *status = lStatus;
    }
    if (lStatus != NO_ERROR) {
        mLock.unlock();
        delete in;
        return 0;
    }

    mInputs.add(in);
    mLock.unlock();

    return in;
}

void AudioHardware::closeInputStream(AudioStreamIn* in) {
    Mutex::Autolock lock(mLock);

    ssize_t index = mInputs.indexOf((AudioStreamInMSM72xx *)in);
    if (index < 0) {
        ALOGW("Attempt to close invalid input stream");
    } else {
        mLock.unlock();
        delete mInputs[index];
        mLock.lock();
        mInputs.removeAt(index);
    }
}

status_t AudioHardware::setMode(int mode)
{
    // VR mode is never used in a call and must be cleared when entering the IN_CALL mode
    if (mode == AudioSystem::MODE_IN_CALL) {
        vr_mode_enabled = 0;
    }

    if (support_tpa2018d1)
        do_tpa2018_control(mode);

    int prevMode = mMode;
    status_t status = AudioHardwareBase::setMode(mode);
    if (status == NO_ERROR) {
        // make sure that doAudioRouteOrMute() is called by doRouting()
        // when entering or exiting in call mode even if the new device
        // selected is the same as current one.
        if (((prevMode != AudioSystem::MODE_IN_CALL) && (mMode == AudioSystem::MODE_IN_CALL)) ||
            ((prevMode == AudioSystem::MODE_IN_CALL) && (mMode != AudioSystem::MODE_IN_CALL))) {
            clearCurDevice();
        }
    }

    return status;
}

bool AudioHardware::checkOutputStandby()
{
    if (mOutput)
        if (!mOutput->checkStandby())
            return false;

    return true;
}
static status_t set_mic_mute(bool _mute)
{
    uint32_t mute = _mute;
    int fd = -1;
    fd = open("/dev/msm_audio_ctl", O_RDWR);
    if (fd < 0) {
        ALOGE("Cannot open msm_audio_ctl device\n");
        return -1;
    }
    ALOGD("Setting mic mute to %d\n", mute);
    if (ioctl(fd, AUDIO_SET_MUTE, &mute)) {
        ALOGE("Cannot set mic mute on current device\n");
        close(fd);
        return -1;
    }
    close(fd);
    return NO_ERROR;
}

status_t AudioHardware::setMicMute(bool state)
{
    Mutex::Autolock lock(mLock);
    return setMicMute_nosync(state);
}

// always call with mutex held
status_t AudioHardware::setMicMute_nosync(bool state)
{
    if (mMicMute != state) {
        mMicMute = state;
        return set_mic_mute(mMicMute); //always set current TX device
    }
    return NO_ERROR;
}

status_t AudioHardware::getMicMute(bool* state)
{
    *state = mMicMute;
    return NO_ERROR;
}

status_t AudioHardware::setParameters(const String8& keyValuePairs)
{
    AudioParameter param = AudioParameter(keyValuePairs);
    String8 value;
    String8 key;
    const char BT_NREC_KEY[] = "bt_headset_nrec";
    const char BT_NAME_KEY[] = "bt_headset_name";
    const char HAC_KEY[] = "HACSetting";
    const char BT_NREC_VALUE_ON[] = "on";
    const char HAC_VALUE_ON[] = "ON";


    ALOGV("setParameters() %s", keyValuePairs.string());

    if (keyValuePairs.length() == 0) return BAD_VALUE;

    if(hac_enable) {
        key = String8(HAC_KEY);
        if (param.get(key, value) == NO_ERROR) {
            if (value == HAC_VALUE_ON) {
                mHACSetting = true;
                ALOGD("Enable HAC");
            } else {
                mHACSetting = false;
                ALOGD("Disable HAC");
            }
        }
    }

    key = String8(BT_NREC_KEY);
    if (param.get(key, value) == NO_ERROR) {
        if (value == BT_NREC_VALUE_ON) {
            mBluetoothNrec = true;
        } else {
            mBluetoothNrec = false;
            ALOGD("Turning noise reduction and echo cancellation off for BT "
                 "headset");
        }
    }
    key = String8(BT_NAME_KEY);
    if (param.get(key, value) == NO_ERROR) {
        mBluetoothIdTx = 0;
        mBluetoothIdRx = 0;
        for (int i = 0; i < mNumBTEndpoints; i++) {
            if (!strcasecmp(value.string(), mBTEndpoints[i].name)) {
                mBluetoothIdTx = mBTEndpoints[i].tx;
                mBluetoothIdRx = mBTEndpoints[i].rx;
                ALOGD("Using custom acoustic parameters for %s", value.string());
                break;
            }
        }
        if (mBluetoothIdTx == 0) {
            ALOGD("Using default acoustic parameters "
                 "(%s not in acoustic database)", value.string());
        }
        doRouting();
    }
    key = String8("noise_suppression");
    if (param.get(key, value) == NO_ERROR) {
        if (support_a1026 == 1) {
            int noiseSuppressionState;
            if (value == "off") {
                noiseSuppressionState = A1026_NS_STATE_OFF;
            } else if (value == "auto") {
                noiseSuppressionState = A1026_NS_STATE_AUTO;
            } else if (value == "far_talk") {
                noiseSuppressionState = A1026_NS_STATE_FT;
            } else if (value == "close_talk") {
                noiseSuppressionState = A1026_NS_STATE_CT;
            } else {
                return BAD_VALUE;
            }

            if (noiseSuppressionState != mNoiseSuppressionState) {
                if (!mA1026Init) {
                    ALOGW("Audience A1026 not initialized.\n");
                    return INVALID_OPERATION;
                }

                mA1026Lock.lock();
                if (fd_a1026 < 0) {
                    fd_a1026 = open("/dev/audience_a1026", O_RDWR);
                    if (fd_a1026 < 0) {
                        ALOGE("Cannot open audience_a1026 device (%d)\n", fd_a1026);
                        mA1026Lock.unlock();
                        return -1;
                    }
                }
                ALOGV("Setting noise suppression %s", value.string());

                int rc = ioctl(fd_a1026, A1026_SET_NS_STATE, &noiseSuppressionState);
                if (!rc) {
                    mNoiseSuppressionState = noiseSuppressionState;
                } else {
                    ALOGE("Failed to set noise suppression %s", value.string());
                }
                close(fd_a1026);
                fd_a1026 = -1;
                mA1026Lock.unlock();
            }
        } else {
            return INVALID_OPERATION;
        }
     }

    key = String8("tty_mode");
    if (param.get(key, value) == NO_ERROR) {
        int ttyMode;
        if (value == "tty_off") {
            ttyMode = TTY_MODE_OFF;
        } else if (value == "tty_full") {
            ttyMode = TTY_MODE_FULL;
        } else if (value == "tty_vco") {
            ttyMode = TTY_MODE_VCO;
        } else if (value == "tty_hco") {
            ttyMode = TTY_MODE_HCO;
        } else {
            return BAD_VALUE;
        }

        if (ttyMode != mTTYMode) {
            ALOGV("new tty mode %d", ttyMode);
            mTTYMode = ttyMode;
            doRouting();
        }
     }

    return NO_ERROR;
}

String8 AudioHardware::getParameters(const String8& keys)
{
    AudioParameter request = AudioParameter(keys);
    AudioParameter reply = AudioParameter();
    String8 value;
    String8 key;

    ALOGV("getParameters() %s", keys.string());

    key = "noise_suppression";
    if (request.get(key, value) == NO_ERROR) {
        switch(mNoiseSuppressionState) {
        case A1026_NS_STATE_OFF:
            value = "off";
            break;
        case A1026_NS_STATE_AUTO:
            value = "auto";
            break;
        case A1026_NS_STATE_FT:
            value = "far_talk";
            break;
        case A1026_NS_STATE_CT:
            value = "close_talk";
            break;
        }
        reply.add(key, value);
    }

    return reply.toString();
}


static unsigned calculate_audpre_table_index(unsigned index)
{
    switch (index) {
        case 48000:    return SAMP_RATE_INDX_48000;
        case 44100:    return SAMP_RATE_INDX_44100;
        case 32000:    return SAMP_RATE_INDX_32000;
        case 24000:    return SAMP_RATE_INDX_24000;
        case 22050:    return SAMP_RATE_INDX_22050;
        case 16000:    return SAMP_RATE_INDX_16000;
        case 12000:    return SAMP_RATE_INDX_12000;
        case 11025:    return SAMP_RATE_INDX_11025;
        case 8000:    return SAMP_RATE_INDX_8000;
        default:     return -1;
    }
}

size_t AudioHardware::getBufferSize(uint32_t sampleRate, int channelCount)
{
    size_t bufSize;

    if (sampleRate < 11025) {
        bufSize = 256;
    } else if (sampleRate < 22050) {
        bufSize = 512;
    } else if (sampleRate < 32000) {
        bufSize = 768;
    } else if (sampleRate < 44100) {
        bufSize = 1024;
    } else {
        bufSize = 1536;
    }

    return bufSize*channelCount;
}


size_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
{
    if (format != AudioSystem::PCM_16_BIT) {
        ALOGW("getInputBufferSize bad format: %d", format);
        return 0;
    }
    if (channelCount < 1 || channelCount > 2) {
        ALOGW("getInputBufferSize bad channel count: %d", channelCount);
        return 0;
    }
    if (sampleRate < 8000 || sampleRate > 48000) {
        ALOGW("getInputBufferSize bad sample rate: %d", sampleRate);
        return 0;
    }

    return getBufferSize(sampleRate, channelCount);
}

static status_t set_volume_rpc(uint32_t volume)
{
    int fd = -1;
    fd = open("/dev/msm_audio_ctl", O_RDWR);
    if (fd < 0) {
        ALOGE("Cannot open msm_audio_ctl device\n");
        return -1;
    }
    volume *= 20; //percentage
    ALOGD("Setting in-call volume to %d\n", volume);
    if (ioctl(fd, AUDIO_SET_VOLUME, &volume)) {
        ALOGW("Cannot set volume on current device\n");
    }
    close(fd);
    return NO_ERROR;
}

status_t AudioHardware::setVoiceVolume(float v)
{
    if (v < 0.0) {
        ALOGW("setVoiceVolume(%f) under 0.0, assuming 0.0", v);
        v = 0.0;
    } else if (v > 1.0) {
        ALOGW("setVoiceVolume(%f) over 1.0, assuming 1.0", v);
        v = 1.0;
    }

    int vol = lrint(v * VOICE_VOLUME_MAX);

    Mutex::Autolock lock(mLock);
    if (mHACSetting && hac_enable && mCurSndDevice == (int) SND_DEVICE_HANDSET) {
        ALOGD("HAC enable: Setting in-call volume to maximum.\n");
        set_volume_rpc(VOICE_VOLUME_MAX);
    } else {
        ALOGI("voice volume %d (range is 0 to %d)", vol, VOICE_VOLUME_MAX);
        set_volume_rpc(vol); //always set current device
    }
    mVoiceVolume = vol;
    return NO_ERROR;
}

status_t AudioHardware::setMasterVolume(float v)
{
    ALOGI("Set master volume to %f", v);
    // We return an error code here to let the audioflinger do in-software
    // volume on top of the maximum volume that we set through the SND API.
    // return error - software mixer will handle it
    return -1;
}

static status_t do_route_audio_dev_ctrl(uint32_t device, bool inCall, uint32_t rx_acdb_id, uint32_t tx_acdb_id)
{
    uint32_t out_device = 0, mic_device = 0;
    uint32_t path[2];
    int fd = 0;

    if (device == SND_DEVICE_CURRENT)
        goto Incall;

    // hack -- kernel needs to put these in include file
    ALOGD("Switching audio device to ");
    if (device == SND_DEVICE_HANDSET) {
           out_device = HANDSET_SPKR;
           mic_device = HANDSET_MIC;
           ALOGD("Handset");
    } else if ((device  == SND_DEVICE_BT) || (device == SND_DEVICE_BT_EC_OFF)) {
           out_device = BT_SCO_SPKR;
           mic_device = BT_SCO_MIC;
           ALOGD("BT Headset");
    } else if (device == SND_DEVICE_SPEAKER ||
               device == SND_DEVICE_SPEAKER_BACK_MIC) {
           out_device = SPKR_PHONE_MONO;
           mic_device = SPKR_PHONE_MIC;
           ALOGD("Speakerphone");
    } else if (device == SND_DEVICE_HEADSET) {
           out_device = HEADSET_SPKR_STEREO;
           mic_device = HEADSET_MIC;
           ALOGD("Stereo Headset");
    } else if (device == SND_DEVICE_HEADSET_AND_SPEAKER) {
           out_device = SPKR_PHONE_HEADSET_STEREO;
           mic_device = HEADSET_MIC;
           ALOGD("Stereo Headset + Speaker");
    } else if (device == SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC) {
           out_device = SPKR_PHONE_HEADSET_STEREO;
           mic_device = SPKR_PHONE_MIC;
           ALOGD("Stereo Headset + Speaker and back mic");
    } else if (device == SND_DEVICE_NO_MIC_HEADSET) {
           out_device = HEADSET_SPKR_STEREO;
           mic_device = HANDSET_MIC;
           ALOGD("No microphone Wired Headset");
    } else if (device == SND_DEVICE_NO_MIC_HEADSET_BACK_MIC) {
           out_device = HEADSET_SPKR_STEREO;
           mic_device = SPKR_PHONE_MIC;
           ALOGD("No microphone Wired Headset and back mic");
    } else if (device == SND_DEVICE_HANDSET_BACK_MIC) {
           out_device = HANDSET_SPKR;
           mic_device = SPKR_PHONE_MIC;
           ALOGD("Handset and back mic");
    } else if (device == SND_DEVICE_FM_HEADSET) {
           out_device = FM_HEADSET;
           mic_device = HEADSET_MIC;
           ALOGD("Stereo FM headset");
    } else if (device == SND_DEVICE_FM_SPEAKER) {
           out_device = FM_SPKR;
           mic_device = HEADSET_MIC;
           ALOGD("Stereo FM speaker");
    } else if (device == SND_DEVICE_CARKIT) {
           out_device = BT_SCO_SPKR;
           mic_device = BT_SCO_MIC;
           ALOGD("Carkit");
    } else if (device == SND_DEVICE_TTY_FULL) {
        out_device = TTY_HEADSET_SPKR;
        mic_device = TTY_HEADSET_MIC;
        ALOGD("TTY FULL headset");
    } else if (device == SND_DEVICE_TTY_VCO) {
        out_device = TTY_HEADSET_SPKR;
        mic_device = SPKR_PHONE_MIC;
        ALOGD("TTY VCO headset");
    } else if (device == SND_DEVICE_TTY_HCO) {
        out_device = SPKR_PHONE_MONO;
        mic_device = TTY_HEADSET_MIC;
        ALOGD("TTY HCO headset");
    } else {
        ALOGE("unknown device %d", device);
        return -1;
    }

#if 0 //Add for FM support
    if (out_device == FM_HEADSET ||
        out_device == FM_SPKR) {
        if (fd_fm_device < 0) {
            fd_fm_device = open("/dev/msm_htc_fm", O_RDWR);
            if (fd_fm_device < 0) {
                ALOGE("Cannot open msm_htc_fm device");
                return -1;
            }
            ALOGD("Opened msm_htc_fm for FM radio");
        }
    } else if (fd_fm_device >= 0) {
        close(fd_fm_device);
        fd_fm_device = -1;
        ALOGD("Closed msm_htc_fm after FM radio");
    }
#endif

    fd = open("/dev/msm_audio_ctl", O_RDWR);
    if (fd < 0)        {
       ALOGE("Cannot open msm_audio_ctl");
       return -1;
    }
    path[0] = out_device;
    path[1] = rx_acdb_id;
    if (ioctl(fd, AUDIO_SWITCH_DEVICE, &path)) {
       ALOGE("Cannot switch audio device");
       close(fd);
       return -1;
    }
    path[0] = mic_device;
    path[1] = tx_acdb_id;
    if (ioctl(fd, AUDIO_SWITCH_DEVICE, &path)) {
       ALOGE("Cannot switch mic device");
       close(fd);
       return -1;
    }
    curr_out_device = out_device;
    curr_mic_device = mic_device;

Incall:
    if (inCall == true && !voice_started) {
        if (fd < 0) {
            fd = open("/dev/msm_audio_ctl", O_RDWR);

            if (fd < 0) {
                ALOGE("Cannot open msm_audio_ctl");
                return -1;
            }
        }
        path[0] = rx_acdb_id;
        path[1] = tx_acdb_id;
        if (ioctl(fd, AUDIO_START_VOICE, &path)) {
            ALOGE("Cannot start voice");
            close(fd);
            return -1;
        }
        ALOGD("Voice Started!!");
        voice_started = 1;
    }
    else if (inCall == false && voice_started) {
        if (fd < 0) {
            fd = open("/dev/msm_audio_ctl", O_RDWR);

            if (fd < 0) {
                ALOGE("Cannot open msm_audio_ctl");
                return -1;
            }
        }
        if (ioctl(fd, AUDIO_STOP_VOICE, NULL)) {
               ALOGE("Cannot stop voice");
               close(fd);
               return -1;
        }
        ALOGD("Voice Stopped!!");
        voice_started = 0;
    }

    close(fd);
    return NO_ERROR;
}


// always call with mutex held
status_t AudioHardware::doAudioRouteOrMute(uint32_t device)
{
    uint32_t rx_acdb_id = 0;
    uint32_t tx_acdb_id = 0;

    if (support_a1026 == 1)
            doAudience_A1026_Control(mMode, mRecordState, device);

    if (device == (uint32_t)SND_DEVICE_BT) {
        if (!mBluetoothNrec) {
            device = SND_DEVICE_BT_EC_OFF;
        }
    }


    if (device == (int) SND_DEVICE_BT) {
        if (mBluetoothIdTx != 0) {
            rx_acdb_id = mBluetoothIdRx;
            tx_acdb_id = mBluetoothIdTx;
        } else {
            /* use default BT entry defined in AudioBTID.csv */
            rx_acdb_id = mBTEndpoints[0].rx;
            tx_acdb_id = mBTEndpoints[0].tx;
            ALOGD("Update ACDB ID to default BT setting\n");
        }
    }  else if (device == (int) SND_DEVICE_CARKIT
                || device == (int) SND_DEVICE_BT_EC_OFF) {
        if (mBluetoothIdTx != 0) {
            rx_acdb_id = mBluetoothIdRx;
            tx_acdb_id = mBluetoothIdTx;
        } else {
            /* use default carkit entry defined in AudioBTID.csv */
            rx_acdb_id = mBTEndpoints[1].rx;
            tx_acdb_id = mBTEndpoints[1].tx;
            ALOGD("Update ACDB ID to default carkit setting");
        }
    } else if (mMode == AudioSystem::MODE_IN_CALL
               && hac_enable && mHACSetting &&
               device == (int) SND_DEVICE_HANDSET) {
        ALOGD("Update acdb id to hac profile.");
        rx_acdb_id = ACDB_ID_HAC_HANDSET_SPKR;
        tx_acdb_id = ACDB_ID_HAC_HANDSET_MIC;
    } else {
        if (!checkOutputStandby() || mMode != AudioSystem::MODE_IN_CALL)
            rx_acdb_id = getACDB(MOD_PLAY, device);
        if (mRecordState)
            tx_acdb_id = getACDB(MOD_REC, device);
    }
    ALOGV("doAudioRouteOrMute: rx acdb %d, tx acdb %d\n", rx_acdb_id, tx_acdb_id);

    return do_route_audio_dev_ctrl(device, mMode == AudioSystem::MODE_IN_CALL, rx_acdb_id, tx_acdb_id);
}

status_t AudioHardware::get_mMode(void)
{
    return mMode;
}

status_t AudioHardware::get_mRoutes(void)
{
    return mRoutes[mMode];
}

status_t AudioHardware::set_mRecordState(bool onoff)
{
    mRecordState = onoff;
    return 0;
}

status_t AudioHardware::get_batt_temp(int *batt_temp)
{
    int fd, len;
    const char *fn =
            "/sys/devices/platform/ds2784-battery/power_supply/battery/temp";
    char get_batt_temp[6] = { 0 };

    if ((fd = open(fn, O_RDONLY)) < 0) {
        ALOGE("%s: cannot open %s: %s\n", __FUNCTION__, fn, strerror(errno));
        return UNKNOWN_ERROR;
    }

    if ((len = read(fd, get_batt_temp, sizeof(get_batt_temp))) <= 1) {
        ALOGE("read battery temp fail: %s\n", strerror(errno));
        close(fd);
        return BAD_VALUE;
    }

    *batt_temp = strtol(get_batt_temp, NULL, 10);
    close(fd);
    return NO_ERROR;
}

/*
 * Note: upon exiting doA1026_init(), fd_a1026 will be -1
 */
status_t AudioHardware::doA1026_init(void)
{
    struct a1026img fwimg;
    char char_tmp = 0;
    unsigned char local_vpimg_buf[A1026_MAX_FW_SIZE], *ptr = local_vpimg_buf;
    int rc = 0, fw_fd = -1;
    ssize_t nr;
    size_t remaining;
    struct stat fw_stat;

    static const char *const fn = "/system/etc/vpimg";
    static const char *const path = "/dev/audience_a1026";

    if (fd_a1026 < 0)
        fd_a1026 = open(path, O_RDWR | O_NONBLOCK, 0);

    if (fd_a1026 < 0) {
        ALOGE("Cannot open %s %d\n", path, fd_a1026);
        support_a1026 = 0;
        goto open_drv_err;
    }

    fw_fd = open(fn, O_RDONLY);
    if (fw_fd < 0) {
        ALOGE("Fail to open %s\n", fn);
        goto ld_img_error;
    } else {
        ALOGD("open %s success\n", fn);
    }

    rc = fstat(fw_fd, &fw_stat);
    if (rc < 0) {
        ALOGE("Cannot stat file %s: %s\n", fn, strerror(errno));
        goto ld_img_error;
    }

    remaining = (int)fw_stat.st_size;

    ALOGD("Firmware %s size %d\n", fn, remaining);

    if (remaining > sizeof(local_vpimg_buf)) {
        ALOGE("File %s size %d exceeds internal limit %d\n",
             fn, remaining, sizeof(local_vpimg_buf));
        goto ld_img_error;
    }

    while (remaining) {
        nr = read(fw_fd, ptr, remaining);
        if (nr < 0) {
            ALOGE("Error reading firmware: %s\n", strerror(errno));
            goto ld_img_error;
        }
        else if (!nr) {
            if (remaining)
                ALOGW("EOF reading firmware %s while %d bytes remain\n",
                     fn, remaining);
            break;
        }
        remaining -= nr;
        ptr += nr;
    }

    close (fw_fd);
    fw_fd = -1;

    fwimg.buf = local_vpimg_buf;
    fwimg.img_size = (int)(fw_stat.st_size - remaining);
    ALOGD("Total %d bytes put to user space buffer.\n", fwimg.img_size);

    rc = ioctl(fd_a1026, A1026_BOOTUP_INIT, &fwimg);
    if (!rc) {
        ALOGD("audience_a1026 init OK\n");
        mA1026Init = 1;
    } else
        ALOGE("audience_a1026 init failed\n");

ld_img_error:
    if (fw_fd >= 0)
        close(fw_fd);
    close(fd_a1026);
open_drv_err:
    fd_a1026 = -1;
    return rc;
}

status_t AudioHardware::get_snd_dev(void)
{
    Mutex::Autolock lock(mLock);
    return mCurSndDevice;
}

uint32_t AudioHardware::getACDB(int mode, int device)
{
    uint32_t acdb_id = 0;
    int batt_temp = 0;
    if (mMode == AudioSystem::MODE_IN_CALL) {
        ALOGD("skip update ACDB due to in-call");
        return 0;
    }

    if (mode == MOD_PLAY) {
        switch (device) {
            case SND_DEVICE_HEADSET:
            case SND_DEVICE_NO_MIC_HEADSET:
            case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC:
            case SND_DEVICE_FM_HEADSET:
                acdb_id = ACDB_ID_HEADSET_PLAYBACK;
                break;
            case SND_DEVICE_SPEAKER:
            case SND_DEVICE_FM_SPEAKER:
            case SND_DEVICE_SPEAKER_BACK_MIC:
                acdb_id = ACDB_ID_SPKR_PLAYBACK;
                if(alt_enable) {
                    ALOGD("Enable ALT for speaker\n");
                    if (get_batt_temp(&batt_temp) == NO_ERROR) {
                        if (batt_temp < 50)
                            acdb_id = ACDB_ID_ALT_SPKR_PLAYBACK;
                        ALOGD("ALT batt temp = %d\n", batt_temp);
                    }
                }
                break;
            case SND_DEVICE_HEADSET_AND_SPEAKER:
            case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC:
                acdb_id = ACDB_ID_HEADSET_RINGTONE_PLAYBACK;
                break;
            default:
                break;
        }
    } else if (mode == MOD_REC) {
        switch (device) {
            case SND_DEVICE_HEADSET:
            case SND_DEVICE_FM_HEADSET:
            case SND_DEVICE_FM_SPEAKER:
            case SND_DEVICE_HEADSET_AND_SPEAKER:
                acdb_id = ACDB_ID_EXT_MIC_REC;
                break;
            case SND_DEVICE_HANDSET:
            case SND_DEVICE_NO_MIC_HEADSET:
            case SND_DEVICE_SPEAKER:
                if (vr_mode_enabled == 0) {
                    acdb_id = ACDB_ID_INT_MIC_REC;
                } else {
                    acdb_id = ACDB_ID_INT_MIC_VR;
                }
                break;
            case SND_DEVICE_SPEAKER_BACK_MIC:
            case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC:
            case SND_DEVICE_HANDSET_BACK_MIC:
            case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC:
                acdb_id = ACDB_ID_CAMCORDER;
                break;
            default:
                break;
        }
    }
    ALOGV("getACDB, return ID %d\n", acdb_id);
    return acdb_id;
}

status_t AudioHardware::do_tpa2018_control(int mode)
{
    if (curr_out_device == HANDSET_SPKR ||
        curr_out_device == SPKR_PHONE_MONO ||
        curr_out_device == HEADSET_SPKR_STEREO ||
        curr_out_device == SPKR_PHONE_HEADSET_STEREO ||
        curr_out_device == FM_SPKR) {

	int fd, rc;
        int retry = 3;

        switch (mode) {
        case AudioSystem::MODE_NORMAL:
            mode = TPA2018_MODE_PLAYBACK;
            break;
        case AudioSystem::MODE_RINGTONE:
            mode = TPA2018_MODE_RINGTONE;
            break;
        case AudioSystem::MODE_IN_CALL:
            mode = TPA2018_MODE_VOICE_CALL;
            break;
        default:
            return 0;
        }

        fd = open("/dev/tpa2018d1", O_RDWR);
        if (fd < 0) {
            ALOGE("can't open /dev/tpa2018d1 %d", fd);
            return -1;
        }

        do {
            rc = ioctl(fd, TPA2018_SET_MODE, &mode);
            if (!rc)
                break;
        } while (--retry);

        if (rc < 0) {
            ALOGE("ioctl TPA2018_SET_MODE failed: %s", strerror(errno));
        } else
            ALOGD("Update TPA2018_SET_MODE to mode %d success", mode);

        close(fd);
    }
    return 0;
}

status_t AudioHardware::doAudience_A1026_Control(int Mode, bool Record, uint32_t Routes)
{
    int rc = 0;
    int retry = 4;

    if (!mA1026Init) {
        ALOGW("Audience A1026 not initialized.\n");
        return NO_INIT;
    }

    mA1026Lock.lock();
    if (fd_a1026 < 0) {
        fd_a1026 = open("/dev/audience_a1026", O_RDWR);
        if (fd_a1026 < 0) {
            ALOGE("Cannot open audience_a1026 device (%d)\n", fd_a1026);
            mA1026Lock.unlock();
            return -1;
        }
    }

    if ((Mode < AudioSystem::MODE_CURRENT) || (Mode >= AudioSystem::NUM_MODES)) {
        ALOGW("Illegal value: doAudience_A1026_Control(%d, %u, %u)", Mode, Record, Routes);
        mA1026Lock.unlock();
        return BAD_VALUE;
    }

    if (Mode == AudioSystem::MODE_IN_CALL) {
        if (Record == 1) {
	    switch (Routes) {
	        case SND_DEVICE_HANDSET:
	        case SND_DEVICE_NO_MIC_HEADSET:
	            //TODO: what do we do for camcorder when in call?
	        case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC:
	        case SND_DEVICE_HANDSET_BACK_MIC:
	        case SND_DEVICE_TTY_VCO:
	            if (enable1026) {
                    new_pathid = A1026_PATH_INCALL_RECEIVER;
                    ALOGV("A1026 control: new path is A1026_PATH_INCALL_RECEIVER");
	            } else {
	                new_pathid = A1026_PATH_INCALL_NO_NS_RECEIVER;
	                ALOGV("A1026 control: new path is A1026_PATH_INCALL_NO_NS_RECEIVER");
	            }
	            break;
	        case SND_DEVICE_HEADSET:
	        case SND_DEVICE_HEADSET_AND_SPEAKER:
	        case SND_DEVICE_FM_HEADSET:
	        case SND_DEVICE_FM_SPEAKER:
	        case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC:
	            new_pathid = A1026_PATH_INCALL_HEADSET;
	            ALOGV("A1026 control: new path is A1026_PATH_INCALL_HEADSET");
	            break;
	        case SND_DEVICE_SPEAKER:
	            //TODO: what do we do for camcorder when in call?
	        case SND_DEVICE_SPEAKER_BACK_MIC:
	            new_pathid = A1026_PATH_INCALL_SPEAKER;
	            ALOGV("A1026 control: new path is A1026_PATH_INCALL_SPEAKER");
	            break;
	        case SND_DEVICE_BT:
	        case SND_DEVICE_BT_EC_OFF:
	        case SND_DEVICE_CARKIT:
	            new_pathid = A1026_PATH_INCALL_BT;
	            ALOGV("A1026 control: new path is A1026_PATH_INCALL_BT");
	            break;
	        case SND_DEVICE_TTY_HCO:
	        case SND_DEVICE_TTY_FULL:
	            new_pathid = A1026_PATH_INCALL_TTY;
	            ALOGV("A1026 control: new path is A1026_PATH_INCALL_TTY");
	            break;
	        default:
	            break;
            }
       } else {
           switch (Routes) {
	        case SND_DEVICE_HANDSET:
	        case SND_DEVICE_NO_MIC_HEADSET:
	        case SND_DEVICE_TTY_VCO:
	            if (enable1026) {
	                new_pathid = A1026_PATH_INCALL_RECEIVER; /* NS CT mode, Dual MIC */
                    ALOGV("A1026 control: new path is A1026_PATH_INCALL_RECEIVER");
	            } else {
	                new_pathid = A1026_PATH_INCALL_NO_NS_RECEIVER;
	                ALOGV("A1026 control: new path is A1026_PATH_INCALL_NO_NS_RECEIVER");
	            }
	            break;
	        case SND_DEVICE_HEADSET:
	        case SND_DEVICE_HEADSET_AND_SPEAKER:
	        case SND_DEVICE_FM_HEADSET:
	        case SND_DEVICE_FM_SPEAKER:
	            new_pathid = A1026_PATH_INCALL_HEADSET; /* NS disable, Headset MIC */
	            ALOGV("A1026 control: new path is A1026_PATH_INCALL_HEADSET");
	            break;
	        case SND_DEVICE_SPEAKER:
	            new_pathid = A1026_PATH_INCALL_SPEAKER; /* NS FT mode, Main MIC */
	            ALOGV("A1026 control: new path is A1026_PATH_INCALL_SPEAKER");
	            break;
	        case SND_DEVICE_BT:
	        case SND_DEVICE_BT_EC_OFF:
	        case SND_DEVICE_CARKIT:
	            new_pathid = A1026_PATH_INCALL_BT; /* QCOM NS, BT MIC */
	            ALOGV("A1026 control: new path is A1026_PATH_INCALL_BT");
	            break;
	        case SND_DEVICE_TTY_HCO:
	        case SND_DEVICE_TTY_FULL:
	            new_pathid = A1026_PATH_INCALL_TTY;
	            ALOGV("A1026 control: new path is A1026_PATH_INCALL_TTY");
	            break;
	        default:
	            break;
            }
       }
    } else if (Record == 1) {
        switch (Routes) {
        case SND_DEVICE_SPEAKER:
            // default output is speaker, recording from phone mic, user RECEIVER configuration
        case SND_DEVICE_HANDSET:
        case SND_DEVICE_NO_MIC_HEADSET:
	        if (vr_mode_enabled) {
	            if (vr_uses_ns) {
	                new_pathid = A1026_PATH_VR_NS_RECEIVER;
	                ALOGV("A1026 control: new path is A1026_PATH_VR_NS_RECEIVER");
	            } else {
	                new_pathid = A1026_PATH_VR_NO_NS_RECEIVER;
	                ALOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_RECEIVER");
	            }
	        } else {
	            new_pathid = A1026_PATH_RECORD_RECEIVER; /* INT-MIC Recording: NS disable, Main MIC */
                ALOGV("A1026 control: new path is A1026_PATH_RECORD_RECEIVER");
	        }
	        break;
        case SND_DEVICE_HEADSET:
        case SND_DEVICE_HEADSET_AND_SPEAKER:
        case SND_DEVICE_FM_HEADSET:
        case SND_DEVICE_FM_SPEAKER:
	        if (vr_mode_enabled) {
	            if (vr_uses_ns) {
	                new_pathid = A1026_PATH_VR_NS_HEADSET;
	                ALOGV("A1026 control: new path is A1026_PATH_VR_NS_HEADSET");
	            } else {
	                new_pathid = A1026_PATH_VR_NO_NS_HEADSET;
	                ALOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_HEADSET");
	            }
	        } else {
	            new_pathid = A1026_PATH_RECORD_HEADSET; /* EXT-MIC Recording: NS disable, Headset MIC */
	            ALOGV("A1026 control: new path is A1026_PATH_RECORD_HEADSET");
	        }
	        break;
        case SND_DEVICE_SPEAKER_BACK_MIC:
        case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC:
        case SND_DEVICE_HANDSET_BACK_MIC:
        case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC:
	        new_pathid = A1026_PATH_CAMCORDER; /* CAM-Coder: NS FT mode, Back MIC */
	        ALOGV("A1026 control: new path is A1026_PATH_CAMCORDER");
	        break;
        case SND_DEVICE_BT:
        case SND_DEVICE_BT_EC_OFF:
        case SND_DEVICE_CARKIT:
	        if (vr_mode_enabled) {
	            if (vr_uses_ns) {
	                new_pathid = A1026_PATH_VR_NS_BT;
	                ALOGV("A1026 control: new path is A1026_PATH_VR_NS_BT");
	            } else {
	                new_pathid = A1026_PATH_VR_NO_NS_BT;
	                ALOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_BT");
	            }
	        } else {
	            new_pathid = A1026_PATH_RECORD_BT; /* BT MIC */
	            ALOGV("A1026 control: new path is A1026_PATH_RECORD_BT");
	        }
	        break;
        default:
	        break;
        }
    }
    else {
        switch (Routes) {
        case SND_DEVICE_BT:
        case SND_DEVICE_BT_EC_OFF:
        case SND_DEVICE_CARKIT:
            new_pathid = A1026_PATH_RECORD_BT; /* BT MIC */
            ALOGV("A1026 control: new path is A1026_PATH_RECORD_BT");
            break;
        default:
            new_pathid = A1026_PATH_SUSPEND;
            break;
        }
    }

    if (old_pathid != new_pathid) {
        //ALOGI("A1026: do ioctl(A1026_SET_CONFIG) to %d\n", new_pathid);
        do {
            rc = ioctl(fd_a1026, A1026_SET_CONFIG, &new_pathid);
            if (!rc) {
                old_pathid = new_pathid;
                break;
            }
        } while (--retry);

        if (rc < 0) {
            ALOGW("A1026 do hard reset to recover from error!\n");
            rc = doA1026_init(); /* A1026 needs to do hard reset! */
            if (!rc) {
                /* after doA1026_init(), fd_a1026 is -1*/
                fd_a1026 = open("/dev/audience_a1026", O_RDWR);
                if (fd_a1026 < 0) {
                    ALOGE("A1026 Fatal Error: unable to open A1026 after hard reset\n");
                } else {
                    rc = ioctl(fd_a1026, A1026_SET_CONFIG, &new_pathid);
                    if (!rc) {
                        old_pathid = new_pathid;
                    } else {
                        ALOGE("A1026 Fatal Error: unable to A1026_SET_CONFIG after hard reset\n");
                    }
                }
            } else
                ALOGE("A1026 Fatal Error: Re-init A1026 Failed\n");
        }
    }

    if (fd_a1026 >= 0) {
        close(fd_a1026);
    }
    fd_a1026 = -1;
    mA1026Lock.unlock();

    return rc;
}


status_t AudioHardware::doRouting()
{
    Mutex::Autolock lock(mLock);
    uint32_t outputDevices = mOutput->devices();
    status_t ret = NO_ERROR;
    AudioStreamInMSM72xx *input = getActiveInput_l();
    uint32_t inputDevice = (input == NULL) ? 0 : input->devices();
    int sndDevice = -1;

    if (mMode == AudioSystem::MODE_IN_CALL && mTTYMode != TTY_MODE_OFF) {
        if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
            (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
            switch (mTTYMode) {
            case TTY_MODE_FULL:
                sndDevice = SND_DEVICE_TTY_FULL;
                break;
            case TTY_MODE_VCO:
                sndDevice = SND_DEVICE_TTY_VCO;
                break;
            case TTY_MODE_HCO:
                sndDevice = SND_DEVICE_TTY_HCO;
                break;
            }
        }
    }

    if (sndDevice == -1 && inputDevice != 0) {
        ALOGI("do input routing device %x\n", inputDevice);
        if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
            ALOGI("Routing audio to Bluetooth PCM\n");
            sndDevice = SND_DEVICE_BT;
        } else if (inputDevice & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
            ALOGI("Routing audio to Bluetooth car kit\n");
            sndDevice = SND_DEVICE_CARKIT;
        } else if (inputDevice & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
            if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) &&
                    (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) {
                        ALOGI("Routing audio to Wired Headset and Speaker\n");
                        sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
            } else {
                ALOGI("Routing audio to Wired Headset\n");
                sndDevice = SND_DEVICE_HEADSET;
            }
        } else if (inputDevice & AudioSystem::DEVICE_IN_BACK_MIC) {
            if (outputDevices & (AudioSystem:: DEVICE_OUT_WIRED_HEADSET) &&
                   (outputDevices & AudioSystem:: DEVICE_OUT_SPEAKER)) {
                ALOGI("Routing audio to Wired Headset and Speaker with back mic\n");
                sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC;
            } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
                ALOGI("Routing audio to Speakerphone with back mic\n");
                sndDevice = SND_DEVICE_SPEAKER_BACK_MIC;
            } else if (outputDevices == AudioSystem::DEVICE_OUT_EARPIECE) {
                ALOGI("Routing audio to Handset with back mic\n");
                sndDevice = SND_DEVICE_HANDSET_BACK_MIC;
            } else {
                ALOGI("Routing audio to Headset with back mic\n");
                sndDevice = SND_DEVICE_NO_MIC_HEADSET_BACK_MIC;
            }
        } else {
            if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
                ALOGI("Routing audio to Speakerphone\n");
                sndDevice = SND_DEVICE_SPEAKER;
            } else if (outputDevices == AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
                ALOGI("Routing audio to Speakerphone\n");
                sndDevice = SND_DEVICE_NO_MIC_HEADSET;
            } else {
                ALOGI("Routing audio to Handset\n");
                sndDevice = SND_DEVICE_HANDSET;
            }
        }
    }
    // if inputDevice == 0, restore output routing

    if (sndDevice == -1) {
        if (outputDevices & (outputDevices - 1)) {
            if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) {
                ALOGW("Hardware does not support requested route combination (%#X),"
                        " picking closest possible route...", outputDevices);
            }
        }

        if (outputDevices &
                (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) {
                    ALOGI("Routing audio to Bluetooth PCM\n");
                    sndDevice = SND_DEVICE_BT;
        } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
            ALOGI("Routing audio to Bluetooth PCM\n");
            sndDevice = SND_DEVICE_CARKIT;
        } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) &&
                (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) {
                    ALOGI("Routing audio to Wired Headset and Speaker\n");
                    sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
        } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
            if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
                ALOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices);
                sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
            } else {
                ALOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices);
                sndDevice = SND_DEVICE_NO_MIC_HEADSET;
            }
        } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) {
            ALOGI("Routing audio to Wired Headset\n");
            sndDevice = SND_DEVICE_HEADSET;
        } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
            ALOGI("Routing audio to Speakerphone\n");
            sndDevice = SND_DEVICE_SPEAKER;
        } else {
            ALOGI("Routing audio to Handset\n");
            sndDevice = SND_DEVICE_HANDSET;
        }
    }

    if ((vr_mode_change) || (sndDevice != -1 && sndDevice != mCurSndDevice)) {
        ret = doAudioRouteOrMute(sndDevice);
        mCurSndDevice = sndDevice;
        if (mMode == AudioSystem::MODE_IN_CALL) {
            if (mHACSetting && hac_enable && mCurSndDevice == (int) SND_DEVICE_HANDSET) {
                ALOGD("HAC enable: Setting in-call volume to maximum.\n");
                set_volume_rpc(VOICE_VOLUME_MAX);
            } else {
                set_volume_rpc(mVoiceVolume);
            }
        }
    }

    return ret;
}

status_t AudioHardware::checkMicMute()
{
    Mutex::Autolock lock(mLock);
    if (mMode != AudioSystem::MODE_IN_CALL) {
        setMicMute_nosync(true);
    }

    return NO_ERROR;
}

status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;
    result.append("AudioHardware::dumpInternals\n");
    snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false");
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false");
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmBluetoothIdtx: %d\n", mBluetoothIdTx);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmBluetoothIdrx: %d\n", mBluetoothIdRx);
    result.append(buffer);
    ::write(fd, result.string(), result.size());
    return NO_ERROR;
}

status_t AudioHardware::dump(int fd, const Vector<String16>& args)
{
    dumpInternals(fd, args);
    for (size_t index = 0; index < mInputs.size(); index++) {
        mInputs[index]->dump(fd, args);
    }

    if (mOutput) {
        mOutput->dump(fd, args);
    }
    return NO_ERROR;
}

uint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate)
{
    uint32_t i;
    uint32_t prevDelta;
    uint32_t delta;

    for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) {
        delta = abs(sampleRate - inputSamplingRates[i]);
        if (delta > prevDelta) break;
    }
    // i is always > 0 here
    return inputSamplingRates[i-1];
}

// getActiveInput_l() must be called with mLock held
AudioHardware::AudioStreamInMSM72xx *AudioHardware::getActiveInput_l()
{
    for (size_t i = 0; i < mInputs.size(); i++) {
        // return first input found not being in standby mode
        // as only one input can be in this state
        if (!mInputs[i]->checkStandby()) {
            return mInputs[i];
        }
    }

    return NULL;
}
// ----------------------------------------------------------------------------

AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() :
    mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true),
    mDevices(0), mChannels(AUDIO_HW_OUT_CHANNELS), mSampleRate(AUDIO_HW_OUT_SAMPLERATE),
    mBufferSize(AUDIO_HW_OUT_BUFSZ)
{
}

status_t AudioHardware::AudioStreamOutMSM72xx::set(
        AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate)
{
    int lFormat = pFormat ? *pFormat : 0;
    uint32_t lChannels = pChannels ? *pChannels : 0;
    uint32_t lRate = pRate ? *pRate : 0;

    mHardware = hw;
    mDevices = devices;

    // fix up defaults
    if (lFormat == 0) lFormat = format();
    if (lChannels == 0) lChannels = channels();
    if (lRate == 0) lRate = sampleRate();

    // check values
    if ((lFormat != format()) ||
        (lChannels != channels()) ||
        (lRate != sampleRate())) {
        if (pFormat) *pFormat = format();
        if (pChannels) *pChannels = channels();
        if (pRate) *pRate = sampleRate();
        return BAD_VALUE;
    }

    if (pFormat) *pFormat = lFormat;
    if (pChannels) *pChannels = lChannels;
    if (pRate) *pRate = lRate;

    mChannels = lChannels;
    mSampleRate = lRate;
    mBufferSize = hw->getBufferSize(lRate, AudioSystem::popCount(lChannels));

    return NO_ERROR;
}

AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx()
{
    standby();
}

ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes)
{
    // ALOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes);
    status_t status = NO_INIT;
    size_t count = bytes;
    const uint8_t* p = static_cast<const uint8_t*>(buffer);

    if (mStandby) {

        ALOGV("acquire output wakelock");
        acquire_wake_lock(PARTIAL_WAKE_LOCK, kOutputWakelockStr);

        // open driver
        ALOGV("open pcm_out driver");
        status = ::open("/dev/msm_pcm_out", O_RDWR);
        if (status < 0) {
            if (errCount++ < 10) {
                ALOGE("Cannot open /dev/msm_pcm_out errno: %d", errno);
            }
            release_wake_lock(kOutputWakelockStr);
            goto Error;
        }
        mFd = status;
        mStandby = false;

        // configuration
        ALOGV("get config");
        struct msm_audio_config config;
        status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
        if (status < 0) {
            ALOGE("Cannot read pcm_out config");
            goto Error;
        }

        ALOGV("set pcm_out config");
        config.channel_count = AudioSystem::popCount(channels());
        config.sample_rate = mSampleRate;
        config.buffer_size = mBufferSize;
        config.buffer_count = AUDIO_HW_NUM_OUT_BUF;
        config.codec_type = CODEC_TYPE_PCM;
        status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
        if (status < 0) {
            ALOGE("Cannot set config");
            goto Error;
        }

        ALOGV("buffer_size: %u", config.buffer_size);
        ALOGV("buffer_count: %u", config.buffer_count);
        ALOGV("channel_count: %u", config.channel_count);
        ALOGV("sample_rate: %u", config.sample_rate);

        uint32_t acdb_id = mHardware->getACDB(MOD_PLAY, mHardware->get_snd_dev());
        status = ioctl(mFd, AUDIO_START, &acdb_id);
        if (status < 0) {
            ALOGE("Cannot start pcm playback");
            goto Error;
        }

        status = ioctl(mFd, AUDIO_SET_VOLUME, &stream_volume);
        if (status < 0) {
            ALOGE("Cannot start pcm playback");
            goto Error;
        }
    }

    while (count) {
        ssize_t written = ::write(mFd, p, count);
        if (written >= 0) {
            count -= written;
            p += written;
        } else {
            if (errno != EAGAIN) {
                status = written;
                goto Error;
            }
            mRetryCount++;
            ALOGD("EAGAIN - retry");
        }
    }

    return bytes;

Error:

    standby();

    // Simulate audio output timing in case of error
    usleep((((bytes * 1000) / frameSize()) * 1000) / sampleRate());
    return status;
}

status_t AudioHardware::AudioStreamOutMSM72xx::standby()
{
    if (!mStandby) {
        ALOGD("AudioHardware pcm playback is going to standby.");
        if (mFd >= 0) {
            ::close(mFd);
            mFd = -1;
        }
        ALOGV("release output wakelock");
        release_wake_lock(kOutputWakelockStr);
        mStandby = true;
    }
    return NO_ERROR;
}

status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;
    result.append("AudioStreamOutMSM72xx::dump\n");
    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
    result.append(buffer);
    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
    result.append(buffer);
    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
    result.append(buffer);
    snprintf(buffer, SIZE, "\tformat: %d\n", format());
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false");
    result.append(buffer);
    ::write(fd, result.string(), result.size());
    return NO_ERROR;
}


bool AudioHardware::AudioStreamOutMSM72xx::checkStandby()
{
    return mStandby;
}


status_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs)
{
    AudioParameter param = AudioParameter(keyValuePairs);
    String8 key = String8(AudioParameter::keyRouting);
    status_t status = NO_ERROR;
    int device;
    ALOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string());

    if (param.getInt(key, device) == NO_ERROR) {
        mDevices = device;
        ALOGV("set output routing %x", mDevices);
        status = mHardware->doRouting();
        param.remove(key);
    }

    if (param.size()) {
        status = BAD_VALUE;
    }
    return status;
}

String8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys)
{
    AudioParameter param = AudioParameter(keys);
    String8 value;
    String8 key = String8(AudioParameter::keyRouting);

    if (param.get(key, value) == NO_ERROR) {
        ALOGV("get routing %x", mDevices);
        param.addInt(key, (int)mDevices);
    }

    ALOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string());
    return param.toString();
}

status_t AudioHardware::AudioStreamOutMSM72xx::getRenderPosition(uint32_t *dspFrames)
{
    //TODO: enable when supported by driver
    return INVALID_OPERATION;
}

// ----------------------------------------------------------------------------

AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() :
    mHardware(0), mFd(-1), mStandby(true), mRetryCount(0),
    mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS),
    mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFSZ),
    mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0)
{
}

status_t AudioHardware::AudioStreamInMSM72xx::set(
        AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate,
        AudioSystem::audio_in_acoustics acoustic_flags)
{
    if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) {
        *pFormat = AUDIO_HW_IN_FORMAT;
        return BAD_VALUE;
    }
    if (pRate == 0) {
        return BAD_VALUE;
    }
    uint32_t rate = hw->getInputSampleRate(*pRate);
    if (rate != *pRate) {
        *pRate = rate;
        return BAD_VALUE;
    }

    if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO &&
        *pChannels != AudioSystem::CHANNEL_IN_STEREO)) {
        *pChannels = AUDIO_HW_IN_CHANNELS;
        return BAD_VALUE;
    }

    mHardware = hw;

    ALOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate);
    if (mFd >= 0) {
        ALOGE("Audio record already open");
        return -EPERM;
    }

    mBufferSize = hw->getBufferSize(*pRate, AudioSystem::popCount(*pChannels));
    mDevices = devices;
    mFormat = AUDIO_HW_IN_FORMAT;
    mChannels = *pChannels;
    mSampleRate = *pRate;

    return NO_ERROR;

}

AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx()
{
    ALOGV("AudioStreamInMSM72xx destructor");
    standby();
}

ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes)
{
//    ALOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes);
    if (!mHardware) return -1;

    size_t count = bytes;
    uint8_t* p = static_cast<uint8_t*>(buffer);
    status_t status = NO_ERROR;

    if (mStandby) {
        {   // scope for the lock
            Mutex::Autolock lock(mHardware->mLock);
            ALOGV("acquire input wakelock");
            acquire_wake_lock(PARTIAL_WAKE_LOCK, kInputWakelockStr);
            // open audio input device
            status = ::open("/dev/msm_pcm_in", O_RDWR);
            if (status < 0) {
                ALOGE("Cannot open /dev/msm_pcm_in errno: %d", errno);
                ALOGV("release input wakelock");
                release_wake_lock(kInputWakelockStr);
                goto Error;
            }
            mFd = status;
            mStandby = false;

            // configuration
            ALOGV("get config");
            struct msm_audio_config config;
            status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
            if (status < 0) {
                ALOGE("Cannot read config");
                goto Error;
            }

            ALOGV("set config");
            config.channel_count = AudioSystem::popCount(mChannels);
            config.sample_rate = mSampleRate;
            config.buffer_size = mBufferSize;
            config.buffer_count = 2;
            config.codec_type = CODEC_TYPE_PCM;
            status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
            if (status < 0) {
                ALOGE("Cannot set config");
                goto Error;
            }

            ALOGV("buffer_size: %u", config.buffer_size);
            ALOGV("buffer_count: %u", config.buffer_count);
            ALOGV("channel_count: %u", config.channel_count);
            ALOGV("sample_rate: %u", config.sample_rate);
        }

        mHardware->set_mRecordState(1);
        // make sure a1026 config is re-applied even is input device is not changed
        mHardware->clearCurDevice();
        mHardware->doRouting();

        uint32_t acdb_id = mHardware->getACDB(MOD_REC, mHardware->get_snd_dev());
        if (ioctl(mFd, AUDIO_START, &acdb_id)) {
            ALOGE("Error starting record");
            goto Error;
        }
    }

    while (count) {
        ssize_t bytesRead = ::read(mFd, buffer, count);
        if (bytesRead >= 0) {
            count -= bytesRead;
            p += bytesRead;
        } else {
            if (errno != EAGAIN) {
                status = bytesRead;
                goto Error;
            }
            mRetryCount++;
            ALOGD("EAGAIN - retrying");
        }
    }
    return bytes;

Error:
    standby();

    // Simulate audio input timing in case of error
    usleep((((bytes * 1000) / frameSize()) * 1000) / sampleRate());

    return status;
}

status_t AudioHardware::AudioStreamInMSM72xx::standby()
{
    if (!mStandby) {
        ALOGD("AudioHardware PCM record is going to standby.");
        if (mFd >= 0) {
            ::close(mFd);
            mFd = -1;
        }
        ALOGV("release input wakelock");
        release_wake_lock(kInputWakelockStr);

        mStandby = true;

        if (!mHardware) return -1;

        mHardware->set_mRecordState(0);
        // make sure a1026 config is re-applied even is input device is not changed
        mHardware->clearCurDevice();
        mHardware->doRouting();
    }

    return NO_ERROR;
}

bool AudioHardware::AudioStreamInMSM72xx::checkStandby()
{
    return mStandby;
}

status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
    char buffer[SIZE];
    String8 result;
    result.append("AudioStreamInMSM72xx::dump\n");
    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
    result.append(buffer);
    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
    result.append(buffer);
    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
    result.append(buffer);
    snprintf(buffer, SIZE, "\tformat: %d\n", format());
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmStandby: %d\n", mStandby);
    result.append(buffer);
    snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
    result.append(buffer);
    ::write(fd, result.string(), result.size());
    return NO_ERROR;
}

status_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs)
{
    AudioParameter param = AudioParameter(keyValuePairs);
    status_t status = NO_ERROR;
    int device;
    String8 key = String8(AudioParameter::keyInputSource);
    int source;
    ALOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string());

    // reading input source for voice recognition mode parameter
    if (param.getInt(key, source) == NO_ERROR) {
        ALOGV("set input source %d", source);
        int uses_vr = (source == AUDIO_SOURCE_VOICE_RECOGNITION);
        vr_mode_change = (vr_mode_enabled != uses_vr);
        vr_mode_enabled = uses_vr;
        param.remove(key);
    }

    // reading routing parameter
    key = String8(AudioParameter::keyRouting);
    if (param.getInt(key, device) == NO_ERROR) {
        ALOGV("set input routing %x", device);
        if (device & (device - 1)) {
            status = BAD_VALUE;
        } else {
            mDevices = device;
            status = mHardware->doRouting();
        }
        param.remove(key);
    }

    if (param.size()) {
        status = BAD_VALUE;
    }
    return status;
}

String8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys)
{
    AudioParameter param = AudioParameter(keys);
    String8 value;
    String8 key = String8(AudioParameter::keyRouting);

    if (param.get(key, value) == NO_ERROR) {
        ALOGV("get routing %x", mDevices);
        param.addInt(key, (int)mDevices);
    }

    ALOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string());
    return param.toString();
}

// ----------------------------------------------------------------------------

extern "C" AudioHardwareInterface* createAudioHardware(void) {
    return new AudioHardware();
}

}; // namespace android
